hv_net_vsc.c revision 285236
1/*- 2 * Copyright (c) 2009-2012 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 285236 2015-07-07 04:15:22Z whu $ 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 "hv_net_vsc.h" 48#include "hv_rndis.h" 49#include "hv_rndis_filter.h" 50 51MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver"); 52 53/* 54 * Forward declarations 55 */ 56static void hv_nv_on_channel_callback(void *context); 57static int hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device); 58static int hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device); 59static int hv_nv_destroy_send_buffer(netvsc_dev *net_dev); 60static int hv_nv_destroy_rx_buffer(netvsc_dev *net_dev); 61static int hv_nv_connect_to_vsp(struct hv_device *device); 62static void hv_nv_on_send_completion(netvsc_dev *net_dev, 63 struct hv_device *device, hv_vm_packet_descriptor *pkt); 64static void hv_nv_on_receive(netvsc_dev *net_dev, 65 struct hv_device *device, hv_vm_packet_descriptor *pkt); 66 67/* 68 * 69 */ 70static inline netvsc_dev * 71hv_nv_alloc_net_device(struct hv_device *device) 72{ 73 netvsc_dev *net_dev; 74 hn_softc_t *sc = device_get_softc(device->device); 75 76 net_dev = malloc(sizeof(netvsc_dev), M_NETVSC, M_NOWAIT | M_ZERO); 77 if (net_dev == NULL) { 78 return (NULL); 79 } 80 81 net_dev->dev = device; 82 net_dev->destroy = FALSE; 83 sc->net_dev = net_dev; 84 85 return (net_dev); 86} 87 88/* 89 * 90 */ 91static inline netvsc_dev * 92hv_nv_get_outbound_net_device(struct hv_device *device) 93{ 94 hn_softc_t *sc = device_get_softc(device->device); 95 netvsc_dev *net_dev = sc->net_dev;; 96 97 if ((net_dev != NULL) && net_dev->destroy) { 98 return (NULL); 99 } 100 101 return (net_dev); 102} 103 104/* 105 * 106 */ 107static inline netvsc_dev * 108hv_nv_get_inbound_net_device(struct hv_device *device) 109{ 110 hn_softc_t *sc = device_get_softc(device->device); 111 netvsc_dev *net_dev = sc->net_dev;; 112 113 if (net_dev == NULL) { 114 return (net_dev); 115 } 116 /* 117 * When the device is being destroyed; we only 118 * permit incoming packets if and only if there 119 * are outstanding sends. 120 */ 121 if (net_dev->destroy && net_dev->num_outstanding_sends == 0) { 122 return (NULL); 123 } 124 125 return (net_dev); 126} 127 128int 129hv_nv_get_next_send_section(netvsc_dev *net_dev) 130{ 131 unsigned long bitsmap_words = net_dev->bitsmap_words; 132 unsigned long *bitsmap = net_dev->send_section_bitsmap; 133 unsigned long idx; 134 int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX; 135 int i; 136 137 for (i = 0; i < bitsmap_words; i++) { 138 idx = ffs(~bitsmap[i]); 139 if (0 == idx) 140 continue; 141 142 idx--; 143 if (i * BITS_PER_LONG + idx >= net_dev->send_section_count) 144 return (ret); 145 146 if (synch_test_and_set_bit(idx, &bitsmap[i])) 147 continue; 148 149 ret = i * BITS_PER_LONG + idx; 150 break; 151 } 152 153 return (ret); 154} 155 156/* 157 * Net VSC initialize receive buffer with net VSP 158 * 159 * Net VSP: Network virtual services client, also known as the 160 * Hyper-V extensible switch and the synthetic data path. 161 */ 162static int 163hv_nv_init_rx_buffer_with_net_vsp(struct hv_device *device) 164{ 165 netvsc_dev *net_dev; 166 nvsp_msg *init_pkt; 167 int ret = 0; 168 169 net_dev = hv_nv_get_outbound_net_device(device); 170 if (!net_dev) { 171 return (ENODEV); 172 } 173 174 net_dev->rx_buf = contigmalloc(net_dev->rx_buf_size, M_NETVSC, 175 M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0); 176 177 /* 178 * Establish the GPADL handle for this buffer on this channel. 179 * Note: This call uses the vmbus connection rather than the 180 * channel to establish the gpadl handle. 181 * GPADL: Guest physical address descriptor list. 182 */ 183 ret = hv_vmbus_channel_establish_gpadl( 184 device->channel, net_dev->rx_buf, 185 net_dev->rx_buf_size, &net_dev->rx_buf_gpadl_handle); 186 if (ret != 0) { 187 goto cleanup; 188 } 189 190 /* sema_wait(&ext->channel_init_sema); KYS CHECK */ 191 192 /* Notify the NetVsp of the gpadl handle */ 193 init_pkt = &net_dev->channel_init_packet; 194 195 memset(init_pkt, 0, sizeof(nvsp_msg)); 196 197 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_rx_buf; 198 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle = 199 net_dev->rx_buf_gpadl_handle; 200 init_pkt->msgs.vers_1_msgs.send_rx_buf.id = 201 NETVSC_RECEIVE_BUFFER_ID; 202 203 /* Send the gpadl notification request */ 204 205 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, 206 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, 207 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 208 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 209 if (ret != 0) { 210 goto cleanup; 211 } 212 213 sema_wait(&net_dev->channel_init_sema); 214 215 /* Check the response */ 216 if (init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.status 217 != nvsp_status_success) { 218 ret = EINVAL; 219 goto cleanup; 220 } 221 222 net_dev->rx_section_count = 223 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.num_sections; 224 225 net_dev->rx_sections = malloc(net_dev->rx_section_count * 226 sizeof(nvsp_1_rx_buf_section), M_NETVSC, M_NOWAIT); 227 if (net_dev->rx_sections == NULL) { 228 ret = EINVAL; 229 goto cleanup; 230 } 231 memcpy(net_dev->rx_sections, 232 init_pkt->msgs.vers_1_msgs.send_rx_buf_complete.sections, 233 net_dev->rx_section_count * sizeof(nvsp_1_rx_buf_section)); 234 235 236 /* 237 * For first release, there should only be 1 section that represents 238 * the entire receive buffer 239 */ 240 if (net_dev->rx_section_count != 1 241 || net_dev->rx_sections->offset != 0) { 242 ret = EINVAL; 243 goto cleanup; 244 } 245 246 goto exit; 247 248cleanup: 249 hv_nv_destroy_rx_buffer(net_dev); 250 251exit: 252 return (ret); 253} 254 255/* 256 * Net VSC initialize send buffer with net VSP 257 */ 258static int 259hv_nv_init_send_buffer_with_net_vsp(struct hv_device *device) 260{ 261 netvsc_dev *net_dev; 262 nvsp_msg *init_pkt; 263 int ret = 0; 264 265 net_dev = hv_nv_get_outbound_net_device(device); 266 if (!net_dev) { 267 return (ENODEV); 268 } 269 270 net_dev->send_buf = contigmalloc(net_dev->send_buf_size, M_NETVSC, 271 M_ZERO, 0UL, BUS_SPACE_MAXADDR, PAGE_SIZE, 0); 272 if (net_dev->send_buf == NULL) { 273 ret = ENOMEM; 274 goto cleanup; 275 } 276 277 /* 278 * Establish the gpadl handle for this buffer on this channel. 279 * Note: This call uses the vmbus connection rather than the 280 * channel to establish the gpadl handle. 281 */ 282 ret = hv_vmbus_channel_establish_gpadl(device->channel, 283 net_dev->send_buf, net_dev->send_buf_size, 284 &net_dev->send_buf_gpadl_handle); 285 if (ret != 0) { 286 goto cleanup; 287 } 288 289 /* Notify the NetVsp of the gpadl handle */ 290 291 init_pkt = &net_dev->channel_init_packet; 292 293 memset(init_pkt, 0, sizeof(nvsp_msg)); 294 295 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_send_buf; 296 init_pkt->msgs.vers_1_msgs.send_rx_buf.gpadl_handle = 297 net_dev->send_buf_gpadl_handle; 298 init_pkt->msgs.vers_1_msgs.send_rx_buf.id = 299 NETVSC_SEND_BUFFER_ID; 300 301 /* Send the gpadl notification request */ 302 303 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, 304 sizeof(nvsp_msg), (uint64_t)init_pkt, 305 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 306 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 307 if (ret != 0) { 308 goto cleanup; 309 } 310 311 sema_wait(&net_dev->channel_init_sema); 312 313 /* Check the response */ 314 if (init_pkt->msgs.vers_1_msgs.send_send_buf_complete.status 315 != nvsp_status_success) { 316 ret = EINVAL; 317 goto cleanup; 318 } 319 320 net_dev->send_section_size = 321 init_pkt->msgs.vers_1_msgs.send_send_buf_complete.section_size; 322 net_dev->send_section_count = 323 net_dev->send_buf_size / net_dev->send_section_size; 324 net_dev->bitsmap_words = howmany(net_dev->send_section_count, 325 BITS_PER_LONG); 326 net_dev->send_section_bitsmap = 327 malloc(net_dev->bitsmap_words * sizeof(long), M_NETVSC, 328 M_NOWAIT | M_ZERO); 329 if (NULL == net_dev->send_section_bitsmap) { 330 ret = ENOMEM; 331 goto cleanup; 332 } 333 334 goto exit; 335 336cleanup: 337 hv_nv_destroy_send_buffer(net_dev); 338 339exit: 340 return (ret); 341} 342 343/* 344 * Net VSC destroy receive buffer 345 */ 346static int 347hv_nv_destroy_rx_buffer(netvsc_dev *net_dev) 348{ 349 nvsp_msg *revoke_pkt; 350 int ret = 0; 351 352 /* 353 * If we got a section count, it means we received a 354 * send_rx_buf_complete msg 355 * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore, 356 * we need to send a revoke msg here 357 */ 358 if (net_dev->rx_section_count) { 359 /* Send the revoke receive buffer */ 360 revoke_pkt = &net_dev->revoke_packet; 361 memset(revoke_pkt, 0, sizeof(nvsp_msg)); 362 363 revoke_pkt->hdr.msg_type = nvsp_msg_1_type_revoke_rx_buf; 364 revoke_pkt->msgs.vers_1_msgs.revoke_rx_buf.id = 365 NETVSC_RECEIVE_BUFFER_ID; 366 367 ret = hv_vmbus_channel_send_packet(net_dev->dev->channel, 368 revoke_pkt, sizeof(nvsp_msg), 369 (uint64_t)(uintptr_t)revoke_pkt, 370 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); 371 372 /* 373 * If we failed here, we might as well return and have a leak 374 * rather than continue and a bugchk 375 */ 376 if (ret != 0) { 377 return (ret); 378 } 379 } 380 381 /* Tear down the gpadl on the vsp end */ 382 if (net_dev->rx_buf_gpadl_handle) { 383 ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel, 384 net_dev->rx_buf_gpadl_handle); 385 /* 386 * If we failed here, we might as well return and have a leak 387 * rather than continue and a bugchk 388 */ 389 if (ret != 0) { 390 return (ret); 391 } 392 net_dev->rx_buf_gpadl_handle = 0; 393 } 394 395 if (net_dev->rx_buf) { 396 /* Free up the receive buffer */ 397 contigfree(net_dev->rx_buf, net_dev->rx_buf_size, M_NETVSC); 398 net_dev->rx_buf = NULL; 399 } 400 401 if (net_dev->rx_sections) { 402 free(net_dev->rx_sections, M_NETVSC); 403 net_dev->rx_sections = NULL; 404 net_dev->rx_section_count = 0; 405 } 406 407 return (ret); 408} 409 410/* 411 * Net VSC destroy send buffer 412 */ 413static int 414hv_nv_destroy_send_buffer(netvsc_dev *net_dev) 415{ 416 nvsp_msg *revoke_pkt; 417 int ret = 0; 418 419 /* 420 * If we got a section count, it means we received a 421 * send_rx_buf_complete msg 422 * (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore, 423 * we need to send a revoke msg here 424 */ 425 if (net_dev->send_section_size) { 426 /* Send the revoke send buffer */ 427 revoke_pkt = &net_dev->revoke_packet; 428 memset(revoke_pkt, 0, sizeof(nvsp_msg)); 429 430 revoke_pkt->hdr.msg_type = 431 nvsp_msg_1_type_revoke_send_buf; 432 revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id = 433 NETVSC_SEND_BUFFER_ID; 434 435 ret = hv_vmbus_channel_send_packet(net_dev->dev->channel, 436 revoke_pkt, sizeof(nvsp_msg), 437 (uint64_t)(uintptr_t)revoke_pkt, 438 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); 439 /* 440 * If we failed here, we might as well return and have a leak 441 * rather than continue and a bugchk 442 */ 443 if (ret != 0) { 444 return (ret); 445 } 446 } 447 448 /* Tear down the gpadl on the vsp end */ 449 if (net_dev->send_buf_gpadl_handle) { 450 ret = hv_vmbus_channel_teardown_gpdal(net_dev->dev->channel, 451 net_dev->send_buf_gpadl_handle); 452 453 /* 454 * If we failed here, we might as well return and have a leak 455 * rather than continue and a bugchk 456 */ 457 if (ret != 0) { 458 return (ret); 459 } 460 net_dev->send_buf_gpadl_handle = 0; 461 } 462 463 if (net_dev->send_buf) { 464 /* Free up the receive buffer */ 465 contigfree(net_dev->send_buf, net_dev->send_buf_size, M_NETVSC); 466 net_dev->send_buf = NULL; 467 } 468 469 if (net_dev->send_section_bitsmap) { 470 free(net_dev->send_section_bitsmap, M_NETVSC); 471 } 472 473 return (ret); 474} 475 476 477/* 478 * Attempt to negotiate the caller-specified NVSP version 479 * 480 * For NVSP v2, Server 2008 R2 does not set 481 * init_pkt->msgs.init_msgs.init_compl.negotiated_prot_vers 482 * to the negotiated version, so we cannot rely on that. 483 */ 484static int 485hv_nv_negotiate_nvsp_protocol(struct hv_device *device, netvsc_dev *net_dev, 486 uint32_t nvsp_ver) 487{ 488 nvsp_msg *init_pkt; 489 int ret; 490 491 init_pkt = &net_dev->channel_init_packet; 492 memset(init_pkt, 0, sizeof(nvsp_msg)); 493 init_pkt->hdr.msg_type = nvsp_msg_type_init; 494 495 /* 496 * Specify parameter as the only acceptable protocol version 497 */ 498 init_pkt->msgs.init_msgs.init.p1.protocol_version = nvsp_ver; 499 init_pkt->msgs.init_msgs.init.protocol_version_2 = nvsp_ver; 500 501 /* Send the init request */ 502 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, 503 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, 504 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 505 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 506 if (ret != 0) 507 return (-1); 508 509 sema_wait(&net_dev->channel_init_sema); 510 511 if (init_pkt->msgs.init_msgs.init_compl.status != nvsp_status_success) 512 return (EINVAL); 513 514 return (0); 515} 516 517/* 518 * Send NDIS version 2 config packet containing MTU. 519 * 520 * Not valid for NDIS version 1. 521 */ 522static int 523hv_nv_send_ndis_config(struct hv_device *device, uint32_t mtu) 524{ 525 netvsc_dev *net_dev; 526 nvsp_msg *init_pkt; 527 int ret; 528 529 net_dev = hv_nv_get_outbound_net_device(device); 530 if (!net_dev) 531 return (-ENODEV); 532 533 /* 534 * Set up configuration packet, write MTU 535 * Indicate we are capable of handling VLAN tags 536 */ 537 init_pkt = &net_dev->channel_init_packet; 538 memset(init_pkt, 0, sizeof(nvsp_msg)); 539 init_pkt->hdr.msg_type = nvsp_msg_2_type_send_ndis_config; 540 init_pkt->msgs.vers_2_msgs.send_ndis_config.mtu = mtu; 541 init_pkt-> 542 msgs.vers_2_msgs.send_ndis_config.capabilities.u1.u2.ieee8021q 543 = 1; 544 545 /* Send the configuration packet */ 546 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, 547 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, 548 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); 549 if (ret != 0) 550 return (-EINVAL); 551 552 return (0); 553} 554 555/* 556 * Net VSC connect to VSP 557 */ 558static int 559hv_nv_connect_to_vsp(struct hv_device *device) 560{ 561 netvsc_dev *net_dev; 562 nvsp_msg *init_pkt; 563 uint32_t ndis_version; 564 uint32_t protocol_list[] = { NVSP_PROTOCOL_VERSION_1, 565 NVSP_PROTOCOL_VERSION_2, 566 NVSP_PROTOCOL_VERSION_4, 567 NVSP_PROTOCOL_VERSION_5 }; 568 int i; 569 int protocol_number = nitems(protocol_list); 570 int ret = 0; 571 device_t dev = device->device; 572 hn_softc_t *sc = device_get_softc(dev); 573 struct ifnet *ifp = sc->arpcom.ac_ifp; 574 575 net_dev = hv_nv_get_outbound_net_device(device); 576 if (!net_dev) { 577 return (ENODEV); 578 } 579 580 /* 581 * Negotiate the NVSP version. Try the latest NVSP first. 582 */ 583 for (i = protocol_number - 1; i >= 0; i--) { 584 if (hv_nv_negotiate_nvsp_protocol(device, net_dev, 585 protocol_list[i]) == 0) { 586 net_dev->nvsp_version = protocol_list[i]; 587 if (bootverbose) 588 device_printf(dev, "Netvsc: got version 0x%x\n", 589 net_dev->nvsp_version); 590 break; 591 } 592 } 593 594 if (i < 0) { 595 if (bootverbose) 596 device_printf(dev, "failed to negotiate a valid " 597 "protocol.\n"); 598 return (EPROTO); 599 } 600 601 /* 602 * Set the MTU if supported by this NVSP protocol version 603 * This needs to be right after the NVSP init message per Haiyang 604 */ 605 if (net_dev->nvsp_version >= NVSP_PROTOCOL_VERSION_2) 606 ret = hv_nv_send_ndis_config(device, ifp->if_mtu); 607 608 /* 609 * Send the NDIS version 610 */ 611 init_pkt = &net_dev->channel_init_packet; 612 613 memset(init_pkt, 0, sizeof(nvsp_msg)); 614 615 if (net_dev->nvsp_version <= NVSP_PROTOCOL_VERSION_4) { 616 ndis_version = NDIS_VERSION_6_1; 617 } else { 618 ndis_version = NDIS_VERSION_6_30; 619 } 620 621 init_pkt->hdr.msg_type = nvsp_msg_1_type_send_ndis_vers; 622 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_major_vers = 623 (ndis_version & 0xFFFF0000) >> 16; 624 init_pkt->msgs.vers_1_msgs.send_ndis_vers.ndis_minor_vers = 625 ndis_version & 0xFFFF; 626 627 /* Send the init request */ 628 629 ret = hv_vmbus_channel_send_packet(device->channel, init_pkt, 630 sizeof(nvsp_msg), (uint64_t)(uintptr_t)init_pkt, 631 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); 632 if (ret != 0) { 633 goto cleanup; 634 } 635 /* 636 * TODO: BUGBUG - We have to wait for the above msg since the netvsp 637 * uses KMCL which acknowledges packet (completion packet) 638 * since our Vmbus always set the 639 * HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag 640 */ 641 /* sema_wait(&NetVscChannel->channel_init_sema); */ 642 643 /* Post the big receive buffer to NetVSP */ 644 ret = hv_nv_init_rx_buffer_with_net_vsp(device); 645 if (ret == 0) 646 ret = hv_nv_init_send_buffer_with_net_vsp(device); 647 648cleanup: 649 return (ret); 650} 651 652/* 653 * Net VSC disconnect from VSP 654 */ 655static void 656hv_nv_disconnect_from_vsp(netvsc_dev *net_dev) 657{ 658 hv_nv_destroy_rx_buffer(net_dev); 659 hv_nv_destroy_send_buffer(net_dev); 660} 661 662/* 663 * Net VSC on device add 664 * 665 * Callback when the device belonging to this driver is added 666 */ 667netvsc_dev * 668hv_nv_on_device_add(struct hv_device *device, void *additional_info) 669{ 670 netvsc_dev *net_dev; 671 int ret = 0; 672 673 net_dev = hv_nv_alloc_net_device(device); 674 if (!net_dev) 675 goto cleanup; 676 677 /* Initialize the NetVSC channel extension */ 678 net_dev->rx_buf_size = NETVSC_RECEIVE_BUFFER_SIZE; 679 680 net_dev->send_buf_size = NETVSC_SEND_BUFFER_SIZE; 681 682 sema_init(&net_dev->channel_init_sema, 0, "netdev_sema"); 683 684 /* 685 * Open the channel 686 */ 687 ret = hv_vmbus_channel_open(device->channel, 688 NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE, 689 NULL, 0, hv_nv_on_channel_callback, device); 690 if (ret != 0) 691 goto cleanup; 692 693 /* 694 * Connect with the NetVsp 695 */ 696 ret = hv_nv_connect_to_vsp(device); 697 if (ret != 0) 698 goto close; 699 700 return (net_dev); 701 702close: 703 /* Now, we can close the channel safely */ 704 705 hv_vmbus_channel_close(device->channel); 706 707cleanup: 708 /* 709 * Free the packet buffers on the netvsc device packet queue. 710 * Release other resources. 711 */ 712 if (net_dev) { 713 sema_destroy(&net_dev->channel_init_sema); 714 free(net_dev, M_NETVSC); 715 } 716 717 return (NULL); 718} 719 720/* 721 * Net VSC on device remove 722 */ 723int 724hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel) 725{ 726 hn_softc_t *sc = device_get_softc(device->device); 727 netvsc_dev *net_dev = sc->net_dev;; 728 729 /* Stop outbound traffic ie sends and receives completions */ 730 mtx_lock(&device->channel->inbound_lock); 731 net_dev->destroy = TRUE; 732 mtx_unlock(&device->channel->inbound_lock); 733 734 /* Wait for all send completions */ 735 while (net_dev->num_outstanding_sends) { 736 DELAY(100); 737 } 738 739 hv_nv_disconnect_from_vsp(net_dev); 740 741 /* At this point, no one should be accessing net_dev except in here */ 742 743 /* Now, we can close the channel safely */ 744 745 if (!destroy_channel) { 746 device->channel->state = 747 HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE; 748 } 749 750 hv_vmbus_channel_close(device->channel); 751 752 sema_destroy(&net_dev->channel_init_sema); 753 free(net_dev, M_NETVSC); 754 755 return (0); 756} 757 758/* 759 * Net VSC on send completion 760 */ 761static void 762hv_nv_on_send_completion(netvsc_dev *net_dev, 763 struct hv_device *device, hv_vm_packet_descriptor *pkt) 764{ 765 nvsp_msg *nvsp_msg_pkt; 766 netvsc_packet *net_vsc_pkt; 767 768 nvsp_msg_pkt = 769 (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3)); 770 771 if (nvsp_msg_pkt->hdr.msg_type == nvsp_msg_type_init_complete 772 || nvsp_msg_pkt->hdr.msg_type 773 == nvsp_msg_1_type_send_rx_buf_complete 774 || nvsp_msg_pkt->hdr.msg_type 775 == nvsp_msg_1_type_send_send_buf_complete) { 776 /* Copy the response back */ 777 memcpy(&net_dev->channel_init_packet, nvsp_msg_pkt, 778 sizeof(nvsp_msg)); 779 sema_post(&net_dev->channel_init_sema); 780 } else if (nvsp_msg_pkt->hdr.msg_type == 781 nvsp_msg_1_type_send_rndis_pkt_complete) { 782 /* Get the send context */ 783 net_vsc_pkt = 784 (netvsc_packet *)(unsigned long)pkt->transaction_id; 785 if (NULL != net_vsc_pkt) { 786 if (net_vsc_pkt->send_buf_section_idx != 787 NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) { 788 synch_change_bit(net_vsc_pkt->send_buf_section_idx, 789 net_dev->send_section_bitsmap); 790 } 791 792 /* Notify the layer above us */ 793 net_vsc_pkt->compl.send.on_send_completion( 794 net_vsc_pkt->compl.send.send_completion_context); 795 796 } 797 798 atomic_subtract_int(&net_dev->num_outstanding_sends, 1); 799 } 800} 801 802/* 803 * Net VSC on send 804 * Sends a packet on the specified Hyper-V device. 805 * Returns 0 on success, non-zero on failure. 806 */ 807int 808hv_nv_on_send(struct hv_device *device, netvsc_packet *pkt) 809{ 810 netvsc_dev *net_dev; 811 nvsp_msg send_msg; 812 int ret; 813 814 net_dev = hv_nv_get_outbound_net_device(device); 815 if (!net_dev) 816 return (ENODEV); 817 818 send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt; 819 if (pkt->is_data_pkt) { 820 /* 0 is RMC_DATA */ 821 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0; 822 } else { 823 /* 1 is RMC_CONTROL */ 824 send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1; 825 } 826 827 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx = 828 pkt->send_buf_section_idx; 829 send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size = 830 pkt->send_buf_section_size; 831 832 if (pkt->page_buf_count) { 833 ret = hv_vmbus_channel_send_packet_pagebuffer(device->channel, 834 pkt->page_buffers, pkt->page_buf_count, 835 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt); 836 } else { 837 ret = hv_vmbus_channel_send_packet(device->channel, 838 &send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)pkt, 839 HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 840 HV_VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 841 } 842 843 /* Record outstanding send only if send_packet() succeeded */ 844 if (ret == 0) 845 atomic_add_int(&net_dev->num_outstanding_sends, 1); 846 847 return (ret); 848} 849 850/* 851 * Net VSC on receive 852 * 853 * In the FreeBSD Hyper-V virtual world, this function deals exclusively 854 * with virtual addresses. 855 */ 856static void 857hv_nv_on_receive(netvsc_dev *net_dev, struct hv_device *device, 858 hv_vm_packet_descriptor *pkt) 859{ 860 hv_vm_transfer_page_packet_header *vm_xfer_page_pkt; 861 nvsp_msg *nvsp_msg_pkt; 862 netvsc_packet vsc_pkt; 863 netvsc_packet *net_vsc_pkt = &vsc_pkt; 864 device_t dev = device->device; 865 int count = 0; 866 int i = 0; 867 int status = nvsp_status_success; 868 869 /* 870 * All inbound packets other than send completion should be 871 * xfer page packet. 872 */ 873 if (pkt->type != HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES) { 874 device_printf(dev, "packet type %d is invalid!\n", pkt->type); 875 return; 876 } 877 878 nvsp_msg_pkt = (nvsp_msg *)((unsigned long)pkt 879 + (pkt->data_offset8 << 3)); 880 881 /* Make sure this is a valid nvsp packet */ 882 if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) { 883 device_printf(dev, "packet hdr type %d is invalid!\n", 884 pkt->type); 885 return; 886 } 887 888 vm_xfer_page_pkt = (hv_vm_transfer_page_packet_header *)pkt; 889 890 if (vm_xfer_page_pkt->transfer_page_set_id != 891 NETVSC_RECEIVE_BUFFER_ID) { 892 device_printf(dev, "transfer_page_set_id %d is invalid!\n", 893 vm_xfer_page_pkt->transfer_page_set_id); 894 return; 895 } 896 897 count = vm_xfer_page_pkt->range_count; 898 net_vsc_pkt->device = device; 899 900 /* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */ 901 for (i = 0; i < count; i++) { 902 net_vsc_pkt->status = nvsp_status_success; 903 net_vsc_pkt->data = (void *)((unsigned long)net_dev->rx_buf + 904 vm_xfer_page_pkt->ranges[i].byte_offset); 905 net_vsc_pkt->tot_data_buf_len = 906 vm_xfer_page_pkt->ranges[i].byte_count; 907 908 hv_rf_on_receive(net_dev, device, net_vsc_pkt); 909 if (net_vsc_pkt->status != nvsp_status_success) { 910 status = nvsp_status_failure; 911 } 912 } 913 914 /* 915 * Moved completion call back here so that all received 916 * messages (not just data messages) will trigger a response 917 * message back to the host. 918 */ 919 hv_nv_on_receive_completion(device, vm_xfer_page_pkt->d.transaction_id, 920 status); 921} 922 923/* 924 * Net VSC on receive completion 925 * 926 * Send a receive completion packet to RNDIS device (ie NetVsp) 927 */ 928void 929hv_nv_on_receive_completion(struct hv_device *device, uint64_t tid, 930 uint32_t status) 931{ 932 nvsp_msg rx_comp_msg; 933 int retries = 0; 934 int ret = 0; 935 936 rx_comp_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt_complete; 937 938 /* Pass in the status */ 939 rx_comp_msg.msgs.vers_1_msgs.send_rndis_pkt_complete.status = 940 status; 941 942retry_send_cmplt: 943 /* Send the completion */ 944 ret = hv_vmbus_channel_send_packet(device->channel, &rx_comp_msg, 945 sizeof(nvsp_msg), tid, HV_VMBUS_PACKET_TYPE_COMPLETION, 0); 946 if (ret == 0) { 947 /* success */ 948 /* no-op */ 949 } else if (ret == EAGAIN) { 950 /* no more room... wait a bit and attempt to retry 3 times */ 951 retries++; 952 953 if (retries < 4) { 954 DELAY(100); 955 goto retry_send_cmplt; 956 } 957 } 958} 959 960/* 961 * Net VSC on channel callback 962 */ 963static void 964hv_nv_on_channel_callback(void *context) 965{ 966 struct hv_device *device = (struct hv_device *)context; 967 netvsc_dev *net_dev; 968 device_t dev = device->device; 969 uint32_t bytes_rxed; 970 uint64_t request_id; 971 hv_vm_packet_descriptor *desc; 972 uint8_t *buffer; 973 int bufferlen = NETVSC_PACKET_SIZE; 974 int ret = 0; 975 976 net_dev = hv_nv_get_inbound_net_device(device); 977 if (net_dev == NULL) 978 return; 979 980 buffer = net_dev->callback_buf; 981 982 do { 983 ret = hv_vmbus_channel_recv_packet_raw(device->channel, 984 buffer, bufferlen, &bytes_rxed, &request_id); 985 if (ret == 0) { 986 if (bytes_rxed > 0) { 987 desc = (hv_vm_packet_descriptor *)buffer; 988 switch (desc->type) { 989 case HV_VMBUS_PACKET_TYPE_COMPLETION: 990 hv_nv_on_send_completion(net_dev, device, desc); 991 break; 992 case HV_VMBUS_PACKET_TYPE_DATA_USING_TRANSFER_PAGES: 993 hv_nv_on_receive(net_dev, device, desc); 994 break; 995 default: 996 device_printf(dev, 997 "hv_cb recv unknow type %d " 998 " packet\n", desc->type); 999 break; 1000 } 1001 } else { 1002 break; 1003 } 1004 } else if (ret == ENOBUFS) { 1005 /* Handle large packet */ 1006 if (bufferlen > NETVSC_PACKET_SIZE) { 1007 free(buffer, M_NETVSC); 1008 buffer = NULL; 1009 } 1010 1011 /* alloc new buffer */ 1012 buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT); 1013 if (buffer == NULL) { 1014 device_printf(dev, 1015 "hv_cb malloc buffer failed, len=%u\n", 1016 bytes_rxed); 1017 bufferlen = 0; 1018 break; 1019 } 1020 bufferlen = bytes_rxed; 1021 } 1022 } while (1); 1023 1024 if (bufferlen > NETVSC_PACKET_SIZE) 1025 free(buffer, M_NETVSC); 1026} 1027