1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2011 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, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 #include <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include <sys/param.h> 35 #include <sys/linker_set.h> 36 #include <sys/select.h> 37 #include <sys/uio.h> 38 #include <sys/ioctl.h> 39 #include <net/ethernet.h> 40 #include <net/if.h> /* IFNAMSIZ */ 41 42 #include <err.h> 43 #include <errno.h> 44 #include <fcntl.h> 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <stdint.h> 48 #include <string.h> 49 #include <strings.h> 50 #include <unistd.h> 51 #include <assert.h> 52 #include <pthread.h> 53 #include <pthread_np.h> 54 55 #include "bhyverun.h" 56 #include "debug.h" 57 #include "pci_emul.h" 58 #include "mevent.h" 59 #include "virtio.h" 60 #include "net_utils.h" 61 #include "net_backends.h" 62 #include "iov.h" 63 64 #define VTNET_RINGSZ 1024 65 66 #define VTNET_MAXSEGS 256 67 68 #define VTNET_MAX_PKT_LEN (65536 + 64) 69 70 #define VTNET_MIN_MTU ETHERMIN 71 #define VTNET_MAX_MTU 65535 72 73 #define VTNET_S_HOSTCAPS \ 74 ( VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | \ 75 VIRTIO_F_NOTIFY_ON_EMPTY | VIRTIO_RING_F_INDIRECT_DESC) 76 77 /* 78 * PCI config-space "registers" 79 */ 80 struct virtio_net_config { 81 uint8_t mac[6]; 82 uint16_t status; 83 uint16_t max_virtqueue_pairs; 84 uint16_t mtu; 85 } __packed; 86 87 /* 88 * Queue definitions. 89 */ 90 #define VTNET_RXQ 0 91 #define VTNET_TXQ 1 92 #define VTNET_CTLQ 2 /* NB: not yet supported */ 93 94 #define VTNET_MAXQ 3 95 96 /* 97 * Debug printf 98 */ 99 static int pci_vtnet_debug; 100 #define DPRINTF(params) if (pci_vtnet_debug) PRINTLN params 101 #define WPRINTF(params) PRINTLN params 102 103 /* 104 * Per-device softc 105 */ 106 struct pci_vtnet_softc { 107 struct virtio_softc vsc_vs; 108 struct vqueue_info vsc_queues[VTNET_MAXQ - 1]; 109 pthread_mutex_t vsc_mtx; 110 111 net_backend_t *vsc_be; 112 113 int resetting; /* protected by tx_mtx */ 114 115 uint64_t vsc_features; /* negotiated features */ 116 117 pthread_mutex_t rx_mtx; 118 int rx_merge; /* merged rx bufs in use */ 119 120 pthread_t tx_tid; 121 pthread_mutex_t tx_mtx; 122 pthread_cond_t tx_cond; 123 int tx_in_progress; 124 125 size_t vhdrlen; 126 size_t be_vhdrlen; 127 128 struct virtio_net_config vsc_config; 129 struct virtio_consts vsc_consts; 130 }; 131 132 static void pci_vtnet_reset(void *); 133 /* static void pci_vtnet_notify(void *, struct vqueue_info *); */ 134 static int pci_vtnet_cfgread(void *, int, int, uint32_t *); 135 static int pci_vtnet_cfgwrite(void *, int, int, uint32_t); 136 static void pci_vtnet_neg_features(void *, uint64_t); 137 138 static struct virtio_consts vtnet_vi_consts = { 139 "vtnet", /* our name */ 140 VTNET_MAXQ - 1, /* we currently support 2 virtqueues */ 141 sizeof(struct virtio_net_config), /* config reg size */ 142 pci_vtnet_reset, /* reset */ 143 NULL, /* device-wide qnotify -- not used */ 144 pci_vtnet_cfgread, /* read PCI config */ 145 pci_vtnet_cfgwrite, /* write PCI config */ 146 pci_vtnet_neg_features, /* apply negotiated features */ 147 VTNET_S_HOSTCAPS, /* our capabilities */ 148 }; 149 150 static void 151 pci_vtnet_reset(void *vsc) 152 { 153 struct pci_vtnet_softc *sc = vsc; 154 155 DPRINTF(("vtnet: device reset requested !")); 156 157 /* Acquire the RX lock to block RX processing. */ 158 pthread_mutex_lock(&sc->rx_mtx); 159 160 /* 161 * Make sure receive operation is disabled at least until we 162 * re-negotiate the features, since receive operation depends 163 * on the value of sc->rx_merge and the header length, which 164 * are both set in pci_vtnet_neg_features(). 165 * Receive operation will be enabled again once the guest adds 166 * the first receive buffers and kicks us. 167 */ 168 netbe_rx_disable(sc->vsc_be); 169 170 /* Set sc->resetting and give a chance to the TX thread to stop. */ 171 pthread_mutex_lock(&sc->tx_mtx); 172 sc->resetting = 1; 173 while (sc->tx_in_progress) { 174 pthread_mutex_unlock(&sc->tx_mtx); 175 usleep(10000); 176 pthread_mutex_lock(&sc->tx_mtx); 177 } 178 179 /* 180 * Now reset rings, MSI-X vectors, and negotiated capabilities. 181 * Do that with the TX lock held, since we need to reset 182 * sc->resetting. 183 */ 184 vi_reset_dev(&sc->vsc_vs); 185 186 sc->resetting = 0; 187 pthread_mutex_unlock(&sc->tx_mtx); 188 pthread_mutex_unlock(&sc->rx_mtx); 189 } 190 191 static __inline struct iovec * 192 iov_trim_hdr(struct iovec *iov, int *iovcnt, unsigned int hlen) 193 { 194 struct iovec *riov; 195 196 if (iov[0].iov_len < hlen) { 197 /* 198 * Not enough header space in the first fragment. 199 * That's not ok for us. 200 */ 201 return NULL; 202 } 203 204 iov[0].iov_len -= hlen; 205 if (iov[0].iov_len == 0) { 206 *iovcnt -= 1; 207 if (*iovcnt == 0) { 208 /* 209 * Only space for the header. That's not 210 * enough for us. 211 */ 212 return NULL; 213 } 214 riov = &iov[1]; 215 } else { 216 iov[0].iov_base = (void *)((uintptr_t)iov[0].iov_base + hlen); 217 riov = &iov[0]; 218 } 219 220 return (riov); 221 } 222 223 struct virtio_mrg_rxbuf_info { 224 uint16_t idx; 225 uint16_t pad; 226 uint32_t len; 227 }; 228 229 static void 230 pci_vtnet_rx(struct pci_vtnet_softc *sc) 231 { 232 int prepend_hdr_len = sc->vhdrlen - sc->be_vhdrlen; 233 struct virtio_mrg_rxbuf_info info[VTNET_MAXSEGS]; 234 struct iovec iov[VTNET_MAXSEGS + 1]; 235 struct vqueue_info *vq; 236 237 vq = &sc->vsc_queues[VTNET_RXQ]; 238 for (;;) { 239 struct virtio_net_rxhdr *hdr; 240 uint32_t riov_bytes; 241 struct iovec *riov; 242 uint32_t ulen; 243 int riov_len; 244 int n_chains; 245 ssize_t rlen; 246 ssize_t plen; 247 248 plen = netbe_peek_recvlen(sc->vsc_be); 249 if (plen <= 0) { 250 /* 251 * No more packets (plen == 0), or backend errored 252 * (plen < 0). Interrupt if needed and stop. 253 */ 254 vq_endchains(vq, /*used_all_avail=*/0); 255 return; 256 } 257 plen += prepend_hdr_len; 258 259 /* 260 * Get a descriptor chain to store the next ingress 261 * packet. In case of mergeable rx buffers, get as 262 * many chains as necessary in order to make room 263 * for plen bytes. 264 */ 265 riov_bytes = 0; 266 riov_len = 0; 267 riov = iov; 268 n_chains = 0; 269 do { 270 int n = vq_getchain(vq, &info[n_chains].idx, riov, 271 VTNET_MAXSEGS - riov_len, NULL); 272 273 if (n == 0) { 274 /* 275 * No rx buffers. Enable RX kicks and double 276 * check. 277 */ 278 vq_kick_enable(vq); 279 if (!vq_has_descs(vq)) { 280 /* 281 * Still no buffers. Return the unused 282 * chains (if any), interrupt if needed 283 * (including for NOTIFY_ON_EMPTY), and 284 * disable the backend until the next 285 * kick. 286 */ 287 vq_retchains(vq, n_chains); 288 vq_endchains(vq, /*used_all_avail=*/1); 289 netbe_rx_disable(sc->vsc_be); 290 return; 291 } 292 293 /* More rx buffers found, so keep going. */ 294 vq_kick_disable(vq); 295 continue; 296 } 297 assert(n >= 1 && riov_len + n <= VTNET_MAXSEGS); 298 riov_len += n; 299 if (!sc->rx_merge) { 300 n_chains = 1; 301 break; 302 } 303 info[n_chains].len = (uint32_t)count_iov(riov, n); 304 riov_bytes += info[n_chains].len; 305 riov += n; 306 n_chains++; 307 } while (riov_bytes < plen && riov_len < VTNET_MAXSEGS); 308 309 riov = iov; 310 hdr = riov[0].iov_base; 311 if (prepend_hdr_len > 0) { 312 /* 313 * The frontend uses a virtio-net header, but the 314 * backend does not. We need to prepend a zeroed 315 * header. 316 */ 317 riov = iov_trim_hdr(riov, &riov_len, prepend_hdr_len); 318 if (riov == NULL) { 319 /* 320 * The first collected chain is nonsensical, 321 * as it is not even enough to store the 322 * virtio-net header. Just drop it. 323 */ 324 vq_relchain(vq, info[0].idx, 0); 325 vq_retchains(vq, n_chains - 1); 326 continue; 327 } 328 memset(hdr, 0, prepend_hdr_len); 329 } 330 331 rlen = netbe_recv(sc->vsc_be, riov, riov_len); 332 if (rlen != plen - prepend_hdr_len) { 333 /* 334 * If this happens it means there is something 335 * wrong with the backend (e.g., some other 336 * process is stealing our packets). 337 */ 338 WPRINTF(("netbe_recv: expected %zd bytes, " 339 "got %zd", plen - prepend_hdr_len, rlen)); 340 vq_retchains(vq, n_chains); 341 continue; 342 } 343 344 ulen = (uint32_t)plen; 345 346 /* 347 * Publish the used buffers to the guest, reporting the 348 * number of bytes that we wrote. 349 */ 350 if (!sc->rx_merge) { 351 vq_relchain(vq, info[0].idx, ulen); 352 } else { 353 uint32_t iolen; 354 int i = 0; 355 356 do { 357 iolen = info[i].len; 358 if (iolen > ulen) { 359 iolen = ulen; 360 } 361 vq_relchain_prepare(vq, info[i].idx, iolen); 362 ulen -= iolen; 363 i++; 364 } while (ulen > 0); 365 366 hdr->vrh_bufs = i; 367 vq_relchain_publish(vq); 368 assert(i == n_chains); 369 } 370 } 371 372 } 373 374 /* 375 * Called when there is read activity on the backend file descriptor. 376 * Each buffer posted by the guest is assumed to be able to contain 377 * an entire ethernet frame + rx header. 378 */ 379 static void 380 pci_vtnet_rx_callback(int fd, enum ev_type type, void *param) 381 { 382 struct pci_vtnet_softc *sc = param; 383 384 pthread_mutex_lock(&sc->rx_mtx); 385 pci_vtnet_rx(sc); 386 pthread_mutex_unlock(&sc->rx_mtx); 387 388 } 389 390 /* Called on RX kick. */ 391 static void 392 pci_vtnet_ping_rxq(void *vsc, struct vqueue_info *vq) 393 { 394 struct pci_vtnet_softc *sc = vsc; 395 396 /* 397 * A qnotify means that the rx process can now begin. 398 */ 399 pthread_mutex_lock(&sc->rx_mtx); 400 vq_kick_disable(vq); 401 netbe_rx_enable(sc->vsc_be); 402 pthread_mutex_unlock(&sc->rx_mtx); 403 } 404 405 /* TX virtqueue processing, called by the TX thread. */ 406 static void 407 pci_vtnet_proctx(struct pci_vtnet_softc *sc, struct vqueue_info *vq) 408 { 409 struct iovec iov[VTNET_MAXSEGS + 1]; 410 struct iovec *siov = iov; 411 uint16_t idx; 412 ssize_t len; 413 int n; 414 415 /* 416 * Obtain chain of descriptors. The first descriptor also 417 * contains the virtio-net header. 418 */ 419 n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); 420 assert(n >= 1 && n <= VTNET_MAXSEGS); 421 422 if (sc->vhdrlen != sc->be_vhdrlen) { 423 /* 424 * The frontend uses a virtio-net header, but the backend 425 * does not. We simply strip the header and ignore it, as 426 * it should be zero-filled. 427 */ 428 siov = iov_trim_hdr(siov, &n, sc->vhdrlen); 429 } 430 431 if (siov == NULL) { 432 /* The chain is nonsensical. Just drop it. */ 433 len = 0; 434 } else { 435 len = netbe_send(sc->vsc_be, siov, n); 436 if (len < 0) { 437 /* 438 * If send failed, report that 0 bytes 439 * were read. 440 */ 441 len = 0; 442 } 443 } 444 445 /* 446 * Return the processed chain to the guest, reporting 447 * the number of bytes that we read. 448 */ 449 vq_relchain(vq, idx, len); 450 } 451 452 /* Called on TX kick. */ 453 static void 454 pci_vtnet_ping_txq(void *vsc, struct vqueue_info *vq) 455 { 456 struct pci_vtnet_softc *sc = vsc; 457 458 /* 459 * Any ring entries to process? 460 */ 461 if (!vq_has_descs(vq)) 462 return; 463 464 /* Signal the tx thread for processing */ 465 pthread_mutex_lock(&sc->tx_mtx); 466 vq_kick_disable(vq); 467 if (sc->tx_in_progress == 0) 468 pthread_cond_signal(&sc->tx_cond); 469 pthread_mutex_unlock(&sc->tx_mtx); 470 } 471 472 /* 473 * Thread which will handle processing of TX desc 474 */ 475 static void * 476 pci_vtnet_tx_thread(void *param) 477 { 478 struct pci_vtnet_softc *sc = param; 479 struct vqueue_info *vq; 480 int error; 481 482 vq = &sc->vsc_queues[VTNET_TXQ]; 483 484 /* 485 * Let us wait till the tx queue pointers get initialised & 486 * first tx signaled 487 */ 488 pthread_mutex_lock(&sc->tx_mtx); 489 error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx); 490 assert(error == 0); 491 492 for (;;) { 493 /* note - tx mutex is locked here */ 494 while (sc->resetting || !vq_has_descs(vq)) { 495 vq_kick_enable(vq); 496 if (!sc->resetting && vq_has_descs(vq)) 497 break; 498 499 sc->tx_in_progress = 0; 500 error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx); 501 assert(error == 0); 502 } 503 vq_kick_disable(vq); 504 sc->tx_in_progress = 1; 505 pthread_mutex_unlock(&sc->tx_mtx); 506 507 do { 508 /* 509 * Run through entries, placing them into 510 * iovecs and sending when an end-of-packet 511 * is found 512 */ 513 pci_vtnet_proctx(sc, vq); 514 } while (vq_has_descs(vq)); 515 516 /* 517 * Generate an interrupt if needed. 518 */ 519 vq_endchains(vq, /*used_all_avail=*/1); 520 521 pthread_mutex_lock(&sc->tx_mtx); 522 } 523 } 524 525 #ifdef notyet 526 static void 527 pci_vtnet_ping_ctlq(void *vsc, struct vqueue_info *vq) 528 { 529 530 DPRINTF(("vtnet: control qnotify!")); 531 } 532 #endif 533 534 static int 535 pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) 536 { 537 struct pci_vtnet_softc *sc; 538 char tname[MAXCOMLEN + 1]; 539 int mac_provided; 540 int mtu_provided; 541 unsigned long mtu = ETHERMTU; 542 543 /* 544 * Allocate data structures for further virtio initializations. 545 * sc also contains a copy of vtnet_vi_consts, since capabilities 546 * change depending on the backend. 547 */ 548 sc = calloc(1, sizeof(struct pci_vtnet_softc)); 549 550 sc->vsc_consts = vtnet_vi_consts; 551 pthread_mutex_init(&sc->vsc_mtx, NULL); 552 553 sc->vsc_queues[VTNET_RXQ].vq_qsize = VTNET_RINGSZ; 554 sc->vsc_queues[VTNET_RXQ].vq_notify = pci_vtnet_ping_rxq; 555 sc->vsc_queues[VTNET_TXQ].vq_qsize = VTNET_RINGSZ; 556 sc->vsc_queues[VTNET_TXQ].vq_notify = pci_vtnet_ping_txq; 557 #ifdef notyet 558 sc->vsc_queues[VTNET_CTLQ].vq_qsize = VTNET_RINGSZ; 559 sc->vsc_queues[VTNET_CTLQ].vq_notify = pci_vtnet_ping_ctlq; 560 #endif 561 562 /* 563 * Attempt to open the backend device and read the MAC address 564 * if specified. 565 */ 566 mac_provided = 0; 567 mtu_provided = 0; 568 if (opts != NULL) { 569 char *devname; 570 char *vtopts; 571 int err = 0; 572 573 /* Get the device name. */ 574 devname = vtopts = strdup(opts); 575 (void) strsep(&vtopts, ","); 576 577 /* 578 * Parse the list of options in the form 579 * key1=value1,...,keyN=valueN. 580 */ 581 while (vtopts != NULL) { 582 char *value = vtopts; 583 char *key; 584 585 key = strsep(&value, "="); 586 if (value == NULL) 587 break; 588 vtopts = value; 589 (void) strsep(&vtopts, ","); 590 591 if (strcmp(key, "mac") == 0) { 592 err = net_parsemac(value, sc->vsc_config.mac); 593 if (err) 594 break; 595 mac_provided = 1; 596 } else if (strcmp(key, "mtu") == 0) { 597 err = net_parsemtu(value, &mtu); 598 if (err) 599 break; 600 601 if (mtu < VTNET_MIN_MTU || mtu > VTNET_MAX_MTU) { 602 err = EINVAL; 603 errno = EINVAL; 604 break; 605 } 606 mtu_provided = 1; 607 } 608 } 609 610 if (err) { 611 free(devname); 612 free(sc); 613 return (err); 614 } 615 616 err = netbe_init(&sc->vsc_be, devname, pci_vtnet_rx_callback, 617 sc); 618 free(devname); 619 if (err) { 620 free(sc); 621 return (err); 622 } 623 sc->vsc_consts.vc_hv_caps |= VIRTIO_NET_F_MRG_RXBUF | 624 netbe_get_cap(sc->vsc_be); 625 } 626 627 if (!mac_provided) { 628 net_genmac(pi, sc->vsc_config.mac); 629 } 630 631 sc->vsc_config.mtu = mtu; 632 if (mtu_provided) { 633 sc->vsc_consts.vc_hv_caps |= VIRTIO_NET_F_MTU; 634 } 635 636 /* 637 * Since we do not actually support multiqueue, 638 * set the maximum virtqueue pairs to 1. 639 */ 640 sc->vsc_config.max_virtqueue_pairs = 1; 641 642 /* initialize config space */ 643 pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_NET); 644 pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); 645 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); 646 pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET); 647 pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); 648 649 /* Link is up if we managed to open backend device. */ 650 sc->vsc_config.status = (opts == NULL || sc->vsc_be); 651 652 vi_softc_linkup(&sc->vsc_vs, &sc->vsc_consts, sc, pi, sc->vsc_queues); 653 sc->vsc_vs.vs_mtx = &sc->vsc_mtx; 654 655 /* use BAR 1 to map MSI-X table and PBA, if we're using MSI-X */ 656 if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix())) { 657 free(sc); 658 return (1); 659 } 660 661 /* use BAR 0 to map config regs in IO space */ 662 vi_set_io_bar(&sc->vsc_vs, 0); 663 664 sc->resetting = 0; 665 666 sc->rx_merge = 0; 667 sc->vhdrlen = sizeof(struct virtio_net_rxhdr) - 2; 668 pthread_mutex_init(&sc->rx_mtx, NULL); 669 670 /* 671 * Initialize tx semaphore & spawn TX processing thread. 672 * As of now, only one thread for TX desc processing is 673 * spawned. 674 */ 675 sc->tx_in_progress = 0; 676 pthread_mutex_init(&sc->tx_mtx, NULL); 677 pthread_cond_init(&sc->tx_cond, NULL); 678 pthread_create(&sc->tx_tid, NULL, pci_vtnet_tx_thread, (void *)sc); 679 snprintf(tname, sizeof(tname), "vtnet-%d:%d tx", pi->pi_slot, 680 pi->pi_func); 681 pthread_set_name_np(sc->tx_tid, tname); 682 683 return (0); 684 } 685 686 static int 687 pci_vtnet_cfgwrite(void *vsc, int offset, int size, uint32_t value) 688 { 689 struct pci_vtnet_softc *sc = vsc; 690 void *ptr; 691 692 if (offset < (int)sizeof(sc->vsc_config.mac)) { 693 assert(offset + size <= (int)sizeof(sc->vsc_config.mac)); 694 /* 695 * The driver is allowed to change the MAC address 696 */ 697 ptr = &sc->vsc_config.mac[offset]; 698 memcpy(ptr, &value, size); 699 } else { 700 /* silently ignore other writes */ 701 DPRINTF(("vtnet: write to readonly reg %d", offset)); 702 } 703 704 return (0); 705 } 706 707 static int 708 pci_vtnet_cfgread(void *vsc, int offset, int size, uint32_t *retval) 709 { 710 struct pci_vtnet_softc *sc = vsc; 711 void *ptr; 712 713 ptr = (uint8_t *)&sc->vsc_config + offset; 714 memcpy(retval, ptr, size); 715 return (0); 716 } 717 718 static void 719 pci_vtnet_neg_features(void *vsc, uint64_t negotiated_features) 720 { 721 struct pci_vtnet_softc *sc = vsc; 722 723 sc->vsc_features = negotiated_features; 724 725 if (negotiated_features & VIRTIO_NET_F_MRG_RXBUF) { 726 sc->vhdrlen = sizeof(struct virtio_net_rxhdr); 727 sc->rx_merge = 1; 728 } else { 729 /* 730 * Without mergeable rx buffers, virtio-net header is 2 731 * bytes shorter than sizeof(struct virtio_net_rxhdr). 732 */ 733 sc->vhdrlen = sizeof(struct virtio_net_rxhdr) - 2; 734 sc->rx_merge = 0; 735 } 736 737 /* Tell the backend to enable some capabilities it has advertised. */ 738 netbe_set_cap(sc->vsc_be, negotiated_features, sc->vhdrlen); 739 sc->be_vhdrlen = netbe_get_vnet_hdr_len(sc->vsc_be); 740 assert(sc->be_vhdrlen == 0 || sc->be_vhdrlen == sc->vhdrlen); 741 } 742 743 static struct pci_devemu pci_de_vnet = { 744 .pe_emu = "virtio-net", 745 .pe_init = pci_vtnet_init, 746 .pe_barwrite = vi_pci_write, 747 .pe_barread = vi_pci_read 748 }; 749 PCI_EMUL_SET(pci_de_vnet); 750