View | Details | Raw Unified | Return to bug 203630 | Differences between
and this patch

Collapse All | Expand All

(-)sys/dev/hyperv/netvsc/hv_net_vsc.c (-177 / +294 lines)
Lines 48-54 Link Here
48
#include "hv_rndis.h"
48
#include "hv_rndis.h"
49
#include "hv_rndis_filter.h"
49
#include "hv_rndis_filter.h"
50
50
51
MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
52
51
53
/*
52
/*
54
 * Forward declarations
53
 * Forward declarations
Lines 59-69 Link Here
59
static int  hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
58
static int  hv_nv_destroy_send_buffer(netvsc_dev *net_dev);
60
static int  hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
59
static int  hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
61
static int  hv_nv_connect_to_vsp(struct hv_device *device);
60
static int  hv_nv_connect_to_vsp(struct hv_device *device);
62
static void hv_nv_on_send_completion(netvsc_dev *net_dev,
61
static void hv_nv_on_send_completion(struct hv_device *device,
63
    struct hv_device *device, hv_vm_packet_descriptor *pkt);
62
				     hv_vm_packet_descriptor *pkt);
64
static void hv_nv_on_receive(netvsc_dev *net_dev,
63
static void hv_nv_on_receive(struct hv_device *device,
65
    struct hv_device *device, hv_vm_packet_descriptor *pkt);
64
			     hv_vm_packet_descriptor *pkt);
65
static void hv_nv_send_receive_completion(struct hv_device *device,
66
					  uint64_t tid);
66
67
68
67
/*
69
/*
68
 *
70
 *
69
 */
71
 */
Lines 73-79 Link Here
73
	netvsc_dev *net_dev;
75
	netvsc_dev *net_dev;
74
	hn_softc_t *sc = device_get_softc(device->device);
76
	hn_softc_t *sc = device_get_softc(device->device);
75
77
76
	net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_NOWAIT | M_ZERO);
78
	net_dev = malloc(sizeof(netvsc_dev), M_DEVBUF, M_NOWAIT | M_ZERO);
77
	if (net_dev == NULL) {
79
	if (net_dev == NULL) {
78
		return (NULL);
80
		return (NULL);
79
	}
81
	}
Lines 125-158 Link Here
125
	return (net_dev);
127
	return (net_dev);
126
}
128
}
127
129
128
int
129
hv_nv_get_next_send_section(netvsc_dev *net_dev)
130
{
131
	unsigned long bitsmap_words = net_dev->bitsmap_words;
132
	unsigned long *bitsmap = net_dev->send_section_bitsmap;
133
	unsigned long idx;
134
	int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
135
	int i;
136
137
	for (i = 0; i < bitsmap_words; i++) {
138
		idx = ffs(~bitsmap[i]);
139
		if (0 == idx)
140
			continue;
141
142
		idx--;
143
		if (i * BITS_PER_LONG + idx >= net_dev->send_section_count)
144
			return (ret);
145
146
		if (synch_test_and_set_bit(idx, &bitsmap[i]))
147
			continue;
148
149
		ret = i * BITS_PER_LONG + idx;
150
		break;
151
	}
152
153
	return (ret);
154
}
155
156
/*
130
/*
157
 * Net VSC initialize receive buffer with net VSP
131
 * Net VSC initialize receive buffer with net VSP
158
 * 
132
 * 
Lines 171-178 Link Here
171
		return (ENODEV);
145
		return (ENODEV);
172
	}
146
	}
173
147
174
	net_dev->rx_buf = contigmalloc(net_dev->rx_buf_size, M_NETVSC,
148
	net_dev->rx_buf = contigmalloc(net_dev->rx_buf_size, M_DEVBUF,
175
	    M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
149
	    M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
150
	if (net_dev->rx_buf == NULL) {
151
		ret = ENOMEM;
152
		goto cleanup;
153
	}
176
154
177
	/*
155
	/*
178
	 * Establish the GPADL handle for this buffer on this channel.
156
	 * Establish the GPADL handle for this buffer on this channel.
Lines 223-229 Link Here
223
	    init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
201
	    init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections;
224
202
225
	net_dev->rx_sections = malloc(net_dev->rx_section_count *
203
	net_dev->rx_sections = malloc(net_dev->rx_section_count *
226
	    sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_NOWAIT);
204
	    sizeof(nvsp_1_rx_buf_section), M_DEVBUF, M_NOWAIT);
227
	if (net_dev->rx_sections == NULL) {
205
	if (net_dev->rx_sections == NULL) {
228
		ret = EINVAL;
206
		ret = EINVAL;
229
		goto cleanup;
207
		goto cleanup;
Lines 267-273 Link Here
267
		return (ENODEV);
245
		return (ENODEV);
268
	}
246
	}
269
247
270
	net_dev->send_buf  = contigmalloc(net_dev->send_buf_size, M_NETVSC,
248
	net_dev->send_buf  = contigmalloc(net_dev->send_buf_size, M_DEVBUF,
271
	    M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
249
	    M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0);
272
	if (net_dev->send_buf == NULL) {
250
	if (net_dev->send_buf == NULL) {
273
		ret = ENOMEM;
251
		ret = ENOMEM;
Lines 280-286 Link Here
280
	 * channel to establish the gpadl handle. 
258
	 * channel to establish the gpadl handle. 
281
	 */
259
	 */
282
	ret = hv_vmbus_channel_establish_gpadl(device->channel,
260
	ret = hv_vmbus_channel_establish_gpadl(device->channel,
283
  	    net_dev->send_buf, net_dev->send_buf_size,
261
	    net_dev->send_buf, net_dev->send_buf_size,
284
	    &net_dev->send_buf_gpadl_handle);
262
	    &net_dev->send_buf_gpadl_handle);
285
	if (ret != 0) {
263
	if (ret != 0) {
286
		goto cleanup;
264
		goto cleanup;
Lines 301-307 Link Here
301
	/* Send the gpadl notification request */
279
	/* Send the gpadl notification request */
302
280
303
	ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
281
	ret = hv_vmbus_channel_send_packet(device->channel, init_pkt,
304
  	    sizeof(nvsp_msg), (uint64_t)init_pkt,
282
	    sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt,
305
	    HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
283
	    HV_VMBUS_PACKET_TYPE_DATA_IN_BAND,
306
	    HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
284
	    HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
307
	if (ret != 0) {
285
	if (ret != 0) {
Lines 319-335 Link Here
319
297
320
	net_dev->send_section_size =
298
	net_dev->send_section_size =
321
	    init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
299
	    init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size;
322
	net_dev->send_section_count =
323
	    net_dev->send_buf_size / net_dev->send_section_size;
324
	net_dev->bitsmap_words = howmany(net_dev->send_section_count,
325
	    BITS_PER_LONG);
326
	net_dev->send_section_bitsmap =
327
	    malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC,
328
	    M_NOWAIT | M_ZERO);
329
	if (NULL == net_dev->send_section_bitsmap) {
330
		ret = ENOMEM;
331
		goto cleanup;
332
	}
333
300
334
	goto exit;
301
	goto exit;
335
302
Lines 394-405 Link Here
394
361
395
	if (net_dev->rx_buf) {
362
	if (net_dev->rx_buf) {
396
		/* Free up the receive buffer */
363
		/* Free up the receive buffer */
397
		contigfree(net_dev->rx_buf, net_dev->rx_buf_size, M_NETVSC);
364
		contigfree(net_dev->rx_buf, net_dev->rx_buf_size, M_DEVBUF);
398
		net_dev->rx_buf = NULL;
365
		net_dev->rx_buf = NULL;
399
	}
366
	}
400
367
401
	if (net_dev->rx_sections) {
368
	if (net_dev->rx_sections) {
402
		free(net_dev->rx_sections, M_NETVSC);
369
		free(net_dev->rx_sections, M_DEVBUF);
403
		net_dev->rx_sections = NULL;
370
		net_dev->rx_sections = NULL;
404
		net_dev->rx_section_count = 0;
371
		net_dev->rx_section_count = 0;
405
	}
372
	}
Lines 462-475 Link Here
462
429
463
	if (net_dev->send_buf) {
430
	if (net_dev->send_buf) {
464
		/* Free up the receive buffer */
431
		/* Free up the receive buffer */
465
		contigfree(net_dev->send_buf, net_dev->send_buf_size, M_NETVSC);
432
		contigfree(net_dev->send_buf, net_dev->send_buf_size, M_DEVBUF);
466
		net_dev->send_buf = NULL;
433
		net_dev->send_buf = NULL;
467
	}
434
	}
468
435
469
	if (net_dev->send_section_bitsmap) {
470
		free(net_dev->send_section_bitsmap, M_NETVSC);
471
	}
472
473
	return (ret);
436
	return (ret);
474
}
437
}
475
438
Lines 483-489 Link Here
483
 */
446
 */
484
static int
447
static int
485
hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
448
hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev,
486
    uint32_t nvsp_ver)
449
			      uint32_t nvsp_ver)
487
{
450
{
488
	nvsp_msg *init_pkt;
451
	nvsp_msg *init_pkt;
489
	int ret;
452
	int ret;
Lines 560-572 Link Here
560
{
523
{
561
	netvsc_dev *net_dev;
524
	netvsc_dev *net_dev;
562
	nvsp_msg *init_pkt;
525
	nvsp_msg *init_pkt;
526
	uint32_t nvsp_vers;
563
	uint32_t ndis_version;
527
	uint32_t ndis_version;
564
	uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1,
565
	    NVSP_PROTOCOL_VERSION_2,
566
	    NVSP_PROTOCOL_VERSION_4,
567
	    NVSP_PROTOCOL_VERSION_5 };
568
	int i;
569
	int protocol_number = nitems(protocol_list);
570
	int ret = 0;
528
	int ret = 0;
571
	device_t dev = device->device;
529
	device_t dev = device->device;
572
	hn_softc_t *sc = device_get_softc(dev);
530
	hn_softc_t *sc = device_get_softc(dev);
Lines 578-608 Link Here
578
	}
536
	}
579
537
580
	/*
538
	/*
581
	 * Negotiate the NVSP version.  Try the latest NVSP first.
539
	 * Negotiate the NVSP version.  Try NVSP v2 first.
582
	 */
540
	 */
583
	for (i = protocol_number - 1; i >= 0; i--) {
541
	nvsp_vers = NVSP_PROTOCOL_VERSION_2;
584
		if (hv_nv_negotiate_nvsp_protocol(device, net_dev,
542
	ret = hv_nv_negotiate_nvsp_protocol(device, net_dev, nvsp_vers);
585
		    protocol_list[i]) == 0) {
543
	if (ret != 0) {
586
			net_dev->nvsp_version = protocol_list[i];
544
		/* NVSP v2 failed, try NVSP v1 */
587
			if (bootverbose)
545
		nvsp_vers = NVSP_PROTOCOL_VERSION_1;
588
				device_printf(dev, "Netvsc: got version 0x%x\n",
546
		ret = hv_nv_negotiate_nvsp_protocol(device, net_dev, nvsp_vers);
589
				    net_dev->nvsp_version);
547
		if (ret != 0) {
590
			break;
548
			/* NVSP v1 failed, return bad status */
549
			return (ret);
591
		}
550
		}
592
	}
551
	}
552
	net_dev->nvsp_version = nvsp_vers;
593
553
594
	if (i < 0) {
595
		if (bootverbose)
596
			device_printf(dev, "failed to negotiate a valid "
597
			    "protocol.\n");
598
		return (EPROTO);
599
	}
600
601
	/*
554
	/*
602
	 * Set the MTU if supported by this NVSP protocol version
555
	 * Set the MTU if supported by this NVSP protocol version
603
	 * This needs to be right after the NVSP init message per Haiyang
556
	 * This needs to be right after the NVSP init message per Haiyang
604
	 */
557
	 */
605
	if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
558
	if (nvsp_vers >= NVSP_PROTOCOL_VERSION_2)
606
		ret = hv_nv_send_ndis_config(device, ifp->if_mtu);
559
		ret = hv_nv_send_ndis_config(device, ifp->if_mtu);
607
560
608
	/*
561
	/*
Lines 612-622 Link Here
612
565
613
	memset(init_pkt, 0, sizeof(nvsp_msg));
566
	memset(init_pkt, 0, sizeof(nvsp_msg));
614
567
615
	if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) {
568
	/*
616
		ndis_version = NDIS_VERSION_6_1;
569
	 * Updated to version 5.1, minimum, for VLAN per Haiyang
617
	} else {
570
	 */
618
		ndis_version = NDIS_VERSION_6_30;
571
	ndis_version = NDIS_VERSION;
619
	}
620
572
621
	init_pkt->hdr.msg_type = nvsp_msg_1_type_send_ndis_vers;
573
	init_pkt->hdr.msg_type = nvsp_msg_1_type_send_ndis_vers;
622
	init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_major_vers =
574
	init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_major_vers =
