]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
MFC r256362
[FreeBSD/stable/10.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 = sc->hn_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->arpcom.ac_ifp;
633
634         if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
635                 return (0);
636         }
637
638         /*
639          * Bail out if packet contains more data than configured MTU.
640          */
641         if (packet->tot_data_buf_len > (ifp->if_mtu + ETHER_HDR_LEN)) {
642                 return (0);
643         }
644
645         /*
646          * Get an mbuf with a cluster.  For packets 2K or less,
647          * get a standard 2K cluster.  For anything larger, get a
648          * 4K cluster.  Any buffers larger than 4K can cause problems
649          * if looped around to the Hyper-V TX channel, so avoid them.
650          */
651         size = MCLBYTES;
652
653         if (packet->tot_data_buf_len > MCLBYTES) {
654                 /* 4096 */
655                 size = MJUMPAGESIZE;
656         }
657
658         m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, size);
659
660         if (m_new == NULL)
661                 return (0);
662
663         /*
664          * Remove trailing junk from RX data buffer.
665          * Fixme:  This will not work for multiple Hyper-V RX buffers.
666          * Fortunately, the channel gathers all RX data into one buffer.
667          *
668          * L2 frame length, with L2 header, not including CRC
669          */
670         packet->page_buffers[0].length = packet->tot_data_buf_len;
671
672         /*
673          * Copy the received packet to one or more mbufs. 
674          * The copy is required since the memory pointed to by netvsc_packet
675          * cannot be deallocated
676          */
677         for (i=0; i < packet->page_buf_count; i++) {
678                 /* Shift virtual page number to form virtual page address */
679                 uint8_t *vaddr = (uint8_t *)
680                     (packet->page_buffers[i].pfn << PAGE_SHIFT);
681
682                 hv_m_append(m_new, packet->page_buffers[i].length,
683                     vaddr + packet->page_buffers[i].offset);
684         }
685
686         m_new->m_pkthdr.rcvif = ifp;
687
688         if ((packet->vlan_tci != 0) &&
689                             (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
690                 m_new->m_pkthdr.ether_vtag = packet->vlan_tci;
691                 m_new->m_flags |= M_VLANTAG;
692         }
693
694         /*
695          * Note:  Moved RX completion back to hv_nv_on_receive() so all
696          * messages (not just data messages) will trigger a response.
697          */
698
699         ifp->if_ipackets++;
700
701         /* We're not holding the lock here, so don't release it */
702         (*ifp->if_input)(ifp, m_new);
703
704         return (0);
705 }
706
707 /*
708  * Rules for using sc->temp_unusable:
709  * 1.  sc->temp_unusable can only be read or written while holding NV_LOCK()
710  * 2.  code reading sc->temp_unusable under NV_LOCK(), and finding 
711  *     sc->temp_unusable set, must release NV_LOCK() and exit
712  * 3.  to retain exclusive control of the interface,
713  *     sc->temp_unusable must be set by code before releasing NV_LOCK()
714  * 4.  only code setting sc->temp_unusable can clear sc->temp_unusable
715  * 5.  code setting sc->temp_unusable must eventually clear sc->temp_unusable
716  */
717
718 /*
719  * Standard ioctl entry point.  Called when the user wants to configure
720  * the interface.
721  */
722 static int
723 hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
724 {
725         hn_softc_t *sc = ifp->if_softc;
726         struct ifreq *ifr = (struct ifreq *)data;
727         netvsc_device_info device_info;
728         struct hv_device *hn_dev;
729         int mask, error = 0;
730         int retry_cnt = 500;
731         
732         switch(cmd) {
733
734         case SIOCSIFADDR:
735         case SIOCGIFADDR:
736                 error = ether_ioctl(ifp, cmd, data);
737                 break;
738         case SIOCSIFMTU:
739                 hn_dev = vmbus_get_devctx(sc->hn_dev);
740
741                 /* Check MTU value change */
742                 if (ifp->if_mtu == ifr->ifr_mtu)
743                         break;
744
745                 if (ifr->ifr_mtu > NETVSC_MAX_CONFIGURABLE_MTU) {
746                         error = EINVAL;
747                         break;
748                 }
749
750                 /* Obtain and record requested MTU */
751                 ifp->if_mtu = ifr->ifr_mtu;
752                 
753                 do {
754                         NV_LOCK(sc);
755                         if (!sc->temp_unusable) {
756                                 sc->temp_unusable = TRUE;
757                                 retry_cnt = -1;
758                         }
759                         NV_UNLOCK(sc);
760                         if (retry_cnt > 0) {
761                                 retry_cnt--;
762                                 DELAY(5 * 1000);
763                         }
764                 } while (retry_cnt > 0);
765
766                 if (retry_cnt == 0) {
767                         error = EINVAL;
768                         break;
769                 }
770
771                 /* We must remove and add back the device to cause the new
772                  * MTU to take effect.  This includes tearing down, but not
773                  * deleting the channel, then bringing it back up.
774                  */
775                 error = hv_rf_on_device_remove(hn_dev, HV_RF_NV_RETAIN_CHANNEL);
776                 if (error) {
777                         NV_LOCK(sc);
778                         sc->temp_unusable = FALSE;
779                         NV_UNLOCK(sc);
780                         break;
781                 }
782                 error = hv_rf_on_device_add(hn_dev, &device_info);
783                 if (error) {
784                         NV_LOCK(sc);
785                         sc->temp_unusable = FALSE;
786                         NV_UNLOCK(sc);
787                         break;
788                 }
789
790                 hn_ifinit_locked(sc);
791
792                 NV_LOCK(sc);
793                 sc->temp_unusable = FALSE;
794                 NV_UNLOCK(sc);
795                 break;
796         case SIOCSIFFLAGS:
797                 do {
798                        NV_LOCK(sc);
799                        if (!sc->temp_unusable) {
800                                sc->temp_unusable = TRUE;
801                                retry_cnt = -1;
802                        }
803                        NV_UNLOCK(sc);
804                        if (retry_cnt > 0) {
805                                 retry_cnt--;
806                                 DELAY(5 * 1000);
807                        }
808                 } while (retry_cnt > 0);
809
810                 if (retry_cnt == 0) {
811                        error = EINVAL;
812                        break;
813                 }
814
815                 if (ifp->if_flags & IFF_UP) {
816                         /*
817                          * If only the state of the PROMISC flag changed,
818                          * then just use the 'set promisc mode' command
819                          * instead of reinitializing the entire NIC. Doing
820                          * a full re-init means reloading the firmware and
821                          * waiting for it to start up, which may take a
822                          * second or two.
823                          */
824 #ifdef notyet
825                         /* Fixme:  Promiscuous mode? */
826                         if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
827                             ifp->if_flags & IFF_PROMISC &&
828                             !(sc->hn_if_flags & IFF_PROMISC)) {
829                                 /* do something here for Hyper-V */
830                         } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
831                             !(ifp->if_flags & IFF_PROMISC) &&
832                             sc->hn_if_flags & IFF_PROMISC) {
833                                 /* do something here for Hyper-V */
834                         } else
835 #endif
836                                 hn_ifinit_locked(sc);
837                 } else {
838                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
839                                 hn_stop(sc);
840                         }
841                 }
842                 NV_LOCK(sc);
843                 sc->temp_unusable = FALSE;
844                 NV_UNLOCK(sc);
845                 sc->hn_if_flags = ifp->if_flags;
846                 error = 0;
847                 break;
848         case SIOCSIFCAP:
849                 mask = ifr->ifr_reqcap ^ ifp->if_capenable;
850                 if (mask & IFCAP_HWCSUM) {
851                         if (IFCAP_HWCSUM & ifp->if_capenable) {
852                                 ifp->if_capenable &= ~IFCAP_HWCSUM;
853                         } else {
854                                 ifp->if_capenable |= IFCAP_HWCSUM;
855                         }
856                 }
857                 error = 0;
858                 break;
859         case SIOCADDMULTI:
860         case SIOCDELMULTI:
861 #ifdef notyet
862                 /* Fixme:  Multicast mode? */
863                 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
864                         NV_LOCK(sc);
865                         netvsc_setmulti(sc);
866                         NV_UNLOCK(sc);
867                         error = 0;
868                 }
869 #endif
870                 /* FALLTHROUGH */
871         case SIOCSIFMEDIA:
872         case SIOCGIFMEDIA:
873                 error = EINVAL;
874                 break;
875         default:
876                 error = ether_ioctl(ifp, cmd, data);
877                 break;
878         }
879
880         return (error);
881 }
882
883 /*
884  *
885  */
886 static void
887 hn_stop(hn_softc_t *sc)
888 {
889         struct ifnet *ifp;
890         int ret;
891         struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
892
893         ifp = sc->hn_ifp;
894
895         printf(" Closing Device ...\n");
896
897         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
898         sc->hn_initdone = 0;
899
900         ret = hv_rf_on_close(device_ctx);
901 }
902
903 /*
904  * FreeBSD transmit entry point
905  */
906 static void
907 hn_start(struct ifnet *ifp)
908 {
909         hn_softc_t *sc;
910
911         sc = ifp->if_softc;
912         NV_LOCK(sc);
913         if (sc->temp_unusable) {
914                 NV_UNLOCK(sc);
915                 return;
916         }
917         hn_start_locked(ifp);
918         NV_UNLOCK(sc);
919 }
920
921 /*
922  *
923  */
924 static void
925 hn_ifinit_locked(hn_softc_t *sc)
926 {
927         struct ifnet *ifp;
928         struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
929         int ret;
930
931         ifp = sc->hn_ifp;
932
933         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
934                 return;
935         }
936
937         hv_promisc_mode = 1;
938
939         ret = hv_rf_on_open(device_ctx);
940         if (ret != 0) {
941                 return;
942         } else {
943                 sc->hn_initdone = 1;
944         }
945         ifp->if_drv_flags |= IFF_DRV_RUNNING;
946         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
947 }
948
949 /*
950  *
951  */
952 static void
953 hn_ifinit(void *xsc)
954 {
955         hn_softc_t *sc = xsc;
956
957         NV_LOCK(sc);
958         if (sc->temp_unusable) {
959                 NV_UNLOCK(sc);
960                 return;
961         }
962         sc->temp_unusable = TRUE;
963         NV_UNLOCK(sc);
964
965         hn_ifinit_locked(sc);
966
967         NV_LOCK(sc);
968         sc->temp_unusable = FALSE;
969         NV_UNLOCK(sc);
970 }
971
972 #ifdef LATER
973 /*
974  *
975  */
976 static void
977 hn_watchdog(struct ifnet *ifp)
978 {
979         hn_softc_t *sc;
980         sc = ifp->if_softc;
981
982         printf("hn%d: watchdog timeout -- resetting\n", sc->hn_unit);
983         hn_ifinit(sc);    /*???*/
984         ifp->if_oerrors++;
985 }
986 #endif
987
988 static device_method_t netvsc_methods[] = {
989         /* Device interface */
990         DEVMETHOD(device_probe,         netvsc_probe),
991         DEVMETHOD(device_attach,        netvsc_attach),
992         DEVMETHOD(device_detach,        netvsc_detach),
993         DEVMETHOD(device_shutdown,      netvsc_shutdown),
994
995         { 0, 0 }
996 };
997
998 static driver_t netvsc_driver = {
999         NETVSC_DEVNAME,
1000         netvsc_methods,
1001         sizeof(hn_softc_t)
1002 };
1003
1004 static devclass_t netvsc_devclass;
1005
1006 DRIVER_MODULE(hn, vmbus, netvsc_driver, netvsc_devclass, 0, 0);
1007 MODULE_VERSION(hn, 1);
1008 MODULE_DEPEND(hn, vmbus, 1, 1, 1);
1009 SYSINIT(netvsc_initx, SI_SUB_KTHREAD_IDLE, SI_ORDER_MIDDLE + 1, netvsc_init,
1010      NULL);
1011