]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / hyperv / netvsc / hv_netvsc_drv_freebsd.c
1 /*-
2  * Copyright (c) 2010-2012 Citrix Inc.
3  * Copyright (c) 2009-2012 Microsoft Corp.
4  * Copyright (c) 2012 NetApp Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
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
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*-
30  * Copyright (c) 2004-2006 Kip Macy
31  * All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  * 1. Redistributions of source code must retain the above copyright
37  *    notice, this list of conditions and the following disclaimer.
38  * 2. Redistributions in binary form must reproduce the above copyright
39  *    notice, this list of conditions and the following disclaimer in the
40  *    documentation and/or other materials provided with the distribution.
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
43  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
46  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52  * SUCH DAMAGE.
53  */
54
55 #include <sys/cdefs.h>
56 __FBSDID("$FreeBSD$");
57
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/sockio.h>
61 #include <sys/mbuf.h>
62 #include <sys/malloc.h>
63 #include <sys/module.h>
64 #include <sys/kernel.h>
65 #include <sys/socket.h>
66 #include <sys/queue.h>
67 #include <sys/lock.h>
68 #include <sys/sx.h>
69
70 #include <net/if.h>
71 #include <net/if_arp.h>
72 #include <net/ethernet.h>
73 #include <net/if_dl.h>
74 #include <net/if_media.h>
75
76 #include <net/bpf.h>
77
78 #include <net/if_types.h>
79 #include <net/if_vlan_var.h>
80 #include <net/if.h>
81
82 #include <netinet/in_systm.h>
83 #include <netinet/in.h>
84 #include <netinet/ip.h>
85 #include <netinet/if_ether.h>
86
87 #include <vm/vm.h>
88 #include <vm/vm_param.h>
89 #include <vm/vm_kern.h>
90 #include <vm/pmap.h>
91
92 #include <machine/bus.h>
93 #include <machine/resource.h>
94 #include <machine/frame.h>
95 #include <machine/vmparam.h>
96
97 #include <sys/bus.h>
98 #include <sys/rman.h>
99 #include <sys/mutex.h>
100 #include <sys/errno.h>
101 #include <sys/types.h>
102 #include <machine/atomic.h>
103
104 #include <machine/intr_machdep.h>
105
106 #include <dev/hyperv/include/hyperv.h>
107 #include "hv_net_vsc.h"
108 #include "hv_rndis.h"
109 #include "hv_rndis_filter.h"
110
111
112 /* Short for Hyper-V network interface */
113 #define NETVSC_DEVNAME    "hn"
114
115 /*
116  * It looks like offset 0 of buf is reserved to hold the softc pointer.
117  * The sc pointer evidently not needed, and is not presently populated.
118  * The packet offset is where the netvsc_packet starts in the buffer.
119  */
120 #define HV_NV_SC_PTR_OFFSET_IN_BUF         0
121 #define HV_NV_PACKET_OFFSET_IN_BUF         16
122
123
124 /*
125  * Data types
126  */
127
128 struct hv_netvsc_driver_context {
129         uint32_t                drv_inited;
130 };
131
132 /*
133  * Be aware that this sleepable mutex will exhibit WITNESS errors when
134  * certain TCP and ARP code paths are taken.  This appears to be a
135  * well-known condition, as all other drivers checked use a sleeping
136  * mutex to protect their transmit paths.
137  * Also Be aware that mutexes do not play well with semaphores, and there
138  * is a conflicting semaphore in a certain channel code path.
139  */
140 #define NV_LOCK_INIT(_sc, _name) \
141             mtx_init(&(_sc)->hn_lock, _name, MTX_NETWORK_LOCK, MTX_DEF)
142 #define NV_LOCK(_sc)            mtx_lock(&(_sc)->hn_lock)
143 #define NV_LOCK_ASSERT(_sc)     mtx_assert(&(_sc)->hn_lock, MA_OWNED)
144 #define NV_UNLOCK(_sc)          mtx_unlock(&(_sc)->hn_lock)
145 #define NV_LOCK_DESTROY(_sc)    mtx_destroy(&(_sc)->hn_lock)
146
147
148 /*
149  * Globals
150  */
151
152 int hv_promisc_mode = 0;    /* normal mode by default */
153
154 /* The one and only one */
155 static struct hv_netvsc_driver_context g_netvsc_drv;
156
157
158 /*
159  * Forward declarations
160  */
161 static void hn_stop(hn_softc_t *sc);
162 static void hn_ifinit_locked(hn_softc_t *sc);
163 static void hn_ifinit(void *xsc);
164 static int  hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
165 static int  hn_start_locked(struct ifnet *ifp);
166 static void hn_start(struct ifnet *ifp);
167
168
169 /*
170  * NetVsc driver initialization
171  * Note:  Filter init is no longer required
172  */
173 static int
174 netvsc_drv_init(void)
175 {
176         return (0);
177 }
178
179 /*
180  * NetVsc global initialization entry point
181  */
182 static void
183 netvsc_init(void)
184 {
185         printf("Netvsc initializing... ");
186
187         /*
188          * XXXKYS: cleanup initialization
189          */
190         if (!cold && !g_netvsc_drv.drv_inited) {
191                 g_netvsc_drv.drv_inited = 1;
192                 netvsc_drv_init();
193         } else {
194                 printf("Already initialized!\n");
195         }
196 }
197
198 /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
199 static const hv_guid g_net_vsc_device_type = {
200         .data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
201                 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}
202 };
203
204 /*
205  * Standard probe entry point.
206  *
207  */
208 static int
209 netvsc_probe(device_t dev)
210 {
211         const char *p;
212
213         p = vmbus_get_type(dev);
214         if (!memcmp(p, &g_net_vsc_device_type.data, sizeof(hv_guid))) {
215                 device_set_desc(dev, "Synthetic Network Interface");
216                 printf("Netvsc probe... DONE \n");
217
218                 return (0);
219         }
220
221         return (ENXIO);
222 }
223
224 /*
225  * Standard attach entry point.
226  *
227  * Called when the driver is loaded.  It allocates needed resources,
228  * and initializes the "hardware" and software.
229  */
230 static int
231 netvsc_attach(device_t dev)
232 {
233         struct hv_device *device_ctx = vmbus_get_devctx(dev);
234         netvsc_device_info device_info;
235         hn_softc_t *sc;
236         int unit = device_get_unit(dev);
237         struct ifnet *ifp;
238         int ret;
239
240         netvsc_init();
241
242         sc = device_get_softc(dev);
243         if (sc == NULL) {
244                 return (ENOMEM);
245         }
246
247         bzero(sc, sizeof(hn_softc_t));
248         sc->hn_unit = unit;
249         sc->hn_dev = dev;
250
251         NV_LOCK_INIT(sc, "NetVSCLock");
252
253         sc->hn_dev_obj = device_ctx;
254
255         ifp = sc->hn_ifp = sc->arpcom.ac_ifp = if_alloc(IFT_ETHER);
256         ifp->if_softc = sc;
257
258         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
259         ifp->if_dunit = unit;
260         ifp->if_dname = NETVSC_DEVNAME;
261
262         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
263         ifp->if_ioctl = hn_ioctl;
264         ifp->if_start = hn_start;
265         ifp->if_init = hn_ifinit;
266         /* needed by hv_rf_on_device_add() code */
267         ifp->if_mtu = ETHERMTU;
268         IFQ_SET_MAXLEN(&ifp->if_snd, 512);
269         ifp->if_snd.ifq_drv_maxlen = 511;
270         IFQ_SET_READY(&ifp->if_snd);
271
272         /*
273          * Tell upper layers that we support full VLAN capability.
274          */
275         ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
276         ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
277         ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
278
279         ret = hv_rf_on_device_add(device_ctx, &device_info);
280         if (ret != 0) {
281                 if_free(ifp);
282
283                 return (ret);
284         }
285         if (device_info.link_state == 0) {
286                 sc->hn_carrier = 1;
287         }
288
289         ether_ifattach(ifp, device_info.mac_addr);
290
291         return (0);
292 }
293
294 /*
295  * Standard detach entry point
296  */
297 static int
298 netvsc_detach(device_t dev)
299 {
300         struct hv_device *hv_device = vmbus_get_devctx(dev); 
301
302         printf("netvsc_detach\n");
303
304         /*
305          * XXXKYS:  Need to clean up all our
306          * driver state; this is the driver
307          * unloading.
308          */
309
310         /*
311          * XXXKYS:  Need to stop outgoing traffic and unregister
312          * the netdevice.
313          */
314
315         hv_rf_on_device_remove(hv_device, HV_RF_NV_DESTROY_CHANNEL);
316
317         return (0);
318 }
319
320 /*
321  * Standard shutdown entry point
322  */
323 static int
324 netvsc_shutdown(device_t dev)
325 {
326         return (0);
327 }
328
329 /*
330  * Send completion processing
331  *
332  * Note:  It looks like offset 0 of buf is reserved to hold the softc
333  * pointer.  The sc pointer is not currently needed in this function, and
334  * it is not presently populated by the TX function.
335  */
336 void
337 netvsc_xmit_completion(void *context)
338 {
339         netvsc_packet *packet = (netvsc_packet *)context;
340         struct mbuf *mb;
341         uint8_t *buf;
342
343         mb = (struct mbuf *)packet->compl.send.send_completion_tid;
344         buf = ((uint8_t *)packet) - HV_NV_PACKET_OFFSET_IN_BUF;
345
346         free(buf, M_DEVBUF);
347
348         if (mb != NULL) {
349                 m_freem(mb);
350         }
351 }
352
353 /*
354  * Start a transmit of one or more packets
355  */
356 static int
357 hn_start_locked(struct ifnet *ifp)
358 {
359         hn_softc_t *sc = ifp->if_softc;
360         struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
361         uint8_t *buf;
362         netvsc_packet *packet;
363         struct mbuf *m_head, *m;
364         struct mbuf *mc_head = NULL;
365         int i;
366         int num_frags;
367         int len;
368         int xlen;
369         int rppi_size;
370         int retries = 0;
371         int ret = 0;
372
373         while (!IFQ_DRV_IS_EMPTY(&sc->hn_ifp->if_snd)) {
374                 IFQ_DRV_DEQUEUE(&sc->hn_ifp->if_snd, m_head);
375                 if (m_head == NULL) {
376                         break;
377                 }
378
379                 len = 0;
380                 num_frags = 0;
381                 xlen = 0;
382
383                 /* Walk the mbuf list computing total length and num frags */
384                 for (m = m_head; m != NULL; m = m->m_next) {
385                         if (m->m_len != 0) {
386                                 num_frags++;
387                                 len += m->m_len;
388                         }
389                 }
390
391                 /*
392                  * Reserve the number of pages requested.  Currently,
393                  * one page is reserved for the message in the RNDIS
394                  * filter packet
395                  */
396                 num_frags += HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
397
398                 /* If exceeds # page_buffers in netvsc_packet */
399                 if (num_frags > NETVSC_PACKET_MAXPAGE) {
400                         m_freem(m);
401
402                         return (EINVAL);
403                 }
404
405                 rppi_size = 0;
406                 if (m_head->m_flags & M_VLANTAG) {
407                         rppi_size = sizeof(rndis_per_packet_info) + 
408                             sizeof(ndis_8021q_info);
409                 }
410
411                 /*
412                  * Allocate a buffer with space for a netvsc packet plus a
413                  * number of reserved areas.  First comes a (currently 16
414                  * bytes, currently unused) reserved data area.  Second is
415                  * the netvsc_packet, which includes (currently 4) page
416                  * buffers.  Third (optional) is a rndis_per_packet_info
417                  * struct, but only if a VLAN tag should be inserted into the
418                  * Ethernet frame by the Hyper-V infrastructure.  Fourth is
419                  * an area reserved for an rndis_filter_packet struct.
420                  * Changed malloc to M_NOWAIT to avoid sleep under spin lock.
421                  * No longer reserving extra space for page buffers, as they
422                  * are already part of the netvsc_packet.
423                  */
424                 buf = malloc(HV_NV_PACKET_OFFSET_IN_BUF +
425                     sizeof(netvsc_packet) + rppi_size +
426                     sizeof(rndis_filter_packet),
427                     M_DEVBUF, M_ZERO | M_NOWAIT);
428                 if (buf == NULL) {
429                         m_freem(m);
430
431                         return (ENOMEM);
432                 }
433
434                 packet = (netvsc_packet *)(buf + HV_NV_PACKET_OFFSET_IN_BUF);
435                 *(vm_offset_t *)buf = HV_NV_SC_PTR_OFFSET_IN_BUF;
436
437                 /*
438                  * extension points to the area reserved for the
439                  * rndis_filter_packet, which is placed just after
440                  * the netvsc_packet (and rppi struct, if present;
441                  * length is updated later).
442                  */
443                 packet->extension = packet + 1;
444
445                 /* Set up the rndis header */
446                 packet->page_buf_count = num_frags;
447
448                 /* Initialize it from the mbuf */
449                 packet->tot_data_buf_len = len;
450
451                 /*
452                  * If the Hyper-V infrastructure needs to embed a VLAN tag,
453                  * initialize netvsc_packet and rppi struct values as needed.
454                  */
455                 if (rppi_size) {
456                         /* Lower layers need the VLAN TCI */
457                         packet->vlan_tci = m_head->m_pkthdr.ether_vtag;
458                 }
459
460                 /*
461                  * Fill the page buffers with mbuf info starting at index
462                  * HV_RF_NUM_TX_RESERVED_PAGE_BUFS.
463                  */
464                 i = HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
465                 for (m = m_head; m != NULL; m = m->m_next) {
466                         if (m->m_len) {
467                                 vm_offset_t paddr =
468                                     vtophys(mtod(m, vm_offset_t));
469                                 packet->page_buffers[i].pfn =
470                                     paddr >> PAGE_SHIFT;
471                                 packet->page_buffers[i].offset =
472                                     paddr & (PAGE_SIZE - 1);
473                                 packet->page_buffers[i].length = m->m_len;
474                                 i++;
475                         }
476                 }
477
478                 /*
479                  * If bpf, copy the mbuf chain.  This is less expensive than
480                  * it appears; the mbuf clusters are not copied, only their
481                  * reference counts are incremented.
482                  * Needed to avoid a race condition where the completion
483                  * callback is invoked, freeing the mbuf chain, before the
484                  * bpf_mtap code has a chance to run.
485                  */
486                 if (ifp->if_bpf) {
487                         mc_head = m_copypacket(m_head, M_DONTWAIT);
488                 }
489 retry_send:
490                 /* Set the completion routine */
491                 packet->compl.send.on_send_completion = netvsc_xmit_completion;
492                 packet->compl.send.send_completion_context = packet;
493                 packet->compl.send.send_completion_tid = (uint64_t)m_head;
494
495                 /* Removed critical_enter(), does not appear necessary */
496                 ret = hv_rf_on_send(device_ctx, packet);
497
498                 if (ret == 0) {
499                         ifp->if_opackets++;
500                         /* if bpf && mc_head, call bpf_mtap code */
501                         if (mc_head) {
502                                 ETHER_BPF_MTAP(ifp, mc_head);
503                         }
504                 } else {
505                         retries++;
506                         if (retries < 4) {
507                                 goto retry_send;
508                         }
509
510                         IF_PREPEND(&ifp->if_snd, m_head);
511                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
512
513                         /*
514                          * Null the mbuf pointer so the completion function
515                          * does not free the mbuf chain.  We just pushed the
516                          * mbuf chain back on the if_snd queue.
517                          */
518                         packet->compl.send.send_completion_tid = 0;
519
520                         /*
521                          * Release the resources since we will not get any
522                          * send completion
523                          */
524                         netvsc_xmit_completion(packet);
525                 }
526
527                 /* if bpf && mc_head, free the mbuf chain copy */
528                 if (mc_head) {
529                         m_freem(mc_head);
530                 }
531         }
532
533         return (ret);
534 }
535
536 /*
537  * Link up/down notification
538  */
539 void
540 netvsc_linkstatus_callback(struct hv_device *device_obj, uint32_t status)
541 {
542         hn_softc_t *sc = device_get_softc(device_obj->device);
543
544         if (sc == NULL) {
545                 return;
546         }
547
548         if (status == 1) {
549                 sc->hn_carrier = 1;
550         } else {
551                 sc->hn_carrier = 0;
552         }
553 }
554
555 /*
556  * Append the specified data to the indicated mbuf chain,
557  * Extend the mbuf chain if the new data does not fit in
558  * existing space.
559  *
560  * This is a minor rewrite of m_append() from sys/kern/uipc_mbuf.c.
561  * There should be an equivalent in the kernel mbuf code,
562  * but there does not appear to be one yet.
563  *
564  * Differs from m_append() in that additional mbufs are
565  * allocated with cluster size MJUMPAGESIZE, and filled
566  * accordingly.
567  *
568  * Return 1 if able to complete the job; otherwise 0.
569  */
570 static int
571 hv_m_append(struct mbuf *m0, int len, c_caddr_t cp)
572 {
573         struct mbuf *m, *n;
574         int remainder, space;
575
576         for (m = m0; m->m_next != NULL; m = m->m_next)
577                 ;
578         remainder = len;
579         space = M_TRAILINGSPACE(m);
580         if (space > 0) {
581                 /*
582                  * Copy into available space.
583                  */
584                 if (space > remainder)
585                         space = remainder;
586                 bcopy(cp, mtod(m, caddr_t) + m->m_len, space);
587                 m->m_len += space;
588                 cp += space;
589                 remainder -= space;
590         }
591         while (remainder > 0) {
592                 /*
593                  * Allocate a new mbuf; could check space
594                  * and allocate a cluster instead.
595                  */
596                 n = m_getjcl(M_DONTWAIT, m->m_type, 0, MJUMPAGESIZE);
597                 if (n == NULL)
598                         break;
599                 n->m_len = min(MJUMPAGESIZE, remainder);
600                 bcopy(cp, mtod(n, caddr_t), n->m_len);
601                 cp += n->m_len;
602                 remainder -= n->m_len;
603                 m->m_next = n;
604                 m = n;
605         }
606         if (m0->m_flags & M_PKTHDR)
607                 m0->m_pkthdr.len += len - remainder;
608
609         return (remainder == 0);
610 }
611
612
613 /*
614  * Called when we receive a data packet from the "wire" on the
615  * specified device
616  *
617  * Note:  This is no longer used as a callback
618  */
619 int
620 netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet)
621 {
622         hn_softc_t *sc = (hn_softc_t *)device_get_softc(device_ctx->device);
623         struct mbuf *m_new;
624         struct ifnet *ifp;
625         int size;
626         int i;
627
628         if (sc == NULL) {
629                 return (0); /* TODO: KYS how can this be! */
630         }
631
632         ifp = sc->hn_ifp;
633         
634         ifp = sc->arpcom.ac_ifp;
635
636         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
637                 return (0);
638         }
639
640         /*
641          * Bail out if packet contains more data than configured MTU.
642          */
643         if (packet->tot_data_buf_len > (ifp->if_mtu + ETHER_HDR_LEN)) {
644                 return (0);
645         }
646
647         /*
648          * Get an mbuf with a cluster.  For packets 2K or less,
649          * get a standard 2K cluster.  For anything larger, get a
650          * 4K cluster.  Any buffers larger than 4K can cause problems
651          * if looped around to the Hyper-V TX channel, so avoid them.
652          */
653         size = MCLBYTES;
654
655         if (packet->tot_data_buf_len > MCLBYTES) {
656                 /* 4096 */
657                 size = MJUMPAGESIZE;
658         }
659
660         m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, size);
661
662         if (m_new == NULL)
663                 return (0);
664
665         /*
666          * Remove trailing junk from RX data buffer.
667          * Fixme:  This will not work for multiple Hyper-V RX buffers.
668          * Fortunately, the channel gathers all RX data into one buffer.
669          *
670          * L2 frame length, with L2 header, not including CRC
671          */
672         packet->page_buffers[0].length = packet->tot_data_buf_len;
673
674         /*
675          * Copy the received packet to one or more mbufs. 
676          * The copy is required since the memory pointed to by netvsc_packet
677          * cannot be deallocated
678          */
679         for (i=0; i < packet->page_buf_count; i++) {
680                 /* Shift virtual page number to form virtual page address */
681                 uint8_t *vaddr = (uint8_t *)
682                     (packet->page_buffers[i].pfn << PAGE_SHIFT);
683
684                 hv_m_append(m_new, packet->page_buffers[i].length,
685                     vaddr + packet->page_buffers[i].offset);
686         }
687
688         m_new->m_pkthdr.rcvif = ifp;
689
690         if ((packet->vlan_tci != 0) &&
691                             (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
692                 m_new->m_pkthdr.ether_vtag = packet->vlan_tci;
693                 m_new->m_flags |= M_VLANTAG;
694         }
695
696         /*
697          * Note:  Moved RX completion back to hv_nv_on_receive() so all
698          * messages (not just data messages) will trigger a response.
699          */
700
701         ifp->if_ipackets++;
702
703         /* We're not holding the lock here, so don't release it */
704         (*ifp->if_input)(ifp, m_new);
705
706         return (0);
707 }
708
709 /*
710  * Rules for using sc->temp_unusable:
711  * 1.  sc->temp_unusable can only be read or written while holding NV_LOCK()
712  * 2.  code reading sc->temp_unusable under NV_LOCK(), and finding 
713  *     sc->temp_unusable set, must release NV_LOCK() and exit
714  * 3.  to retain exclusive control of the interface,
715  *     sc->temp_unusable must be set by code before releasing NV_LOCK()
716  * 4.  only code setting sc->temp_unusable can clear sc->temp_unusable
717  * 5.  code setting sc->temp_unusable must eventually clear sc->temp_unusable
718  */
719
720 /*
721  * Standard ioctl entry point.  Called when the user wants to configure
722  * the interface.
723  */
724 static int
725 hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
726 {
727         hn_softc_t *sc = ifp->if_softc;
728         struct ifreq *ifr = (struct ifreq *)data;
729         netvsc_device_info device_info;
730         struct hv_device *hn_dev;
731         int mask, error = 0;
732         int retry_cnt = 500;
733         
734         switch(cmd) {
735
736         case SIOCSIFADDR:
737         case SIOCGIFADDR:
738                 error = ether_ioctl(ifp, cmd, data);
739                 break;
740         case SIOCSIFMTU:
741                 hn_dev = vmbus_get_devctx(sc->hn_dev);
742
743                 /* Check MTU value change */
744                 if (ifp->if_mtu == ifr->ifr_mtu)
745                         break;
746
747                 if (ifr->ifr_mtu > NETVSC_MAX_CONFIGURABLE_MTU) {
748                         error = EINVAL;
749                         break;
750                 }
751
752                 /* Obtain and record requested MTU */
753                 ifp->if_mtu = ifr->ifr_mtu;
754                 
755                 do {
756                         NV_LOCK(sc);
757                         if (!sc->temp_unusable) {
758                                 sc->temp_unusable = TRUE;
759                                 retry_cnt = -1;
760                         }
761                         NV_UNLOCK(sc);
762                         if (retry_cnt > 0) {
763                                 retry_cnt--;
764                                 DELAY(5 * 1000);
765                         }
766                 } while (retry_cnt > 0);
767
768                 if (retry_cnt == 0) {
769                         error = EINVAL;
770                         break;
771                 }
772
773                 /* We must remove and add back the device to cause the new
774                  * MTU to take effect.  This includes tearing down, but not
775                  * deleting the channel, then bringing it back up.
776                  */
777                 error = hv_rf_on_device_remove(hn_dev, HV_RF_NV_RETAIN_CHANNEL);
778                 if (error) {
779                         NV_LOCK(sc);
780                         sc->temp_unusable = FALSE;
781                         NV_UNLOCK(sc);
782                         break;
783                 }
784                 error = hv_rf_on_device_add(hn_dev, &device_info);
785                 if (error) {
786                         NV_LOCK(sc);
787                         sc->temp_unusable = FALSE;
788                         NV_UNLOCK(sc);
789                         break;
790                 }
791
792                 hn_ifinit_locked(sc);
793
794                 NV_LOCK(sc);
795                 sc->temp_unusable = FALSE;
796                 NV_UNLOCK(sc);
797                 break;
798         case SIOCSIFFLAGS:
799                 do {
800                        NV_LOCK(sc);
801                        if (!sc->temp_unusable) {
802                                sc->temp_unusable = TRUE;
803                                retry_cnt = -1;
804                        }
805                        NV_UNLOCK(sc);
806                        if (retry_cnt > 0) {
807                                 retry_cnt--;
808                                 DELAY(5 * 1000);
809                        }
810                 } while (retry_cnt > 0);
811
812                 if (retry_cnt == 0) {
813                        error = EINVAL;
814                        break;
815                 }
816
817                 if (ifp->if_flags & IFF_UP) {
818                         /*
819                          * If only the state of the PROMISC flag changed,
820                          * then just use the 'set promisc mode' command
821                          * instead of reinitializing the entire NIC. Doing
822                          * a full re-init means reloading the firmware and
823                          * waiting for it to start up, which may take a
824                          * second or two.
825                          */
826 #ifdef notyet
827                         /* Fixme:  Promiscuous mode? */
828                         if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
829                             ifp->if_flags & IFF_PROMISC &&
830                             !(sc->hn_if_flags & IFF_PROMISC)) {
831                                 /* do something here for Hyper-V */
832                         } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
833                             !(ifp->if_flags & IFF_PROMISC) &&
834                             sc->hn_if_flags & IFF_PROMISC) {
835                                 /* do something here for Hyper-V */
836                         } else
837 #endif
838                                 hn_ifinit_locked(sc);
839                 } else {
840                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
841                                 hn_stop(sc);
842                         }
843                 }
844                 NV_LOCK(sc);
845                 sc->temp_unusable = FALSE;
846                 NV_UNLOCK(sc);
847                 sc->hn_if_flags = ifp->if_flags;
848                 error = 0;
849                 break;
850         case SIOCSIFCAP:
851                 mask = ifr->ifr_reqcap ^ ifp->if_capenable;
852                 if (mask & IFCAP_HWCSUM) {
853                         if (IFCAP_HWCSUM & ifp->if_capenable) {
854                                 ifp->if_capenable &= ~IFCAP_HWCSUM;
855                         } else {
856                                 ifp->if_capenable |= IFCAP_HWCSUM;
857                         }
858                 }
859                 error = 0;
860                 break;
861         case SIOCADDMULTI:
862         case SIOCDELMULTI:
863 #ifdef notyet
864                 /* Fixme:  Multicast mode? */
865                 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
866                         NV_LOCK(sc);
867                         netvsc_setmulti(sc);
868                         NV_UNLOCK(sc);
869                         error = 0;
870                 }
871 #endif
872                 /* FALLTHROUGH */
873         case SIOCSIFMEDIA:
874         case SIOCGIFMEDIA:
875                 error = EINVAL;
876                 break;
877         default:
878                 error = ether_ioctl(ifp, cmd, data);
879                 break;
880         }
881
882         return (error);
883 }
884
885 /*
886  *
887  */
888 static void
889 hn_stop(hn_softc_t *sc)
890 {
891         struct ifnet *ifp;
892         int ret;
893         struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
894
895         ifp = sc->hn_ifp;
896
897         printf(" Closing Device ...\n");
898
899         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
900         sc->hn_initdone = 0;
901
902         ret = hv_rf_on_close(device_ctx);
903 }
904
905 /*
906  * FreeBSD transmit entry point
907  */
908 static void
909 hn_start(struct ifnet *ifp)
910 {
911         hn_softc_t *sc;
912
913         sc = ifp->if_softc;
914         NV_LOCK(sc);
915         if (sc->temp_unusable) {
916                 NV_UNLOCK(sc);
917                 return;
918         }
919         hn_start_locked(ifp);
920         NV_UNLOCK(sc);
921 }
922
923 /*
924  *
925  */
926 static void
927 hn_ifinit_locked(hn_softc_t *sc)
928 {
929         struct ifnet *ifp;
930         struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
931         int ret;
932
933         ifp = sc->hn_ifp;
934
935         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
936                 return;
937         }
938
939         hv_promisc_mode = 1;
940
941         ret = hv_rf_on_open(device_ctx);
942         if (ret != 0) {
943                 return;
944         } else {
945                 sc->hn_initdone = 1;
946         }
947         ifp->if_drv_flags |= IFF_DRV_RUNNING;
948         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
949 }
950
951 /*
952  *
953  */
954 static void
955 hn_ifinit(void *xsc)
956 {
957         hn_softc_t *sc = xsc;
958
959         NV_LOCK(sc);
960         if (sc->temp_unusable) {
961                 NV_UNLOCK(sc);
962                 return;
963         }
964         sc->temp_unusable = TRUE;
965         NV_UNLOCK(sc);
966
967         hn_ifinit_locked(sc);
968
969         NV_LOCK(sc);
970         sc->temp_unusable = FALSE;
971         NV_UNLOCK(sc);
972 }
973
974 #ifdef LATER
975 /*
976  *
977  */
978 static void
979 hn_watchdog(struct ifnet *ifp)
980 {
981         hn_softc_t *sc;
982         sc = ifp->if_softc;
983
984         printf("hn%d: watchdog timeout -- resetting\n", sc->hn_unit);
985         hn_ifinit(sc);    /*???*/
986         ifp->if_oerrors++;
987 }
988 #endif
989
990 static device_method_t netvsc_methods[] = {
991         /* Device interface */
992         DEVMETHOD(device_probe,         netvsc_probe),
993         DEVMETHOD(device_attach,        netvsc_attach),
994         DEVMETHOD(device_detach,        netvsc_detach),
995         DEVMETHOD(device_shutdown,      netvsc_shutdown),
996
997         { 0, 0 }
998 };
999
1000 static driver_t netvsc_driver = {
1001         NETVSC_DEVNAME,
1002         netvsc_methods,
1003         sizeof(hn_softc_t)
1004 };
1005
1006 static devclass_t netvsc_devclass;
1007
1008 DRIVER_MODULE(hn, vmbus, netvsc_driver, netvsc_devclass, 0, 0);
1009 MODULE_VERSION(hn, 1);
1010 MODULE_DEPEND(hn, vmbus, 1, 1, 1);
1011 SYSINIT(netvsc_initx, SI_SUB_KTHREAD_IDLE, SI_ORDER_MIDDLE + 1, netvsc_init,
1012      NULL);
1013