Lines 668-674 Link Here
668
hv_nv_on_device_add(struct hv_device *device, void *additional_info)
620
hv_nv_on_device_add(struct hv_device *device, void *additional_info)
669
{
621
{
670
	netvsc_dev *net_dev;
622
	netvsc_dev *net_dev;
671
	int ret = 0;
623
	netvsc_packet *packet;
624
	netvsc_packet *next_packet;
625
	int i, ret = 0;
672
626
673
	net_dev = hv_nv_alloc_net_device(device);
627
	net_dev = hv_nv_alloc_net_device(device);
674
	if (!net_dev)
628
	if (!net_dev)
Lines 676-684 Link Here
676
630
677
	/* Initialize the NetVSC channel extension */
631
	/* Initialize the NetVSC channel extension */
678
	net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
632
	net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
633
	mtx_init(&net_dev->rx_pkt_list_lock, "HV-RPL", NULL,
634
	    MTX_SPIN | MTX_RECURSE);
679
635
680
	net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
636
	net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
681
637
638
	/* Same effect as STAILQ_HEAD_INITIALIZER() static initializer */
639
	STAILQ_INIT(&net_dev->myrx_packet_list);
640
641
	/* 
642
	 * malloc a sufficient number of netvsc_packet buffers to hold
643
	 * a packet list.  Add them to the netvsc device packet queue.
644
	 */
645
	for (i=0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
646
		packet = malloc(sizeof(netvsc_packet) +
647
		    (NETVSC_RECEIVE_SG_COUNT * sizeof(hv_vmbus_page_buffer)),
648
		    M_DEVBUF, M_NOWAIT | M_ZERO);
649
		if (!packet) {
650
			break;
651
		}
652
		STAILQ_INSERT_TAIL(&net_dev->myrx_packet_list, packet,
653
		    mylist_entry);
654
	}
655
682
	sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");
656
	sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");
683
657
684
	/*
658
	/*
Lines 711-717 Link Here
711
	 */
685
	 */
712
	if (net_dev) {
686
	if (net_dev) {
713
		sema_destroy(&net_dev->channel_init_sema);
687
		sema_destroy(&net_dev->channel_init_sema);
714
		free(net_dev, M_NETVSC);
688
689
		packet = STAILQ_FIRST(&net_dev->myrx_packet_list);
690
		while (packet != NULL) {
691
			next_packet = STAILQ_NEXT(packet, mylist_entry);
692
			free(packet, M_DEVBUF);
693
			packet = next_packet;
694
		}
695
		/* Reset the list to initial state */
696
		STAILQ_INIT(&net_dev->myrx_packet_list);
697
698
		mtx_destroy(&net_dev->rx_pkt_list_lock);
699
700
		free(net_dev, M_DEVBUF);
715
	}
701
	}
716
702
717
	return (NULL);
703
	return (NULL);
Lines 723-728 Link Here
723
int
709
int
724
hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
710
hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
725
{
711
{
712
	netvsc_packet *net_vsc_pkt;
713
	netvsc_packet *next_net_vsc_pkt;
726
	hn_softc_t *sc = device_get_softc(device->device);
714
	hn_softc_t *sc = device_get_softc(device->device);
727
	netvsc_dev *net_dev = sc->net_dev;;
715
	netvsc_dev *net_dev = sc->net_dev;;
728
	
716
	
Lines 749-756 Link Here
749
737
750
	hv_vmbus_channel_close(device->channel);
738
	hv_vmbus_channel_close(device->channel);
751
739
740
	/* Release all resources */
741
	net_vsc_pkt = STAILQ_FIRST(&net_dev->myrx_packet_list);
742
	while (net_vsc_pkt != NULL) {
743
		next_net_vsc_pkt = STAILQ_NEXT(net_vsc_pkt, mylist_entry);
744
		free(net_vsc_pkt, M_DEVBUF);
745
		net_vsc_pkt = next_net_vsc_pkt;
746
	}
747
748
	/* Reset the list to initial state */
749
	STAILQ_INIT(&net_dev->myrx_packet_list);
750
751
	mtx_destroy(&net_dev->rx_pkt_list_lock);
752
	sema_destroy(&net_dev->channel_init_sema);
752
	sema_destroy(&net_dev->channel_init_sema);
753
	free(net_dev, M_NETVSC);
753
	free(net_dev, M_DEVBUF);
754
754
755
	return (0);
755
	return (0);
756
}
756
}
Lines 758-770 Link Here
758
/*
758
/*
759
 * Net VSC on send completion
759
 * Net VSC on send completion
760
 */
760
 */
761
static void
761
static void 
762
hv_nv_on_send_completion(netvsc_dev *net_dev,
762
hv_nv_on_send_completion(struct hv_device *device, hv_vm_packet_descriptor *pkt)
763
    struct hv_device *device, hv_vm_packet_descriptor *pkt)
764
{
763
{
764
	netvsc_dev *net_dev;
765
	nvsp_msg *nvsp_msg_pkt;
765
	nvsp_msg *nvsp_msg_pkt;
766
	netvsc_packet *net_vsc_pkt;
766
	netvsc_packet *net_vsc_pkt;
767
767
768
	net_dev = hv_nv_get_inbound_net_device(device);
769
	if (!net_dev) {
770
		return;
771
	}
772
768
	nvsp_msg_pkt =
773
	nvsp_msg_pkt =
769
	    (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3));
774
	    (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3));
770
775
Lines 775-799 Link Here
775
			== nvsp_msg_1_type_send_send_buf_complete) {
780
			== nvsp_msg_1_type_send_send_buf_complete) {
776
		/* Copy the response back */
781
		/* Copy the response back */
777
		memcpy(&net_dev->channel_init_packet, nvsp_msg_pkt,
782
		memcpy(&net_dev->channel_init_packet, nvsp_msg_pkt,
778
		    sizeof(nvsp_msg));
783
		    sizeof(nvsp_msg));			
779
		sema_post(&net_dev->channel_init_sema);
784
		sema_post(&net_dev->channel_init_sema);
780
	} else if (nvsp_msg_pkt->hdr.msg_type ==
785
	} else if (nvsp_msg_pkt->hdr.msg_type ==
781
		    nvsp_msg_1_type_send_rndis_pkt_complete) {
786
				   nvsp_msg_1_type_send_rndis_pkt_complete) {
782
		/* Get the send context */
787
		/* Get the send context */
783
		net_vsc_pkt =
788
		net_vsc_pkt =
784
		    (netvsc_packet *)(unsigned long)pkt->transaction_id;
789
		    (netvsc_packet *)(unsigned long)pkt->transaction_id;
785
		if (NULL != net_vsc_pkt) {
786
			if (net_vsc_pkt->send_buf_section_idx !=
787
			    NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
788
				synch_change_bit(net_vsc_pkt->send_buf_section_idx,
789
				    net_dev->send_section_bitsmap);
790
			}
791
			
792
			/* Notify the layer above us */
793
			net_vsc_pkt->compl.send.on_send_completion(
794
			    net_vsc_pkt->compl.send.send_completion_context);
795
790
796
		}
791
		/* Notify the layer above us */
792
		net_vsc_pkt->compl.send.on_send_completion(
793
		    net_vsc_pkt->compl.send.send_completion_context);
797
794
798
		atomic_subtract_int(&net_dev->num_outstanding_sends, 1);
795
		atomic_subtract_int(&net_dev->num_outstanding_sends, 1);
799
	}
796
	}
Lines 824-833 Link Here
824
		send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
821
		send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
825
	}
822
	}
826
823
824
	/* Not using send buffer section */
827
	send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
825
	send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
828
	    pkt->send_buf_section_idx;
826
	    0xFFFFFFFF;
829
	send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
827
	send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size = 0;
830
	    pkt->send_buf_section_size;
