Deleted Added
full compact
hv_netvsc_drv_freebsd.c (270856) hv_netvsc_drv_freebsd.c (271849)
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>
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: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c 270856 2014-08-30 19:55:54Z glebius $");
56__FBSDID("$FreeBSD: head/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c 271849 2014-09-19 03:51:26Z glebius $");
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_var.h>
79#include <net/if_types.h>
80#include <net/if_vlan_var.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
128struct 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
152int hv_promisc_mode = 0; /* normal mode by default */
153
154/* The one and only one */
155static struct hv_netvsc_driver_context g_netvsc_drv;
156
157
158/*
159 * Forward declarations
160 */
161static void hn_stop(hn_softc_t *sc);
162static void hn_ifinit_locked(hn_softc_t *sc);
163static void hn_ifinit(void *xsc);
164static int hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
165static int hn_start_locked(struct ifnet *ifp);
166static void hn_start(struct ifnet *ifp);
167
168
169/*
170 * NetVsc driver initialization
171 * Note: Filter init is no longer required
172 */
173static int
174netvsc_drv_init(void)
175{
176 return (0);
177}
178
179/*
180 * NetVsc global initialization entry point
181 */
182static void
183netvsc_init(void)
184{
185 if (bootverbose)
186 printf("Netvsc initializing... ");
187
188 /*
189 * XXXKYS: cleanup initialization
190 */
191 if (!cold && !g_netvsc_drv.drv_inited) {
192 g_netvsc_drv.drv_inited = 1;
193 netvsc_drv_init();
194 if (bootverbose)
195 printf("done!\n");
196 } else if (bootverbose)
197 printf("Already initialized!\n");
198}
199
200/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
201static const hv_guid g_net_vsc_device_type = {
202 .data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
203 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}
204};
205
206/*
207 * Standard probe entry point.
208 *
209 */
210static int
211netvsc_probe(device_t dev)
212{
213 const char *p;
214
215 p = vmbus_get_type(dev);
216 if (!memcmp(p, &g_net_vsc_device_type.data, sizeof(hv_guid))) {
217 device_set_desc(dev, "Synthetic Network Interface");
218 if (bootverbose)
219 printf("Netvsc probe... DONE \n");
220
221 return (0);
222 }
223
224 return (ENXIO);
225}
226
227/*
228 * Standard attach entry point.
229 *
230 * Called when the driver is loaded. It allocates needed resources,
231 * and initializes the "hardware" and software.
232 */
233static int
234netvsc_attach(device_t dev)
235{
236 struct hv_device *device_ctx = vmbus_get_devctx(dev);
237 netvsc_device_info device_info;
238 hn_softc_t *sc;
239 int unit = device_get_unit(dev);
240 struct ifnet *ifp;
241 int ret;
242
243 netvsc_init();
244
245 sc = device_get_softc(dev);
246 if (sc == NULL) {
247 return (ENOMEM);
248 }
249
250 bzero(sc, sizeof(hn_softc_t));
251 sc->hn_unit = unit;
252 sc->hn_dev = dev;
253
254 NV_LOCK_INIT(sc, "NetVSCLock");
255
256 sc->hn_dev_obj = device_ctx;
257
258 ifp = sc->hn_ifp = sc->arpcom.ac_ifp = if_alloc(IFT_ETHER);
259 ifp->if_softc = sc;
260
261 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
262 ifp->if_dunit = unit;
263 ifp->if_dname = NETVSC_DEVNAME;
264
265 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
266 ifp->if_ioctl = hn_ioctl;
267 ifp->if_start = hn_start;
268 ifp->if_init = hn_ifinit;
269 /* needed by hv_rf_on_device_add() code */
270 ifp->if_mtu = ETHERMTU;
271 IFQ_SET_MAXLEN(&ifp->if_snd, 512);
272 ifp->if_snd.ifq_drv_maxlen = 511;
273 IFQ_SET_READY(&ifp->if_snd);
274
275 /*
276 * Tell upper layers that we support full VLAN capability.
277 */
278 ifp->if_hdrlen = sizeof(struct ether_vlan_header);
279 ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
280 ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
281
282 ret = hv_rf_on_device_add(device_ctx, &device_info);
283 if (ret != 0) {
284 if_free(ifp);
285
286 return (ret);
287 }
288 if (device_info.link_state == 0) {
289 sc->hn_carrier = 1;
290 }
291
292 ether_ifattach(ifp, device_info.mac_addr);
293
294 return (0);
295}
296
297/*
298 * Standard detach entry point
299 */
300static int
301netvsc_detach(device_t dev)
302{
303 struct hv_device *hv_device = vmbus_get_devctx(dev);
304
305 if (bootverbose)
306 printf("netvsc_detach\n");
307
308 /*
309 * XXXKYS: Need to clean up all our
310 * driver state; this is the driver
311 * unloading.
312 */
313
314 /*
315 * XXXKYS: Need to stop outgoing traffic and unregister
316 * the netdevice.
317 */
318
319 hv_rf_on_device_remove(hv_device, HV_RF_NV_DESTROY_CHANNEL);
320
321 return (0);
322}
323
324/*
325 * Standard shutdown entry point
326 */
327static int
328netvsc_shutdown(device_t dev)
329{
330 return (0);
331}
332
333/*
334 * Send completion processing
335 *
336 * Note: It looks like offset 0 of buf is reserved to hold the softc
337 * pointer. The sc pointer is not currently needed in this function, and
338 * it is not presently populated by the TX function.
339 */
340void
341netvsc_xmit_completion(void *context)
342{
343 netvsc_packet *packet = (netvsc_packet *)context;
344 struct mbuf *mb;
345 uint8_t *buf;
346
347 mb = (struct mbuf *)(uintptr_t)packet->compl.send.send_completion_tid;
348 buf = ((uint8_t *)packet) - HV_NV_PACKET_OFFSET_IN_BUF;
349
350 free(buf, M_DEVBUF);
351
352 if (mb != NULL) {
353 m_freem(mb);
354 }
355}
356
357/*
358 * Start a transmit of one or more packets
359 */
360static int
361hn_start_locked(struct ifnet *ifp)
362{
363 hn_softc_t *sc = ifp->if_softc;
364 struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
365 uint8_t *buf;
366 netvsc_packet *packet;
367 struct mbuf *m_head, *m;
368 struct mbuf *mc_head = NULL;
369 int i;
370 int num_frags;
371 int len;
372 int xlen;
373 int rppi_size;
374 int retries = 0;
375 int ret = 0;
376
377 while (!IFQ_DRV_IS_EMPTY(&sc->hn_ifp->if_snd)) {
378 IFQ_DRV_DEQUEUE(&sc->hn_ifp->if_snd, m_head);
379 if (m_head == NULL) {
380 break;
381 }
382
383 len = 0;
384 num_frags = 0;
385 xlen = 0;
386
387 /* Walk the mbuf list computing total length and num frags */
388 for (m = m_head; m != NULL; m = m->m_next) {
389 if (m->m_len != 0) {
390 num_frags++;
391 len += m->m_len;
392 }
393 }
394
395 /*
396 * Reserve the number of pages requested. Currently,
397 * one page is reserved for the message in the RNDIS
398 * filter packet
399 */
400 num_frags += HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
401
402 /* If exceeds # page_buffers in netvsc_packet */
403 if (num_frags > NETVSC_PACKET_MAXPAGE) {
404 m_freem(m);
405
406 return (EINVAL);
407 }
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
415 /*
416 * Allocate a buffer with space for a netvsc packet plus a
417 * number of reserved areas. First comes a (currently 16
418 * bytes, currently unused) reserved data area. Second is
419 * the netvsc_packet, which includes (currently 4) page
420 * buffers. Third (optional) is a rndis_per_packet_info
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.
424 * Changed malloc to M_NOWAIT to avoid sleep under spin lock.
425 * No longer reserving extra space for page buffers, as they
426 * are already part of the netvsc_packet.
427 */
428 buf = malloc(HV_NV_PACKET_OFFSET_IN_BUF +
429 sizeof(netvsc_packet) + rppi_size +
430 sizeof(rndis_filter_packet),
431 M_DEVBUF, M_ZERO | M_NOWAIT);
432 if (buf == NULL) {
433 m_freem(m);
434
435 return (ENOMEM);
436 }
437
438 packet = (netvsc_packet *)(buf + HV_NV_PACKET_OFFSET_IN_BUF);
439 *(vm_offset_t *)buf = HV_NV_SC_PTR_OFFSET_IN_BUF;
440
441 /*
442 * extension points to the area reserved for the
443 * rndis_filter_packet, which is placed just after
444 * the netvsc_packet (and rppi struct, if present;
445 * length is updated later).
446 */
447 packet->extension = packet + 1;
448
449 /* Set up the rndis header */
450 packet->page_buf_count = num_frags;
451
452 /* Initialize it from the mbuf */
453 packet->tot_data_buf_len = len;
454
455 /*
456 * If the Hyper-V infrastructure needs to embed a VLAN tag,
457 * initialize netvsc_packet and rppi struct values as needed.
458 */
459 if (rppi_size) {
460 /* Lower layers need the VLAN TCI */
461 packet->vlan_tci = m_head->m_pkthdr.ether_vtag;
462 }
463
464 /*
465 * Fill the page buffers with mbuf info starting at index
466 * HV_RF_NUM_TX_RESERVED_PAGE_BUFS.
467 */
468 i = HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
469 for (m = m_head; m != NULL; m = m->m_next) {
470 if (m->m_len) {
471 vm_offset_t paddr =
472 vtophys(mtod(m, vm_offset_t));
473 packet->page_buffers[i].pfn =
474 paddr >> PAGE_SHIFT;
475 packet->page_buffers[i].offset =
476 paddr & (PAGE_SIZE - 1);
477 packet->page_buffers[i].length = m->m_len;
478 i++;
479 }
480 }
481
482 /*
483 * If bpf, copy the mbuf chain. This is less expensive than
484 * it appears; the mbuf clusters are not copied, only their
485 * reference counts are incremented.
486 * Needed to avoid a race condition where the completion
487 * callback is invoked, freeing the mbuf chain, before the
488 * bpf_mtap code has a chance to run.
489 */
490 if (ifp->if_bpf) {
491 mc_head = m_copypacket(m_head, M_NOWAIT);
492 }
493retry_send:
494 /* Set the completion routine */
495 packet->compl.send.on_send_completion = netvsc_xmit_completion;
496 packet->compl.send.send_completion_context = packet;
497 packet->compl.send.send_completion_tid = (uint64_t)(uintptr_t)m_head;
498
499 /* Removed critical_enter(), does not appear necessary */
500 ret = hv_rf_on_send(device_ctx, packet);
501
502 if (ret == 0) {
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_var.h>
79#include <net/if_types.h>
80#include <net/if_vlan_var.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
128struct 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
152int hv_promisc_mode = 0; /* normal mode by default */
153
154/* The one and only one */
155static struct hv_netvsc_driver_context g_netvsc_drv;
156
157
158/*
159 * Forward declarations
160 */
161static void hn_stop(hn_softc_t *sc);
162static void hn_ifinit_locked(hn_softc_t *sc);
163static void hn_ifinit(void *xsc);
164static int hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
165static int hn_start_locked(struct ifnet *ifp);
166static void hn_start(struct ifnet *ifp);
167
168
169/*
170 * NetVsc driver initialization
171 * Note: Filter init is no longer required
172 */
173static int
174netvsc_drv_init(void)
175{
176 return (0);
177}
178
179/*
180 * NetVsc global initialization entry point
181 */
182static void
183netvsc_init(void)
184{
185 if (bootverbose)
186 printf("Netvsc initializing... ");
187
188 /*
189 * XXXKYS: cleanup initialization
190 */
191 if (!cold && !g_netvsc_drv.drv_inited) {
192 g_netvsc_drv.drv_inited = 1;
193 netvsc_drv_init();
194 if (bootverbose)
195 printf("done!\n");
196 } else if (bootverbose)
197 printf("Already initialized!\n");
198}
199
200/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
201static const hv_guid g_net_vsc_device_type = {
202 .data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
203 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}
204};
205
206/*
207 * Standard probe entry point.
208 *
209 */
210static int
211netvsc_probe(device_t dev)
212{
213 const char *p;
214
215 p = vmbus_get_type(dev);
216 if (!memcmp(p, &g_net_vsc_device_type.data, sizeof(hv_guid))) {
217 device_set_desc(dev, "Synthetic Network Interface");
218 if (bootverbose)
219 printf("Netvsc probe... DONE \n");
220
221 return (0);
222 }
223
224 return (ENXIO);
225}
226
227/*
228 * Standard attach entry point.
229 *
230 * Called when the driver is loaded. It allocates needed resources,
231 * and initializes the "hardware" and software.
232 */
233static int
234netvsc_attach(device_t dev)
235{
236 struct hv_device *device_ctx = vmbus_get_devctx(dev);
237 netvsc_device_info device_info;
238 hn_softc_t *sc;
239 int unit = device_get_unit(dev);
240 struct ifnet *ifp;
241 int ret;
242
243 netvsc_init();
244
245 sc = device_get_softc(dev);
246 if (sc == NULL) {
247 return (ENOMEM);
248 }
249
250 bzero(sc, sizeof(hn_softc_t));
251 sc->hn_unit = unit;
252 sc->hn_dev = dev;
253
254 NV_LOCK_INIT(sc, "NetVSCLock");
255
256 sc->hn_dev_obj = device_ctx;
257
258 ifp = sc->hn_ifp = sc->arpcom.ac_ifp = if_alloc(IFT_ETHER);
259 ifp->if_softc = sc;
260
261 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
262 ifp->if_dunit = unit;
263 ifp->if_dname = NETVSC_DEVNAME;
264
265 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
266 ifp->if_ioctl = hn_ioctl;
267 ifp->if_start = hn_start;
268 ifp->if_init = hn_ifinit;
269 /* needed by hv_rf_on_device_add() code */
270 ifp->if_mtu = ETHERMTU;
271 IFQ_SET_MAXLEN(&ifp->if_snd, 512);
272 ifp->if_snd.ifq_drv_maxlen = 511;
273 IFQ_SET_READY(&ifp->if_snd);
274
275 /*
276 * Tell upper layers that we support full VLAN capability.
277 */
278 ifp->if_hdrlen = sizeof(struct ether_vlan_header);
279 ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
280 ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
281
282 ret = hv_rf_on_device_add(device_ctx, &device_info);
283 if (ret != 0) {
284 if_free(ifp);
285
286 return (ret);
287 }
288 if (device_info.link_state == 0) {
289 sc->hn_carrier = 1;
290 }
291
292 ether_ifattach(ifp, device_info.mac_addr);
293
294 return (0);
295}
296
297/*
298 * Standard detach entry point
299 */
300static int
301netvsc_detach(device_t dev)
302{
303 struct hv_device *hv_device = vmbus_get_devctx(dev);
304
305 if (bootverbose)
306 printf("netvsc_detach\n");
307
308 /*
309 * XXXKYS: Need to clean up all our
310 * driver state; this is the driver
311 * unloading.
312 */
313
314 /*
315 * XXXKYS: Need to stop outgoing traffic and unregister
316 * the netdevice.
317 */
318
319 hv_rf_on_device_remove(hv_device, HV_RF_NV_DESTROY_CHANNEL);
320
321 return (0);
322}
323
324/*
325 * Standard shutdown entry point
326 */
327static int
328netvsc_shutdown(device_t dev)
329{
330 return (0);
331}
332
333/*
334 * Send completion processing
335 *
336 * Note: It looks like offset 0 of buf is reserved to hold the softc
337 * pointer. The sc pointer is not currently needed in this function, and
338 * it is not presently populated by the TX function.
339 */
340void
341netvsc_xmit_completion(void *context)
342{
343 netvsc_packet *packet = (netvsc_packet *)context;
344 struct mbuf *mb;
345 uint8_t *buf;
346
347 mb = (struct mbuf *)(uintptr_t)packet->compl.send.send_completion_tid;
348 buf = ((uint8_t *)packet) - HV_NV_PACKET_OFFSET_IN_BUF;
349
350 free(buf, M_DEVBUF);
351
352 if (mb != NULL) {
353 m_freem(mb);
354 }
355}
356
357/*
358 * Start a transmit of one or more packets
359 */
360static int
361hn_start_locked(struct ifnet *ifp)
362{
363 hn_softc_t *sc = ifp->if_softc;
364 struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
365 uint8_t *buf;
366 netvsc_packet *packet;
367 struct mbuf *m_head, *m;
368 struct mbuf *mc_head = NULL;
369 int i;
370 int num_frags;
371 int len;
372 int xlen;
373 int rppi_size;
374 int retries = 0;
375 int ret = 0;
376
377 while (!IFQ_DRV_IS_EMPTY(&sc->hn_ifp->if_snd)) {
378 IFQ_DRV_DEQUEUE(&sc->hn_ifp->if_snd, m_head);
379 if (m_head == NULL) {
380 break;
381 }
382
383 len = 0;
384 num_frags = 0;
385 xlen = 0;
386
387 /* Walk the mbuf list computing total length and num frags */
388 for (m = m_head; m != NULL; m = m->m_next) {
389 if (m->m_len != 0) {
390 num_frags++;
391 len += m->m_len;
392 }
393 }
394
395 /*
396 * Reserve the number of pages requested. Currently,
397 * one page is reserved for the message in the RNDIS
398 * filter packet
399 */
400 num_frags += HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
401
402 /* If exceeds # page_buffers in netvsc_packet */
403 if (num_frags > NETVSC_PACKET_MAXPAGE) {
404 m_freem(m);
405
406 return (EINVAL);
407 }
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
415 /*
416 * Allocate a buffer with space for a netvsc packet plus a
417 * number of reserved areas. First comes a (currently 16
418 * bytes, currently unused) reserved data area. Second is
419 * the netvsc_packet, which includes (currently 4) page
420 * buffers. Third (optional) is a rndis_per_packet_info
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.
424 * Changed malloc to M_NOWAIT to avoid sleep under spin lock.
425 * No longer reserving extra space for page buffers, as they
426 * are already part of the netvsc_packet.
427 */
428 buf = malloc(HV_NV_PACKET_OFFSET_IN_BUF +
429 sizeof(netvsc_packet) + rppi_size +
430 sizeof(rndis_filter_packet),
431 M_DEVBUF, M_ZERO | M_NOWAIT);
432 if (buf == NULL) {
433 m_freem(m);
434
435 return (ENOMEM);
436 }
437
438 packet = (netvsc_packet *)(buf + HV_NV_PACKET_OFFSET_IN_BUF);
439 *(vm_offset_t *)buf = HV_NV_SC_PTR_OFFSET_IN_BUF;
440
441 /*
442 * extension points to the area reserved for the
443 * rndis_filter_packet, which is placed just after
444 * the netvsc_packet (and rppi struct, if present;
445 * length is updated later).
446 */
447 packet->extension = packet + 1;
448
449 /* Set up the rndis header */
450 packet->page_buf_count = num_frags;
451
452 /* Initialize it from the mbuf */
453 packet->tot_data_buf_len = len;
454
455 /*
456 * If the Hyper-V infrastructure needs to embed a VLAN tag,
457 * initialize netvsc_packet and rppi struct values as needed.
458 */
459 if (rppi_size) {
460 /* Lower layers need the VLAN TCI */
461 packet->vlan_tci = m_head->m_pkthdr.ether_vtag;
462 }
463
464 /*
465 * Fill the page buffers with mbuf info starting at index
466 * HV_RF_NUM_TX_RESERVED_PAGE_BUFS.
467 */
468 i = HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
469 for (m = m_head; m != NULL; m = m->m_next) {
470 if (m->m_len) {
471 vm_offset_t paddr =
472 vtophys(mtod(m, vm_offset_t));
473 packet->page_buffers[i].pfn =
474 paddr >> PAGE_SHIFT;
475 packet->page_buffers[i].offset =
476 paddr & (PAGE_SIZE - 1);
477 packet->page_buffers[i].length = m->m_len;
478 i++;
479 }
480 }
481
482 /*
483 * If bpf, copy the mbuf chain. This is less expensive than
484 * it appears; the mbuf clusters are not copied, only their
485 * reference counts are incremented.
486 * Needed to avoid a race condition where the completion
487 * callback is invoked, freeing the mbuf chain, before the
488 * bpf_mtap code has a chance to run.
489 */
490 if (ifp->if_bpf) {
491 mc_head = m_copypacket(m_head, M_NOWAIT);
492 }
493retry_send:
494 /* Set the completion routine */
495 packet->compl.send.on_send_completion = netvsc_xmit_completion;
496 packet->compl.send.send_completion_context = packet;
497 packet->compl.send.send_completion_tid = (uint64_t)(uintptr_t)m_head;
498
499 /* Removed critical_enter(), does not appear necessary */
500 ret = hv_rf_on_send(device_ctx, packet);
501
502 if (ret == 0) {
503 ifp->if_opackets++;
503 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
504 /* if bpf && mc_head, call bpf_mtap code */
505 if (mc_head) {
506 ETHER_BPF_MTAP(ifp, mc_head);
507 }
508 } else {
509 retries++;
510 if (retries < 4) {
511 goto retry_send;
512 }
513
514 IF_PREPEND(&ifp->if_snd, m_head);
515 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
516
517 /*
518 * Null the mbuf pointer so the completion function
519 * does not free the mbuf chain. We just pushed the
520 * mbuf chain back on the if_snd queue.
521 */
522 packet->compl.send.send_completion_tid = 0;
523
524 /*
525 * Release the resources since we will not get any
526 * send completion
527 */
528 netvsc_xmit_completion(packet);
529 }
530
531 /* if bpf && mc_head, free the mbuf chain copy */
532 if (mc_head) {
533 m_freem(mc_head);
534 }
535 }
536
537 return (ret);
538}
539
540/*
541 * Link up/down notification
542 */
543void
544netvsc_linkstatus_callback(struct hv_device *device_obj, uint32_t status)
545{
546 hn_softc_t *sc = device_get_softc(device_obj->device);
547
548 if (sc == NULL) {
549 return;
550 }
551
552 if (status == 1) {
553 sc->hn_carrier = 1;
554 } else {
555 sc->hn_carrier = 0;
556 }
557}
558
559/*
560 * Append the specified data to the indicated mbuf chain,
561 * Extend the mbuf chain if the new data does not fit in
562 * existing space.
563 *
564 * This is a minor rewrite of m_append() from sys/kern/uipc_mbuf.c.
565 * There should be an equivalent in the kernel mbuf code,
566 * but there does not appear to be one yet.
567 *
568 * Differs from m_append() in that additional mbufs are
569 * allocated with cluster size MJUMPAGESIZE, and filled
570 * accordingly.
571 *
572 * Return 1 if able to complete the job; otherwise 0.
573 */
574static int
575hv_m_append(struct mbuf *m0, int len, c_caddr_t cp)
576{
577 struct mbuf *m, *n;
578 int remainder, space;
579
580 for (m = m0; m->m_next != NULL; m = m->m_next)
581 ;
582 remainder = len;
583 space = M_TRAILINGSPACE(m);
584 if (space > 0) {
585 /*
586 * Copy into available space.
587 */
588 if (space > remainder)
589 space = remainder;
590 bcopy(cp, mtod(m, caddr_t) + m->m_len, space);
591 m->m_len += space;
592 cp += space;
593 remainder -= space;
594 }
595 while (remainder > 0) {
596 /*
597 * Allocate a new mbuf; could check space
598 * and allocate a cluster instead.
599 */
600 n = m_getjcl(M_NOWAIT, m->m_type, 0, MJUMPAGESIZE);
601 if (n == NULL)
602 break;
603 n->m_len = min(MJUMPAGESIZE, remainder);
604 bcopy(cp, mtod(n, caddr_t), n->m_len);
605 cp += n->m_len;
606 remainder -= n->m_len;
607 m->m_next = n;
608 m = n;
609 }
610 if (m0->m_flags & M_PKTHDR)
611 m0->m_pkthdr.len += len - remainder;
612
613 return (remainder == 0);
614}
615
616
617/*
618 * Called when we receive a data packet from the "wire" on the
619 * specified device
620 *
621 * Note: This is no longer used as a callback
622 */
623int
624netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet)
625{
626 hn_softc_t *sc = (hn_softc_t *)device_get_softc(device_ctx->device);
627 struct mbuf *m_new;
628 struct ifnet *ifp;
629 int size;
630 int i;
631
632 if (sc == NULL) {
633 return (0); /* TODO: KYS how can this be! */
634 }
635
636 ifp = sc->hn_ifp;
637
638 ifp = sc->arpcom.ac_ifp;
639
640 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
641 return (0);
642 }
643
644 /*
645 * Bail out if packet contains more data than configured MTU.
646 */
647 if (packet->tot_data_buf_len > (ifp->if_mtu + ETHER_HDR_LEN)) {
648 return (0);
649 }
650
651 /*
652 * Get an mbuf with a cluster. For packets 2K or less,
653 * get a standard 2K cluster. For anything larger, get a
654 * 4K cluster. Any buffers larger than 4K can cause problems
655 * if looped around to the Hyper-V TX channel, so avoid them.
656 */
657 size = MCLBYTES;
658
659 if (packet->tot_data_buf_len > MCLBYTES) {
660 /* 4096 */
661 size = MJUMPAGESIZE;
662 }
663
664 m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, size);
665
666 if (m_new == NULL)
667 return (0);
668
669 /*
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;
677
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);
687
688 hv_m_append(m_new, packet->page_buffers[i].length,
689 vaddr + packet->page_buffers[i].offset);
690 }
691
692 m_new->m_pkthdr.rcvif = ifp;
693
694 if ((packet->vlan_tci != 0) &&
695 (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
696 m_new->m_pkthdr.ether_vtag = packet->vlan_tci;
697 m_new->m_flags |= M_VLANTAG;
698 }
699
700 /*
701 * Note: Moved RX completion back to hv_nv_on_receive() so all
702 * messages (not just data messages) will trigger a response.
703 */
704
504 /* if bpf && mc_head, call bpf_mtap code */
505 if (mc_head) {
506 ETHER_BPF_MTAP(ifp, mc_head);
507 }
508 } else {
509 retries++;
510 if (retries < 4) {
511 goto retry_send;
512 }
513
514 IF_PREPEND(&ifp->if_snd, m_head);
515 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
516
517 /*
518 * Null the mbuf pointer so the completion function
519 * does not free the mbuf chain. We just pushed the
520 * mbuf chain back on the if_snd queue.
521 */
522 packet->compl.send.send_completion_tid = 0;
523
524 /*
525 * Release the resources since we will not get any
526 * send completion
527 */
528 netvsc_xmit_completion(packet);
529 }
530
531 /* if bpf && mc_head, free the mbuf chain copy */
532 if (mc_head) {
533 m_freem(mc_head);
534 }
535 }
536
537 return (ret);
538}
539
540/*
541 * Link up/down notification
542 */
543void
544netvsc_linkstatus_callback(struct hv_device *device_obj, uint32_t status)
545{
546 hn_softc_t *sc = device_get_softc(device_obj->device);
547
548 if (sc == NULL) {
549 return;
550 }
551
552 if (status == 1) {
553 sc->hn_carrier = 1;
554 } else {
555 sc->hn_carrier = 0;
556 }
557}
558
559/*
560 * Append the specified data to the indicated mbuf chain,
561 * Extend the mbuf chain if the new data does not fit in
562 * existing space.
563 *
564 * This is a minor rewrite of m_append() from sys/kern/uipc_mbuf.c.
565 * There should be an equivalent in the kernel mbuf code,
566 * but there does not appear to be one yet.
567 *
568 * Differs from m_append() in that additional mbufs are
569 * allocated with cluster size MJUMPAGESIZE, and filled
570 * accordingly.
571 *
572 * Return 1 if able to complete the job; otherwise 0.
573 */
574static int
575hv_m_append(struct mbuf *m0, int len, c_caddr_t cp)
576{
577 struct mbuf *m, *n;
578 int remainder, space;
579
580 for (m = m0; m->m_next != NULL; m = m->m_next)
581 ;
582 remainder = len;
583 space = M_TRAILINGSPACE(m);
584 if (space > 0) {
585 /*
586 * Copy into available space.
587 */
588 if (space > remainder)
589 space = remainder;
590 bcopy(cp, mtod(m, caddr_t) + m->m_len, space);
591 m->m_len += space;
592 cp += space;
593 remainder -= space;
594 }
595 while (remainder > 0) {
596 /*
597 * Allocate a new mbuf; could check space
598 * and allocate a cluster instead.
599 */
600 n = m_getjcl(M_NOWAIT, m->m_type, 0, MJUMPAGESIZE);
601 if (n == NULL)
602 break;
603 n->m_len = min(MJUMPAGESIZE, remainder);
604 bcopy(cp, mtod(n, caddr_t), n->m_len);
605 cp += n->m_len;
606 remainder -= n->m_len;
607 m->m_next = n;
608 m = n;
609 }
610 if (m0->m_flags & M_PKTHDR)
611 m0->m_pkthdr.len += len - remainder;
612
613 return (remainder == 0);
614}
615
616
617/*
618 * Called when we receive a data packet from the "wire" on the
619 * specified device
620 *
621 * Note: This is no longer used as a callback
622 */
623int
624netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet)
625{
626 hn_softc_t *sc = (hn_softc_t *)device_get_softc(device_ctx->device);
627 struct mbuf *m_new;
628 struct ifnet *ifp;
629 int size;
630 int i;
631
632 if (sc == NULL) {
633 return (0); /* TODO: KYS how can this be! */
634 }
635
636 ifp = sc->hn_ifp;
637
638 ifp = sc->arpcom.ac_ifp;
639
640 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
641 return (0);
642 }
643
644 /*
645 * Bail out if packet contains more data than configured MTU.
646 */
647 if (packet->tot_data_buf_len > (ifp->if_mtu + ETHER_HDR_LEN)) {
648 return (0);
649 }
650
651 /*
652 * Get an mbuf with a cluster. For packets 2K or less,
653 * get a standard 2K cluster. For anything larger, get a
654 * 4K cluster. Any buffers larger than 4K can cause problems
655 * if looped around to the Hyper-V TX channel, so avoid them.
656 */
657 size = MCLBYTES;
658
659 if (packet->tot_data_buf_len > MCLBYTES) {
660 /* 4096 */
661 size = MJUMPAGESIZE;
662 }
663
664 m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, size);
665
666 if (m_new == NULL)
667 return (0);
668
669 /*
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;
677
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);
687
688 hv_m_append(m_new, packet->page_buffers[i].length,
689 vaddr + packet->page_buffers[i].offset);
690 }
691
692 m_new->m_pkthdr.rcvif = ifp;
693
694 if ((packet->vlan_tci != 0) &&
695 (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
696 m_new->m_pkthdr.ether_vtag = packet->vlan_tci;
697 m_new->m_flags |= M_VLANTAG;
698 }
699
700 /*
701 * Note: Moved RX completion back to hv_nv_on_receive() so all
702 * messages (not just data messages) will trigger a response.
703 */
704
705 ifp->if_ipackets++;
705 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
706
707 /* We're not holding the lock here, so don't release it */
708 (*ifp->if_input)(ifp, m_new);
709
710 return (0);
711}
712
713/*
714 * Rules for using sc->temp_unusable:
715 * 1. sc->temp_unusable can only be read or written while holding NV_LOCK()
716 * 2. code reading sc->temp_unusable under NV_LOCK(), and finding
717 * sc->temp_unusable set, must release NV_LOCK() and exit
718 * 3. to retain exclusive control of the interface,
719 * sc->temp_unusable must be set by code before releasing NV_LOCK()
720 * 4. only code setting sc->temp_unusable can clear sc->temp_unusable
721 * 5. code setting sc->temp_unusable must eventually clear sc->temp_unusable
722 */
723
724/*
725 * Standard ioctl entry point. Called when the user wants to configure
726 * the interface.
727 */
728static int
729hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
730{
731 hn_softc_t *sc = ifp->if_softc;
732 struct ifreq *ifr = (struct ifreq *)data;
733 netvsc_device_info device_info;
734 struct hv_device *hn_dev;
735 int mask, error = 0;
736 int retry_cnt = 500;
737
738 switch(cmd) {
739
740 case SIOCSIFADDR:
741 case SIOCGIFADDR:
742 error = ether_ioctl(ifp, cmd, data);
743 break;
744 case SIOCSIFMTU:
745 hn_dev = vmbus_get_devctx(sc->hn_dev);
746
747 /* Check MTU value change */
748 if (ifp->if_mtu == ifr->ifr_mtu)
749 break;
750
751 if (ifr->ifr_mtu > NETVSC_MAX_CONFIGURABLE_MTU) {
752 error = EINVAL;
753 break;
754 }
755
756 /* Obtain and record requested MTU */
757 ifp->if_mtu = ifr->ifr_mtu;
758
759 do {
760 NV_LOCK(sc);
761 if (!sc->temp_unusable) {
762 sc->temp_unusable = TRUE;
763 retry_cnt = -1;
764 }
765 NV_UNLOCK(sc);
766 if (retry_cnt > 0) {
767 retry_cnt--;
768 DELAY(5 * 1000);
769 }
770 } while (retry_cnt > 0);
771
772 if (retry_cnt == 0) {
773 error = EINVAL;
774 break;
775 }
776
777 /* We must remove and add back the device to cause the new
778 * MTU to take effect. This includes tearing down, but not
779 * deleting the channel, then bringing it back up.
780 */
781 error = hv_rf_on_device_remove(hn_dev, HV_RF_NV_RETAIN_CHANNEL);
782 if (error) {
783 NV_LOCK(sc);
784 sc->temp_unusable = FALSE;
785 NV_UNLOCK(sc);
786 break;
787 }
788 error = hv_rf_on_device_add(hn_dev, &device_info);
789 if (error) {
790 NV_LOCK(sc);
791 sc->temp_unusable = FALSE;
792 NV_UNLOCK(sc);
793 break;
794 }
795
796 hn_ifinit_locked(sc);
797
798 NV_LOCK(sc);
799 sc->temp_unusable = FALSE;
800 NV_UNLOCK(sc);
801 break;
802 case SIOCSIFFLAGS:
803 do {
804 NV_LOCK(sc);
805 if (!sc->temp_unusable) {
806 sc->temp_unusable = TRUE;
807 retry_cnt = -1;
808 }
809 NV_UNLOCK(sc);
810 if (retry_cnt > 0) {
811 retry_cnt--;
812 DELAY(5 * 1000);
813 }
814 } while (retry_cnt > 0);
815
816 if (retry_cnt == 0) {
817 error = EINVAL;
818 break;
819 }
820
821 if (ifp->if_flags & IFF_UP) {
822 /*
823 * If only the state of the PROMISC flag changed,
824 * then just use the 'set promisc mode' command
825 * instead of reinitializing the entire NIC. Doing
826 * a full re-init means reloading the firmware and
827 * waiting for it to start up, which may take a
828 * second or two.
829 */
830#ifdef notyet
831 /* Fixme: Promiscuous mode? */
832 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 if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
837 !(ifp->if_flags & IFF_PROMISC) &&
838 sc->hn_if_flags & IFF_PROMISC) {
839 /* do something here for Hyper-V */
840 } else
841#endif
842 hn_ifinit_locked(sc);
843 } else {
844 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
845 hn_stop(sc);
846 }
847 }
848 NV_LOCK(sc);
849 sc->temp_unusable = FALSE;
850 NV_UNLOCK(sc);
851 sc->hn_if_flags = ifp->if_flags;
852 error = 0;
853 break;
854 case SIOCSIFCAP:
855 mask = ifr->ifr_reqcap ^ ifp->if_capenable;
856 if (mask & IFCAP_HWCSUM) {
857 if (IFCAP_HWCSUM & ifp->if_capenable) {
858 ifp->if_capenable &= ~IFCAP_HWCSUM;
859 } else {
860 ifp->if_capenable |= IFCAP_HWCSUM;
861 }
862 }
863 error = 0;
864 break;
865 case SIOCADDMULTI:
866 case SIOCDELMULTI:
867#ifdef notyet
868 /* Fixme: Multicast mode? */
869 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
870 NV_LOCK(sc);
871 netvsc_setmulti(sc);
872 NV_UNLOCK(sc);
873 error = 0;
874 }
875#endif
876 /* FALLTHROUGH */
877 case SIOCSIFMEDIA:
878 case SIOCGIFMEDIA:
879 error = EINVAL;
880 break;
881 default:
882 error = ether_ioctl(ifp, cmd, data);
883 break;
884 }
885
886 return (error);
887}
888
889/*
890 *
891 */
892static void
893hn_stop(hn_softc_t *sc)
894{
895 struct ifnet *ifp;
896 int ret;
897 struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
898
899 ifp = sc->hn_ifp;
900
901 if (bootverbose)
902 printf(" Closing Device ...\n");
903
904 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
905 sc->hn_initdone = 0;
906
907 ret = hv_rf_on_close(device_ctx);
908}
909
910/*
911 * FreeBSD transmit entry point
912 */
913static void
914hn_start(struct ifnet *ifp)
915{
916 hn_softc_t *sc;
917
918 sc = ifp->if_softc;
919 NV_LOCK(sc);
920 if (sc->temp_unusable) {
921 NV_UNLOCK(sc);
922 return;
923 }
924 hn_start_locked(ifp);
925 NV_UNLOCK(sc);
926}
927
928/*
929 *
930 */
931static void
932hn_ifinit_locked(hn_softc_t *sc)
933{
934 struct ifnet *ifp;
935 struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
936 int ret;
937
938 ifp = sc->hn_ifp;
939
940 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
941 return;
942 }
943
944 hv_promisc_mode = 1;
945
946 ret = hv_rf_on_open(device_ctx);
947 if (ret != 0) {
948 return;
949 } else {
950 sc->hn_initdone = 1;
951 }
952 ifp->if_drv_flags |= IFF_DRV_RUNNING;
953 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
954}
955
956/*
957 *
958 */
959static void
960hn_ifinit(void *xsc)
961{
962 hn_softc_t *sc = xsc;
963
964 NV_LOCK(sc);
965 if (sc->temp_unusable) {
966 NV_UNLOCK(sc);
967 return;
968 }
969 sc->temp_unusable = TRUE;
970 NV_UNLOCK(sc);
971
972 hn_ifinit_locked(sc);
973
974 NV_LOCK(sc);
975 sc->temp_unusable = FALSE;
976 NV_UNLOCK(sc);
977}
978
979#ifdef LATER
980/*
981 *
982 */
983static void
984hn_watchdog(struct ifnet *ifp)
985{
986 hn_softc_t *sc;
987 sc = ifp->if_softc;
988
989 printf("hn%d: watchdog timeout -- resetting\n", sc->hn_unit);
990 hn_ifinit(sc); /*???*/
706
707 /* We're not holding the lock here, so don't release it */
708 (*ifp->if_input)(ifp, m_new);
709
710 return (0);
711}
712
713/*
714 * Rules for using sc->temp_unusable:
715 * 1. sc->temp_unusable can only be read or written while holding NV_LOCK()
716 * 2. code reading sc->temp_unusable under NV_LOCK(), and finding
717 * sc->temp_unusable set, must release NV_LOCK() and exit
718 * 3. to retain exclusive control of the interface,
719 * sc->temp_unusable must be set by code before releasing NV_LOCK()
720 * 4. only code setting sc->temp_unusable can clear sc->temp_unusable
721 * 5. code setting sc->temp_unusable must eventually clear sc->temp_unusable
722 */
723
724/*
725 * Standard ioctl entry point. Called when the user wants to configure
726 * the interface.
727 */
728static int
729hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
730{
731 hn_softc_t *sc = ifp->if_softc;
732 struct ifreq *ifr = (struct ifreq *)data;
733 netvsc_device_info device_info;
734 struct hv_device *hn_dev;
735 int mask, error = 0;
736 int retry_cnt = 500;
737
738 switch(cmd) {
739
740 case SIOCSIFADDR:
741 case SIOCGIFADDR:
742 error = ether_ioctl(ifp, cmd, data);
743 break;
744 case SIOCSIFMTU:
745 hn_dev = vmbus_get_devctx(sc->hn_dev);
746
747 /* Check MTU value change */
748 if (ifp->if_mtu == ifr->ifr_mtu)
749 break;
750
751 if (ifr->ifr_mtu > NETVSC_MAX_CONFIGURABLE_MTU) {
752 error = EINVAL;
753 break;
754 }
755
756 /* Obtain and record requested MTU */
757 ifp->if_mtu = ifr->ifr_mtu;
758
759 do {
760 NV_LOCK(sc);
761 if (!sc->temp_unusable) {
762 sc->temp_unusable = TRUE;
763 retry_cnt = -1;
764 }
765 NV_UNLOCK(sc);
766 if (retry_cnt > 0) {
767 retry_cnt--;
768 DELAY(5 * 1000);
769 }
770 } while (retry_cnt > 0);
771
772 if (retry_cnt == 0) {
773 error = EINVAL;
774 break;
775 }
776
777 /* We must remove and add back the device to cause the new
778 * MTU to take effect. This includes tearing down, but not
779 * deleting the channel, then bringing it back up.
780 */
781 error = hv_rf_on_device_remove(hn_dev, HV_RF_NV_RETAIN_CHANNEL);
782 if (error) {
783 NV_LOCK(sc);
784 sc->temp_unusable = FALSE;
785 NV_UNLOCK(sc);
786 break;
787 }
788 error = hv_rf_on_device_add(hn_dev, &device_info);
789 if (error) {
790 NV_LOCK(sc);
791 sc->temp_unusable = FALSE;
792 NV_UNLOCK(sc);
793 break;
794 }
795
796 hn_ifinit_locked(sc);
797
798 NV_LOCK(sc);
799 sc->temp_unusable = FALSE;
800 NV_UNLOCK(sc);
801 break;
802 case SIOCSIFFLAGS:
803 do {
804 NV_LOCK(sc);
805 if (!sc->temp_unusable) {
806 sc->temp_unusable = TRUE;
807 retry_cnt = -1;
808 }
809 NV_UNLOCK(sc);
810 if (retry_cnt > 0) {
811 retry_cnt--;
812 DELAY(5 * 1000);
813 }
814 } while (retry_cnt > 0);
815
816 if (retry_cnt == 0) {
817 error = EINVAL;
818 break;
819 }
820
821 if (ifp->if_flags & IFF_UP) {
822 /*
823 * If only the state of the PROMISC flag changed,
824 * then just use the 'set promisc mode' command
825 * instead of reinitializing the entire NIC. Doing
826 * a full re-init means reloading the firmware and
827 * waiting for it to start up, which may take a
828 * second or two.
829 */
830#ifdef notyet
831 /* Fixme: Promiscuous mode? */
832 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 if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
837 !(ifp->if_flags & IFF_PROMISC) &&
838 sc->hn_if_flags & IFF_PROMISC) {
839 /* do something here for Hyper-V */
840 } else
841#endif
842 hn_ifinit_locked(sc);
843 } else {
844 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
845 hn_stop(sc);
846 }
847 }
848 NV_LOCK(sc);
849 sc->temp_unusable = FALSE;
850 NV_UNLOCK(sc);
851 sc->hn_if_flags = ifp->if_flags;
852 error = 0;
853 break;
854 case SIOCSIFCAP:
855 mask = ifr->ifr_reqcap ^ ifp->if_capenable;
856 if (mask & IFCAP_HWCSUM) {
857 if (IFCAP_HWCSUM & ifp->if_capenable) {
858 ifp->if_capenable &= ~IFCAP_HWCSUM;
859 } else {
860 ifp->if_capenable |= IFCAP_HWCSUM;
861 }
862 }
863 error = 0;
864 break;
865 case SIOCADDMULTI:
866 case SIOCDELMULTI:
867#ifdef notyet
868 /* Fixme: Multicast mode? */
869 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
870 NV_LOCK(sc);
871 netvsc_setmulti(sc);
872 NV_UNLOCK(sc);
873 error = 0;
874 }
875#endif
876 /* FALLTHROUGH */
877 case SIOCSIFMEDIA:
878 case SIOCGIFMEDIA:
879 error = EINVAL;
880 break;
881 default:
882 error = ether_ioctl(ifp, cmd, data);
883 break;
884 }
885
886 return (error);
887}
888
889/*
890 *
891 */
892static void
893hn_stop(hn_softc_t *sc)
894{
895 struct ifnet *ifp;
896 int ret;
897 struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
898
899 ifp = sc->hn_ifp;
900
901 if (bootverbose)
902 printf(" Closing Device ...\n");
903
904 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
905 sc->hn_initdone = 0;
906
907 ret = hv_rf_on_close(device_ctx);
908}
909
910/*
911 * FreeBSD transmit entry point
912 */
913static void
914hn_start(struct ifnet *ifp)
915{
916 hn_softc_t *sc;
917
918 sc = ifp->if_softc;
919 NV_LOCK(sc);
920 if (sc->temp_unusable) {
921 NV_UNLOCK(sc);
922 return;
923 }
924 hn_start_locked(ifp);
925 NV_UNLOCK(sc);
926}
927
928/*
929 *
930 */
931static void
932hn_ifinit_locked(hn_softc_t *sc)
933{
934 struct ifnet *ifp;
935 struct hv_device *device_ctx = vmbus_get_devctx(sc->hn_dev);
936 int ret;
937
938 ifp = sc->hn_ifp;
939
940 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
941 return;
942 }
943
944 hv_promisc_mode = 1;
945
946 ret = hv_rf_on_open(device_ctx);
947 if (ret != 0) {
948 return;
949 } else {
950 sc->hn_initdone = 1;
951 }
952 ifp->if_drv_flags |= IFF_DRV_RUNNING;
953 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
954}
955
956/*
957 *
958 */
959static void
960hn_ifinit(void *xsc)
961{
962 hn_softc_t *sc = xsc;
963
964 NV_LOCK(sc);
965 if (sc->temp_unusable) {
966 NV_UNLOCK(sc);
967 return;
968 }
969 sc->temp_unusable = TRUE;
970 NV_UNLOCK(sc);
971
972 hn_ifinit_locked(sc);
973
974 NV_LOCK(sc);
975 sc->temp_unusable = FALSE;
976 NV_UNLOCK(sc);
977}
978
979#ifdef LATER
980/*
981 *
982 */
983static void
984hn_watchdog(struct ifnet *ifp)
985{
986 hn_softc_t *sc;
987 sc = ifp->if_softc;
988
989 printf("hn%d: watchdog timeout -- resetting\n", sc->hn_unit);
990 hn_ifinit(sc); /*???*/
991 ifp->if_oerrors++;
991 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
992}
993#endif
994
995static device_method_t netvsc_methods[] = {
996 /* Device interface */
997 DEVMETHOD(device_probe, netvsc_probe),
998 DEVMETHOD(device_attach, netvsc_attach),
999 DEVMETHOD(device_detach, netvsc_detach),
1000 DEVMETHOD(device_shutdown, netvsc_shutdown),
1001
1002 { 0, 0 }
1003};
1004
1005static driver_t netvsc_driver = {
1006 NETVSC_DEVNAME,
1007 netvsc_methods,
1008 sizeof(hn_softc_t)
1009};
1010
1011static devclass_t netvsc_devclass;
1012
1013DRIVER_MODULE(hn, vmbus, netvsc_driver, netvsc_devclass, 0, 0);
1014MODULE_VERSION(hn, 1);
1015MODULE_DEPEND(hn, vmbus, 1, 1, 1);
1016SYSINIT(netvsc_initx, SI_SUB_KTHREAD_IDLE, SI_ORDER_MIDDLE + 1, netvsc_init,
1017 NULL);
1018
992}
993#endif
994
995static device_method_t netvsc_methods[] = {
996 /* Device interface */
997 DEVMETHOD(device_probe, netvsc_probe),
998 DEVMETHOD(device_attach, netvsc_attach),
999 DEVMETHOD(device_detach, netvsc_detach),
1000 DEVMETHOD(device_shutdown, netvsc_shutdown),
1001
1002 { 0, 0 }
1003};
1004
1005static driver_t netvsc_driver = {
1006 NETVSC_DEVNAME,
1007 netvsc_methods,
1008 sizeof(hn_softc_t)
1009};
1010
1011static devclass_t netvsc_devclass;
1012
1013DRIVER_MODULE(hn, vmbus, netvsc_driver, netvsc_devclass, 0, 0);
1014MODULE_VERSION(hn, 1);
1015MODULE_DEPEND(hn, vmbus, 1, 1, 1);
1016SYSINIT(netvsc_initx, SI_SUB_KTHREAD_IDLE, SI_ORDER_MIDDLE + 1, netvsc_init,
1017 NULL);
1018