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
|