831
828
832
	if (pkt->page_buf_count) {
829
	if (pkt->page_buf_count) {
833
		ret = hv_vmbus_channel_send_packet_pagebuffer(device->channel,
830
		ret = hv_vmbus_channel_send_packet_pagebuffer(device->channel,
Lines 853-933 Link Here
853
 * In the FreeBSD Hyper-V virtual world, this function deals exclusively
850
 * In the FreeBSD Hyper-V virtual world, this function deals exclusively
854
 * with virtual addresses.
851
 * with virtual addresses.
855
 */
852
 */
856
static void
853
static void 
857
hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device,
854
hv_nv_on_receive(struct hv_device *device, hv_vm_packet_descriptor *pkt)
858
    hv_vm_packet_descriptor *pkt)
859
{
855
{
856
	netvsc_dev *net_dev;
860
	hv_vm_transfer_page_packet_header *vm_xfer_page_pkt;
857
	hv_vm_transfer_page_packet_header *vm_xfer_page_pkt;
861
	nvsp_msg *nvsp_msg_pkt;
858
	nvsp_msg *nvsp_msg_pkt;
862
	netvsc_packet vsc_pkt;
859
	netvsc_packet *net_vsc_pkt = NULL;
863
	netvsc_packet *net_vsc_pkt = &vsc_pkt;
860
	unsigned long start;
864
	device_t dev = device->device;
861
	xfer_page_packet *xfer_page_pkt = NULL;
862
	STAILQ_HEAD(PKT_LIST, netvsc_packet_) mylist_head =
863
	    STAILQ_HEAD_INITIALIZER(mylist_head);
865
	int count = 0;
864
	int count = 0;
866
	int i = 0;
865
	int i = 0;
867
	int status = nvsp_status_success;
868
866
867
	net_dev = hv_nv_get_inbound_net_device(device);
868
	if (!net_dev)
869
		return;
870
869
	/*
871
	/*
870
	 * All inbound packets other than send completion should be
872
	 * All inbound packets other than send completion should be
871
	 * xfer page packet.
873
	 * xfer page packet.
872
	 */
874
	 */
873
	if (pkt->type != HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES) {
875
	if (pkt->type != HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES)
874
		device_printf(dev, "packet type %d is invalid!\n", pkt->type);
875
		return;
876
		return;
876
	}
877
877
878
	nvsp_msg_pkt = (nvsp_msg *)((unsigned long)pkt
878
	nvsp_msg_pkt = (nvsp_msg *)((unsigned long)pkt
879
		+ (pkt->data_offset8 << 3));
879
		+ (pkt->data_offset8 << 3));
880
880
881
	/* Make sure this is a valid nvsp packet */
881
	/* Make sure this is a valid nvsp packet */
882
	if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
882
	if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt)
883
		device_printf(dev, "packet hdr type %d is invalid!\n",
884
		    pkt->type);
885
		return;
883
		return;
886
	}
887
	
884
	
888
	vm_xfer_page_pkt = (hv_vm_transfer_page_packet_header *)pkt;
885
	vm_xfer_page_pkt = (hv_vm_transfer_page_packet_header *)pkt;
889
886
890
	if (vm_xfer_page_pkt->transfer_page_set_id !=
887
	if (vm_xfer_page_pkt->transfer_page_set_id
891
	    NETVSC_RECEIVE_BUFFER_ID) {
888
		!= NETVSC_RECEIVE_BUFFER_ID) {
892
		device_printf(dev, "transfer_page_set_id %d is invalid!\n",
893
		    vm_xfer_page_pkt->transfer_page_set_id);
894
		return;
889
		return;
895
	}
890
	}
896
891
897
	count = vm_xfer_page_pkt->range_count;
892
	STAILQ_INIT(&mylist_head);
898
	net_vsc_pkt->device = device;
899
893
894
	/*
895
	 * Grab free packets (range count + 1) to represent this xfer page
896
	 * packet.  +1 to represent the xfer page packet itself.  We grab it
897
	 * here so that we know exactly how many we can fulfill.
898
	 */
899
	mtx_lock_spin(&net_dev->rx_pkt_list_lock);
900
	while (!STAILQ_EMPTY(&net_dev->myrx_packet_list)) {	
901
		net_vsc_pkt = STAILQ_FIRST(&net_dev->myrx_packet_list);
902
		STAILQ_REMOVE_HEAD(&net_dev->myrx_packet_list, mylist_entry);
903
904
		STAILQ_INSERT_TAIL(&mylist_head, net_vsc_pkt, mylist_entry);
905
906
		if (++count == vm_xfer_page_pkt->range_count + 1)
907
			break;
908
	}
909
910
	mtx_unlock_spin(&net_dev->rx_pkt_list_lock);
911
912
	/*
913
	 * We need at least 2 netvsc pkts (1 to represent the xfer page
914
	 * and at least 1 for the range) i.e. we can handle some of the
915
	 * xfer page packet ranges...
916
	 */
917
	if (count < 2) {
918
		/* Return netvsc packet to the freelist */
919
		mtx_lock_spin(&net_dev->rx_pkt_list_lock);
920
		for (i=count; i != 0; i--) {
921
			net_vsc_pkt = STAILQ_FIRST(&mylist_head);
922
			STAILQ_REMOVE_HEAD(&mylist_head, mylist_entry);
923
924
			STAILQ_INSERT_TAIL(&net_dev->myrx_packet_list,
925
			    net_vsc_pkt, mylist_entry);
926
		}
927
		mtx_unlock_spin(&net_dev->rx_pkt_list_lock);
928
929
		hv_nv_send_receive_completion(device,
930
		    vm_xfer_page_pkt->d.transaction_id);
931
932
		return;
933
	}
934
935
	/* Take the first packet in the list */
936
	xfer_page_pkt = (xfer_page_packet *)STAILQ_FIRST(&mylist_head);
937
	STAILQ_REMOVE_HEAD(&mylist_head, mylist_entry);
938
939
	/* This is how many data packets we can supply */
940
	xfer_page_pkt->count = count - 1;
941
900
	/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
942
	/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
901
	for (i = 0; i < count; i++) {
943
	for (i=0; i < (count - 1); i++) {
902
		net_vsc_pkt->status = nvsp_status_success;
944
		net_vsc_pkt = STAILQ_FIRST(&mylist_head);
903
		net_vsc_pkt->data = (void *)((unsigned long)net_dev->rx_buf +
945
		STAILQ_REMOVE_HEAD(&mylist_head, mylist_entry);
904
		    vm_xfer_page_pkt->ranges[i].byte_offset);
946
905
		net_vsc_pkt->tot_data_buf_len = 
947
		/*
948
		 * Initialize the netvsc packet
949
		 */
950
		net_vsc_pkt->xfer_page_pkt = xfer_page_pkt;
951
		net_vsc_pkt->compl.rx.rx_completion_context = net_vsc_pkt;
952
		net_vsc_pkt->device = device;
953
		/* Save this so that we can send it back */
954
		net_vsc_pkt->compl.rx.rx_completion_tid =
955
		    vm_xfer_page_pkt->d.transaction_id;
956
957
		net_vsc_pkt->tot_data_buf_len =
906
		    vm_xfer_page_pkt->ranges[i].byte_count;
958
		    vm_xfer_page_pkt->ranges[i].byte_count;
959
		net_vsc_pkt->page_buf_count = 1;
907
960
908
		hv_rf_on_receive(net_dev, device, net_vsc_pkt);
961
		net_vsc_pkt->page_buffers[0].length =
909
		if (net_vsc_pkt->status != nvsp_status_success) {
962
		    vm_xfer_page_pkt->ranges[i].byte_count;
910
			status = nvsp_status_failure;
963
911
		}
964
		/* The virtual address of the packet in the receive buffer */
965
		start = ((unsigned long)net_dev->rx_buf +
966
		    vm_xfer_page_pkt->ranges[i].byte_offset);
967
		start = ((unsigned long)start) & ~(PAGE_SIZE - 1);
968
969
		/* Page number of the virtual page containing packet start */
970
		net_vsc_pkt->page_buffers[0].pfn = start >> PAGE_SHIFT;
971
972
		/* Calculate the page relative offset */
973
		net_vsc_pkt->page_buffers[0].offset =
974
		    vm_xfer_page_pkt->ranges[i].byte_offset & (PAGE_SIZE - 1);
975
976
		/*
977
		 * In this implementation, we are dealing with virtual
978
		 * addresses exclusively.  Since we aren't using physical
979
		 * addresses at all, we don't care if a packet crosses a
980
		 * page boundary.  For this reason, the original code to
981
		 * check for and handle page crossings has been removed.
982
		 */
983
984
		/*
985
		 * Pass it to the upper layer.  The receive completion call
986
		 * has been moved into this function.
987
		 */
988
		hv_rf_on_receive(device, net_vsc_pkt);
989
990
		/*
991
		 * Moved completion call back here so that all received 
992
		 * messages (not just data messages) will trigger a response
993
		 * message back to the host.
994
		 */
995
		hv_nv_on_receive_completion(net_vsc_pkt);
912
	}
996
	}
913
	
914
	/*
915
	 * Moved completion call back here so that all received 
916
	 * messages (not just data messages) will trigger a response
917
	 * message back to the host.
918
	 */
919
	hv_nv_on_receive_completion(device, vm_xfer_page_pkt->d.transaction_id,
920
	    status);
921
}
997
}
922
998
923
/*
999
/*
924
 * Net VSC on receive completion
1000
 * Net VSC send receive completion
925
 *
926
 * Send a receive completion packet to RNDIS device (ie NetVsp)
927
 */
1001
 */
928
void
1002
static void
929
hv_nv_on_receive_completion(struct hv_device *device, uint64_t tid,
1003
hv_nv_send_receive_completion(struct hv_device *device, uint64_t tid)
930
    uint32_t status)
931
{
1004
{
932
	nvsp_msg rx_comp_msg;
1005
	nvsp_msg rx_comp_msg;
933
	int retries = 0;
1006
	int retries = 0;
Lines 937-943 Link Here
937
1010
938
	/* Pass in the status */
1011
	/* Pass in the status */
939
	rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status =
1012
	rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status =
940
	    status;
1013
	    nvsp_status_success;
941
1014
942
retry_send_cmplt:
1015
retry_send_cmplt:
943
	/* Send the completion */
1016
	/* Send the completion */
Lines 958-984 Link Here
958
}
1031
}
959
1032
960
/*
1033
/*
1034
 * Net VSC on receive completion
1035
 *
1036
 * Send a receive completion packet to RNDIS device (ie NetVsp)
1037
 */
1038
void
1039
hv_nv_on_receive_completion(void *context)
1040
{
1041
	netvsc_packet *packet = (netvsc_packet *)context;
1042
	struct hv_device *device = (struct hv_device *)packet->device;
1043
	netvsc_dev    *net_dev;
1044
	uint64_t       tid = 0;
1045
	boolean_t send_rx_completion = FALSE;
1046
1047
	/*
1048
	 * Even though it seems logical to do a hv_nv_get_outbound_net_device()
1049
	 * here to send out receive completion, we are using
1050
	 * hv_nv_get_inbound_net_device() since we may have disabled
1051
	 * outbound traffic already.
1052
	 */
1053
	net_dev = hv_nv_get_inbound_net_device(device);
1054
	if (net_dev == NULL)
1055
		return;
1056
	
1057
	/* Overloading use of the lock. */
1058
	mtx_lock_spin(&net_dev->rx_pkt_list_lock);
1059
1060
	packet->xfer_page_pkt->count--;
1061
1062
	/*
1063
	 * Last one in the line that represent 1 xfer page packet.
1064
	 * Return the xfer page packet itself to the free list.
1065
	 */
1066
	if (packet->xfer_page_pkt->count == 0) {
1067
		send_rx_completion = TRUE;
1068
		tid = packet->compl.rx.rx_completion_tid;
1069
		STAILQ_INSERT_TAIL(&net_dev->myrx_packet_list,
1070
		    (netvsc_packet *)(packet->xfer_page_pkt), mylist_entry);
1071
	}
1072
1073
	/* Put the packet back on the free list */
1074
	STAILQ_INSERT_TAIL(&net_dev->myrx_packet_list, packet, mylist_entry);
1075
	mtx_unlock_spin(&net_dev->rx_pkt_list_lock);
1076
1077
	/* Send a receive completion for the xfer page packet */
1078
	if (send_rx_completion)
1079
		hv_nv_send_receive_completion(device, tid);
1080
}
1081
1082
/*
961
 * Net VSC on channel callback
1083
 * Net VSC on channel callback
962
 */
1084
 */
963
static void
1085
static void
964
hv_nv_on_channel_callback(void *context)
1086
hv_nv_on_channel_callback(void *context)
965
{
1087
{
1088
	/* Fixme:  Magic number */
1089
	const int net_pkt_size = 2048;
966
	struct hv_device *device = (struct hv_device *)context;
1090
	struct hv_device *device = (struct hv_device *)context;
967
	netvsc_dev *net_dev;
1091
	netvsc_dev *net_dev;
968
	device_t dev = device->device;
969
	uint32_t bytes_rxed;
1092
	uint32_t bytes_rxed;
970
	uint64_t request_id;
1093
	uint64_t request_id;
971
 	hv_vm_packet_descriptor *desc;
1094
	uint8_t  *packet;
1095
	hv_vm_packet_descriptor *desc;
972
	uint8_t *buffer;
1096
	uint8_t *buffer;
973
	int bufferlen = NETVSC_PACKET_SIZE;
1097
	int     bufferlen = net_pkt_size;
974
	int ret = 0;
1098
	int     ret = 0;
975
1099
1100
	packet = malloc(net_pkt_size * sizeof(uint8_t), M_DEVBUF, M_NOWAIT);
1101
	if (!packet)
1102
		return;
1103
1104
	buffer = packet;
1105
976
	net_dev = hv_nv_get_inbound_net_device(device);
1106
	net_dev = hv_nv_get_inbound_net_device(device);
977
	if (net_dev == NULL)
1107
	if (net_dev == NULL)
978
		return;
1108
		goto out;
979
1109
980
	buffer = net_dev->callback_buf;
981
982
	do {
1110
	do {
983
		ret = hv_vmbus_channel_recv_packet_raw(device->channel,
1111
		ret = hv_vmbus_channel_recv_packet_raw(device->channel,
984
		    buffer, bufferlen, &bytes_rxed, &request_id);
1112
		    buffer, bufferlen, &bytes_rxed, &request_id);
Lines 987-1001 Link Here
987
				desc = (hv_vm_packet_descriptor *)buffer;
1115
				desc = (hv_vm_packet_descriptor *)buffer;
988
				switch (desc->type) {
1116
				switch (desc->type) {
989
				case HV_VMBUS_PACKET_TYPE_COMPLETION:
1117
				case HV_VMBUS_PACKET_TYPE_COMPLETION:
990
					hv_nv_on_send_completion(net_dev, device, desc);
1118
					hv_nv_on_send_completion(device, desc);
991
					break;
1119
					break;
992
				case HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES:
1120
				case HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES:
993
					hv_nv_on_receive(net_dev, device, desc);
1121
					hv_nv_on_receive(device, desc);
994
					break;
1122
					break;
995
				default:
1123
				default:
996
					device_printf(dev,
997
					    "hv_cb recv unknow type %d "
998
					    " packet\n", desc->type);
999
					break;
1124
					break;
1000
				}
1125
				}
1001
			} else {
1126
			} else {
Lines 1003-1020 Link Here
1003
			}
1128
			}
1004
		} else if (ret == ENOBUFS) {
1129
		} else if (ret == ENOBUFS) {
1005
			/* Handle large packet */
1130
			/* Handle large packet */
1006
			if (bufferlen > NETVSC_PACKET_SIZE) {
1131
			free(buffer, M_DEVBUF);
1007
				free(buffer, M_NETVSC);
1132
			buffer = malloc(bytes_rxed, M_DEVBUF, M_NOWAIT);
1008
				buffer = NULL;
1009
			}
1010
1011
			/* alloc new buffer */
1012
			buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
1013
			if (buffer == NULL) {
1133
			if (buffer == NULL) {
1014
				device_printf(dev,
1015
				    "hv_cb malloc buffer failed, len=%u\n",
1016
				    bytes_rxed);
1017
				bufferlen = 0;
1018
				break;
1134
				break;
1019
			}
1135
			}
1020
			bufferlen = bytes_rxed;
1136
			bufferlen = bytes_rxed;
Lines 1021-1026 Link Here
1021
		}
1137
		}
1022
	} while (1);
1138
	} while (1);
1023
1139
1024
	if (bufferlen > NETVSC_PACKET_SIZE)
1140
out:
1025
		free(buffer, M_NETVSC);
1141
	free(buffer, M_DEVBUF);
1026
}
1142
}
1143
(-)sys/dev/hyperv/netvsc/hv_rndis.h (-149 lines)
Lines 24-31 Link Here
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 *
28
 * $FreeBSD$
29
 */
27
 */
30
28
31
#ifndef __HV_RNDIS_H__
29
#ifndef __HV_RNDIS_H__
Lines 38-46 Link Here
38
#define NDIS_VERSION_5_0                        0x00050000
36
#define NDIS_VERSION_5_0                        0x00050000
39
#define NDIS_VERSION_5_1                        0x00050001
37
#define NDIS_VERSION_5_1                        0x00050001
40
#define NDIS_VERSION_6_0                        0x00060000
38
#define NDIS_VERSION_6_0                        0x00060000
41
#define NDIS_VERSION_6_1                        0x00060001
42
#define NDIS_VERSION_6_30                       0x0006001e
43
44
#define NDIS_VERSION                            (NDIS_VERSION_5_1)
39
#define NDIS_VERSION                            (NDIS_VERSION_5_1)
45
40
46
/*
41
/*
Lines 352-388 Link Here
352
#define RNDIS_MAJOR_VERSION                             0x00000001
347
#define RNDIS_MAJOR_VERSION                             0x00000001
353
#define RNDIS_MINOR_VERSION                             0x00000000
348
#define RNDIS_MINOR_VERSION                             0x00000000
354
349
355
356
/*
350
/*
357
 * Remote NDIS offload parameters
358
 */
359
#define RNDIS_OBJECT_TYPE_DEFAULT			0x80
360
 
361
#define RNDIS_OFFLOAD_PARAMETERS_REVISION_3		3
362
#define RNDIS_OFFLOAD_PARAMETERS_NO_CHANGE		0
363
#define RNDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED		1
364
#define RNDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED 		2
365
#define RNDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED		2
366
#define RNDIS_OFFLOAD_PARAMETERS_RSC_DISABLED		1
367
#define RNDIS_OFFLOAD_PARAMETERS_RSC_ENABLED		2
368
#define RNDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED		1
369
#define RNDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED	2
370
#define RNDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED	3
371
#define RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED		4
372
373
#define RNDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE		1
374
#define RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV4		0
375
#define RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV6		1
376
377
378
#define RNDIS_OID_TCP_OFFLOAD_CURRENT_CONFIG		0xFC01020B /* query only */
379
#define RNDIS_OID_TCP_OFFLOAD_PARAMETERS		0xFC01020C /* set only */
380
#define RNDIS_OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES	0xFC01020D/* query only */
381
#define RNDIS_OID_TCP_CONNECTION_OFFLOAD_CURRENT_CONFIG	0xFC01020E /* query only */
382
#define RNDIS_OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES	0xFC01020F /* query */
383
#define RNDIS_OID_OFFLOAD_ENCAPSULATION			0x0101010A /* set/query */
384
385
/*
386
 * NdisInitialize message
351
 * NdisInitialize message
387
 */
352
 */
388
typedef struct rndis_initialize_request_ {
353
typedef struct rndis_initialize_request_ {
Lines 620-727 Link Here
620
	} u1;
585
	} u1;
