示例#1
0
/*
 * Net VSC receiving vRSS send table from VSP
 */
static void
hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
{
	netvsc_dev *net_dev;
	const nvsp_msg *nvsp_msg_pkt;
	int i;
	uint32_t count;
	const uint32_t *table;

	net_dev = hv_nv_get_inbound_net_device(sc);
	if (!net_dev)
        	return;

	nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);

	if (nvsp_msg_pkt->hdr.msg_type !=
	    nvsp_msg5_type_send_indirection_table) {
		printf("Netvsc: !Warning! receive msg type not "
			"send_indirection_table. type = %d\n",
			nvsp_msg_pkt->hdr.msg_type);
		return;
	}

	count = nvsp_msg_pkt->msgs.vers_5_msgs.send_table.count;
	if (count != VRSS_SEND_TABLE_SIZE) {
        	printf("Netvsc: Received wrong send table size: %u\n", count);
	        return;
	}

	table = (const uint32_t *)
	    ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
	     nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset);

	for (i = 0; i < count; i++)
        	net_dev->vrss_send_table[i] = table[i];
}
示例#2
0
/*
 * Net VSC on channel callback
 */
static void
hv_nv_on_channel_callback(void *xchan)
{
	struct hv_vmbus_channel *chan = xchan;
	struct hv_device *device = chan->device;
	netvsc_dev *net_dev;
	device_t dev = device->device;
	uint32_t bytes_rxed;
	uint64_t request_id;
 	hv_vm_packet_descriptor *desc;
	uint8_t *buffer;
	int bufferlen = NETVSC_PACKET_SIZE;
	int ret = 0;

	net_dev = hv_nv_get_inbound_net_device(device);
	if (net_dev == NULL)
		return;

	buffer = chan->hv_chan_rdbuf;

	do {
		ret = hv_vmbus_channel_recv_packet_raw(chan,
		    buffer, bufferlen, &bytes_rxed, &request_id);
		if (ret == 0) {
			if (bytes_rxed > 0) {
				desc = (hv_vm_packet_descriptor *)buffer;
				switch (desc->type) {
				case HV_VMBUS_PACKET_TYPE_COMPLETION:
					hv_nv_on_send_completion(net_dev, device, desc);
					break;
				case HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES:
					hv_nv_on_receive(net_dev, device, chan, desc);
					break;
				default:
					device_printf(dev,
					    "hv_cb recv unknow type %d "
					    " packet\n", desc->type);
					break;
				}
			} else {
				break;
			}
		} else if (ret == ENOBUFS) {
			/* Handle large packet */
			if (bufferlen > NETVSC_PACKET_SIZE) {
				free(buffer, M_NETVSC);
				buffer = NULL;
			}

			/* alloc new buffer */
			buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
			if (buffer == NULL) {
				device_printf(dev,
				    "hv_cb malloc buffer failed, len=%u\n",
				    bytes_rxed);
				bufferlen = 0;
				break;
			}
			bufferlen = bytes_rxed;
		}
	} while (1);

	if (bufferlen > NETVSC_PACKET_SIZE)
		free(buffer, M_NETVSC);

	hv_rf_channel_rollup(chan);
}
示例#3
0
/*
 * Net VSC on channel callback
 */
static void
hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr)
{
	struct hn_rx_ring *rxr = xrxr;
	struct hn_softc *sc = rxr->hn_ifp->if_softc;
	netvsc_dev *net_dev;
	void *buffer;
	int bufferlen = NETVSC_PACKET_SIZE;

	net_dev = hv_nv_get_inbound_net_device(sc);
	if (net_dev == NULL)
		return;

	buffer = rxr->hn_rdbuf;
	do {
		struct vmbus_chanpkt_hdr *pkt = buffer;
		uint32_t bytes_rxed;
		int ret;

		bytes_rxed = bufferlen;
		ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed);
		if (ret == 0) {
			if (bytes_rxed > 0) {
				switch (pkt->cph_type) {
				case VMBUS_CHANPKT_TYPE_COMP:
					hv_nv_on_send_completion(net_dev, chan,
					    pkt);
					break;
				case VMBUS_CHANPKT_TYPE_RXBUF:
					hv_nv_on_receive(net_dev, rxr, chan, pkt);
					break;
				case VMBUS_CHANPKT_TYPE_INBAND:
					hv_nv_send_table(sc, pkt);
					break;
				default:
					if_printf(rxr->hn_ifp,
					    "unknown chan pkt %u\n",
					    pkt->cph_type);
					break;
				}
			}
		} else if (ret == ENOBUFS) {
			/* Handle large packet */
			if (bufferlen > NETVSC_PACKET_SIZE) {
				free(buffer, M_NETVSC);
				buffer = NULL;
			}

			/* alloc new buffer */
			buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
			if (buffer == NULL) {
				if_printf(rxr->hn_ifp,
				    "hv_cb malloc buffer failed, len=%u\n",
				    bytes_rxed);
				bufferlen = 0;
				break;
			}
			bufferlen = bytes_rxed;
		} else {
			/* No more packets */
			break;
		}
	} while (1);

	if (bufferlen > NETVSC_PACKET_SIZE)
		free(buffer, M_NETVSC);

	hv_rf_channel_rollup(rxr, rxr->hn_txr);
}