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