621
} ndis_8021q_info;
586
} ndis_8021q_info;
622
587
623
struct rndis_object_header {
624
	uint8_t type;
625
	uint8_t revision;
626
	uint16_t size;
627
};
628
629
typedef struct rndis_offload_params_ {
630
	struct rndis_object_header header;
631
	uint8_t ipv4_csum;
632
	uint8_t tcp_ipv4_csum;
633
	uint8_t udp_ipv4_csum;
634
	uint8_t tcp_ipv6_csum;
635
	uint8_t udp_ipv6_csum;
636
	uint8_t lso_v1;
637
	uint8_t ip_sec_v1;
638
	uint8_t lso_v2_ipv4;
639
	uint8_t lso_v2_ipv6;
640
	uint8_t tcp_connection_ipv4;
641
	uint8_t tcp_connection_ipv6;
642
	uint32_t flags;
643
	uint8_t ip_sec_v2;
644
	uint8_t ip_sec_v2_ipv4;
645
	struct {
646
		uint8_t rsc_ipv4;
647
		uint8_t rsc_ipv6;
648
	};
649
	struct {
650
		uint8_t encapsulated_packet_task_offload;
651
		uint8_t encapsulation_types;
652
	};
653
654
} rndis_offload_params;
655
656
657
typedef struct rndis_tcp_ip_csum_info_ {
658
	union {
659
		struct {
660
			uint32_t is_ipv4:1;
661
			uint32_t is_ipv6:1;
662
			uint32_t tcp_csum:1;
663
			uint32_t udp_csum:1;
664
			uint32_t ip_header_csum:1;
665
			uint32_t reserved:11;
666
			uint32_t tcp_header_offset:10;
667
		} xmit;
668
		struct {
669
			uint32_t tcp_csum_failed:1;
670
			uint32_t udp_csum_failed:1;
671
			uint32_t ip_csum_failed:1;
672
			uint32_t tcp_csum_succeeded:1;
673
			uint32_t udp_csum_succeeded:1;
674
			uint32_t ip_csum_succeeded:1;
675
			uint32_t loopback:1;
676
			uint32_t tcp_csum_value_invalid:1;
677
			uint32_t ip_csum_value_invalid:1;
678
		} receive;
679
		uint32_t  value;
680
	};
681
} rndis_tcp_ip_csum_info;
682
683
typedef struct rndis_tcp_tso_info_ {
684
	union {
685
		struct {
686
			uint32_t unused:30;
687
			uint32_t type:1;
688
			uint32_t reserved2:1;
689
		} xmit;
690
		struct {
691
			uint32_t mss:20;
692
			uint32_t tcp_header_offset:10;
693
			uint32_t type:1;
694
			uint32_t reserved2:1;
695
		} lso_v1_xmit;
696
		struct {
697
			uint32_t tcp_payload:30;
698
			uint32_t type:1;
699
			uint32_t reserved2:1;
700
		} lso_v1_xmit_complete;
701
		struct {
702
			uint32_t mss:20;
703
			uint32_t tcp_header_offset:10;
704
			uint32_t type:1;
705
			uint32_t ip_version:1;
706
		} lso_v2_xmit;
707
		struct {
708
			uint32_t reserved:30;
709
			uint32_t type:1;
710
			uint32_t reserved2:1;
711
		} lso_v2_xmit_complete;
712
		uint32_t  value;
713
	};
714
} rndis_tcp_tso_info;
715
716
#define RNDIS_VLAN_PPI_SIZE	(sizeof(rndis_per_packet_info) + \
717
				sizeof(ndis_8021q_info))
718
719
#define RNDIS_CSUM_PPI_SIZE	(sizeof(rndis_per_packet_info) + \
720
				sizeof(rndis_tcp_ip_csum_info))
721
722
#define RNDIS_TSO_PPI_SIZE	(sizeof(rndis_per_packet_info) + \
723
				sizeof(rndis_tcp_tso_info))
724
725
/*
588
/*
726
 * Format of Information buffer passed in a SetRequest for the OID
589
 * Format of Information buffer passed in a SetRequest for the OID
727
 * OID_GEN_RNDIS_CONFIG_PARAMETER.
590
 * OID_GEN_RNDIS_CONFIG_PARAMETER.
Lines 1043-1060 Link Here
1043
#define NDIS_PACKET_TYPE_FUNCTIONAL	0x00000400
906
#define NDIS_PACKET_TYPE_FUNCTIONAL	0x00000400
1044
#define NDIS_PACKET_TYPE_MAC_FRAME	0x00000800
907
#define NDIS_PACKET_TYPE_MAC_FRAME	0x00000800
1045
908
1046
/*
1047
 * Externs
1048
 */
1049
int netvsc_recv(struct hv_device *device_ctx, 
1050
    netvsc_packet *packet, 
1051
    rndis_tcp_ip_csum_info *csum_info);
1052
909
1053
void* hv_set_rppi_data(rndis_msg *rndis_mesg,
1054
    uint32_t rppi_size,
1055
    int pkt_type);
1056
1057
void* hv_get_ppi_data(rndis_packet *rpkt, uint32_t type);
1058
1059
#endif  /* __HV_RNDIS_H__ */
910
#endif  /* __HV_RNDIS_H__ */
1060
911
(-)sys/dev/hyperv/netvsc/hv_rndis_filter.c (-201 / +168 lines)
Lines 67-133 Link Here
67
static int  hv_rf_init_device(rndis_device *device);
67
static int  hv_rf_init_device(rndis_device *device);
68
static int  hv_rf_open_device(rndis_device *device);
68
static int  hv_rf_open_device(rndis_device *device);
69
static int  hv_rf_close_device(rndis_device *device);
69
static int  hv_rf_close_device(rndis_device *device);
70
static void hv_rf_on_send_completion(void *context);
70
static void hv_rf_on_send_request_completion(void *context);
71
static void hv_rf_on_send_request_completion(void *context);
71
static void hv_rf_on_send_request_halt_completion(void *context);
72
static void hv_rf_on_send_request_halt_completion(void *context);
72
int
73
hv_rf_send_offload_request(struct hv_device *device,
74
    rndis_offload_params *offloads);
75
/*
76
 * Set the Per-Packet-Info with the specified type
77
 */
78
void *
79
hv_set_rppi_data(rndis_msg *rndis_mesg, uint32_t rppi_size,
80
	int pkt_type)
81
{
82
	rndis_packet *rndis_pkt;
83
	rndis_per_packet_info *rppi;
84
73
85
	rndis_pkt = &rndis_mesg->msg.packet;
86
	rndis_pkt->data_offset += rppi_size;
87
74
88
	rppi = (rndis_per_packet_info *)((char *)rndis_pkt +
89
	    rndis_pkt->per_pkt_info_offset + rndis_pkt->per_pkt_info_length);
90
91
	rppi->size = rppi_size;
92
	rppi->type = pkt_type;
93
	rppi->per_packet_info_offset = sizeof(rndis_per_packet_info);
94
95
	rndis_pkt->per_pkt_info_length += rppi_size;
96
97
	return (rppi);
98
}
99
100
/*
75
/*
101
 * Get the Per-Packet-Info with the specified type
102
 * return NULL if not found.
103
 */
104
void *
105
hv_get_ppi_data(rndis_packet *rpkt, uint32_t type)
106
{
107
	rndis_per_packet_info *ppi;
108
	int len;
109
110
	if (rpkt->per_pkt_info_offset == 0)
111
		return (NULL);
112
113
	ppi = (rndis_per_packet_info *)((unsigned long)rpkt +
114
	    rpkt->per_pkt_info_offset);
115
	len = rpkt->per_pkt_info_length;
116
117
	while (len > 0) {
118
		if (ppi->type == type)
119
			return (void *)((unsigned long)ppi +
120
			    ppi->per_packet_info_offset);
121
122
		len -= ppi->size;
123
		ppi = (rndis_per_packet_info *)((unsigned long)ppi + ppi->size);
124
	}
125
126
	return (NULL);
127
}
128
129
130
/*
131
 * Allow module_param to work and override to switch to promiscuous mode.
76
 * Allow module_param to work and override to switch to promiscuous mode.
132
 */
77
 */
133
static inline rndis_device *
78
static inline rndis_device *
Lines 135-141 Link Here
135
{
80
{
136
	rndis_device *device;
81
	rndis_device *device;
137
82
138
	device = malloc(sizeof(rndis_device), M_NETVSC, M_NOWAIT | M_ZERO);
83
	device = malloc(sizeof(rndis_device), M_DEVBUF, M_NOWAIT | M_ZERO);
139
	if (device == NULL) {
84
	if (device == NULL) {
140
		return (NULL);
85
		return (NULL);
141
	}
86
	}
Lines 157-163 Link Here
157
hv_put_rndis_device(rndis_device *device)
102
hv_put_rndis_device(rndis_device *device)
158
{
103
{
159
	mtx_destroy(&device->req_lock);
104
	mtx_destroy(&device->req_lock);
160
	free(device, M_NETVSC);
105
	free(device, M_DEVBUF);
161
}
106
}
162
107
163
/*
108
/*
Lines 171-177 Link Here
171
	rndis_msg *rndis_mesg;
116
	rndis_msg *rndis_mesg;
172
	rndis_set_request *set;
117
	rndis_set_request *set;
173
118
174
	request = malloc(sizeof(rndis_request), M_NETVSC, M_NOWAIT | M_ZERO);
119
	request = malloc(sizeof(rndis_request), M_DEVBUF, M_NOWAIT | M_ZERO);
175
	if (request == NULL) {
120
	if (request == NULL) {
176
		return (NULL);
121
		return (NULL);
177
	}
122
	}
Lines 216-222 Link Here
216
	mtx_unlock_spin(&device->req_lock);
161
	mtx_unlock_spin(&device->req_lock);
217
162
218
	sema_destroy(&request->wait_sema);
163
	sema_destroy(&request->wait_sema);
219
	free(request, M_NETVSC);
164
	free(request, M_DEVBUF);
220
}
165
}
221
166
222
/*
167
/*
Lines 224-230 Link Here
224
 */
169
 */
225
static int
170
static int
226
hv_rf_send_request(rndis_device *device, rndis_request *request,
171
hv_rf_send_request(rndis_device *device, rndis_request *request,
227
    uint32_t message_type)
172
		   uint32_t message_type)
228
{
173
{
229
	int ret;
174
	int ret;
230
	netvsc_packet *packet;
175
	netvsc_packet *packet;
Lines 251-259 Link Here
251
		    hv_rf_on_send_request_halt_completion;
196
		    hv_rf_on_send_request_halt_completion;
252
	}
197
	}
253
	packet->compl.send.send_completion_tid = (unsigned long)device;
198
	packet->compl.send.send_completion_tid = (unsigned long)device;
254
	packet->send_buf_section_idx =
255
	    NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
256
	packet->send_buf_section_size = 0;
257
199
258
	ret = hv_nv_on_send(device->net_dev->dev, packet);
200
	ret = hv_nv_on_send(device->net_dev->dev, packet);
259
201
Lines 306-389 Link Here
306
	}
248
	}
307
}
249
}
308
250
309
int
310
hv_rf_send_offload_request(struct hv_device *device,
311
    rndis_offload_params *offloads)
312
{
313
	rndis_request *request;
314
	rndis_set_request *set;
315
	rndis_offload_params *offload_req;
316
	rndis_set_complete *set_complete;	
317
	rndis_device *rndis_dev;
318
	hn_softc_t *sc = device_get_softc(device->device);
319
	device_t dev = device->device;
320
	netvsc_dev *net_dev = sc->net_dev;
321
	uint32_t vsp_version = net_dev->nvsp_version;
322
	uint32_t extlen = sizeof(rndis_offload_params);
323
	int ret;
324
325
	if (vsp_version <= NVSP_PROTOCOL_VERSION_4) {
326
		extlen = VERSION_4_OFFLOAD_SIZE;
327
		/* On NVSP_PROTOCOL_VERSION_4 and below, we do not support
328
		 * UDP checksum offload.
329
		 */
330
		offloads->udp_ipv4_csum = 0;
331
		offloads->udp_ipv6_csum = 0;
332
	}
333
334
	rndis_dev = net_dev->extension;
335
336
	request = hv_rndis_request(rndis_dev, REMOTE_NDIS_SET_MSG,
337
	    RNDIS_MESSAGE_SIZE(rndis_set_request) + extlen);
338
	if (!request)
339
		return (ENOMEM);
340
341
	set = &request->request_msg.msg.set_request;
342
	set->oid = RNDIS_OID_TCP_OFFLOAD_PARAMETERS;
343
	set->info_buffer_length = extlen;
344
	set->info_buffer_offset = sizeof(rndis_set_request);
345
	set->device_vc_handle = 0;
346
347
	offload_req = (rndis_offload_params *)((unsigned long)set +
348
	    set->info_buffer_offset);
349
	*offload_req = *offloads;
350
	offload_req->header.type = RNDIS_OBJECT_TYPE_DEFAULT;
351
	offload_req->header.revision = RNDIS_OFFLOAD_PARAMETERS_REVISION_3;
352
	offload_req->header.size = extlen;
353
354
	ret = hv_rf_send_request(rndis_dev, request, REMOTE_NDIS_SET_MSG);
355
	if (ret != 0) {
356
		device_printf(dev, "hv send offload request failed, ret=%d!\n",
357
		    ret);
358
		goto cleanup;
359
	}
360
361
	ret = sema_timedwait(&request->wait_sema, 500);
362
	if (ret != 0) {
363
		device_printf(dev, "hv send offload request timeout\n");
364
		goto cleanup;
365
	}
366
367
	set_complete = &request->response_msg.msg.set_complete;
368
	if (set_complete->status == RNDIS_STATUS_SUCCESS) {
369
		device_printf(dev, "hv send offload request succeeded\n");
370
		ret = 0;
371
	} else {
372
		if (set_complete->status == STATUS_NOT_SUPPORTED) {
373
			device_printf(dev, "HV Not support offload\n");
374
			ret = 0;
375
		} else {
376
			ret = set_complete->status;
377
		}
378
	}
379
380
cleanup:
381
	if (request)
382
		hv_put_rndis_request(rndis_dev, request);
383
384
	return (ret);
385
}
386
387
/*
251
/*
388
 * RNDIS filter receive indicate status
252
 * RNDIS filter receive indicate status
389
 */
253
 */
