if_vioif.c revision 1.17
169800Stomsoft/* $NetBSD: if_vioif.c,v 1.17 2015/10/26 01:44:48 ozaki-r Exp $ */ 269800Stomsoft 369800Stomsoft/* 469800Stomsoft * Copyright (c) 2010 Minoura Makoto. 569800Stomsoft * All rights reserved. 669800Stomsoft * 769800Stomsoft * Redistribution and use in source and binary forms, with or without 869800Stomsoft * modification, are permitted provided that the following conditions 969800Stomsoft * are met: 1069800Stomsoft * 1. Redistributions of source code must retain the above copyright 1169800Stomsoft * notice, this list of conditions and the following disclaimer. 1269800Stomsoft * 2. Redistributions in binary form must reproduce the above copyright 1369800Stomsoft * notice, this list of conditions and the following disclaimer in the 1469800Stomsoft * documentation and/or other materials provided with the distribution. 1569800Stomsoft * 1669800Stomsoft * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1769800Stomsoft * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1869800Stomsoft * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1969800Stomsoft * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2069800Stomsoft * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2169800Stomsoft * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> 29__KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.17 2015/10/26 01:44:48 ozaki-r Exp $"); 30 31#ifdef _KERNEL_OPT 32#include "opt_net_mpsafe.h" 33#endif 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#include <sys/bus.h> 39#include <sys/condvar.h> 40#include <sys/device.h> 41#include <sys/intr.h> 42#include <sys/kmem.h> 43#include <sys/mbuf.h> 44#include <sys/mutex.h> 45#include <sys/sockio.h> 46#include <sys/cpu.h> 47 48#include <dev/pci/pcidevs.h> 49#include <dev/pci/pcireg.h> 50#include <dev/pci/pcivar.h> 51#include <dev/pci/virtioreg.h> 52#include <dev/pci/virtiovar.h> 53 54#include <net/if.h> 55#include <net/if_media.h> 56#include <net/if_ether.h> 57 58#include <net/bpf.h> 59 60 61#ifdef NET_MPSAFE 62#define VIOIF_MPSAFE 1 63#endif 64 65#ifdef SOFTINT_INTR 66#define VIOIF_SOFTINT_INTR 1 67#endif 68 69/* 70 * if_vioifreg.h: 71 */ 72/* Configuration registers */ 73#define VIRTIO_NET_CONFIG_MAC 0 /* 8bit x 6byte */ 74#define VIRTIO_NET_CONFIG_STATUS 6 /* 16bit */ 75 76/* Feature bits */ 77#define VIRTIO_NET_F_CSUM (1<<0) 78#define VIRTIO_NET_F_GUEST_CSUM (1<<1) 79#define VIRTIO_NET_F_MAC (1<<5) 80#define VIRTIO_NET_F_GSO (1<<6) 81#define VIRTIO_NET_F_GUEST_TSO4 (1<<7) 82#define VIRTIO_NET_F_GUEST_TSO6 (1<<8) 83#define VIRTIO_NET_F_GUEST_ECN (1<<9) 84#define VIRTIO_NET_F_GUEST_UFO (1<<10) 85#define VIRTIO_NET_F_HOST_TSO4 (1<<11) 86#define VIRTIO_NET_F_HOST_TSO6 (1<<12) 87#define VIRTIO_NET_F_HOST_ECN (1<<13) 88#define VIRTIO_NET_F_HOST_UFO (1<<14) 89#define VIRTIO_NET_F_MRG_RXBUF (1<<15) 90#define VIRTIO_NET_F_STATUS (1<<16) 91#define VIRTIO_NET_F_CTRL_VQ (1<<17) 92#define VIRTIO_NET_F_CTRL_RX (1<<18) 93#define VIRTIO_NET_F_CTRL_VLAN (1<<19) 94 95/* Status */ 96#define VIRTIO_NET_S_LINK_UP 1 97 98/* Packet header structure */ 99struct virtio_net_hdr { 100 uint8_t flags; 101 uint8_t gso_type; 102 uint16_t hdr_len; 103 uint16_t gso_size; 104 uint16_t csum_start; 105 uint16_t csum_offset; 106#if 0 107 uint16_t num_buffers; /* if VIRTIO_NET_F_MRG_RXBUF enabled */ 108#endif 109} __packed; 110 111#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* flags */ 112#define VIRTIO_NET_HDR_GSO_NONE 0 /* gso_type */ 113#define VIRTIO_NET_HDR_GSO_TCPV4 1 /* gso_type */ 114#define VIRTIO_NET_HDR_GSO_UDP 3 /* gso_type */ 115#define VIRTIO_NET_HDR_GSO_TCPV6 4 /* gso_type */ 116#define VIRTIO_NET_HDR_GSO_ECN 0x80 /* gso_type, |'ed */ 117 118#define VIRTIO_NET_MAX_GSO_LEN (65536+ETHER_HDR_LEN) 119 120/* Control virtqueue */ 121struct virtio_net_ctrl_cmd { 122 uint8_t class; 123 uint8_t command; 124} __packed; 125#define VIRTIO_NET_CTRL_RX 0 126# define VIRTIO_NET_CTRL_RX_PROMISC 0 127# define VIRTIO_NET_CTRL_RX_ALLMULTI 1 128 129#define VIRTIO_NET_CTRL_MAC 1 130# define VIRTIO_NET_CTRL_MAC_TABLE_SET 0 131 132#define VIRTIO_NET_CTRL_VLAN 2 133# define VIRTIO_NET_CTRL_VLAN_ADD 0 134# define VIRTIO_NET_CTRL_VLAN_DEL 1 135 136struct virtio_net_ctrl_status { 137 uint8_t ack; 138} __packed; 139#define VIRTIO_NET_OK 0 140#define VIRTIO_NET_ERR 1 141 142struct virtio_net_ctrl_rx { 143 uint8_t onoff; 144} __packed; 145 146struct virtio_net_ctrl_mac_tbl { 147 uint32_t nentries; 148 uint8_t macs[][ETHER_ADDR_LEN]; 149} __packed; 150 151struct virtio_net_ctrl_vlan { 152 uint16_t id; 153} __packed; 154 155 156/* 157 * if_vioifvar.h: 158 */ 159struct vioif_softc { 160 device_t sc_dev; 161 162 struct virtio_softc *sc_virtio; 163 struct virtqueue sc_vq[3]; 164 165 uint8_t sc_mac[ETHER_ADDR_LEN]; 166 struct ethercom sc_ethercom; 167 short sc_deferred_init_done; 168 169 /* bus_dmamem */ 170 bus_dma_segment_t sc_hdr_segs[1]; 171 struct virtio_net_hdr *sc_hdrs; 172#define sc_rx_hdrs sc_hdrs 173 struct virtio_net_hdr *sc_tx_hdrs; 174 struct virtio_net_ctrl_cmd *sc_ctrl_cmd; 175 struct virtio_net_ctrl_status *sc_ctrl_status; 176 struct virtio_net_ctrl_rx *sc_ctrl_rx; 177 struct virtio_net_ctrl_mac_tbl *sc_ctrl_mac_tbl_uc; 178 struct virtio_net_ctrl_mac_tbl *sc_ctrl_mac_tbl_mc; 179 180 /* kmem */ 181 bus_dmamap_t *sc_arrays; 182#define sc_rxhdr_dmamaps sc_arrays 183 bus_dmamap_t *sc_txhdr_dmamaps; 184 bus_dmamap_t *sc_rx_dmamaps; 185 bus_dmamap_t *sc_tx_dmamaps; 186 struct mbuf **sc_rx_mbufs; 187 struct mbuf **sc_tx_mbufs; 188 189 bus_dmamap_t sc_ctrl_cmd_dmamap; 190 bus_dmamap_t sc_ctrl_status_dmamap; 191 bus_dmamap_t sc_ctrl_rx_dmamap; 192 bus_dmamap_t sc_ctrl_tbl_uc_dmamap; 193 bus_dmamap_t sc_ctrl_tbl_mc_dmamap; 194 195 void *sc_rx_softint; 196 197 enum { 198 FREE, INUSE, DONE 199 } sc_ctrl_inuse; 200 kcondvar_t sc_ctrl_wait; 201 kmutex_t sc_ctrl_wait_lock; 202 kmutex_t *sc_tx_lock; 203 kmutex_t *sc_rx_lock; 204 bool sc_stopping; 205}; 206#define VIRTIO_NET_TX_MAXNSEGS (16) /* XXX */ 207#define VIRTIO_NET_CTRL_MAC_MAXENTRIES (64) /* XXX */ 208 209#define VIOIF_TX_LOCK(_sc) if ((_sc)->sc_tx_lock) mutex_enter((_sc)->sc_tx_lock) 210#define VIOIF_TX_UNLOCK(_sc) if ((_sc)->sc_tx_lock) mutex_exit((_sc)->sc_tx_lock) 211#define VIOIF_TX_LOCKED(_sc) (!(_sc)->sc_tx_lock || mutex_owned((_sc)->sc_tx_lock)) 212#define VIOIF_RX_LOCK(_sc) if ((_sc)->sc_rx_lock) mutex_enter((_sc)->sc_rx_lock) 213#define VIOIF_RX_UNLOCK(_sc) if ((_sc)->sc_rx_lock) mutex_exit((_sc)->sc_rx_lock) 214#define VIOIF_RX_LOCKED(_sc) (!(_sc)->sc_rx_lock || mutex_owned((_sc)->sc_rx_lock)) 215 216/* cfattach interface functions */ 217static int vioif_match(device_t, cfdata_t, void *); 218static void vioif_attach(device_t, device_t, void *); 219static void vioif_deferred_init(device_t); 220 221/* ifnet interface functions */ 222static int vioif_init(struct ifnet *); 223static void vioif_stop(struct ifnet *, int); 224static void vioif_start(struct ifnet *); 225static int vioif_ioctl(struct ifnet *, u_long, void *); 226static void vioif_watchdog(struct ifnet *); 227 228/* rx */ 229static int vioif_add_rx_mbuf(struct vioif_softc *, int); 230static void vioif_free_rx_mbuf(struct vioif_softc *, int); 231static void vioif_populate_rx_mbufs(struct vioif_softc *); 232static void vioif_populate_rx_mbufs_locked(struct vioif_softc *); 233static int vioif_rx_deq(struct vioif_softc *); 234static int vioif_rx_deq_locked(struct vioif_softc *); 235static int vioif_rx_vq_done(struct virtqueue *); 236static void vioif_rx_softint(void *); 237static void vioif_rx_drain(struct vioif_softc *); 238 239/* tx */ 240static int vioif_tx_vq_done(struct virtqueue *); 241static int vioif_tx_vq_done_locked(struct virtqueue *); 242static void vioif_tx_drain(struct vioif_softc *); 243 244/* other control */ 245static int vioif_updown(struct vioif_softc *, bool); 246static int vioif_ctrl_rx(struct vioif_softc *, int, bool); 247static int vioif_set_promisc(struct vioif_softc *, bool); 248static int vioif_set_allmulti(struct vioif_softc *, bool); 249static int vioif_set_rx_filter(struct vioif_softc *); 250static int vioif_rx_filter(struct vioif_softc *); 251static int vioif_ctrl_vq_done(struct virtqueue *); 252 253CFATTACH_DECL_NEW(vioif, sizeof(struct vioif_softc), 254 vioif_match, vioif_attach, NULL, NULL); 255 256static int 257vioif_match(device_t parent, cfdata_t match, void *aux) 258{ 259 struct virtio_softc *va = aux; 260 261 if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_NETWORK) 262 return 1; 263 264 return 0; 265} 266 267/* allocate memory */ 268/* 269 * dma memory is used for: 270 * sc_rx_hdrs[slot]: metadata array for recieved frames (READ) 271 * sc_tx_hdrs[slot]: metadata array for frames to be sent (WRITE) 272 * sc_ctrl_cmd: command to be sent via ctrl vq (WRITE) 273 * sc_ctrl_status: return value for a command via ctrl vq (READ) 274 * sc_ctrl_rx: parameter for a VIRTIO_NET_CTRL_RX class command 275 * (WRITE) 276 * sc_ctrl_mac_tbl_uc: unicast MAC address filter for a VIRTIO_NET_CTRL_MAC 277 * class command (WRITE) 278 * sc_ctrl_mac_tbl_mc: multicast MAC address filter for a VIRTIO_NET_CTRL_MAC 279 * class command (WRITE) 280 * sc_ctrl_* structures are allocated only one each; they are protected by 281 * sc_ctrl_inuse variable and sc_ctrl_wait condvar. 282 */ 283/* 284 * dynamically allocated memory is used for: 285 * sc_rxhdr_dmamaps[slot]: bus_dmamap_t array for sc_rx_hdrs[slot] 286 * sc_txhdr_dmamaps[slot]: bus_dmamap_t array for sc_tx_hdrs[slot] 287 * sc_rx_dmamaps[slot]: bus_dmamap_t array for recieved payload 288 * sc_tx_dmamaps[slot]: bus_dmamap_t array for sent payload 289 * sc_rx_mbufs[slot]: mbuf pointer array for recieved frames 290 * sc_tx_mbufs[slot]: mbuf pointer array for sent frames 291 */ 292static int 293vioif_alloc_mems(struct vioif_softc *sc) 294{ 295 struct virtio_softc *vsc = sc->sc_virtio; 296 int allocsize, allocsize2, r, rsegs, i; 297 void *vaddr; 298 intptr_t p; 299 int rxqsize, txqsize; 300 301 rxqsize = vsc->sc_vqs[0].vq_num; 302 txqsize = vsc->sc_vqs[1].vq_num; 303 304 allocsize = sizeof(struct virtio_net_hdr) * rxqsize; 305 allocsize += sizeof(struct virtio_net_hdr) * txqsize; 306 if (vsc->sc_nvqs == 3) { 307 allocsize += sizeof(struct virtio_net_ctrl_cmd) * 1; 308 allocsize += sizeof(struct virtio_net_ctrl_status) * 1; 309 allocsize += sizeof(struct virtio_net_ctrl_rx) * 1; 310 allocsize += sizeof(struct virtio_net_ctrl_mac_tbl) 311 + sizeof(struct virtio_net_ctrl_mac_tbl) 312 + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES; 313 } 314 r = bus_dmamem_alloc(vsc->sc_dmat, allocsize, 0, 0, 315 &sc->sc_hdr_segs[0], 1, &rsegs, BUS_DMA_NOWAIT); 316 if (r != 0) { 317 aprint_error_dev(sc->sc_dev, 318 "DMA memory allocation failed, size %d, " 319 "error code %d\n", allocsize, r); 320 goto err_none; 321 } 322 r = bus_dmamem_map(vsc->sc_dmat, 323 &sc->sc_hdr_segs[0], 1, allocsize, 324 &vaddr, BUS_DMA_NOWAIT); 325 if (r != 0) { 326 aprint_error_dev(sc->sc_dev, 327 "DMA memory map failed, " 328 "error code %d\n", r); 329 goto err_dmamem_alloc; 330 } 331 sc->sc_hdrs = vaddr; 332 memset(vaddr, 0, allocsize); 333 p = (intptr_t) vaddr; 334 p += sizeof(struct virtio_net_hdr) * rxqsize; 335#define P(name,size) do { sc->sc_ ##name = (void*) p; \ 336 p += size; } while (0) 337 P(tx_hdrs, sizeof(struct virtio_net_hdr) * txqsize); 338 if (vsc->sc_nvqs == 3) { 339 P(ctrl_cmd, sizeof(struct virtio_net_ctrl_cmd)); 340 P(ctrl_status, sizeof(struct virtio_net_ctrl_status)); 341 P(ctrl_rx, sizeof(struct virtio_net_ctrl_rx)); 342 P(ctrl_mac_tbl_uc, sizeof(struct virtio_net_ctrl_mac_tbl)); 343 P(ctrl_mac_tbl_mc, 344 (sizeof(struct virtio_net_ctrl_mac_tbl) 345 + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES)); 346 } 347#undef P 348 349 allocsize2 = sizeof(bus_dmamap_t) * (rxqsize + txqsize); 350 allocsize2 += sizeof(bus_dmamap_t) * (rxqsize + txqsize); 351 allocsize2 += sizeof(struct mbuf*) * (rxqsize + txqsize); 352 sc->sc_arrays = kmem_zalloc(allocsize2, KM_SLEEP); 353 if (sc->sc_arrays == NULL) 354 goto err_dmamem_map; 355 sc->sc_txhdr_dmamaps = sc->sc_arrays + rxqsize; 356 sc->sc_rx_dmamaps = sc->sc_txhdr_dmamaps + txqsize; 357 sc->sc_tx_dmamaps = sc->sc_rx_dmamaps + rxqsize; 358 sc->sc_rx_mbufs = (void*) (sc->sc_tx_dmamaps + txqsize); 359 sc->sc_tx_mbufs = sc->sc_rx_mbufs + rxqsize; 360 361#define C(map, buf, size, nsegs, rw, usage) \ 362 do { \ 363 r = bus_dmamap_create(vsc->sc_dmat, size, nsegs, size, 0, \ 364 BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, \ 365 &sc->sc_ ##map); \ 366 if (r != 0) { \ 367 aprint_error_dev(sc->sc_dev, \ 368 usage " dmamap creation failed, " \ 369 "error code %d\n", r); \ 370 goto err_reqs; \ 371 } \ 372 } while (0) 373#define C_L1(map, buf, size, nsegs, rw, usage) \ 374 C(map, buf, size, nsegs, rw, usage); \ 375 do { \ 376 r = bus_dmamap_load(vsc->sc_dmat, sc->sc_ ##map, \ 377 &sc->sc_ ##buf, size, NULL, \ 378 BUS_DMA_ ##rw | BUS_DMA_NOWAIT); \ 379 if (r != 0) { \ 380 aprint_error_dev(sc->sc_dev, \ 381 usage " dmamap load failed, " \ 382 "error code %d\n", r); \ 383 goto err_reqs; \ 384 } \ 385 } while (0) 386#define C_L2(map, buf, size, nsegs, rw, usage) \ 387 C(map, buf, size, nsegs, rw, usage); \ 388 do { \ 389 r = bus_dmamap_load(vsc->sc_dmat, sc->sc_ ##map, \ 390 sc->sc_ ##buf, size, NULL, \ 391 BUS_DMA_ ##rw | BUS_DMA_NOWAIT); \ 392 if (r != 0) { \ 393 aprint_error_dev(sc->sc_dev, \ 394 usage " dmamap load failed, " \ 395 "error code %d\n", r); \ 396 goto err_reqs; \ 397 } \ 398 } while (0) 399 for (i = 0; i < rxqsize; i++) { 400 C_L1(rxhdr_dmamaps[i], rx_hdrs[i], 401 sizeof(struct virtio_net_hdr), 1, 402 READ, "rx header"); 403 C(rx_dmamaps[i], NULL, MCLBYTES, 1, 0, "rx payload"); 404 } 405 406 for (i = 0; i < txqsize; i++) { 407 C_L1(txhdr_dmamaps[i], rx_hdrs[i], 408 sizeof(struct virtio_net_hdr), 1, 409 WRITE, "tx header"); 410 C(tx_dmamaps[i], NULL, ETHER_MAX_LEN, 256 /* XXX */, 0, 411 "tx payload"); 412 } 413 414 if (vsc->sc_nvqs == 3) { 415 /* control vq class & command */ 416 C_L2(ctrl_cmd_dmamap, ctrl_cmd, 417 sizeof(struct virtio_net_ctrl_cmd), 1, WRITE, 418 "control command"); 419 420 /* control vq status */ 421 C_L2(ctrl_status_dmamap, ctrl_status, 422 sizeof(struct virtio_net_ctrl_status), 1, READ, 423 "control status"); 424 425 /* control vq rx mode command parameter */ 426 C_L2(ctrl_rx_dmamap, ctrl_rx, 427 sizeof(struct virtio_net_ctrl_rx), 1, WRITE, 428 "rx mode control command"); 429 430 /* control vq MAC filter table for unicast */ 431 /* do not load now since its length is variable */ 432 C(ctrl_tbl_uc_dmamap, NULL, 433 sizeof(struct virtio_net_ctrl_mac_tbl) + 0, 1, WRITE, 434 "unicast MAC address filter command"); 435 436 /* control vq MAC filter table for multicast */ 437 C(ctrl_tbl_mc_dmamap, NULL, 438 (sizeof(struct virtio_net_ctrl_mac_tbl) 439 + ETHER_ADDR_LEN * VIRTIO_NET_CTRL_MAC_MAXENTRIES), 440 1, WRITE, "multicast MAC address filter command"); 441 } 442#undef C_L2 443#undef C_L1 444#undef C 445 446 return 0; 447 448err_reqs: 449#define D(map) \ 450 do { \ 451 if (sc->sc_ ##map) { \ 452 bus_dmamap_destroy(vsc->sc_dmat, sc->sc_ ##map); \ 453 sc->sc_ ##map = NULL; \ 454 } \ 455 } while (0) 456 D(ctrl_tbl_mc_dmamap); 457 D(ctrl_tbl_uc_dmamap); 458 D(ctrl_rx_dmamap); 459 D(ctrl_status_dmamap); 460 D(ctrl_cmd_dmamap); 461 for (i = 0; i < txqsize; i++) { 462 D(tx_dmamaps[i]); 463 D(txhdr_dmamaps[i]); 464 } 465 for (i = 0; i < rxqsize; i++) { 466 D(rx_dmamaps[i]); 467 D(rxhdr_dmamaps[i]); 468 } 469#undef D 470 if (sc->sc_arrays) { 471 kmem_free(sc->sc_arrays, allocsize2); 472 sc->sc_arrays = 0; 473 } 474err_dmamem_map: 475 bus_dmamem_unmap(vsc->sc_dmat, sc->sc_hdrs, allocsize); 476err_dmamem_alloc: 477 bus_dmamem_free(vsc->sc_dmat, &sc->sc_hdr_segs[0], 1); 478err_none: 479 return -1; 480} 481 482static void 483vioif_attach(device_t parent, device_t self, void *aux) 484{ 485 struct vioif_softc *sc = device_private(self); 486 struct virtio_softc *vsc = device_private(parent); 487 uint32_t features; 488 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 489 u_int flags; 490 int r; 491 492 if (vsc->sc_child != NULL) { 493 aprint_normal(": child already attached for %s; " 494 "something wrong...\n", 495 device_xname(parent)); 496 return; 497 } 498 499 sc->sc_dev = self; 500 sc->sc_virtio = vsc; 501 502 vsc->sc_child = self; 503 vsc->sc_ipl = IPL_NET; 504 vsc->sc_vqs = &sc->sc_vq[0]; 505 vsc->sc_config_change = NULL; 506 vsc->sc_intrhand = virtio_vq_intr; 507 vsc->sc_flags = 0; 508 509#ifdef VIOIF_MPSAFE 510 vsc->sc_flags |= VIRTIO_F_PCI_INTR_MPSAFE; 511#endif 512#ifdef VIOIF_SOFTINT_INTR 513 vsc->sc_flags |= VIRTIO_F_PCI_INTR_SOFTINT; 514#endif 515 vsc->sc_flags |= VIRTIO_F_PCI_INTR_MSIX; 516 517 features = virtio_negotiate_features(vsc, 518 (VIRTIO_NET_F_MAC | 519 VIRTIO_NET_F_STATUS | 520 VIRTIO_NET_F_CTRL_VQ | 521 VIRTIO_NET_F_CTRL_RX | 522 VIRTIO_F_NOTIFY_ON_EMPTY)); 523 if (features & VIRTIO_NET_F_MAC) { 524 sc->sc_mac[0] = virtio_read_device_config_1(vsc, 525 VIRTIO_NET_CONFIG_MAC+0); 526 sc->sc_mac[1] = virtio_read_device_config_1(vsc, 527 VIRTIO_NET_CONFIG_MAC+1); 528 sc->sc_mac[2] = virtio_read_device_config_1(vsc, 529 VIRTIO_NET_CONFIG_MAC+2); 530 sc->sc_mac[3] = virtio_read_device_config_1(vsc, 531 VIRTIO_NET_CONFIG_MAC+3); 532 sc->sc_mac[4] = virtio_read_device_config_1(vsc, 533 VIRTIO_NET_CONFIG_MAC+4); 534 sc->sc_mac[5] = virtio_read_device_config_1(vsc, 535 VIRTIO_NET_CONFIG_MAC+5); 536 } else { 537 /* code stolen from sys/net/if_tap.c */ 538 struct timeval tv; 539 uint32_t ui; 540 getmicrouptime(&tv); 541 ui = (tv.tv_sec ^ tv.tv_usec) & 0xffffff; 542 memcpy(sc->sc_mac+3, (uint8_t *)&ui, 3); 543 virtio_write_device_config_1(vsc, 544 VIRTIO_NET_CONFIG_MAC+0, 545 sc->sc_mac[0]); 546 virtio_write_device_config_1(vsc, 547 VIRTIO_NET_CONFIG_MAC+1, 548 sc->sc_mac[1]); 549 virtio_write_device_config_1(vsc, 550 VIRTIO_NET_CONFIG_MAC+2, 551 sc->sc_mac[2]); 552 virtio_write_device_config_1(vsc, 553 VIRTIO_NET_CONFIG_MAC+3, 554 sc->sc_mac[3]); 555 virtio_write_device_config_1(vsc, 556 VIRTIO_NET_CONFIG_MAC+4, 557 sc->sc_mac[4]); 558 virtio_write_device_config_1(vsc, 559 VIRTIO_NET_CONFIG_MAC+5, 560 sc->sc_mac[5]); 561 } 562 aprint_normal(": Ethernet address %s\n", ether_sprintf(sc->sc_mac)); 563 aprint_naive("\n"); 564 565#ifdef VIOIF_MPSAFE 566 sc->sc_tx_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); 567 sc->sc_rx_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); 568#else 569 sc->sc_tx_lock = NULL; 570 sc->sc_rx_lock = NULL; 571#endif 572 sc->sc_stopping = false; 573 574 /* 575 * Allocating a virtqueue for Rx 576 */ 577 r = virtio_alloc_vq(vsc, &sc->sc_vq[0], 0, 578 MCLBYTES+sizeof(struct virtio_net_hdr), 2, "rx"); 579 if (r != 0) 580 goto err; 581 vsc->sc_nvqs = 1; 582 sc->sc_vq[0].vq_done = vioif_rx_vq_done; 583 584 /* 585 * Allocating a virtqueue for Tx 586 */ 587 r = virtio_alloc_vq(vsc, &sc->sc_vq[1], 1, 588 (sizeof(struct virtio_net_hdr) + (ETHER_MAX_LEN - ETHER_HDR_LEN)), 589 VIRTIO_NET_TX_MAXNSEGS + 1, "tx"); 590 if (r != 0) 591 goto err; 592 vsc->sc_nvqs = 2; 593 sc->sc_vq[1].vq_done = vioif_tx_vq_done; 594 595 virtio_start_vq_intr(vsc, &sc->sc_vq[0]); 596 virtio_stop_vq_intr(vsc, &sc->sc_vq[1]); /* not urgent; do it later */ 597 598 if ((features & VIRTIO_NET_F_CTRL_VQ) && 599 (features & VIRTIO_NET_F_CTRL_RX)) { 600 /* 601 * Allocating a virtqueue for control channel 602 */ 603 r = virtio_alloc_vq(vsc, &sc->sc_vq[2], 2, 604 NBPG, 1, "control"); 605 if (r != 0) { 606 aprint_error_dev(self, "failed to allocate " 607 "a virtqueue for control channel\n"); 608 goto skip; 609 } 610 611 sc->sc_vq[2].vq_done = vioif_ctrl_vq_done; 612 cv_init(&sc->sc_ctrl_wait, "ctrl_vq"); 613 mutex_init(&sc->sc_ctrl_wait_lock, MUTEX_DEFAULT, IPL_NET); 614 sc->sc_ctrl_inuse = FREE; 615 virtio_start_vq_intr(vsc, &sc->sc_vq[2]); 616 vsc->sc_nvqs = 3; 617 } 618skip: 619 620#ifdef VIOIF_MPSAFE 621 flags = SOFTINT_NET | SOFTINT_MPSAFE; 622#else 623 flags = SOFTINT_NET; 624#endif 625 sc->sc_rx_softint = softint_establish(flags, vioif_rx_softint, sc); 626 if (sc->sc_rx_softint == NULL) { 627 aprint_error_dev(self, "cannot establish softint\n"); 628 goto err; 629 } 630 631 if (vioif_alloc_mems(sc) < 0) 632 goto err; 633 634 strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); 635 ifp->if_softc = sc; 636 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 637 ifp->if_start = vioif_start; 638 ifp->if_ioctl = vioif_ioctl; 639 ifp->if_init = vioif_init; 640 ifp->if_stop = vioif_stop; 641 ifp->if_capabilities = 0; 642 ifp->if_watchdog = vioif_watchdog; 643 644 sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; 645 646 if_attach(ifp); 647 ether_ifattach(ifp, sc->sc_mac); 648 649 return; 650 651err: 652 if (sc->sc_tx_lock) 653 mutex_obj_free(sc->sc_tx_lock); 654 if (sc->sc_rx_lock) 655 mutex_obj_free(sc->sc_rx_lock); 656 657 if (vsc->sc_nvqs == 3) { 658 virtio_free_vq(vsc, &sc->sc_vq[2]); 659 cv_destroy(&sc->sc_ctrl_wait); 660 mutex_destroy(&sc->sc_ctrl_wait_lock); 661 vsc->sc_nvqs = 2; 662 } 663 if (vsc->sc_nvqs == 2) { 664 virtio_free_vq(vsc, &sc->sc_vq[1]); 665 vsc->sc_nvqs = 1; 666 } 667 if (vsc->sc_nvqs == 1) { 668 virtio_free_vq(vsc, &sc->sc_vq[0]); 669 vsc->sc_nvqs = 0; 670 } 671 vsc->sc_child = (void*)1; 672 return; 673} 674 675/* we need interrupts to make promiscuous mode off */ 676static void 677vioif_deferred_init(device_t self) 678{ 679 struct vioif_softc *sc = device_private(self); 680 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 681 int r; 682 683 if (ifp->if_flags & IFF_PROMISC) 684 return; 685 686 r = vioif_set_promisc(sc, false); 687 if (r != 0) 688 aprint_error_dev(self, "resetting promisc mode failed, " 689 "errror code %d\n", r); 690} 691 692/* 693 * Interface functions for ifnet 694 */ 695static int 696vioif_init(struct ifnet *ifp) 697{ 698 struct vioif_softc *sc = ifp->if_softc; 699 700 vioif_stop(ifp, 0); 701 702 if (!sc->sc_deferred_init_done) { 703 struct virtio_softc *vsc = sc->sc_virtio; 704 705 sc->sc_deferred_init_done = 1; 706 if (vsc->sc_nvqs == 3) 707 vioif_deferred_init(sc->sc_dev); 708 } 709 710 /* Have to set false before vioif_populate_rx_mbufs */ 711 sc->sc_stopping = false; 712 713 vioif_populate_rx_mbufs(sc); 714 715 vioif_updown(sc, true); 716 ifp->if_flags |= IFF_RUNNING; 717 ifp->if_flags &= ~IFF_OACTIVE; 718 vioif_rx_filter(sc); 719 720 return 0; 721} 722 723static void 724vioif_stop(struct ifnet *ifp, int disable) 725{ 726 struct vioif_softc *sc = ifp->if_softc; 727 struct virtio_softc *vsc = sc->sc_virtio; 728 729 /* Take the locks to ensure that ongoing TX/RX finish */ 730 VIOIF_TX_LOCK(sc); 731 VIOIF_RX_LOCK(sc); 732 sc->sc_stopping = true; 733 VIOIF_RX_UNLOCK(sc); 734 VIOIF_TX_UNLOCK(sc); 735 736 /* only way to stop I/O and DMA is resetting... */ 737 virtio_reset(vsc); 738 vioif_rx_deq(sc); 739 vioif_tx_drain(sc); 740 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 741 742 if (disable) 743 vioif_rx_drain(sc); 744 745 virtio_reinit_start(vsc); 746 virtio_negotiate_features(vsc, vsc->sc_features); 747 virtio_start_vq_intr(vsc, &sc->sc_vq[0]); 748 virtio_stop_vq_intr(vsc, &sc->sc_vq[1]); 749 if (vsc->sc_nvqs >= 3) 750 virtio_start_vq_intr(vsc, &sc->sc_vq[2]); 751 virtio_reinit_end(vsc); 752 vioif_updown(sc, false); 753} 754 755static void 756vioif_start(struct ifnet *ifp) 757{ 758 struct vioif_softc *sc = ifp->if_softc; 759 struct virtio_softc *vsc = sc->sc_virtio; 760 struct virtqueue *vq = &sc->sc_vq[1]; /* tx vq */ 761 struct mbuf *m; 762 int queued = 0, retry = 0; 763 764 VIOIF_TX_LOCK(sc); 765 766 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 767 goto out; 768 769 if (sc->sc_stopping) 770 goto out; 771 772 for (;;) { 773 int slot, r; 774 775 IFQ_DEQUEUE(&ifp->if_snd, m); 776 777 if (m == NULL) 778 break; 779 780retry: 781 r = virtio_enqueue_prep(vsc, vq, &slot); 782 if (r == EAGAIN) { 783 ifp->if_flags |= IFF_OACTIVE; 784 vioif_tx_vq_done_locked(vq); 785 if (retry++ == 0) 786 goto retry; 787 else 788 break; 789 } 790 if (r != 0) 791 panic("enqueue_prep for a tx buffer"); 792 r = bus_dmamap_load_mbuf(vsc->sc_dmat, 793 sc->sc_tx_dmamaps[slot], 794 m, BUS_DMA_WRITE|BUS_DMA_NOWAIT); 795 if (r != 0) { 796 virtio_enqueue_abort(vsc, vq, slot); 797 printf("%s: tx dmamap load failed, error code %d\n", 798 device_xname(sc->sc_dev), r); 799 break; 800 } 801 r = virtio_enqueue_reserve(vsc, vq, slot, 802 sc->sc_tx_dmamaps[slot]->dm_nsegs + 1); 803 if (r != 0) { 804 bus_dmamap_unload(vsc->sc_dmat, 805 sc->sc_tx_dmamaps[slot]); 806 ifp->if_flags |= IFF_OACTIVE; 807 vioif_tx_vq_done_locked(vq); 808 if (retry++ == 0) 809 goto retry; 810 else 811 break; 812 } 813 814 sc->sc_tx_mbufs[slot] = m; 815 816 memset(&sc->sc_tx_hdrs[slot], 0, sizeof(struct virtio_net_hdr)); 817 bus_dmamap_sync(vsc->sc_dmat, sc->sc_tx_dmamaps[slot], 818 0, sc->sc_tx_dmamaps[slot]->dm_mapsize, 819 BUS_DMASYNC_PREWRITE); 820 bus_dmamap_sync(vsc->sc_dmat, sc->sc_txhdr_dmamaps[slot], 821 0, sc->sc_txhdr_dmamaps[slot]->dm_mapsize, 822 BUS_DMASYNC_PREWRITE); 823 virtio_enqueue(vsc, vq, slot, sc->sc_txhdr_dmamaps[slot], true); 824 virtio_enqueue(vsc, vq, slot, sc->sc_tx_dmamaps[slot], true); 825 virtio_enqueue_commit(vsc, vq, slot, false); 826 queued++; 827 bpf_mtap(ifp, m); 828 } 829 830 if (m != NULL) { 831 ifp->if_flags |= IFF_OACTIVE; 832 m_freem(m); 833 } 834 835 if (queued > 0) { 836 virtio_enqueue_commit(vsc, vq, -1, true); 837 ifp->if_timer = 5; 838 } 839 840out: 841 VIOIF_TX_UNLOCK(sc); 842} 843 844static int 845vioif_ioctl(struct ifnet *ifp, u_long cmd, void *data) 846{ 847 int s, r; 848 849 s = splnet(); 850 851 r = ether_ioctl(ifp, cmd, data); 852 if ((r == 0 && cmd == SIOCSIFFLAGS) || 853 (r == ENETRESET && (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI))) { 854 if (ifp->if_flags & IFF_RUNNING) 855 r = vioif_rx_filter(ifp->if_softc); 856 else 857 r = 0; 858 } 859 860 splx(s); 861 862 return r; 863} 864 865void 866vioif_watchdog(struct ifnet *ifp) 867{ 868 struct vioif_softc *sc = ifp->if_softc; 869 870 if (ifp->if_flags & IFF_RUNNING) 871 vioif_tx_vq_done(&sc->sc_vq[1]); 872} 873 874 875/* 876 * Recieve implementation 877 */ 878/* allocate and initialize a mbuf for recieve */ 879static int 880vioif_add_rx_mbuf(struct vioif_softc *sc, int i) 881{ 882 struct mbuf *m; 883 int r; 884 885 MGETHDR(m, M_DONTWAIT, MT_DATA); 886 if (m == NULL) 887 return ENOBUFS; 888 MCLGET(m, M_DONTWAIT); 889 if ((m->m_flags & M_EXT) == 0) { 890 m_freem(m); 891 return ENOBUFS; 892 } 893 sc->sc_rx_mbufs[i] = m; 894 m->m_len = m->m_pkthdr.len = m->m_ext.ext_size; 895 r = bus_dmamap_load_mbuf(sc->sc_virtio->sc_dmat, 896 sc->sc_rx_dmamaps[i], 897 m, BUS_DMA_READ|BUS_DMA_NOWAIT); 898 if (r) { 899 m_freem(m); 900 sc->sc_rx_mbufs[i] = 0; 901 return r; 902 } 903 904 return 0; 905} 906 907/* free a mbuf for recieve */ 908static void 909vioif_free_rx_mbuf(struct vioif_softc *sc, int i) 910{ 911 bus_dmamap_unload(sc->sc_virtio->sc_dmat, sc->sc_rx_dmamaps[i]); 912 m_freem(sc->sc_rx_mbufs[i]); 913 sc->sc_rx_mbufs[i] = NULL; 914} 915 916/* add mbufs for all the empty recieve slots */ 917static void 918vioif_populate_rx_mbufs(struct vioif_softc *sc) 919{ 920 VIOIF_RX_LOCK(sc); 921 vioif_populate_rx_mbufs_locked(sc); 922 VIOIF_RX_UNLOCK(sc); 923} 924 925static void 926vioif_populate_rx_mbufs_locked(struct vioif_softc *sc) 927{ 928 struct virtio_softc *vsc = sc->sc_virtio; 929 int i, r, ndone = 0; 930 struct virtqueue *vq = &sc->sc_vq[0]; /* rx vq */ 931 932 KASSERT(VIOIF_RX_LOCKED(sc)); 933 934 if (sc->sc_stopping) 935 return; 936 937 for (i = 0; i < vq->vq_num; i++) { 938 int slot; 939 r = virtio_enqueue_prep(vsc, vq, &slot); 940 if (r == EAGAIN) 941 break; 942 if (r != 0) 943 panic("enqueue_prep for rx buffers"); 944 if (sc->sc_rx_mbufs[slot] == NULL) { 945 r = vioif_add_rx_mbuf(sc, slot); 946 if (r != 0) { 947 printf("%s: rx mbuf allocation failed, " 948 "error code %d\n", 949 device_xname(sc->sc_dev), r); 950 break; 951 } 952 } 953 r = virtio_enqueue_reserve(vsc, vq, slot, 954 sc->sc_rx_dmamaps[slot]->dm_nsegs + 1); 955 if (r != 0) { 956 vioif_free_rx_mbuf(sc, slot); 957 break; 958 } 959 bus_dmamap_sync(vsc->sc_dmat, sc->sc_rxhdr_dmamaps[slot], 960 0, sizeof(struct virtio_net_hdr), BUS_DMASYNC_PREREAD); 961 bus_dmamap_sync(vsc->sc_dmat, sc->sc_rx_dmamaps[slot], 962 0, MCLBYTES, BUS_DMASYNC_PREREAD); 963 virtio_enqueue(vsc, vq, slot, sc->sc_rxhdr_dmamaps[slot], false); 964 virtio_enqueue(vsc, vq, slot, sc->sc_rx_dmamaps[slot], false); 965 virtio_enqueue_commit(vsc, vq, slot, false); 966 ndone++; 967 } 968 if (ndone > 0) 969 virtio_enqueue_commit(vsc, vq, -1, true); 970} 971 972/* dequeue recieved packets */ 973static int 974vioif_rx_deq(struct vioif_softc *sc) 975{ 976 int r; 977 978 KASSERT(sc->sc_stopping); 979 980 VIOIF_RX_LOCK(sc); 981 r = vioif_rx_deq_locked(sc); 982 VIOIF_RX_UNLOCK(sc); 983 984 return r; 985} 986 987/* dequeue recieved packets */ 988static int 989vioif_rx_deq_locked(struct vioif_softc *sc) 990{ 991 struct virtio_softc *vsc = sc->sc_virtio; 992 struct virtqueue *vq = &sc->sc_vq[0]; 993 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 994 struct mbuf *m; 995 int r = 0; 996 int slot, len; 997 998 KASSERT(VIOIF_RX_LOCKED(sc)); 999 1000 while (virtio_dequeue(vsc, vq, &slot, &len) == 0) { 1001 len -= sizeof(struct virtio_net_hdr); 1002 r = 1; 1003 bus_dmamap_sync(vsc->sc_dmat, sc->sc_rxhdr_dmamaps[slot], 1004 0, sizeof(struct virtio_net_hdr), 1005 BUS_DMASYNC_POSTREAD); 1006 bus_dmamap_sync(vsc->sc_dmat, sc->sc_rx_dmamaps[slot], 1007 0, MCLBYTES, 1008 BUS_DMASYNC_POSTREAD); 1009 m = sc->sc_rx_mbufs[slot]; 1010 KASSERT(m != NULL); 1011 bus_dmamap_unload(vsc->sc_dmat, sc->sc_rx_dmamaps[slot]); 1012 sc->sc_rx_mbufs[slot] = 0; 1013 virtio_dequeue_commit(vsc, vq, slot); 1014 m->m_pkthdr.rcvif = ifp; 1015 m->m_len = m->m_pkthdr.len = len; 1016 ifp->if_ipackets++; 1017 bpf_mtap(ifp, m); 1018 1019 VIOIF_RX_UNLOCK(sc); 1020 (*ifp->if_input)(ifp, m); 1021 VIOIF_RX_LOCK(sc); 1022 1023 if (sc->sc_stopping) 1024 break; 1025 } 1026 1027 return r; 1028} 1029 1030/* rx interrupt; call _dequeue above and schedule a softint */ 1031static int 1032vioif_rx_vq_done(struct virtqueue *vq) 1033{ 1034 struct virtio_softc *vsc = vq->vq_owner; 1035 struct vioif_softc *sc = device_private(vsc->sc_child); 1036 int r = 0; 1037 1038#ifdef VIOIF_SOFTINT_INTR 1039 KASSERT(!cpu_intr_p()); 1040#endif 1041 1042 VIOIF_RX_LOCK(sc); 1043 1044 if (sc->sc_stopping) 1045 goto out; 1046 1047 r = vioif_rx_deq_locked(sc); 1048 if (r) 1049#ifdef VIOIF_SOFTINT_INTR 1050 vioif_populate_rx_mbufs_locked(sc); 1051#else 1052 softint_schedule(sc->sc_rx_softint); 1053#endif 1054 1055out: 1056 VIOIF_RX_UNLOCK(sc); 1057 return r; 1058} 1059 1060/* softint: enqueue recieve requests for new incoming packets */ 1061static void 1062vioif_rx_softint(void *arg) 1063{ 1064 struct vioif_softc *sc = arg; 1065 1066 vioif_populate_rx_mbufs(sc); 1067} 1068 1069/* free all the mbufs; called from if_stop(disable) */ 1070static void 1071vioif_rx_drain(struct vioif_softc *sc) 1072{ 1073 struct virtqueue *vq = &sc->sc_vq[0]; 1074 int i; 1075 1076 for (i = 0; i < vq->vq_num; i++) { 1077 if (sc->sc_rx_mbufs[i] == NULL) 1078 continue; 1079 vioif_free_rx_mbuf(sc, i); 1080 } 1081} 1082 1083 1084/* 1085 * Transmition implementation 1086 */ 1087/* actual transmission is done in if_start */ 1088/* tx interrupt; dequeue and free mbufs */ 1089/* 1090 * tx interrupt is actually disabled; this should be called upon 1091 * tx vq full and watchdog 1092 */ 1093static int 1094vioif_tx_vq_done(struct virtqueue *vq) 1095{ 1096 struct virtio_softc *vsc = vq->vq_owner; 1097 struct vioif_softc *sc = device_private(vsc->sc_child); 1098 int r = 0; 1099 1100 VIOIF_TX_LOCK(sc); 1101 1102 if (sc->sc_stopping) 1103 goto out; 1104 1105 r = vioif_tx_vq_done_locked(vq); 1106 1107out: 1108 VIOIF_TX_UNLOCK(sc); 1109 return r; 1110} 1111 1112static int 1113vioif_tx_vq_done_locked(struct virtqueue *vq) 1114{ 1115 struct virtio_softc *vsc = vq->vq_owner; 1116 struct vioif_softc *sc = device_private(vsc->sc_child); 1117 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1118 struct mbuf *m; 1119 int r = 0; 1120 int slot, len; 1121 1122 KASSERT(VIOIF_TX_LOCKED(sc)); 1123 1124 while (virtio_dequeue(vsc, vq, &slot, &len) == 0) { 1125 r++; 1126 bus_dmamap_sync(vsc->sc_dmat, sc->sc_txhdr_dmamaps[slot], 1127 0, sizeof(struct virtio_net_hdr), 1128 BUS_DMASYNC_POSTWRITE); 1129 bus_dmamap_sync(vsc->sc_dmat, sc->sc_tx_dmamaps[slot], 1130 0, sc->sc_tx_dmamaps[slot]->dm_mapsize, 1131 BUS_DMASYNC_POSTWRITE); 1132 m = sc->sc_tx_mbufs[slot]; 1133 bus_dmamap_unload(vsc->sc_dmat, sc->sc_tx_dmamaps[slot]); 1134 sc->sc_tx_mbufs[slot] = 0; 1135 virtio_dequeue_commit(vsc, vq, slot); 1136 ifp->if_opackets++; 1137 m_freem(m); 1138 } 1139 1140 if (r) 1141 ifp->if_flags &= ~IFF_OACTIVE; 1142 return r; 1143} 1144 1145/* free all the mbufs already put on vq; called from if_stop(disable) */ 1146static void 1147vioif_tx_drain(struct vioif_softc *sc) 1148{ 1149 struct virtio_softc *vsc = sc->sc_virtio; 1150 struct virtqueue *vq = &sc->sc_vq[1]; 1151 int i; 1152 1153 KASSERT(sc->sc_stopping); 1154 1155 for (i = 0; i < vq->vq_num; i++) { 1156 if (sc->sc_tx_mbufs[i] == NULL) 1157 continue; 1158 bus_dmamap_unload(vsc->sc_dmat, sc->sc_tx_dmamaps[i]); 1159 m_freem(sc->sc_tx_mbufs[i]); 1160 sc->sc_tx_mbufs[i] = NULL; 1161 } 1162} 1163 1164/* 1165 * Control vq 1166 */ 1167/* issue a VIRTIO_NET_CTRL_RX class command and wait for completion */ 1168static int 1169vioif_ctrl_rx(struct vioif_softc *sc, int cmd, bool onoff) 1170{ 1171 struct virtio_softc *vsc = sc->sc_virtio; 1172 struct virtqueue *vq = &sc->sc_vq[2]; 1173 int r, slot; 1174 1175 if (vsc->sc_nvqs < 3) 1176 return ENOTSUP; 1177 1178 mutex_enter(&sc->sc_ctrl_wait_lock); 1179 while (sc->sc_ctrl_inuse != FREE) 1180 cv_wait(&sc->sc_ctrl_wait, &sc->sc_ctrl_wait_lock); 1181 sc->sc_ctrl_inuse = INUSE; 1182 mutex_exit(&sc->sc_ctrl_wait_lock); 1183 1184 sc->sc_ctrl_cmd->class = VIRTIO_NET_CTRL_RX; 1185 sc->sc_ctrl_cmd->command = cmd; 1186 sc->sc_ctrl_rx->onoff = onoff; 1187 1188 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_cmd_dmamap, 1189 0, sizeof(struct virtio_net_ctrl_cmd), 1190 BUS_DMASYNC_PREWRITE); 1191 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_rx_dmamap, 1192 0, sizeof(struct virtio_net_ctrl_rx), 1193 BUS_DMASYNC_PREWRITE); 1194 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_status_dmamap, 1195 0, sizeof(struct virtio_net_ctrl_status), 1196 BUS_DMASYNC_PREREAD); 1197 1198 r = virtio_enqueue_prep(vsc, vq, &slot); 1199 if (r != 0) 1200 panic("%s: control vq busy!?", device_xname(sc->sc_dev)); 1201 r = virtio_enqueue_reserve(vsc, vq, slot, 3); 1202 if (r != 0) 1203 panic("%s: control vq busy!?", device_xname(sc->sc_dev)); 1204 virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_cmd_dmamap, true); 1205 virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_rx_dmamap, true); 1206 virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_status_dmamap, false); 1207 virtio_enqueue_commit(vsc, vq, slot, true); 1208 1209 /* wait for done */ 1210 mutex_enter(&sc->sc_ctrl_wait_lock); 1211 while (sc->sc_ctrl_inuse != DONE) 1212 cv_wait(&sc->sc_ctrl_wait, &sc->sc_ctrl_wait_lock); 1213 mutex_exit(&sc->sc_ctrl_wait_lock); 1214 /* already dequeueued */ 1215 1216 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_cmd_dmamap, 0, 1217 sizeof(struct virtio_net_ctrl_cmd), 1218 BUS_DMASYNC_POSTWRITE); 1219 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_rx_dmamap, 0, 1220 sizeof(struct virtio_net_ctrl_rx), 1221 BUS_DMASYNC_POSTWRITE); 1222 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_status_dmamap, 0, 1223 sizeof(struct virtio_net_ctrl_status), 1224 BUS_DMASYNC_POSTREAD); 1225 1226 if (sc->sc_ctrl_status->ack == VIRTIO_NET_OK) 1227 r = 0; 1228 else { 1229 printf("%s: failed setting rx mode\n", 1230 device_xname(sc->sc_dev)); 1231 r = EIO; 1232 } 1233 1234 mutex_enter(&sc->sc_ctrl_wait_lock); 1235 sc->sc_ctrl_inuse = FREE; 1236 cv_signal(&sc->sc_ctrl_wait); 1237 mutex_exit(&sc->sc_ctrl_wait_lock); 1238 1239 return r; 1240} 1241 1242static int 1243vioif_set_promisc(struct vioif_softc *sc, bool onoff) 1244{ 1245 int r; 1246 1247 r = vioif_ctrl_rx(sc, VIRTIO_NET_CTRL_RX_PROMISC, onoff); 1248 1249 return r; 1250} 1251 1252static int 1253vioif_set_allmulti(struct vioif_softc *sc, bool onoff) 1254{ 1255 int r; 1256 1257 r = vioif_ctrl_rx(sc, VIRTIO_NET_CTRL_RX_ALLMULTI, onoff); 1258 1259 return r; 1260} 1261 1262/* issue VIRTIO_NET_CTRL_MAC_TABLE_SET command and wait for completion */ 1263static int 1264vioif_set_rx_filter(struct vioif_softc *sc) 1265{ 1266 /* filter already set in sc_ctrl_mac_tbl */ 1267 struct virtio_softc *vsc = sc->sc_virtio; 1268 struct virtqueue *vq = &sc->sc_vq[2]; 1269 int r, slot; 1270 1271 if (vsc->sc_nvqs < 3) 1272 return ENOTSUP; 1273 1274 mutex_enter(&sc->sc_ctrl_wait_lock); 1275 while (sc->sc_ctrl_inuse != FREE) 1276 cv_wait(&sc->sc_ctrl_wait, &sc->sc_ctrl_wait_lock); 1277 sc->sc_ctrl_inuse = INUSE; 1278 mutex_exit(&sc->sc_ctrl_wait_lock); 1279 1280 sc->sc_ctrl_cmd->class = VIRTIO_NET_CTRL_MAC; 1281 sc->sc_ctrl_cmd->command = VIRTIO_NET_CTRL_MAC_TABLE_SET; 1282 1283 r = bus_dmamap_load(vsc->sc_dmat, sc->sc_ctrl_tbl_uc_dmamap, 1284 sc->sc_ctrl_mac_tbl_uc, 1285 (sizeof(struct virtio_net_ctrl_mac_tbl) 1286 + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_uc->nentries), 1287 NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT); 1288 if (r) { 1289 printf("%s: control command dmamap load failed, " 1290 "error code %d\n", device_xname(sc->sc_dev), r); 1291 goto out; 1292 } 1293 r = bus_dmamap_load(vsc->sc_dmat, sc->sc_ctrl_tbl_mc_dmamap, 1294 sc->sc_ctrl_mac_tbl_mc, 1295 (sizeof(struct virtio_net_ctrl_mac_tbl) 1296 + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_mc->nentries), 1297 NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT); 1298 if (r) { 1299 printf("%s: control command dmamap load failed, " 1300 "error code %d\n", device_xname(sc->sc_dev), r); 1301 bus_dmamap_unload(vsc->sc_dmat, sc->sc_ctrl_tbl_uc_dmamap); 1302 goto out; 1303 } 1304 1305 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_cmd_dmamap, 1306 0, sizeof(struct virtio_net_ctrl_cmd), 1307 BUS_DMASYNC_PREWRITE); 1308 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_tbl_uc_dmamap, 0, 1309 (sizeof(struct virtio_net_ctrl_mac_tbl) 1310 + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_uc->nentries), 1311 BUS_DMASYNC_PREWRITE); 1312 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_tbl_mc_dmamap, 0, 1313 (sizeof(struct virtio_net_ctrl_mac_tbl) 1314 + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_mc->nentries), 1315 BUS_DMASYNC_PREWRITE); 1316 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_status_dmamap, 1317 0, sizeof(struct virtio_net_ctrl_status), 1318 BUS_DMASYNC_PREREAD); 1319 1320 r = virtio_enqueue_prep(vsc, vq, &slot); 1321 if (r != 0) 1322 panic("%s: control vq busy!?", device_xname(sc->sc_dev)); 1323 r = virtio_enqueue_reserve(vsc, vq, slot, 4); 1324 if (r != 0) 1325 panic("%s: control vq busy!?", device_xname(sc->sc_dev)); 1326 virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_cmd_dmamap, true); 1327 virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_tbl_uc_dmamap, true); 1328 virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_tbl_mc_dmamap, true); 1329 virtio_enqueue(vsc, vq, slot, sc->sc_ctrl_status_dmamap, false); 1330 virtio_enqueue_commit(vsc, vq, slot, true); 1331 1332 /* wait for done */ 1333 mutex_enter(&sc->sc_ctrl_wait_lock); 1334 while (sc->sc_ctrl_inuse != DONE) 1335 cv_wait(&sc->sc_ctrl_wait, &sc->sc_ctrl_wait_lock); 1336 mutex_exit(&sc->sc_ctrl_wait_lock); 1337 /* already dequeueued */ 1338 1339 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_cmd_dmamap, 0, 1340 sizeof(struct virtio_net_ctrl_cmd), 1341 BUS_DMASYNC_POSTWRITE); 1342 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_tbl_uc_dmamap, 0, 1343 (sizeof(struct virtio_net_ctrl_mac_tbl) 1344 + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_uc->nentries), 1345 BUS_DMASYNC_POSTWRITE); 1346 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_tbl_mc_dmamap, 0, 1347 (sizeof(struct virtio_net_ctrl_mac_tbl) 1348 + ETHER_ADDR_LEN * sc->sc_ctrl_mac_tbl_mc->nentries), 1349 BUS_DMASYNC_POSTWRITE); 1350 bus_dmamap_sync(vsc->sc_dmat, sc->sc_ctrl_status_dmamap, 0, 1351 sizeof(struct virtio_net_ctrl_status), 1352 BUS_DMASYNC_POSTREAD); 1353 bus_dmamap_unload(vsc->sc_dmat, sc->sc_ctrl_tbl_uc_dmamap); 1354 bus_dmamap_unload(vsc->sc_dmat, sc->sc_ctrl_tbl_mc_dmamap); 1355 1356 if (sc->sc_ctrl_status->ack == VIRTIO_NET_OK) 1357 r = 0; 1358 else { 1359 printf("%s: failed setting rx filter\n", 1360 device_xname(sc->sc_dev)); 1361 r = EIO; 1362 } 1363 1364out: 1365 mutex_enter(&sc->sc_ctrl_wait_lock); 1366 sc->sc_ctrl_inuse = FREE; 1367 cv_signal(&sc->sc_ctrl_wait); 1368 mutex_exit(&sc->sc_ctrl_wait_lock); 1369 1370 return r; 1371} 1372 1373/* ctrl vq interrupt; wake up the command issuer */ 1374static int 1375vioif_ctrl_vq_done(struct virtqueue *vq) 1376{ 1377 struct virtio_softc *vsc = vq->vq_owner; 1378 struct vioif_softc *sc = device_private(vsc->sc_child); 1379 int r, slot; 1380 1381 r = virtio_dequeue(vsc, vq, &slot, NULL); 1382 if (r == ENOENT) 1383 return 0; 1384 virtio_dequeue_commit(vsc, vq, slot); 1385 1386 mutex_enter(&sc->sc_ctrl_wait_lock); 1387 sc->sc_ctrl_inuse = DONE; 1388 cv_signal(&sc->sc_ctrl_wait); 1389 mutex_exit(&sc->sc_ctrl_wait_lock); 1390 1391 return 1; 1392} 1393 1394/* 1395 * If IFF_PROMISC requested, set promiscuous 1396 * If multicast filter small enough (<=MAXENTRIES) set rx filter 1397 * If large multicast filter exist use ALLMULTI 1398 */ 1399/* 1400 * If setting rx filter fails fall back to ALLMULTI 1401 * If ALLMULTI fails fall back to PROMISC 1402 */ 1403static int 1404vioif_rx_filter(struct vioif_softc *sc) 1405{ 1406 struct virtio_softc *vsc = sc->sc_virtio; 1407 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1408 struct ether_multi *enm; 1409 struct ether_multistep step; 1410 int nentries; 1411 int promisc = 0, allmulti = 0, rxfilter = 0; 1412 int r; 1413 1414 if (vsc->sc_nvqs < 3) { /* no ctrl vq; always promisc */ 1415 ifp->if_flags |= IFF_PROMISC; 1416 return 0; 1417 } 1418 1419 if (ifp->if_flags & IFF_PROMISC) { 1420 promisc = 1; 1421 goto set; 1422 } 1423 1424 nentries = -1; 1425 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm); 1426 while (nentries++, enm != NULL) { 1427 if (nentries >= VIRTIO_NET_CTRL_MAC_MAXENTRIES) { 1428 allmulti = 1; 1429 goto set; 1430 } 1431 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1432 ETHER_ADDR_LEN)) { 1433 allmulti = 1; 1434 goto set; 1435 } 1436 memcpy(sc->sc_ctrl_mac_tbl_mc->macs[nentries], 1437 enm->enm_addrlo, ETHER_ADDR_LEN); 1438 ETHER_NEXT_MULTI(step, enm); 1439 } 1440 rxfilter = 1; 1441 1442set: 1443 if (rxfilter) { 1444 sc->sc_ctrl_mac_tbl_uc->nentries = 0; 1445 sc->sc_ctrl_mac_tbl_mc->nentries = nentries; 1446 r = vioif_set_rx_filter(sc); 1447 if (r != 0) { 1448 rxfilter = 0; 1449 allmulti = 1; /* fallback */ 1450 } 1451 } else { 1452 /* remove rx filter */ 1453 sc->sc_ctrl_mac_tbl_uc->nentries = 0; 1454 sc->sc_ctrl_mac_tbl_mc->nentries = 0; 1455 r = vioif_set_rx_filter(sc); 1456 /* what to do on failure? */ 1457 } 1458 if (allmulti) { 1459 r = vioif_set_allmulti(sc, true); 1460 if (r != 0) { 1461 allmulti = 0; 1462 promisc = 1; /* fallback */ 1463 } 1464 } else { 1465 r = vioif_set_allmulti(sc, false); 1466 /* what to do on failure? */ 1467 } 1468 if (promisc) { 1469 r = vioif_set_promisc(sc, true); 1470 } else { 1471 r = vioif_set_promisc(sc, false); 1472 } 1473 1474 return r; 1475} 1476 1477/* change link status */ 1478static int 1479vioif_updown(struct vioif_softc *sc, bool isup) 1480{ 1481 struct virtio_softc *vsc = sc->sc_virtio; 1482 1483 if (!(vsc->sc_features & VIRTIO_NET_F_STATUS)) 1484 return ENODEV; 1485 virtio_write_device_config_1(vsc, 1486 VIRTIO_NET_CONFIG_STATUS, 1487 isup?VIRTIO_NET_S_LINK_UP:0); 1488 return 0; 1489} 1490