hn_nvs.c revision 307164
1/*- 2 * Copyright (c) 2009-2012,2016 Microsoft Corp. 3 * Copyright (c) 2010-2012 Citrix Inc. 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 * $FreeBSD: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.c 307164 2016-10-13 02:28:40Z sephe $ 29 */ 30 31/** 32 * HyperV vmbus network VSC (virtual services client) module 33 * 34 */ 35 36 37#include <sys/param.h> 38#include <sys/kernel.h> 39#include <sys/socket.h> 40#include <sys/lock.h> 41#include <net/if.h> 42#include <net/if_arp.h> 43#include <machine/bus.h> 44#include <machine/atomic.h> 45 46#include <dev/hyperv/include/hyperv.h> 47#include <dev/hyperv/include/vmbus_xact.h> 48#include <dev/hyperv/netvsc/hv_net_vsc.h> 49#include <dev/hyperv/netvsc/hv_rndis.h> 50#include <dev/hyperv/netvsc/hv_rndis_filter.h> 51#include <dev/hyperv/netvsc/if_hnreg.h> 52 53MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver"); 54 55/* 56 * Forward declarations 57 */ 58static void hv_nv_on_channel_callback(struct vmbus_channel *chan, 59 void *xrxr); 60static int hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc); 61static int hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *); 62static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev); 63static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev); 64static int hv_nv_connect_to_vsp(struct hn_softc *sc); 65static void hv_nv_on_send_completion(netvsc_dev *net_dev, 66 struct vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt); 67static void hv_nv_on_receive_completion(struct vmbus_channel *chan, 68 uint64_t tid, uint32_t status); 69static void hv_nv_on_receive(netvsc_dev *net_dev, 70 struct hn_rx_ring *rxr, struct vmbus_channel *chan, 71 const struct vmbus_chanpkt_hdr *pkt); 72static void hn_nvs_sent_none(struct hn_send_ctx *sndc, 73 struct netvsc_dev_ *net_dev, struct vmbus_channel *chan, 74 const struct nvsp_msg_ *msg, int); 75 76static struct hn_send_ctx hn_send_ctx_none = 77 HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL); 78 79/* 80 * 81 */ 82static inline netvsc_dev * 83hv_nv_alloc_net_device(struct hn_softc *sc) 84{ 85 netvsc_dev *net_dev; 86 87 net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_WAITOK | M_ZERO); 88 89 net_dev->sc = sc; 90 net_dev->destroy = FALSE; 91 sc->net_dev = net_dev; 92 93 return (net_dev); 94} 95 96/* 97 * XXX unnecessary; nuke it. 98 */ 99static inline netvsc_dev * 100hv_nv_get_outbound_net_device(struct hn_softc *sc) 101{ 102 return sc->net_dev; 103} 104 105/* 106 * XXX unnecessary; nuke it. 107 */ 108static inline netvsc_dev * 109hv_nv_get_inbound_net_device(struct hn_softc *sc) 110{ 111 return sc->net_dev; 112} 113 114int 115hv_nv_get_next_send_section(netvsc_dev *net_dev) 116{ 117 unsigned long bitsmap_words = net_dev->bitsmap_words; 118 unsigned long *bitsmap = net_dev->send_section_bitsmap; 119 unsigned long idx; 120 int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX; 121 int i; 122 123 for (i = 0; i < bitsmap_words; i++) { 124 idx = ffsl(~bitsmap[i]); 125 if (0 == idx) 126 continue; 127 128 idx--; 129 KASSERT(i * BITS_PER_LONG + idx < net_dev->send_section_count, 130 ("invalid i %d and idx %lu", i, idx)); 131 132 if (atomic_testandset_long(&bitsmap[i], idx)) 133 continue; 134 135 ret = i * BITS_PER_LONG + idx; 136 break; 137 } 138 139 return (ret); 140} 141 142/* 143 * Net VSC initialize receive buffer with net VSP 144 * 145 * Net VSP: Network virtual services client, also known as the 146 * Hyper-V extensible switch and the synthetic data path. 147 */ 148static int 149hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc) 150{ 151 struct vmbus_xact *xact; 152 struct hn_nvs_rxbuf_conn *conn; 153 const struct hn_nvs_rxbuf_connresp *resp; 154 size_t resp_len; 155 struct hn_send_ctx sndc; 156 netvsc_dev *net_dev; 157 uint32_t status; 158 int error; 159 160 net_dev = hv_nv_get_outbound_net_device(sc); 161 if (!net_dev) { 162 return (ENODEV); 163 } 164 165 net_dev->rx_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev), 166 PAGE_SIZE, 0, net_dev->rx_buf_size, &net_dev->rxbuf_dma, 167 BUS_DMA_WAITOK | BUS_DMA_ZERO); 168 if (net_dev->rx_buf == NULL) { 169 device_printf(sc->hn_dev, "allocate rxbuf failed\n"); 170 return (ENOMEM); 171 } 172 173 /* 174 * Connect the RXBUF GPADL to the primary channel. 175 * 176 * NOTE: 177 * Only primary channel has RXBUF connected to it. Sub-channels 178 * just share this RXBUF. 179 */ 180 error = vmbus_chan_gpadl_connect(sc->hn_prichan, 181 net_dev->rxbuf_dma.hv_paddr, net_dev->rx_buf_size, 182 &net_dev->rx_buf_gpadl_handle); 183 if (error) { 184 if_printf(sc->hn_ifp, "rxbuf gpadl connect failed: %d\n", 185 error); 186 goto cleanup; 187 } 188 189 /* 190 * Connect RXBUF to NVS. 191 */ 192 193 xact = vmbus_xact_get(sc->hn_xact, sizeof(*conn)); 194 if (xact == NULL) { 195 if_printf(sc->hn_ifp, "no xact for nvs rxbuf conn\n"); 196 error = ENXIO; 197 goto cleanup; 198 } 199 200 conn = vmbus_xact_req_data(xact); 201 conn->nvs_type = HN_NVS_TYPE_RXBUF_CONN; 202 conn->nvs_gpadl = net_dev->rx_buf_gpadl_handle; 203 conn->nvs_sig = HN_NVS_RXBUF_SIG; 204 205 hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); 206 vmbus_xact_activate(xact); 207 208 error = vmbus_chan_send(sc->hn_prichan, 209 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, 210 conn, sizeof(*conn), (uint64_t)(uintptr_t)&sndc); 211 if (error != 0) { 212 if_printf(sc->hn_ifp, "send nvs rxbuf conn failed: %d\n", 213 error); 214 vmbus_xact_deactivate(xact); 215 vmbus_xact_put(xact); 216 goto cleanup; 217 } 218 219 resp = vmbus_xact_wait(xact, &resp_len); 220 if (resp_len < sizeof(*resp)) { 221 if_printf(sc->hn_ifp, "invalid rxbuf conn resp length %zu\n", 222 resp_len); 223 vmbus_xact_put(xact); 224 error = EINVAL; 225 goto cleanup; 226 } 227 if (resp->nvs_type != HN_NVS_TYPE_RXBUF_CONNRESP) { 228 if_printf(sc->hn_ifp, "not rxbuf conn resp, type %u\n", 229 resp->nvs_type); 230 vmbus_xact_put(xact); 231 error = EINVAL; 232 goto cleanup; 233 } 234 235 status = resp->nvs_status; 236 vmbus_xact_put(xact); 237 238 if (status != HN_NVS_STATUS_OK) { 239 if_printf(sc->hn_ifp, "rxbuf conn failed: %x\n", status); 240 error = EIO; 241 goto cleanup; 242 } 243 net_dev->rx_section_count = 1; 244 245 return (0); 246 247cleanup: 248 hv_nv_destroy_rx_buffer(net_dev); 249 return (error); 250} 251 252/* 253 * Net VSC initialize send buffer with net VSP 254 */ 255static int 256hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc) 257{ 258 struct hn_send_ctx sndc; 259 struct vmbus_xact *xact; 260 struct hn_nvs_chim_conn *chim; 261 const struct hn_nvs_chim_connresp *resp; 262 size_t resp_len; 263 uint32_t status, sectsz; 264 netvsc_dev *net_dev; 265 int error; 266 267 net_dev = hv_nv_get_outbound_net_device(sc); 268 if (!net_dev) { 269 return (ENODEV); 270 } 271 272 net_dev->send_buf = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev), 273 PAGE_SIZE, 0, net_dev->send_buf_size, &net_dev->txbuf_dma, 274 BUS_DMA_WAITOK | BUS_DMA_ZERO); 275 if (net_dev->send_buf == NULL) { 276 device_printf(sc->hn_dev, "allocate chimney txbuf failed\n"); 277 return (ENOMEM); 278 } 279 280 /* 281 * Connect chimney sending buffer GPADL to the primary channel. 282 * 283 * NOTE: 284 * Only primary channel has chimney sending buffer connected to it. 285 * Sub-channels just share this chimney sending buffer. 286 */ 287 error = vmbus_chan_gpadl_connect(sc->hn_prichan, 288 net_dev->txbuf_dma.hv_paddr, net_dev->send_buf_size, 289 &net_dev->send_buf_gpadl_handle); 290 if (error) { 291 if_printf(sc->hn_ifp, "chimney sending buffer gpadl " 292 "connect failed: %d\n", error); 293 goto cleanup; 294 } 295 296 /* 297 * Connect chimney sending buffer to NVS 298 */ 299 300 xact = vmbus_xact_get(sc->hn_xact, sizeof(*chim)); 301 if (xact == NULL) { 302 if_printf(sc->hn_ifp, "no xact for nvs chim conn\n"); 303 error = ENXIO; 304 goto cleanup; 305 } 306 307 chim = vmbus_xact_req_data(xact); 308 chim->nvs_type = HN_NVS_TYPE_CHIM_CONN; 309 chim->nvs_gpadl = net_dev->send_buf_gpadl_handle; 310 chim->nvs_sig = HN_NVS_CHIM_SIG; 311 312 hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); 313 vmbus_xact_activate(xact); 314 315 error = vmbus_chan_send(sc->hn_prichan, 316 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, 317 chim, sizeof(*chim), (uint64_t)(uintptr_t)&sndc); 318 if (error) { 319 if_printf(sc->hn_ifp, "send nvs chim conn failed: %d\n", 320 error); 321 vmbus_xact_deactivate(xact); 322 vmbus_xact_put(xact); 323 goto cleanup; 324 } 325 326 resp = vmbus_xact_wait(xact, &resp_len); 327 if (resp_len < sizeof(*resp)) { 328 if_printf(sc->hn_ifp, "invalid chim conn resp length %zu\n", 329 resp_len); 330 vmbus_xact_put(xact); 331 error = EINVAL; 332 goto cleanup; 333 } 334 if (resp->nvs_type != HN_NVS_TYPE_CHIM_CONNRESP) { 335 if_printf(sc->hn_ifp, "not chim conn resp, type %u\n", 336 resp->nvs_type); 337 vmbus_xact_put(xact); 338 error = EINVAL; 339 goto cleanup; 340 } 341 342 status = resp->nvs_status; 343 sectsz = resp->nvs_sectsz; 344 vmbus_xact_put(xact); 345 346 if (status != HN_NVS_STATUS_OK) { 347 if_printf(sc->hn_ifp, "chim conn failed: %x\n", status); 348 error = EIO; 349 goto cleanup; 350 } 351 if (sectsz == 0) { 352 if_printf(sc->hn_ifp, "zero chimney sending buffer " 353 "section size\n"); 354 return 0; 355 } 356 357 net_dev->send_section_size = sectsz; 358 net_dev->send_section_count = 359 net_dev->send_buf_size / net_dev->send_section_size; 360 net_dev->bitsmap_words = howmany(net_dev->send_section_count, 361 BITS_PER_LONG); 362 net_dev->send_section_bitsmap = 363 malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC, 364 M_WAITOK | M_ZERO); 365 366 if (bootverbose) { 367 if_printf(sc->hn_ifp, "chimney sending buffer %u/%u\n", 368 net_dev->send_section_size, net_dev->send_section_count); 369 } 370 return 0; 371 372cleanup: 373 hv_nv_destroy_send_buffer(net_dev); 374 return (error); 375} 376 377/* 378 * Net VSC destroy receive buffer 379 */ 380static int 381hv_nv_destroy_rx_buffer(netvsc_dev *net_dev) 382{ 383 int ret = 0; 384 385 if (net_dev->rx_section_count) { 386 struct hn_nvs_rxbuf_disconn disconn; 387 388 /* 389 * Disconnect RXBUF from NVS. 390 */ 391 memset(&disconn, 0, sizeof(disconn)); 392 disconn.nvs_type = HN_NVS_TYPE_RXBUF_DISCONN; 393 disconn.nvs_sig = HN_NVS_RXBUF_SIG; 394 395 ret = vmbus_chan_send(net_dev->sc->hn_prichan, 396 VMBUS_CHANPKT_TYPE_INBAND, 0, &disconn, sizeof(disconn), 397 (uint64_t)(uintptr_t)&hn_send_ctx_none); 398 if (ret != 0) { 399 if_printf(net_dev->sc->hn_ifp, 400 "send rxbuf disconn failed: %d\n", ret); 401 return (ret); 402 } 403 net_dev->rx_section_count = 0; 404 } 405 406 /* Tear down the gpadl on the vsp end */ 407 if (net_dev->rx_buf_gpadl_handle) { 408 ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan, 409 net_dev->rx_buf_gpadl_handle); 410 /* 411 * If we failed here, we might as well return and have a leak 412 * rather than continue and a bugchk 413 */ 414 if (ret != 0) { 415 return (ret); 416 } 417 net_dev->rx_buf_gpadl_handle = 0; 418 } 419 420 if (net_dev->rx_buf) { 421 /* Free up the receive buffer */ 422 hyperv_dmamem_free(&net_dev->rxbuf_dma, net_dev->rx_buf); 423 net_dev->rx_buf = NULL; 424 } 425 426 return (ret); 427} 428 429/* 430 * Net VSC destroy send buffer 431 */ 432static int 433hv_nv_destroy_send_buffer(netvsc_dev *net_dev) 434{ 435 int ret = 0; 436 437 if (net_dev->send_section_size) { 438 struct hn_nvs_chim_disconn disconn; 439 440 /* 441 * Disconnect chimney sending buffer from NVS. 442 */ 443 memset(&disconn, 0, sizeof(disconn)); 444 disconn.nvs_type = HN_NVS_TYPE_CHIM_DISCONN; 445 disconn.nvs_sig = HN_NVS_CHIM_SIG; 446 447 ret = vmbus_chan_send(net_dev->sc->hn_prichan, 448 VMBUS_CHANPKT_TYPE_INBAND, 0, &disconn, sizeof(disconn), 449 (uint64_t)(uintptr_t)&hn_send_ctx_none); 450 if (ret != 0) { 451 if_printf(net_dev->sc->hn_ifp, 452 "send chim disconn failed: %d\n", ret); 453 return (ret); 454 } 455 } 456 457 /* Tear down the gpadl on the vsp end */ 458 if (net_dev->send_buf_gpadl_handle) { 459 ret = vmbus_chan_gpadl_disconnect(net_dev->sc->hn_prichan, 460 net_dev->send_buf_gpadl_handle); 461 462 /* 463 * If we failed here, we might as well return and have a leak 464 * rather than continue and a bugchk 465 */ 466 if (ret != 0) { 467 return (ret); 468 } 469 net_dev->send_buf_gpadl_handle = 0; 470 } 471 472 if (net_dev->send_buf) { 473 /* Free up the receive buffer */ 474 hyperv_dmamem_free(&net_dev->txbuf_dma, net_dev->send_buf); 475 net_dev->send_buf = NULL; 476 } 477 478 if (net_dev->send_section_bitsmap) { 479 free(net_dev->send_section_bitsmap, M_NETVSC); 480 } 481 482 return (ret); 483} 484 485static int 486hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev, 487 uint32_t nvs_ver) 488{ 489 struct hn_send_ctx sndc; 490 struct vmbus_xact *xact; 491 struct hn_nvs_init *init; 492 const struct hn_nvs_init_resp *resp; 493 size_t resp_len; 494 uint32_t status; 495 int error; 496 497 xact = vmbus_xact_get(sc->hn_xact, sizeof(*init)); 498 if (xact == NULL) { 499 if_printf(sc->hn_ifp, "no xact for nvs init\n"); 500 return (ENXIO); 501 } 502 503 init = vmbus_xact_req_data(xact); 504 init->nvs_type = HN_NVS_TYPE_INIT; 505 init->nvs_ver_min = nvs_ver; 506 init->nvs_ver_max = nvs_ver; 507 508 vmbus_xact_activate(xact); 509 hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); 510 511 error = vmbus_chan_send(sc->hn_prichan, 512 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, 513 init, sizeof(*init), (uint64_t)(uintptr_t)&sndc); 514 if (error) { 515 if_printf(sc->hn_ifp, "send nvs init failed: %d\n", error); 516 vmbus_xact_deactivate(xact); 517 vmbus_xact_put(xact); 518 return (error); 519 } 520 521 resp = vmbus_xact_wait(xact, &resp_len); 522 if (resp_len < sizeof(*resp)) { 523 if_printf(sc->hn_ifp, "invalid init resp length %zu\n", 524 resp_len); 525 vmbus_xact_put(xact); 526 return (EINVAL); 527 } 528 if (resp->nvs_type != HN_NVS_TYPE_INIT_RESP) { 529 if_printf(sc->hn_ifp, "not init resp, type %u\n", 530 resp->nvs_type); 531 vmbus_xact_put(xact); 532 return (EINVAL); 533 } 534 535 status = resp->nvs_status; 536 vmbus_xact_put(xact); 537 538 if (status != HN_NVS_STATUS_OK) { 539 if_printf(sc->hn_ifp, "nvs init failed for ver 0x%x\n", 540 nvs_ver); 541 return (EINVAL); 542 } 543 return (0); 544} 545 546/* 547 * Send NDIS version 2 config packet containing MTU. 548 * 549 * Not valid for NDIS version 1. 550 */ 551static int 552hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu) 553{ 554 struct hn_nvs_ndis_conf conf; 555 int error; 556 557 memset(&conf, 0, sizeof(conf)); 558 conf.nvs_type = HN_NVS_TYPE_NDIS_CONF; 559 conf.nvs_mtu = mtu; 560 conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN; 561 562 error = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, 563 &conf, sizeof(conf), (uint64_t)(uintptr_t)&hn_send_ctx_none); 564 if (error) 565 if_printf(sc->hn_ifp, "send nvs ndis conf failed: %d\n", error); 566 return (error); 567} 568 569/* 570 * Net VSC connect to VSP 571 */ 572static int 573hv_nv_connect_to_vsp(struct hn_softc *sc) 574{ 575 netvsc_dev *net_dev; 576 uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1, 577 NVSP_PROTOCOL_VERSION_2, 578 NVSP_PROTOCOL_VERSION_4, 579 NVSP_PROTOCOL_VERSION_5 }; 580 int i; 581 int protocol_number = nitems(protocol_list); 582 int ret = 0; 583 device_t dev = sc->hn_dev; 584 struct ifnet *ifp = sc->arpcom.ac_ifp; 585 struct hn_nvs_ndis_init ndis; 586 587 net_dev = hv_nv_get_outbound_net_device(sc); 588 589 /* 590 * Negotiate the NVSP version. Try the latest NVSP first. 591 */ 592 for (i = protocol_number - 1; i >= 0; i--) { 593 if (hv_nv_negotiate_nvsp_protocol(sc, net_dev, 594 protocol_list[i]) == 0) { 595 net_dev->nvsp_version = protocol_list[i]; 596 if (bootverbose) 597 device_printf(dev, "Netvsc: got version 0x%x\n", 598 net_dev->nvsp_version); 599 break; 600 } 601 } 602 603 if (i < 0) { 604 if (bootverbose) 605 device_printf(dev, "failed to negotiate a valid " 606 "protocol.\n"); 607 return (EPROTO); 608 } 609 610 /* 611 * Set the MTU if supported by this NVSP protocol version 612 * This needs to be right after the NVSP init message per Haiyang 613 */ 614 if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2) 615 ret = hv_nv_send_ndis_config(sc, ifp->if_mtu); 616 617 /* 618 * Initialize NDIS. 619 */ 620 621 memset(&ndis, 0, sizeof(ndis)); 622 ndis.nvs_type = HN_NVS_TYPE_NDIS_INIT; 623 ndis.nvs_ndis_major = NDIS_VERSION_MAJOR_6; 624 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) 625 ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_1; 626 else 627 ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_30; 628 629 ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0, 630 &ndis, sizeof(ndis), (uint64_t)(uintptr_t)&hn_send_ctx_none); 631 if (ret != 0) { 632 if_printf(sc->hn_ifp, "send nvs ndis init failed: %d\n", ret); 633 goto cleanup; 634 } 635 636 /* Post the big receive buffer to NetVSP */ 637 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_2) 638 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY; 639 else 640 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE; 641 net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE; 642 643 ret = hv_nv_init_rx_buffer_with_net_vsp(sc); 644 if (ret == 0) 645 ret = hv_nv_init_send_buffer_with_net_vsp(sc); 646 647cleanup: 648 return (ret); 649} 650 651/* 652 * Net VSC disconnect from VSP 653 */ 654static void 655hv_nv_disconnect_from_vsp(netvsc_dev *net_dev) 656{ 657 hv_nv_destroy_rx_buffer(net_dev); 658 hv_nv_destroy_send_buffer(net_dev); 659} 660 661void 662hv_nv_subchan_attach(struct vmbus_channel *chan, struct hn_rx_ring *rxr) 663{ 664 KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan), 665 ("chan%u subidx %u, rxr%d mismatch", 666 vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx)); 667 vmbus_chan_open(chan, NETVSC_DEVICE_RING_BUFFER_SIZE, 668 NETVSC_DEVICE_RING_BUFFER_SIZE, NULL, 0, 669 hv_nv_on_channel_callback, rxr); 670} 671 672/* 673 * Net VSC on device add 674 * 675 * Callback when the device belonging to this driver is added 676 */ 677netvsc_dev * 678hv_nv_on_device_add(struct hn_softc *sc, void *additional_info, 679 struct hn_rx_ring *rxr) 680{ 681 struct vmbus_channel *chan = sc->hn_prichan; 682 netvsc_dev *net_dev; 683 int ret = 0; 684 685 net_dev = hv_nv_alloc_net_device(sc); 686 if (net_dev == NULL) 687 return NULL; 688 689 /* Initialize the NetVSC channel extension */ 690 691 sema_init(&net_dev->channel_init_sema, 0, "netdev_sema"); 692 693 /* 694 * Open the channel 695 */ 696 KASSERT(rxr->hn_rx_idx == vmbus_chan_subidx(chan), 697 ("chan%u subidx %u, rxr%d mismatch", 698 vmbus_chan_id(chan), vmbus_chan_subidx(chan), rxr->hn_rx_idx)); 699 ret = vmbus_chan_open(chan, 700 NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE, 701 NULL, 0, hv_nv_on_channel_callback, rxr); 702 if (ret != 0) 703 goto cleanup; 704 705 /* 706 * Connect with the NetVsp 707 */ 708 ret = hv_nv_connect_to_vsp(sc); 709 if (ret != 0) 710 goto close; 711 712 return (net_dev); 713 714close: 715 /* Now, we can close the channel safely */ 716 vmbus_chan_close(chan); 717 718cleanup: 719 /* 720 * Free the packet buffers on the netvsc device packet queue. 721 * Release other resources. 722 */ 723 sema_destroy(&net_dev->channel_init_sema); 724 free(net_dev, M_NETVSC); 725 726 return (NULL); 727} 728 729/* 730 * Net VSC on device remove 731 */ 732int 733hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel) 734{ 735 netvsc_dev *net_dev = sc->net_dev;; 736 737 /* Stop outbound traffic ie sends and receives completions */ 738 net_dev->destroy = TRUE; 739 740 hv_nv_disconnect_from_vsp(net_dev); 741 742 /* At this point, no one should be accessing net_dev except in here */ 743 744 /* Now, we can close the channel safely */ 745 746 vmbus_chan_close(sc->hn_prichan); 747 748 sema_destroy(&net_dev->channel_init_sema); 749 free(net_dev, M_NETVSC); 750 751 return (0); 752} 753 754void 755hn_nvs_sent_xact(struct hn_send_ctx *sndc, 756 struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused, 757 const struct nvsp_msg_ *msg, int dlen) 758{ 759 760 vmbus_xact_wakeup(sndc->hn_cbarg, msg, dlen); 761} 762 763static void 764hn_nvs_sent_none(struct hn_send_ctx *sndc __unused, 765 struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused, 766 const struct nvsp_msg_ *msg __unused, int dlen __unused) 767{ 768 /* EMPTY */ 769} 770 771void 772hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx) 773{ 774 u_long mask; 775 uint32_t idx; 776 777 idx = chim_idx / BITS_PER_LONG; 778 KASSERT(idx < net_dev->bitsmap_words, 779 ("invalid chimney index 0x%x", chim_idx)); 780 781 mask = 1UL << (chim_idx % BITS_PER_LONG); 782 KASSERT(net_dev->send_section_bitsmap[idx] & mask, 783 ("index bitmap 0x%lx, chimney index %u, " 784 "bitmap idx %d, bitmask 0x%lx", 785 net_dev->send_section_bitsmap[idx], chim_idx, idx, mask)); 786 787 atomic_clear_long(&net_dev->send_section_bitsmap[idx], mask); 788} 789 790/* 791 * Net VSC on send completion 792 */ 793static void 794hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan, 795 const struct vmbus_chanpkt_hdr *pkt) 796{ 797 struct hn_send_ctx *sndc; 798 799 sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid; 800 sndc->hn_cb(sndc, net_dev, chan, VMBUS_CHANPKT_CONST_DATA(pkt), 801 VMBUS_CHANPKT_DATALEN(pkt)); 802 /* 803 * NOTE: 804 * 'sndc' CAN NOT be accessed anymore, since it can be freed by 805 * its callback. 806 */ 807} 808 809/* 810 * Net VSC on send 811 * Sends a packet on the specified Hyper-V device. 812 * Returns 0 on success, non-zero on failure. 813 */ 814int 815hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt, 816 struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt) 817{ 818 nvsp_msg send_msg; 819 int ret; 820 821 send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt; 822 if (is_data_pkt) { 823 /* 0 is RMC_DATA */ 824 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0; 825 } else { 826 /* 1 is RMC_CONTROL */ 827 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1; 828 } 829 830 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx = 831 sndc->hn_chim_idx; 832 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size = 833 sndc->hn_chim_sz; 834 835 if (gpa_cnt) { 836 ret = vmbus_chan_send_sglist(chan, gpa, gpa_cnt, 837 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc); 838 } else { 839 ret = vmbus_chan_send(chan, 840 VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC, 841 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc); 842 } 843 844 return (ret); 845} 846 847/* 848 * Net VSC on receive 849 * 850 * In the FreeBSD Hyper-V virtual world, this function deals exclusively 851 * with virtual addresses. 852 */ 853static void 854hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr, 855 struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr) 856{ 857 const struct vmbus_chanpkt_rxbuf *pkt; 858 const nvsp_msg *nvsp_msg_pkt; 859 netvsc_packet vsc_pkt; 860 netvsc_packet *net_vsc_pkt = &vsc_pkt; 861 int count = 0; 862 int i = 0; 863 int status = nvsp_status_success; 864 865 nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr); 866 867 /* Make sure this is a valid nvsp packet */ 868 if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) { 869 if_printf(rxr->hn_ifp, "packet hdr type %u is invalid!\n", 870 nvsp_msg_pkt->hdr.msg_type); 871 return; 872 } 873 874 pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr; 875 876 if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) { 877 if_printf(rxr->hn_ifp, "rxbuf_id %d is invalid!\n", 878 pkt->cp_rxbuf_id); 879 return; 880 } 881 882 count = pkt->cp_rxbuf_cnt; 883 884 /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */ 885 for (i = 0; i < count; i++) { 886 net_vsc_pkt->status = nvsp_status_success; 887 net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf + 888 pkt->cp_rxbuf[i].rb_ofs); 889 net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len; 890 891 hv_rf_on_receive(net_dev, rxr, net_vsc_pkt); 892 if (net_vsc_pkt->status != nvsp_status_success) { 893 status = nvsp_status_failure; 894 } 895 } 896 897 /* 898 * Moved completion call back here so that all received 899 * messages (not just data messages) will trigger a response 900 * message back to the host. 901 */ 902 hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status); 903} 904 905/* 906 * Net VSC on receive completion 907 * 908 * Send a receive completion packet to RNDIS device (ie NetVsp) 909 */ 910static void 911hv_nv_on_receive_completion(struct vmbus_channel *chan, uint64_t tid, 912 uint32_t status) 913{ 914 nvsp_msg rx_comp_msg; 915 int retries = 0; 916 int ret = 0; 917 918 rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete; 919 920 /* Pass in the status */ 921 rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status = 922 status; 923 924retry_send_cmplt: 925 /* Send the completion */ 926 ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, 0, 927 &rx_comp_msg, sizeof(nvsp_msg), tid); 928 if (ret == 0) { 929 /* success */ 930 /* no-op */ 931 } else if (ret == EAGAIN) { 932 /* no more room... wait a bit and attempt to retry 3 times */ 933 retries++; 934 935 if (retries < 4) { 936 DELAY(100); 937 goto retry_send_cmplt; 938 } 939 } 940} 941 942/* 943 * Net VSC receiving vRSS send table from VSP 944 */ 945static void 946hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt) 947{ 948 netvsc_dev *net_dev; 949 const nvsp_msg *nvsp_msg_pkt; 950 int i; 951 uint32_t count; 952 const uint32_t *table; 953 954 net_dev = hv_nv_get_inbound_net_device(sc); 955 if (!net_dev) 956 return; 957 958 nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt); 959 960 if (nvsp_msg_pkt->hdr.msg_type != 961 nvsp_msg5_type_send_indirection_table) { 962 printf("Netvsc: !Warning! receive msg type not " 963 "send_indirection_table. type = %d\n", 964 nvsp_msg_pkt->hdr.msg_type); 965 return; 966 } 967 968 count = nvsp_msg_pkt->msgs.vers_5_msgs.send_table.count; 969 if (count != VRSS_SEND_TABLE_SIZE) { 970 printf("Netvsc: Received wrong send table size: %u\n", count); 971 return; 972 } 973 974 table = (const uint32_t *) 975 ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table + 976 nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset); 977 978 for (i = 0; i < count; i++) 979 net_dev->vrss_send_table[i] = table[i]; 980} 981 982/* 983 * Net VSC on channel callback 984 */ 985static void 986hv_nv_on_channel_callback(struct vmbus_channel *chan, void *xrxr) 987{ 988 struct hn_rx_ring *rxr = xrxr; 989 struct hn_softc *sc = rxr->hn_ifp->if_softc; 990 netvsc_dev *net_dev; 991 void *buffer; 992 int bufferlen = NETVSC_PACKET_SIZE; 993 994 net_dev = hv_nv_get_inbound_net_device(sc); 995 if (net_dev == NULL) 996 return; 997 998 buffer = rxr->hn_rdbuf; 999 do { 1000 struct vmbus_chanpkt_hdr *pkt = buffer; 1001 uint32_t bytes_rxed; 1002 int ret; 1003 1004 bytes_rxed = bufferlen; 1005 ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed); 1006 if (ret == 0) { 1007 if (bytes_rxed > 0) { 1008 switch (pkt->cph_type) { 1009 case VMBUS_CHANPKT_TYPE_COMP: 1010 hv_nv_on_send_completion(net_dev, chan, 1011 pkt); 1012 break; 1013 case VMBUS_CHANPKT_TYPE_RXBUF: 1014 hv_nv_on_receive(net_dev, rxr, chan, pkt); 1015 break; 1016 case VMBUS_CHANPKT_TYPE_INBAND: 1017 hv_nv_send_table(sc, pkt); 1018 break; 1019 default: 1020 if_printf(rxr->hn_ifp, 1021 "unknown chan pkt %u\n", 1022 pkt->cph_type); 1023 break; 1024 } 1025 } 1026 } else if (ret == ENOBUFS) { 1027 /* Handle large packet */ 1028 if (bufferlen > NETVSC_PACKET_SIZE) { 1029 free(buffer, M_NETVSC); 1030 buffer = NULL; 1031 } 1032 1033 /* alloc new buffer */ 1034 buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT); 1035 if (buffer == NULL) { 1036 if_printf(rxr->hn_ifp, 1037 "hv_cb malloc buffer failed, len=%u\n", 1038 bytes_rxed); 1039 bufferlen = 0; 1040 break; 1041 } 1042 bufferlen = bytes_rxed; 1043 } else { 1044 /* No more packets */ 1045 break; 1046 } 1047 } while (1); 1048 1049 if (bufferlen > NETVSC_PACKET_SIZE) 1050 free(buffer, M_NETVSC); 1051 1052 hv_rf_channel_rollup(rxr, rxr->hn_txr); 1053} 1054