Lines 392-409 Link Here
392
{
256
{
393
	rndis_indicate_status *indicate = &response->msg.indicate_status;
257
	rndis_indicate_status *indicate = &response->msg.indicate_status;
394
		
258
		
395
	switch(indicate->status) {
259
	if (indicate->status == RNDIS_STATUS_MEDIA_CONNECT) {
396
	case RNDIS_STATUS_MEDIA_CONNECT:
397
		netvsc_linkstatus_callback(device->net_dev->dev, 1);
260
		netvsc_linkstatus_callback(device->net_dev->dev, 1);
398
		break;
261
	} else if (indicate->status == RNDIS_STATUS_MEDIA_DISCONNECT) {
399
	case RNDIS_STATUS_MEDIA_DISCONNECT:
400
		netvsc_linkstatus_callback(device->net_dev->dev, 0);
262
		netvsc_linkstatus_callback(device->net_dev->dev, 0);
401
		break;
263
	} else {
402
	default:
403
		/* TODO: */
264
		/* TODO: */
404
		device_printf(device->net_dev->dev->device,
405
		    "unknown status %d received\n", indicate->status);
406
		break;
407
	}
265
	}
408
}
266
}
409
267
Lines 414-423 Link Here
414
hv_rf_receive_data(rndis_device *device, rndis_msg *message, netvsc_packet *pkt)
272
hv_rf_receive_data(rndis_device *device, rndis_msg *message, netvsc_packet *pkt)
415
{
273
{
416
	rndis_packet *rndis_pkt;
274
	rndis_packet *rndis_pkt;
417
	ndis_8021q_info *rppi_vlan_info;
275
	rndis_per_packet_info *rppi;
276
	ndis_8021q_info       *rppi_vlan_info;
418
	uint32_t data_offset;
277
	uint32_t data_offset;
419
	rndis_tcp_ip_csum_info *csum_info = NULL;
420
	device_t dev = device->net_dev->dev->device;
421
278
422
	rndis_pkt = &message->msg.packet;
279
	rndis_pkt = &message->msg.packet;
423
280
Lines 429-455 Link Here
429
	/* Remove rndis header, then pass data packet up the stack */
286
	/* Remove rndis header, then pass data packet up the stack */
430
	data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
287
	data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
431
288
432
	pkt->tot_data_buf_len -= data_offset;
289
	/* L2 frame length, with L2 header, not including CRC */
433
	if (pkt->tot_data_buf_len < rndis_pkt->data_length) {
290
	pkt->tot_data_buf_len        = rndis_pkt->data_length;
434
		pkt->status = nvsp_status_failure;
291
	pkt->page_buffers[0].offset += data_offset;
435
		device_printf(dev,
292
	/* Buffer length now L2 frame length plus trailing junk */
436
		    "total length %u is less than data length %u\n",
293
	pkt->page_buffers[0].length -= data_offset;
437
		    pkt->tot_data_buf_len, rndis_pkt->data_length);
438
		return;
439
	}
440
294
441
	pkt->tot_data_buf_len = rndis_pkt->data_length;
295
	pkt->is_data_pkt = TRUE;
442
	pkt->data = (void *)((unsigned long)pkt->data + data_offset);
443
296
444
	rppi_vlan_info = hv_get_ppi_data(rndis_pkt, ieee_8021q_info);
297
	pkt->vlan_tci = 0;
445
	if (rppi_vlan_info) {
298
446
		pkt->vlan_tci = rppi_vlan_info->u1.s1.vlan_id;
299
	/*
447
	} else {
300
	 * Read the VLAN ID if supplied by the Hyper-V infrastructure.
448
		pkt->vlan_tci = 0;
301
	 * Let higher-level driver code decide if it wants to use it.
302
	 * Ignore CFI, priority for now as FreeBSD does not support these.
303
	 */
304
	if (rndis_pkt->per_pkt_info_offset != 0) {
305
		/* rppi struct exists; compute its address */
306
		rppi = (rndis_per_packet_info *)((uint8_t *)rndis_pkt +
307
		    rndis_pkt->per_pkt_info_offset);
308
		/* if VLAN ppi struct, get the VLAN ID */
309
		if (rppi->type == ieee_8021q_info) {
310
			rppi_vlan_info = (ndis_8021q_info *)((uint8_t *)rppi
311
				+  rppi->per_packet_info_offset);
312
			pkt->vlan_tci = rppi_vlan_info->u1.s1.vlan_id;
313
		}
449
	}
314
	}
450
315
451
	csum_info = hv_get_ppi_data(rndis_pkt, tcpip_chksum_info);
316
	netvsc_recv(device->net_dev->dev, pkt);
452
	netvsc_recv(device->net_dev->dev, pkt, csum_info);
453
}
317
}
454
318
455
/*
319
/*
Lines 456-485 Link Here
456
 * RNDIS filter on receive
320
 * RNDIS filter on receive
457
 */
321
 */
458
int
322
int
459
hv_rf_on_receive(netvsc_dev *net_dev, struct hv_device *device, netvsc_packet *pkt)
323
hv_rf_on_receive(struct hv_device *device, netvsc_packet *pkt)
460
{
324
{
325
	hn_softc_t *sc = device_get_softc(device->device);
326
	netvsc_dev *net_dev = sc->net_dev;
461
	rndis_device *rndis_dev;
327
	rndis_device *rndis_dev;
328
	rndis_msg rndis_mesg;
462
	rndis_msg *rndis_hdr;
329
	rndis_msg *rndis_hdr;
463
330
464
	/* Make sure the rndis device state is initialized */
331
	/* Make sure the rndis device state is initialized */
465
	if (net_dev->extension == NULL) {
332
	if (net_dev->extension == NULL)
466
		pkt->status = nvsp_status_failure;
467
		return (ENODEV);
333
		return (ENODEV);
468
	}
469
334
470
	rndis_dev = (rndis_device *)net_dev->extension;
335
	rndis_dev = (rndis_device *)net_dev->extension;
471
	if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
336
	if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED)
472
		pkt->status = nvsp_status_failure;
473
		return (EINVAL);
337
		return (EINVAL);
338
339
	/* Shift virtual page number to form virtual page address */
340
	rndis_hdr = (rndis_msg *)(uintptr_t)(pkt->page_buffers[0].pfn << PAGE_SHIFT);
341
342
	rndis_hdr = (void *)((unsigned long)rndis_hdr
343
			+ pkt->page_buffers[0].offset);
344
	
345
	/*
346
	 * Make sure we got a valid rndis message
347
	 * Fixme:  There seems to be a bug in set completion msg where
348
	 * its msg_len is 16 bytes but the byte_count field in the
349
	 * xfer page range shows 52 bytes
350
	 */
351
#if 0
352
	if (pkt->tot_data_buf_len != rndis_hdr->msg_len) {
353
		DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u "
354
		    "bytes got %u)... dropping this message!",
355
		    rndis_hdr->msg_len, pkt->tot_data_buf_len);
356
		DPRINT_EXIT(NETVSC);
357
358
		return (-1);
474
	}
359
	}
360
#endif
475
361
476
	rndis_hdr = pkt->data;
362
	memcpy(&rndis_mesg, rndis_hdr,
363
	    (rndis_hdr->msg_len > sizeof(rndis_msg)) ?
364
	    sizeof(rndis_msg) : rndis_hdr->msg_len);
477
365
478
	switch (rndis_hdr->ndis_msg_type) {
366
	switch (rndis_mesg.ndis_msg_type) {
479
367
480
	/* data message */
368
	/* data message */
481
	case REMOTE_NDIS_PACKET_MSG:
369
	case REMOTE_NDIS_PACKET_MSG:
482
		hv_rf_receive_data(rndis_dev, rndis_hdr, pkt);
370
		hv_rf_receive_data(rndis_dev, &rndis_mesg, pkt);
483
		break;
371
		break;
484
	/* completion messages */
372
	/* completion messages */
485
	case REMOTE_NDIS_INITIALIZE_CMPLT:
373
	case REMOTE_NDIS_INITIALIZE_CMPLT:
Lines 487-501 Link Here
487
	case REMOTE_NDIS_SET_CMPLT:
375
	case REMOTE_NDIS_SET_CMPLT:
488
	case REMOTE_NDIS_RESET_CMPLT:
376
	case REMOTE_NDIS_RESET_CMPLT:
489
	case REMOTE_NDIS_KEEPALIVE_CMPLT:
377
	case REMOTE_NDIS_KEEPALIVE_CMPLT:
490
		hv_rf_receive_response(rndis_dev, rndis_hdr);
378
		hv_rf_receive_response(rndis_dev, &rndis_mesg);
491
		break;
379
		break;
492
	/* notification message */
380
	/* notification message */
493
	case REMOTE_NDIS_INDICATE_STATUS_MSG:
381
	case REMOTE_NDIS_INDICATE_STATUS_MSG:
494
		hv_rf_receive_indicate_status(rndis_dev, rndis_hdr);
382
		hv_rf_receive_indicate_status(rndis_dev, &rndis_mesg);
495
		break;
383
		break;
496
	default:
384
	default:
497
		printf("hv_rf_on_receive():  Unknown msg_type 0x%x\n",
385
		printf("hv_rf_on_receive():  Unknown msg_type 0x%x\n",
498
			rndis_hdr->ndis_msg_type);
386
		    rndis_mesg.ndis_msg_type);
499
		break;
387
		break;
500
	}
388
	}
501
389
Lines 823-831 Link Here
823
	int ret;
711
	int ret;
824
	netvsc_dev *net_dev;
712
	netvsc_dev *net_dev;
825
	rndis_device *rndis_dev;
713
	rndis_device *rndis_dev;
826
	rndis_offload_params offloads;
827
	netvsc_device_info *dev_info = (netvsc_device_info *)additl_info;
714
	netvsc_device_info *dev_info = (netvsc_device_info *)additl_info;
828
	device_t dev = device->device;
829
715
830
	rndis_dev = hv_get_rndis_device();
716
	rndis_dev = hv_get_rndis_device();
831
	if (rndis_dev == NULL) {
717
	if (rndis_dev == NULL) {
Lines 866-887 Link Here
866
	if (ret != 0) {
752
	if (ret != 0) {
867
		/* TODO: shut down rndis device and the channel */
753
		/* TODO: shut down rndis device and the channel */
868
	}
754
	}
869
870
	/* config csum offload and send request to host */
871
	memset(&offloads, 0, sizeof(offloads));
872
	offloads.ipv4_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
873
	offloads.tcp_ipv4_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
874
	offloads.udp_ipv4_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
875
	offloads.tcp_ipv6_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
876
	offloads.udp_ipv6_csum = RNDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
877
	offloads.lso_v2_ipv4 = RNDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
878
879
	ret = hv_rf_send_offload_request(device, &offloads);
880
	if (ret != 0) {
881
		/* TODO: shut down rndis device and the channel */
882
		device_printf(dev,
883
		    "hv_rf_send_offload_request failed, ret=%d\n", ret);
884
	}
885
	
755
	
886
	memcpy(dev_info->mac_addr, rndis_dev->hw_mac_addr, HW_MACADDR_LEN);
756
	memcpy(dev_info->mac_addr, rndis_dev->hw_mac_addr, HW_MACADDR_LEN);
887
757
Lines 940-945 Link Here
940
}
810
}
941
811
942
/*
812
/*
813
 * RNDIS filter on send
814
 */
815
int
816
hv_rf_on_send(struct hv_device *device, netvsc_packet *pkt)
817
{
818
	rndis_filter_packet *filter_pkt;
819
	rndis_msg *rndis_mesg;
820
	rndis_packet *rndis_pkt;
821
	rndis_per_packet_info *rppi;
822
	ndis_8021q_info       *rppi_vlan_info;
823
	uint32_t rndis_msg_size;
824
	int ret = 0;
825
826
	/* Add the rndis header */
827
	filter_pkt = (rndis_filter_packet *)pkt->extension;
828
829
	memset(filter_pkt, 0, sizeof(rndis_filter_packet));
830
831
	rndis_mesg = &filter_pkt->message;
832
	rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet);
833
834
	if (pkt->vlan_tci != 0) {
835
		rndis_msg_size += sizeof(rndis_per_packet_info) +
836
		    sizeof(ndis_8021q_info);
837
	}
838
839
	rndis_mesg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG;
840
	rndis_mesg->msg_len = pkt->tot_data_buf_len + rndis_msg_size;
841
842
	rndis_pkt = &rndis_mesg->msg.packet;
843
	rndis_pkt->data_offset = sizeof(rndis_packet);
844
	rndis_pkt->data_length = pkt->tot_data_buf_len;
845
846
	pkt->is_data_pkt = TRUE;
847
	pkt->page_buffers[0].pfn = hv_get_phys_addr(rndis_mesg) >> PAGE_SHIFT;
848
	pkt->page_buffers[0].offset =
849
	    (unsigned long)rndis_mesg & (PAGE_SIZE - 1);
850
	pkt->page_buffers[0].length = rndis_msg_size;
851
852
	/* Save the packet context */
853
	filter_pkt->completion_context =
854
	    pkt->compl.send.send_completion_context;
855
856
	/* Use ours */
857
	pkt->compl.send.on_send_completion = hv_rf_on_send_completion;
858
	pkt->compl.send.send_completion_context = filter_pkt;
859
860
	/*
861
	 * If there is a VLAN tag, we need to set up some additional
862
	 * fields so the Hyper-V infrastructure will stuff the VLAN tag
863
	 * into the frame.
864
	 */
865
	if (pkt->vlan_tci != 0) {
866
		/* Move data offset past end of rppi + VLAN structs */
867
		rndis_pkt->data_offset += sizeof(rndis_per_packet_info) +
868
		    sizeof(ndis_8021q_info);
869
870
		/* must be set when we have rppi, VLAN info */
871
		rndis_pkt->per_pkt_info_offset = sizeof(rndis_packet);
872
		rndis_pkt->per_pkt_info_length = sizeof(rndis_per_packet_info) +
873
		    sizeof(ndis_8021q_info);
874
875
		/* rppi immediately follows rndis_pkt */
876
		rppi = (rndis_per_packet_info *)(rndis_pkt + 1);
877
		rppi->size = sizeof(rndis_per_packet_info) +
878
		    sizeof(ndis_8021q_info);
879
		rppi->type = ieee_8021q_info;
880
		rppi->per_packet_info_offset = sizeof(rndis_per_packet_info);
881
882
		/* VLAN info immediately follows rppi struct */
883
		rppi_vlan_info = (ndis_8021q_info *)(rppi + 1);
884
		/* FreeBSD does not support CFI or priority */
885
		rppi_vlan_info->u1.s1.vlan_id = pkt->vlan_tci & 0xfff;
886
	}
887
888
	/*
889
	 * Invoke netvsc send.  If return status is bad, the caller now
890
	 * resets the context pointers before retrying.
891
	 */
892
	ret = hv_nv_on_send(device, pkt);
893
894
	return (ret);
895
}
896
897
/*
898
 * RNDIS filter on send completion callback
899
 */
900
static void 
901
hv_rf_on_send_completion(void *context)
902
{
903
	rndis_filter_packet *filter_pkt = (rndis_filter_packet *)context;
904
905
	/* Pass it back to the original handler */
906
	netvsc_xmit_completion(filter_pkt->completion_context);
907
}
908
909
/*
943
 * RNDIS filter on send request completion callback
910
 * RNDIS filter on send request completion callback
944
 */
911
 */
945
static void 
912
static void 
(-)sys/dev/hyperv/netvsc/hv_net_vsc.h (-52 / +34 lines)
Lines 41-66 Link Here
41
#include <sys/types.h>
41
#include <sys/types.h>
42
#include <sys/param.h>
42
#include <sys/param.h>
43
#include <sys/lock.h>
43
#include <sys/lock.h>
44
#include <sys/malloc.h>
45
#include <sys/sx.h>
44
#include <sys/sx.h>
46
45
47
#include <dev/hyperv/include/hyperv.h>
46
#include <dev/hyperv/include/hyperv.h>
48
47
49
MALLOC_DECLARE(M_NETVSC);
50
48
51
#define NVSP_INVALID_PROTOCOL_VERSION           (0xFFFFFFFF)
49
#define NVSP_INVALID_PROTOCOL_VERSION           (0xFFFFFFFF)
52
50
53
#define NVSP_PROTOCOL_VERSION_1                 2
51
#define NVSP_PROTOCOL_VERSION_1                 2
54
#define NVSP_PROTOCOL_VERSION_2                 0x30002
52
#define NVSP_PROTOCOL_VERSION_2                 0x30002
55
#define NVSP_PROTOCOL_VERSION_4                 0x40000
56
#define NVSP_PROTOCOL_VERSION_5                 0x50000
57
#define NVSP_MIN_PROTOCOL_VERSION               (NVSP_PROTOCOL_VERSION_1)
53
#define NVSP_MIN_PROTOCOL_VERSION               (NVSP_PROTOCOL_VERSION_1)
58
#define NVSP_MAX_PROTOCOL_VERSION               (NVSP_PROTOCOL_VERSION_2)
54
#define NVSP_MAX_PROTOCOL_VERSION               (NVSP_PROTOCOL_VERSION_2)
59
55
60
#define NVSP_PROTOCOL_VERSION_CURRENT           NVSP_PROTOCOL_VERSION_2
56
#define NVSP_PROTOCOL_VERSION_CURRENT           NVSP_PROTOCOL_VERSION_2
61
57
62
#define VERSION_4_OFFLOAD_SIZE                  22
63
64
#define NVSP_OPERATIONAL_STATUS_OK              (0x00000000)
58
#define NVSP_OPERATIONAL_STATUS_OK              (0x00000000)
65
#define NVSP_OPERATIONAL_STATUS_DEGRADED        (0x00000001)
59
#define NVSP_OPERATIONAL_STATUS_DEGRADED        (0x00000001)
66
#define NVSP_OPERATIONAL_STATUS_NONRECOVERABLE  (0x00000002)
60
#define NVSP_OPERATIONAL_STATUS_NONRECOVERABLE  (0x00000002)
Lines 550-556 Link Here
550
544
551
545
552
#define NVSP_1_CHIMNEY_SEND_INVALID_OOB_INDEX       0xffffu
546
#define NVSP_1_CHIMNEY_SEND_INVALID_OOB_INDEX       0xffffu
553
#define NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX   0xffffffff
547
#define NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX   0xffffu
554
548
555
/*
549
/*
556
 * NvspMessage2TypeSendChimneyPacket
550
 * NvspMessage2TypeSendChimneyPacket
Lines 848-858 Link Here
848
 * Defines
842
 * Defines
849
 */
843
 */
850
844
851
#define NETVSC_SEND_BUFFER_SIZE			(1024*1024*15)   /* 15M */
845
#define NETVSC_SEND_BUFFER_SIZE			(64*1024)   /* 64K */
852
#define NETVSC_SEND_BUFFER_ID			0xface
846
#define NETVSC_SEND_BUFFER_ID			0xface
853
847
854
848
855
#define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024*16) /* 16MB */
849
#define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024) /* 1MB */
856
850
857
#define NETVSC_RECEIVE_BUFFER_ID		0xcafe
851
#define NETVSC_RECEIVE_BUFFER_ID		0xcafe
858
852
Lines 868-875 Link Here
868
 */
862
 */
869
#define NETVSC_MAX_CONFIGURABLE_MTU		(9 * 1024)
863
#define NETVSC_MAX_CONFIGURABLE_MTU		(9 * 1024)
870
864
871
#define NETVSC_PACKET_SIZE			PAGE_SIZE
872
873
/*
865
/*
874
 * Data types
866
 * Data types
875
 */
867
 */
Lines 881-894 Link Here
881
	struct hv_device			*dev;
873
	struct hv_device			*dev;
882
	int					num_outstanding_sends;
874
	int					num_outstanding_sends;
883
875
876
	/* List of free preallocated NETVSC_PACKET to represent RX packet */
877
	STAILQ_HEAD(PQ, netvsc_packet_)		myrx_packet_list;
878
	struct mtx				rx_pkt_list_lock;
879
884
	/* Send buffer allocated by us but manages by NetVSP */
880
	/* Send buffer allocated by us but manages by NetVSP */
885
	void					*send_buf;
881
	void					*send_buf;
886
	uint32_t				send_buf_size;
882
	uint32_t				send_buf_size;
887
	uint32_t				send_buf_gpadl_handle;
883
	uint32_t				send_buf_gpadl_handle;
888
	uint32_t				send_section_size;
884
	uint32_t				send_section_size;
889
	uint32_t				send_section_count;
890
	unsigned long				bitsmap_words;
891
	unsigned long				*send_section_bitsmap;
892
885
893
	/* Receive buffer allocated by us but managed by NetVSP */
886
	/* Receive buffer allocated by us but managed by NetVSP */
894
	void					*rx_buf;
887
	void					*rx_buf;
Lines 910-952 Link Here
910
	hv_bool_uint8_t				destroy;
903
	hv_bool_uint8_t				destroy;
911
	/* Negotiated NVSP version */
904
	/* Negotiated NVSP version */
912
	uint32_t				nvsp_version;
905
	uint32_t				nvsp_version;
913
	
914
	uint8_t					callback_buf[NETVSC_PACKET_SIZE]; 
915
} netvsc_dev;
906
} netvsc_dev;
916
907
917
908
918
typedef void (*pfn_on_send_rx_completion)(void *);
909
typedef void (*pfn_on_send_rx_completion)(void *);
919
910
920
#define NETVSC_DEVICE_RING_BUFFER_SIZE	(128 * PAGE_SIZE)
911
#define NETVSC_DEVICE_RING_BUFFER_SIZE   (64 * PAGE_SIZE)
921
#define NETVSC_PACKET_MAXPAGE		32 
912
#define NETVSC_PACKET_MAXPAGE            16
922
913
923
914
924
#define NETVSC_VLAN_PRIO_MASK		0xe000
915
typedef struct xfer_page_packet_ {
925
#define NETVSC_VLAN_PRIO_SHIFT		13
916
	/*
926
#define NETVSC_VLAN_VID_MASK		0x0fff
917
	 * This needs to be here because the network RX code casts
918
	 * an instantiation of this structure to a netvsc_packet.
919
	 */
920
	STAILQ_ENTRY(netvsc_packet_) mylist_entry;
927
921
928
#define TYPE_IPV4			2
922
	uint32_t count;
929
#define TYPE_IPV6			4
923
} xfer_page_packet;
930
#define TYPE_TCP			2
931
#define TYPE_UDP			4
932
924
933
#define TRANSPORT_TYPE_NOT_IP		0
934
#define TRANSPORT_TYPE_IPV4_TCP		((TYPE_IPV4 << 16) | TYPE_TCP)
935
#define TRANSPORT_TYPE_IPV4_UDP		((TYPE_IPV4 << 16) | TYPE_UDP)
936
#define TRANSPORT_TYPE_IPV6_TCP		((TYPE_IPV6 << 16) | TYPE_TCP)
937
#define TRANSPORT_TYPE_IPV6_UDP		((TYPE_IPV6 << 16) | TYPE_UDP)
938
939
#ifdef __LP64__
940
#define BITS_PER_LONG 64
941
#else
942
#define BITS_PER_LONG 32
943
#endif
944
945
typedef struct netvsc_packet_ {
925
typedef struct netvsc_packet_ {
926
	/*
927
	 * List used when enqueued on &net_dev->rx_packet_list,
928
	 * and when enqueued within the netvsc code
929
	 */
930
	STAILQ_ENTRY(netvsc_packet_) mylist_entry;
946
	struct hv_device           *device;
931
	struct hv_device           *device;
947
	hv_bool_uint8_t            is_data_pkt;      /* One byte */
932
	hv_bool_uint8_t            is_data_pkt;      /* One byte */
948
	uint16_t		   vlan_tci;
933
	uint16_t		   vlan_tci;
949
	uint32_t status;
934
	xfer_page_packet           *xfer_page_pkt;
950
935
951
	/* Completion */
936
	/* Completion */
952
	union {
937
	union {
Lines 963-974 Link Here
963
			pfn_on_send_rx_completion   on_send_completion;
948
			pfn_on_send_rx_completion   on_send_completion;
964
		} send;
949
		} send;
965
	} compl;
950
	} compl;
966
	uint32_t	send_buf_section_idx;
967
	uint32_t	send_buf_section_size;
968
951
969
	void		*rndis_mesg;
952
	void		*extension;
970
	uint32_t	tot_data_buf_len;
953
	uint32_t	tot_data_buf_len;
971
	void		*data;
972
	uint32_t	page_buf_count;
954
	uint32_t	page_buf_count;
973
	hv_vmbus_page_buffer	page_buffers[NETVSC_PACKET_MAXPAGE];
955
	hv_vmbus_page_buffer	page_buffers[NETVSC_PACKET_MAXPAGE];
974
} netvsc_packet;
956
} netvsc_packet;
Lines 1002-1017 Link Here
1002
 */
984
 */
1003
extern int hv_promisc_mode;
985
extern int hv_promisc_mode;
1004
986
1005
void netvsc_linkstatus_callback(struct hv_device *device_obj, uint32_t status);
987
extern void netvsc_linkstatus_callback(struct hv_device *device_obj,
1006
void netvsc_xmit_completion(void *context);
988
				       uint32_t status);
1007
void hv_nv_on_receive_completion(struct hv_device *device,
989
extern int  netvsc_recv(struct hv_device *device_obj, netvsc_packet *packet);
1008
    uint64_t tid, uint32_t status);
990
extern void netvsc_xmit_completion(void *context);
1009
netvsc_dev *hv_nv_on_device_add(struct hv_device *device,
1010
    void *additional_info);
1011
int hv_nv_on_device_remove(struct hv_device *device,
1012
    boolean_t destroy_channel);
1013
int hv_nv_on_send(struct hv_device *device, netvsc_packet *pkt);
1014
int hv_nv_get_next_send_section(netvsc_dev *net_dev);
1015
991
992
extern void hv_nv_on_receive_completion(void *context);
993
extern netvsc_dev *hv_nv_on_device_add(struct hv_device *device, void *additional_info);
994
extern int  hv_nv_on_device_remove(struct hv_device *device,
995
				   boolean_t destroy_channel);
996
extern int  hv_nv_on_send(struct hv_device *device, netvsc_packet *pkt);
997
1016
#endif  /* __HV_NET_VSC_H__ */
998
#endif  /* __HV_NET_VSC_H__ */
1017
999
(-)sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c (-328 / +63 lines)
Lines 55-63 Link Here
55
#include <sys/cdefs.h>
55
#include <sys/cdefs.h>
56
__FBSDID("$FreeBSD$");
56
__FBSDID("$FreeBSD$");
57
57
58
#include "opt_inet6.h"
59
#include "opt_inet.h"
60
61
#include <sys/param.h>
58
#include <sys/param.h>
62
#include <sys/systm.h>
59
#include <sys/systm.h>
63
#include <sys/sockio.h>
60
#include <sys/sockio.h>
Lines 86-94 Link Here
86
#include <netinet/in.h>
83
#include <netinet/in.h>
87
#include <netinet/ip.h>
84
#include <netinet/ip.h>
88
#include <netinet/if_ether.h>
85
#include <netinet/if_ether.h>
89
#include <netinet/tcp.h>
90
#include <netinet/udp.h>
91
#include <netinet/ip6.h>
92
86
93
#include <vm/vm.h>
87
#include <vm/vm.h>
94
#include <vm/vm_param.h>
88
#include <vm/vm_param.h>
Lines 109-116 Link Here
109
103
110
#include <machine/intr_machdep.h>
104
#include <machine/intr_machdep.h>
111
105
112
#include <machine/in_cksum.h>
113
114
#include <dev/hyperv/include/hyperv.h>
106
#include <dev/hyperv/include/hyperv.h>
115
#include "hv_net_vsc.h"
107
#include "hv_net_vsc.h"
116
#include "hv_rndis.h"
108
#include "hv_rndis.h"
Lines 173-234 Link Here
173
static int  hn_start_locked(struct ifnet *ifp);
165
static int  hn_start_locked(struct ifnet *ifp);
174
static void hn_start(struct ifnet *ifp);
166
static void hn_start(struct ifnet *ifp);
175
167
176
/*
177
 * NetVsc get message transport protocol type 
178
 */
179
static uint32_t get_transport_proto_type(struct mbuf *m_head)
180
{
181
	uint32_t ret_val = TRANSPORT_TYPE_NOT_IP;
182
	uint16_t ether_type = 0;
183
	int ether_len = 0;
184
	struct ether_vlan_header *eh;
185
#ifdef INET
186
	struct ip *iph;
187
#endif
188
#ifdef INET6
189
	struct ip6_hdr *ip6;
190
#endif
191
168
192
	eh = mtod(m_head, struct ether_vlan_header*);
193
	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
194
		ether_len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
195
		ether_type = eh->evl_proto;
196
	} else {
197
		ether_len = ETHER_HDR_LEN;
198
		ether_type = eh->evl_encap_proto;
199
	}
200
201
	switch (ntohs(ether_type)) {
202
#ifdef INET6
203
	case ETHERTYPE_IPV6:
204
		ip6 = (struct ip6_hdr *)(m_head->m_data + ether_len);
205
206
		if (IPPROTO_TCP == ip6->ip6_nxt) {
207
			ret_val = TRANSPORT_TYPE_IPV6_TCP;
208
		} else if (IPPROTO_UDP == ip6->ip6_nxt) {
209
			ret_val = TRANSPORT_TYPE_IPV6_UDP;
210
		}
211
		break;
212
#endif
213
#ifdef INET
214
	case ETHERTYPE_IP:
215
		iph = (struct ip *)(m_head->m_data + ether_len);
216
217
		if (IPPROTO_TCP == iph->ip_p) {
218
			ret_val = TRANSPORT_TYPE_IPV4_TCP;
219
		} else if (IPPROTO_UDP == iph->ip_p) {
220
			ret_val = TRANSPORT_TYPE_IPV4_UDP;
221
		}
222
		break;
223
#endif
224
	default:
225
		ret_val = TRANSPORT_TYPE_NOT_IP;
226
		break;
227
	}
228
229
	return (ret_val);
230
}
231
232
/*
169
/*
233
 * NetVsc driver initialization
170
 * NetVsc driver initialization
234
 * Note:  Filter init is no longer required
171
 * Note:  Filter init is no longer required
Lines 339-349 Link Here
339
	 * Tell upper layers that we support full VLAN capability.
276
	 * Tell upper layers that we support full VLAN capability.
340
	 */
277
	 */
341
	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
278
	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
342
	ifp->if_capabilities |=
279
	ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
343
	    IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_TSO;
280
	ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
344
	ifp->if_capenable |=
345
	    IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_TSO;
346
	ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_TSO;
347
281
348
	ret = hv_rf_on_device_add(device_ctx, &device_info);
282
	ret = hv_rf_on_device_add(device_ctx, &device_info);
349
	if (ret != 0) {
283
	if (ret != 0) {
Lines 413-419 Link Here
413
	mb = (struct mbuf *)(uintptr_t)packet->compl.send.send_completion_tid;
347
	mb = (struct mbuf *)(uintptr_t)packet->compl.send.send_completion_tid;
414
	buf = ((uint8_t *)packet) - HV_NV_PACKET_OFFSET_IN_BUF;
348
	buf = ((uint8_t *)packet) - HV_NV_PACKET_OFFSET_IN_BUF;
415
349
416
	free(buf, M_NETVSC);
350
	free(buf, M_DEVBUF);
417
351
418
	if (mb != NULL) {
352
	if (mb != NULL) {
419
		m_freem(mb);
353
		m_freem(mb);
Lines 428-456 Link Here
428
{
362
{
429
	hn_softc_t *sc = ifp->if_softc;
363
	hn_softc_t *sc = ifp->if_softc;
430
	struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
364
	struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
431
	netvsc_dev *net_dev = sc->net_dev;
432
	device_t dev = device_ctx->device;
433
	uint8_t *buf;
365
	uint8_t *buf;
434
	netvsc_packet *packet;
366
	netvsc_packet *packet;
435
	struct mbuf *m_head, *m;
367
	struct mbuf *m_head, *m;
436
	struct mbuf *mc_head = NULL;
368
	struct mbuf *mc_head = NULL;
437
	struct ether_vlan_header *eh;
438
	rndis_msg *rndis_mesg;
439
	rndis_packet *rndis_pkt;
440
	rndis_per_packet_info *rppi;
441
	ndis_8021q_info *rppi_vlan_info;
442
	rndis_tcp_ip_csum_info *csum_info;
443
	rndis_tcp_tso_info *tso_info;	
444
	int ether_len;
445
	int i;
369
	int i;
446
	int num_frags;
370
	int num_frags;
447
	int len;
371
	int len;
372
	int xlen;
373
	int rppi_size;
448
	int retries = 0;
374
	int retries = 0;
449
	int ret = 0;	
375
	int ret = 0;
450
	uint32_t rndis_msg_size = 0;
451
	uint32_t trans_proto_type;
452
	uint32_t send_buf_section_idx =
453
	    NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
454
376
455
	while (!IFQ_DRV_IS_EMPTY(&sc->hn_ifp->if_snd)) {
377
	while (!IFQ_DRV_IS_EMPTY(&sc->hn_ifp->if_snd)) {
456
		IFQ_DRV_DEQUEUE(&sc->hn_ifp->if_snd, m_head);
378
		IFQ_DRV_DEQUEUE(&sc->hn_ifp->if_snd, m_head);
Lines 460-465 Link Here
460
382
461
		len = 0;
383
		len = 0;
462
		num_frags = 0;
384
		num_frags = 0;
385
		xlen = 0;
463
386
464
		/* Walk the mbuf list computing total length and num frags */
387
		/* Walk the mbuf list computing total length and num frags */
465
		for (m = m_head; m != NULL; m = m->m_next) {
388
		for (m = m_head; m != NULL; m = m->m_next) {
Lines 478-512 Link Here
478
401
479
		/* If exceeds # page_buffers in netvsc_packet */
402
		/* If exceeds # page_buffers in netvsc_packet */
480
		if (num_frags > NETVSC_PACKET_MAXPAGE) {
403
		if (num_frags > NETVSC_PACKET_MAXPAGE) {
481
			device_printf(dev, "exceed max page buffers,%d,%d\n",
404
			m_freem(m);
482
			    num_frags, NETVSC_PACKET_MAXPAGE);
405
483
			m_freem(m_head);
484
			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
485
			return (EINVAL);
406
			return (EINVAL);
486
		}
407
		}
487
408
409
		rppi_size = 0;
410
		if (m_head->m_flags & M_VLANTAG) {
411
			rppi_size = sizeof(rndis_per_packet_info) + 
412
			    sizeof(ndis_8021q_info);
413
		}
414
488
		/*
415
		/*
489
		 * Allocate a buffer with space for a netvsc packet plus a
416
		 * Allocate a buffer with space for a netvsc packet plus a
490
		 * number of reserved areas.  First comes a (currently 16
417
		 * number of reserved areas.  First comes a (currently 16
491
		 * bytes, currently unused) reserved data area.  Second is
418
		 * bytes, currently unused) reserved data area.  Second is
492
		 * the netvsc_packet. Third is an area reserved for an 
419
		 * the netvsc_packet, which includes (currently 4) page
493
		 * rndis_filter_packet struct. Fourth (optional) is a 
420
		 * buffers.  Third (optional) is a rndis_per_packet_info
494
		 * rndis_per_packet_info struct.
421
		 * struct, but only if a VLAN tag should be inserted into the
422
		 * Ethernet frame by the Hyper-V infrastructure.  Fourth is
423
		 * an area reserved for an rndis_filter_packet struct.
495
		 * Changed malloc to M_NOWAIT to avoid sleep under spin lock.
424
		 * Changed malloc to M_NOWAIT to avoid sleep under spin lock.
496
		 * No longer reserving extra space for page buffers, as they
425
		 * No longer reserving extra space for page buffers, as they
497
		 * are already part of the netvsc_packet.
426
		 * are already part of the netvsc_packet.
498
		 */
427
		 */
499
		buf = malloc(HV_NV_PACKET_OFFSET_IN_BUF +
428
		buf = malloc(HV_NV_PACKET_OFFSET_IN_BUF +
500
			sizeof(netvsc_packet) + 
429
		    sizeof(netvsc_packet) + rppi_size +
501
			sizeof(rndis_msg) +
430
		    sizeof(rndis_filter_packet),
502
			RNDIS_VLAN_PPI_SIZE +
431
		    M_DEVBUF, M_ZERO | M_NOWAIT);
503
			RNDIS_TSO_PPI_SIZE +
504
			RNDIS_CSUM_PPI_SIZE,
505
			M_NETVSC, M_ZERO | M_NOWAIT);
506
		if (buf == NULL) {
432
		if (buf == NULL) {
507
			device_printf(dev, "hn:malloc packet failed\n");
433
			m_freem(m);
508
			m_freem(m_head);
434
509
			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
510
			return (ENOMEM);
435
			return (ENOMEM);
511
		}
436
		}
512
437
Lines 513-526 Link Here
513
		packet = (netvsc_packet *)(buf + HV_NV_PACKET_OFFSET_IN_BUF);
438
		packet = (netvsc_packet *)(buf + HV_NV_PACKET_OFFSET_IN_BUF);
514
		*(vm_offset_t *)buf = HV_NV_SC_PTR_OFFSET_IN_BUF;
439
		*(vm_offset_t *)buf = HV_NV_SC_PTR_OFFSET_IN_BUF;
515
440
516
		packet->is_data_pkt = TRUE;
517
518
		/* Set up the rndis header */
519
		packet->page_buf_count = num_frags;
520
521
		/* Initialize it from the mbuf */
522
		packet->tot_data_buf_len = len;
523
524
		/*
441
		/*
525
		 * extension points to the area reserved for the
442
		 * extension points to the area reserved for the
526
		 * rndis_filter_packet, which is placed just after
443
		 * rndis_filter_packet, which is placed just after
Lines 527-702 Link Here
527
		 * the netvsc_packet (and rppi struct, if present;
444
		 * the netvsc_packet (and rppi struct, if present;
528
		 * length is updated later).
445
		 * length is updated later).
529
		 */
446
		 */
530
		packet->rndis_mesg = packet + 1;
447
		packet->extension = packet + 1;
531
		rndis_mesg = (rndis_msg *)packet->rndis_mesg;
532
		rndis_mesg->ndis_msg_type = REMOTE_NDIS_PACKET_MSG;
533
448
534
		rndis_pkt = &rndis_mesg->msg.packet;
449
		/* Set up the rndis header */
535
		rndis_pkt->data_offset = sizeof(rndis_packet);
450
		packet->page_buf_count = num_frags;
536
		rndis_pkt->data_length = packet->tot_data_buf_len;
537
		rndis_pkt->per_pkt_info_offset = sizeof(rndis_packet);
538
451
539
		rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet);
452
		/* Initialize it from the mbuf */
453
		packet->tot_data_buf_len = len;
540
454
541
		/*
455
		/*
542
		 * If the Hyper-V infrastructure needs to embed a VLAN tag,
456
		 * If the Hyper-V infrastructure needs to embed a VLAN tag,
543
		 * initialize netvsc_packet and rppi struct values as needed.
457
		 * initialize netvsc_packet and rppi struct values as needed.
544
		 */
458
		 */
545
		if (m_head->m_flags & M_VLANTAG) {
459
		if (rppi_size) {
546
			/*
460
			/* Lower layers need the VLAN TCI */
547
			 * set up some additional fields so the Hyper-V infrastructure will stuff the VLAN tag
548
			 * into the frame.
549
			 */
550
			packet->vlan_tci = m_head->m_pkthdr.ether_vtag;
461
			packet->vlan_tci = m_head->m_pkthdr.ether_vtag;
551
552
			rndis_msg_size += RNDIS_VLAN_PPI_SIZE;
553
554
			rppi = hv_set_rppi_data(rndis_mesg, RNDIS_VLAN_PPI_SIZE,
555
			    ieee_8021q_info);
556
		
557
			/* VLAN info immediately follows rppi struct */
558
			rppi_vlan_info = (ndis_8021q_info *)((char*)rppi + 
559
			    rppi->per_packet_info_offset);
560
			/* FreeBSD does not support CFI or priority */
561
			rppi_vlan_info->u1.s1.vlan_id =
562
			    packet->vlan_tci & 0xfff;
563
		}
462
		}
564
463
565
		if (0 == m_head->m_pkthdr.csum_flags) {
566
			goto pre_send;
567
		}
568
569
		eh = mtod(m_head, struct ether_vlan_header*);
570
		if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
571
			ether_len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
572
		} else {
573
			ether_len = ETHER_HDR_LEN;
574
		}
575
576
		trans_proto_type = get_transport_proto_type(m_head);
577
		if (TRANSPORT_TYPE_NOT_IP == trans_proto_type) {
578
			goto pre_send;
579
		}
580
581
		/*
464
		/*
582
		 * TSO packet needless to setup the send side checksum
583
		 * offload.
584
		 */
585
		if (m_head->m_pkthdr.csum_flags & CSUM_TSO) {
586
			goto do_tso;
587
		}
588
589
		/* setup checksum offload */
590
		rndis_msg_size += RNDIS_CSUM_PPI_SIZE;
591
		rppi = hv_set_rppi_data(rndis_mesg, RNDIS_CSUM_PPI_SIZE,
592
		    tcpip_chksum_info);
593
		csum_info = (rndis_tcp_ip_csum_info *)((char*)rppi +
594
		    rppi->per_packet_info_offset);
595
596
		if (trans_proto_type & (TYPE_IPV4 << 16)) {
597
			csum_info->xmit.is_ipv4 = 1;
598
		} else {
599
			csum_info->xmit.is_ipv6 = 1;
600
		}
601
602
		if (trans_proto_type & TYPE_TCP) {
603
			csum_info->xmit.tcp_csum = 1;
604
			csum_info->xmit.tcp_header_offset = 0;
605
		} else if (trans_proto_type & TYPE_UDP) {
606
			csum_info->xmit.udp_csum = 1;
607
		}
608
609
		goto pre_send;
610
611
do_tso:
612
		/* setup TCP segmentation offload */
613
		rndis_msg_size += RNDIS_TSO_PPI_SIZE;
614
		rppi = hv_set_rppi_data(rndis_mesg, RNDIS_TSO_PPI_SIZE,
615
		    tcp_large_send_info);
616
		
617
		tso_info = (rndis_tcp_tso_info *)((char *)rppi +
618
		    rppi->per_packet_info_offset);
619
		tso_info->lso_v2_xmit.type =
620
		    RNDIS_TCP_LARGE_SEND_OFFLOAD_V2_TYPE;
621
		
622
#ifdef INET
623
		if (trans_proto_type & (TYPE_IPV4 << 16)) {
624
			struct ip *ip =
625
			    (struct ip *)(m_head->m_data + ether_len);
626
			unsigned long iph_len = ip->ip_hl << 2;
627
			struct tcphdr *th =
628
			    (struct tcphdr *)((caddr_t)ip + iph_len);
629
		
630
			tso_info->lso_v2_xmit.ip_version =
631
			    RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV4;
632
			ip->ip_len = 0;
633
			ip->ip_sum = 0;
634
		
635
			th->th_sum = in_pseudo(ip->ip_src.s_addr,
636
			    ip->ip_dst.s_addr,
637
			    htons(IPPROTO_TCP));
638
		}
639
#endif
640
#if defined(INET6) && defined(INET)
641
		else
642
#endif
643
#ifdef INET6
644
		{
645
			struct ip6_hdr *ip6 =
646
			    (struct ip6_hdr *)(m_head->m_data + ether_len);
647
			struct tcphdr *th = (struct tcphdr *)(ip6 + 1);
648
649
			tso_info->lso_v2_xmit.ip_version =
650
			    RNDIS_TCP_LARGE_SEND_OFFLOAD_IPV6;
651
			ip6->ip6_plen = 0;
652
			th->th_sum = in6_cksum_pseudo(ip6, 0, IPPROTO_TCP, 0);
653
		}
654
#endif
655
		tso_info->lso_v2_xmit.tcp_header_offset = 0;
656
		tso_info->lso_v2_xmit.mss = m_head->m_pkthdr.tso_segsz;
657
658
pre_send:
659
		rndis_mesg->msg_len = packet->tot_data_buf_len + rndis_msg_size;
660
		packet->tot_data_buf_len = rndis_mesg->msg_len;
661
662
		/* send packet with send buffer */
663
		if (packet->tot_data_buf_len < net_dev->send_section_size) {
664
			send_buf_section_idx =
665
			    hv_nv_get_next_send_section(net_dev);
666
			if (send_buf_section_idx !=
667
			    NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
668
				char *dest = ((char *)net_dev->send_buf +
669
				    send_buf_section_idx *
670
				    net_dev->send_section_size);
671
672
				memcpy(dest, rndis_mesg, rndis_msg_size);
673
				dest += rndis_msg_size;
674
				for (m = m_head; m != NULL; m = m->m_next) {
675
					if (m->m_len) {
676
						memcpy(dest,
677
						    (void *)mtod(m, vm_offset_t),
678
						    m->m_len);
679
						dest += m->m_len;
680
					}
681
				}
682
683
				packet->send_buf_section_idx =
684
				    send_buf_section_idx;
685
				packet->send_buf_section_size =
686
				    packet->tot_data_buf_len;
687
				packet->page_buf_count = 0;
688
				goto do_send;
689
			}
690
		}
691
692
		/* send packet with page buffer */
693
		packet->page_buffers[0].pfn =
694
		    atop(hv_get_phys_addr(rndis_mesg));
695
		packet->page_buffers[0].offset =
696
		    (unsigned long)rndis_mesg & PAGE_MASK;
697
		packet->page_buffers[0].length = rndis_msg_size;
698
699
		/*
700
		 * Fill the page buffers with mbuf info starting at index
465
		 * Fill the page buffers with mbuf info starting at index
701
		 * HV_RF_NUM_TX_RESERVED_PAGE_BUFS.
466
		 * HV_RF_NUM_TX_RESERVED_PAGE_BUFS.
702
		 */
467
		 */
Lines 714-725 Link Here
714
			}
479
			}
715
		}
480
		}
716
481
717
		packet->send_buf_section_idx = 
718
		    NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
719
		packet->send_buf_section_size = 0;
720
721
do_send:
722
723
		/*
482
		/*
724
		 * If bpf, copy the mbuf chain.  This is less expensive than
483
		 * If bpf, copy the mbuf chain.  This is less expensive than
725
		 * it appears; the mbuf clusters are not copied, only their
484
		 * it appears; the mbuf clusters are not copied, only their
Lines 738-744 Link Here
738
		packet->compl.send.send_completion_tid = (uint64_t)(uintptr_t)m_head;
497
		packet->compl.send.send_completion_tid = (uint64_t)(uintptr_t)m_head;
739
498
740
		/* Removed critical_enter(), does not appear necessary */
499
		/* Removed critical_enter(), does not appear necessary */
741
		ret = hv_nv_on_send(device_ctx, packet);
500
		ret = hv_rf_on_send(device_ctx, packet);
501
742
		if (ret == 0) {
502
		if (ret == 0) {
743
			ifp->if_opackets++;
503
			ifp->if_opackets++;
744
			/* if bpf && mc_head, call bpf_mtap code */
504
			/* if bpf && mc_head, call bpf_mtap code */
Lines 766-772 Link Here
766
			 * send completion
526
			 * send completion
767
			 */
527
			 */
768
			netvsc_xmit_completion(packet);
528
			netvsc_xmit_completion(packet);
769
			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
770
		}
529
		}
771
530
772
		/* if bpf && mc_head, free the mbuf chain copy */
531
		/* if bpf && mc_head, free the mbuf chain copy */
Lines 862-875 Link Here
862
 * Note:  This is no longer used as a callback
621
 * Note:  This is no longer used as a callback
863
 */
622
 */
864
int
623
int
865
netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet,
624
netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet)
866
    rndis_tcp_ip_csum_info *csum_info)
867
{
625
{
868
	hn_softc_t *sc = (hn_softc_t *)device_get_softc(device_ctx->device);
626
	hn_softc_t *sc = (hn_softc_t *)device_get_softc(device_ctx->device);
869
	struct mbuf *m_new;
627
	struct mbuf *m_new;
870
	struct ifnet *ifp;
628
	struct ifnet *ifp;
871
	device_t dev = device_ctx->device;
872
	int size;
629
	int size;
630
	int i;
873
631
874
	if (sc == NULL) {
632
	if (sc == NULL) {
875
		return (0); /* TODO: KYS how can this be! */
633
		return (0); /* TODO: KYS how can this be! */
Lines 905-939 Link Here
905
663
906
	m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, size);
664
	m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, size);
907
665
908
	if (m_new == NULL) {
666
	if (m_new == NULL)
909
		device_printf(dev, "alloc mbuf failed.\n");
910
		return (0);
667
		return (0);
911
	}
912
668
913
	hv_m_append(m_new, packet->tot_data_buf_len,
669
	/*
914
			packet->data);
670
	 * Remove trailing junk from RX data buffer.
671
	 * Fixme:  This will not work for multiple Hyper-V RX buffers.
672
	 * Fortunately, the channel gathers all RX data into one buffer.
673
	 *
674
	 * L2 frame length, with L2 header, not including CRC
675
	 */
676
	packet->page_buffers[0].length = packet->tot_data_buf_len;
915
677
916
	m_new->m_pkthdr.rcvif = ifp;
678
	/*
679
	 * Copy the received packet to one or more mbufs. 
680
	 * The copy is required since the memory pointed to by netvsc_packet
681
	 * cannot be deallocated
682
	 */
683
	for (i=0; i < packet->page_buf_count; i++) {
684
		/* Shift virtual page number to form virtual page address */
685
		uint8_t *vaddr = (uint8_t *)(uintptr_t)
686
		    (packet->page_buffers[i].pfn << PAGE_SHIFT);
917
687
918
	/* receive side checksum offload */
688
		hv_m_append(m_new, packet->page_buffers[i].length,
919
	m_new->m_pkthdr.csum_flags = 0;
689
		    vaddr + packet->page_buffers[i].offset);
920
	if (NULL != csum_info) {
921
		/* IP csum offload */
922
		if (csum_info->receive.ip_csum_succeeded) {
923
			m_new->m_pkthdr.csum_flags |=
924
			    (CSUM_IP_CHECKED | CSUM_IP_VALID);
925
		}
926
927
		/* TCP csum offload */
928
		if (csum_info->receive.tcp_csum_succeeded) {
929
			m_new->m_pkthdr.csum_flags |=
930
			    (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
931
			m_new->m_pkthdr.csum_data = 0xffff;
932
		}
933
	}
690
	}
934
691
692
	m_new->m_pkthdr.rcvif = ifp;
693
935
	if ((packet->vlan_tci != 0) &&
694
	if ((packet->vlan_tci != 0) &&
936
	    (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
695
			    (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
937
		m_new->m_pkthdr.ether_vtag = packet->vlan_tci;
696
		m_new->m_pkthdr.ether_vtag = packet->vlan_tci;
938
		m_new->m_flags |= M_VLANTAG;
697
		m_new->m_flags |= M_VLANTAG;
939
	}
698
	}
Lines 971-979 Link Here
971
{
730
{
972
	hn_softc_t *sc = ifp->if_softc;
731
	hn_softc_t *sc = ifp->if_softc;
973
	struct ifreq *ifr = (struct ifreq *)data;
732
	struct ifreq *ifr = (struct ifreq *)data;
974
#ifdef INET
975
	struct ifaddr *ifa = (struct ifaddr *)data;
976
#endif
977
	netvsc_device_info device_info;
733
	netvsc_device_info device_info;
978
	struct hv_device *hn_dev;
734
	struct hv_device *hn_dev;
979
	int mask, error = 0;
735
	int mask, error = 0;
Lines 1104-1137 Link Here
1104
		break;
860
		break;
1105
	case SIOCSIFCAP:
861
	case SIOCSIFCAP:
1106
		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
862
		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
1107
		if (mask & IFCAP_TXCSUM) {
863
		if (mask & IFCAP_HWCSUM) {
1108
			if (IFCAP_TXCSUM & ifp->if_capenable) {
864
			if (IFCAP_HWCSUM & ifp->if_capenable) {
1109
				ifp->if_capenable &= ~IFCAP_TXCSUM;
865
				ifp->if_capenable &= ~IFCAP_HWCSUM;
1110
				ifp->if_hwassist &= ~(CSUM_TCP | CSUM_UDP);
1111
			} else {
866
			} else {
1112
				ifp->if_capenable |= IFCAP_TXCSUM;
867
				ifp->if_capenable |= IFCAP_HWCSUM;
1113
				ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
1114
			}
868
			}
1115
		}
869
		}
1116
1117
		if (mask & IFCAP_RXCSUM) {
1118
			if (IFCAP_RXCSUM & ifp->if_capenable) {
1119
				ifp->if_capenable &= ~IFCAP_RXCSUM;
1120
			} else {
1121
				ifp->if_capenable |= IFCAP_RXCSUM;
1122
			}
1123
		}
1124
1125
		if (mask & IFCAP_TSO4) {
1126
			ifp->if_capenable ^= IFCAP_TSO4;
1127
			ifp->if_hwassist ^= CSUM_IP_TSO;
1128
		}
1129
1130
		if (mask & IFCAP_TSO6) {
1131
			ifp->if_capenable ^= IFCAP_TSO6;
1132
			ifp->if_hwassist ^= CSUM_IP6_TSO;
1133
		}
1134
1135
		error = 0;
870
		error = 0;
1136
		break;
871
		break;
1137
	case SIOCADDMULTI:
872
	case SIOCADDMULTI:
(-)sys/dev/hyperv/netvsc/hv_rndis_filter.h (-8 / +17 lines)
Lines 24-31 Link Here
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 *
28
 * $FreeBSD$
29
 */
27
 */
30
28
31
#ifndef __HV_RNDIS_FILTER_H__
29
#ifndef __HV_RNDIS_FILTER_H__
Lines 92-107 Link Here
92
	uint8_t				hw_mac_addr[HW_MACADDR_LEN];
90
	uint8_t				hw_mac_addr[HW_MACADDR_LEN];
93
} rndis_device;
91
} rndis_device;
94
92
93
typedef struct rndis_filter_packet_ {
94
	void				*completion_context;
95
	/* No longer used */
96
	pfn_on_send_rx_completion	on_completion;
97
98
	rndis_msg			message;
99
} rndis_filter_packet;
100
101
95
/*
102
/*
96
 * Externs
103
 * Externs
97
 */
104
 */
98
105
99
int hv_rf_on_receive(netvsc_dev *net_dev,
106
extern int  hv_rf_on_receive(struct hv_device *device, netvsc_packet *pkt);
100
    struct hv_device *device, netvsc_packet *pkt);
107
extern int  hv_rf_on_device_add(struct hv_device *device, void *additl_info);
101
int hv_rf_on_device_add(struct hv_device *device, void *additl_info);
108
extern int  hv_rf_on_device_remove(struct hv_device *device,
102
int hv_rf_on_device_remove(struct hv_device *device, boolean_t destroy_channel);
109
				   boolean_t destroy_channel);
103
int hv_rf_on_open(struct hv_device *device);
110
extern int  hv_rf_on_open(struct hv_device *device);
104
int hv_rf_on_close(struct hv_device *device);
111
extern int  hv_rf_on_close(struct hv_device *device);
112
extern int  hv_rf_on_send(struct hv_device *device, netvsc_packet *pkt);
105
113
114
106
#endif  /* __HV_RNDIS_FILTER_H__ */
115
#endif  /* __HV_RNDIS_FILTER_H__ */
107
116
(-)sys/dev/hyperv/include/hyperv.h (-1 / +1 lines)
Lines 107-113 Link Here
107
#define HV_MAX_PIPE_USER_DEFINED_BYTES	116
107
#define HV_MAX_PIPE_USER_DEFINED_BYTES	116
108
108
109
109
110
#define HV_MAX_PAGE_BUFFER_COUNT	32
110
#define HV_MAX_PAGE_BUFFER_COUNT	16
111
#define HV_MAX_MULTIPAGE_BUFFER_COUNT	32
111
#define HV_MAX_MULTIPAGE_BUFFER_COUNT	32
112
112
113
#define HV_ALIGN_UP(value, align)					\
113
#define HV_ALIGN_UP(value, align)					\

Return to bug 203630