1/* 2 * Copyright (c) 2009, Microsoft Corporation. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 15 * Place - Suite 330, Boston, MA 02111-1307 USA. 16 * 17 * Authors: 18 * Haiyang Zhang <haiyangz@microsoft.com> 19 * Hank Janssen <hjanssen@microsoft.com> 20 */ 21#include <linux/kernel.h> 22#include <linux/mm.h> 23#include <linux/delay.h> 24#include <linux/io.h> 25#include <linux/slab.h> 26#include "osd.h" 27#include "logging.h" 28#include "netvsc.h" 29#include "rndis_filter.h" 30 31 32/* Globals */ 33static const char *gDriverName = "netvsc"; 34 35/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ 36static const struct hv_guid gNetVscDeviceType = { 37 .data = { 38 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, 39 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E 40 } 41}; 42 43static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); 44 45static int NetVscOnDeviceRemove(struct hv_device *Device); 46 47static void NetVscOnCleanup(struct hv_driver *Driver); 48 49static void NetVscOnChannelCallback(void *context); 50 51static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device); 52 53static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device); 54 55static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice); 56 57static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice); 58 59static int NetVscConnectToVsp(struct hv_device *Device); 60 61static void NetVscOnSendCompletion(struct hv_device *Device, 62 struct vmpacket_descriptor *Packet); 63 64static int NetVscOnSend(struct hv_device *Device, 65 struct hv_netvsc_packet *Packet); 66 67static void NetVscOnReceive(struct hv_device *Device, 68 struct vmpacket_descriptor *Packet); 69 70static void NetVscOnReceiveCompletion(void *Context); 71 72static void NetVscSendReceiveCompletion(struct hv_device *Device, 73 u64 TransactionId); 74 75 76static struct netvsc_device *AllocNetDevice(struct hv_device *Device) 77{ 78 struct netvsc_device *netDevice; 79 80 netDevice = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL); 81 if (!netDevice) 82 return NULL; 83 84 /* Set to 2 to allow both inbound and outbound traffic */ 85 atomic_cmpxchg(&netDevice->RefCount, 0, 2); 86 87 netDevice->Device = Device; 88 Device->Extension = netDevice; 89 90 return netDevice; 91} 92 93static void FreeNetDevice(struct netvsc_device *Device) 94{ 95 WARN_ON(atomic_read(&Device->RefCount) == 0); 96 Device->Device->Extension = NULL; 97 kfree(Device); 98} 99 100 101/* Get the net device object iff exists and its refcount > 1 */ 102static struct netvsc_device *GetOutboundNetDevice(struct hv_device *Device) 103{ 104 struct netvsc_device *netDevice; 105 106 netDevice = Device->Extension; 107 if (netDevice && atomic_read(&netDevice->RefCount) > 1) 108 atomic_inc(&netDevice->RefCount); 109 else 110 netDevice = NULL; 111 112 return netDevice; 113} 114 115/* Get the net device object iff exists and its refcount > 0 */ 116static struct netvsc_device *GetInboundNetDevice(struct hv_device *Device) 117{ 118 struct netvsc_device *netDevice; 119 120 netDevice = Device->Extension; 121 if (netDevice && atomic_read(&netDevice->RefCount)) 122 atomic_inc(&netDevice->RefCount); 123 else 124 netDevice = NULL; 125 126 return netDevice; 127} 128 129static void PutNetDevice(struct hv_device *Device) 130{ 131 struct netvsc_device *netDevice; 132 133 netDevice = Device->Extension; 134 /* ASSERT(netDevice); */ 135 136 atomic_dec(&netDevice->RefCount); 137} 138 139static struct netvsc_device *ReleaseOutboundNetDevice(struct hv_device *Device) 140{ 141 struct netvsc_device *netDevice; 142 143 netDevice = Device->Extension; 144 if (netDevice == NULL) 145 return NULL; 146 147 /* Busy wait until the ref drop to 2, then set it to 1 */ 148 while (atomic_cmpxchg(&netDevice->RefCount, 2, 1) != 2) 149 udelay(100); 150 151 return netDevice; 152} 153 154static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *Device) 155{ 156 struct netvsc_device *netDevice; 157 158 netDevice = Device->Extension; 159 if (netDevice == NULL) 160 return NULL; 161 162 /* Busy wait until the ref drop to 1, then set it to 0 */ 163 while (atomic_cmpxchg(&netDevice->RefCount, 1, 0) != 1) 164 udelay(100); 165 166 Device->Extension = NULL; 167 return netDevice; 168} 169 170/* 171 * NetVscInitialize - Main entry point 172 */ 173int NetVscInitialize(struct hv_driver *drv) 174{ 175 struct netvsc_driver *driver = (struct netvsc_driver *)drv; 176 177 DPRINT_DBG(NETVSC, "sizeof(struct hv_netvsc_packet)=%zd, " 178 "sizeof(struct nvsp_message)=%zd, " 179 "sizeof(struct vmtransfer_page_packet_header)=%zd", 180 sizeof(struct hv_netvsc_packet), 181 sizeof(struct nvsp_message), 182 sizeof(struct vmtransfer_page_packet_header)); 183 184 /* Make sure we are at least 2 pages since 1 page is used for control */ 185 /* ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1)); */ 186 187 drv->name = gDriverName; 188 memcpy(&drv->deviceType, &gNetVscDeviceType, sizeof(struct hv_guid)); 189 190 /* Make sure it is set by the caller */ 191 /* ASSERT(driver->OnReceiveCallback); */ 192 /* ASSERT(driver->OnLinkStatusChanged); */ 193 194 /* Setup the dispatch table */ 195 driver->Base.OnDeviceAdd = NetVscOnDeviceAdd; 196 driver->Base.OnDeviceRemove = NetVscOnDeviceRemove; 197 driver->Base.OnCleanup = NetVscOnCleanup; 198 199 driver->OnSend = NetVscOnSend; 200 201 RndisFilterInit(driver); 202 return 0; 203} 204 205static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) 206{ 207 int ret = 0; 208 struct netvsc_device *netDevice; 209 struct nvsp_message *initPacket; 210 211 netDevice = GetOutboundNetDevice(Device); 212 if (!netDevice) { 213 DPRINT_ERR(NETVSC, "unable to get net device..." 214 "device being destroyed?"); 215 return -1; 216 } 217 /* ASSERT(netDevice->ReceiveBufferSize > 0); */ 218 /* page-size grandularity */ 219 /* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */ 220 221 netDevice->ReceiveBuffer = 222 osd_PageAlloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT); 223 if (!netDevice->ReceiveBuffer) { 224 DPRINT_ERR(NETVSC, 225 "unable to allocate receive buffer of size %d", 226 netDevice->ReceiveBufferSize); 227 ret = -1; 228 goto Cleanup; 229 } 230 /* page-aligned buffer */ 231 /* ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == */ 232 /* 0); */ 233 234 DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL..."); 235 236 /* 237 * Establish the gpadl handle for this buffer on this 238 * channel. Note: This call uses the vmbus connection rather 239 * than the channel to establish the gpadl handle. 240 */ 241 ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device, 242 netDevice->ReceiveBuffer, 243 netDevice->ReceiveBufferSize, 244 &netDevice->ReceiveBufferGpadlHandle); 245 if (ret != 0) { 246 DPRINT_ERR(NETVSC, 247 "unable to establish receive buffer's gpadl"); 248 goto Cleanup; 249 } 250 251 /* osd_WaitEventWait(ext->ChannelInitEvent); */ 252 253 /* Notify the NetVsp of the gpadl handle */ 254 DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer..."); 255 256 initPacket = &netDevice->ChannelInitPacket; 257 258 memset(initPacket, 0, sizeof(struct nvsp_message)); 259 260 initPacket->Header.MessageType = NvspMessage1TypeSendReceiveBuffer; 261 initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->ReceiveBufferGpadlHandle; 262 initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; 263 264 /* Send the gpadl notification request */ 265 ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, 266 initPacket, 267 sizeof(struct nvsp_message), 268 (unsigned long)initPacket, 269 VmbusPacketTypeDataInBand, 270 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 271 if (ret != 0) { 272 DPRINT_ERR(NETVSC, 273 "unable to send receive buffer's gpadl to netvsp"); 274 goto Cleanup; 275 } 276 277 osd_WaitEventWait(netDevice->ChannelInitEvent); 278 279 /* Check the response */ 280 if (initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status != NvspStatusSuccess) { 281 DPRINT_ERR(NETVSC, "Unable to complete receive buffer " 282 "initialzation with NetVsp - status %d", 283 initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status); 284 ret = -1; 285 goto Cleanup; 286 } 287 288 /* Parse the response */ 289 /* ASSERT(netDevice->ReceiveSectionCount == 0); */ 290 /* ASSERT(netDevice->ReceiveSections == NULL); */ 291 292 netDevice->ReceiveSectionCount = initPacket->Messages.Version1Messages.SendReceiveBufferComplete.NumSections; 293 294 netDevice->ReceiveSections = kmalloc(netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL); 295 if (netDevice->ReceiveSections == NULL) { 296 ret = -1; 297 goto Cleanup; 298 } 299 300 memcpy(netDevice->ReceiveSections, 301 initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Sections, 302 netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section)); 303 304 DPRINT_INFO(NETVSC, "Receive sections info (count %d, offset %d, " 305 "endoffset %d, suballoc size %d, num suballocs %d)", 306 netDevice->ReceiveSectionCount, 307 netDevice->ReceiveSections[0].Offset, 308 netDevice->ReceiveSections[0].EndOffset, 309 netDevice->ReceiveSections[0].SubAllocationSize, 310 netDevice->ReceiveSections[0].NumSubAllocations); 311 312 /* 313 * For 1st release, there should only be 1 section that represents the 314 * entire receive buffer 315 */ 316 if (netDevice->ReceiveSectionCount != 1 || 317 netDevice->ReceiveSections->Offset != 0) { 318 ret = -1; 319 goto Cleanup; 320 } 321 322 goto Exit; 323 324Cleanup: 325 NetVscDestroyReceiveBuffer(netDevice); 326 327Exit: 328 PutNetDevice(Device); 329 return ret; 330} 331 332static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) 333{ 334 int ret = 0; 335 struct netvsc_device *netDevice; 336 struct nvsp_message *initPacket; 337 338 netDevice = GetOutboundNetDevice(Device); 339 if (!netDevice) { 340 DPRINT_ERR(NETVSC, "unable to get net device..." 341 "device being destroyed?"); 342 return -1; 343 } 344 if (netDevice->SendBufferSize <= 0) { 345 ret = -EINVAL; 346 goto Cleanup; 347 } 348 349 /* page-size grandularity */ 350 /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ 351 352 netDevice->SendBuffer = 353 osd_PageAlloc(netDevice->SendBufferSize >> PAGE_SHIFT); 354 if (!netDevice->SendBuffer) { 355 DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", 356 netDevice->SendBufferSize); 357 ret = -1; 358 goto Cleanup; 359 } 360 /* page-aligned buffer */ 361 /* ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); */ 362 363 DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL..."); 364 365 /* 366 * Establish the gpadl handle for this buffer on this 367 * channel. Note: This call uses the vmbus connection rather 368 * than the channel to establish the gpadl handle. 369 */ 370 ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device, 371 netDevice->SendBuffer, 372 netDevice->SendBufferSize, 373 &netDevice->SendBufferGpadlHandle); 374 if (ret != 0) { 375 DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl"); 376 goto Cleanup; 377 } 378 379 /* osd_WaitEventWait(ext->ChannelInitEvent); */ 380 381 /* Notify the NetVsp of the gpadl handle */ 382 DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer..."); 383 384 initPacket = &netDevice->ChannelInitPacket; 385 386 memset(initPacket, 0, sizeof(struct nvsp_message)); 387 388 initPacket->Header.MessageType = NvspMessage1TypeSendSendBuffer; 389 initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->SendBufferGpadlHandle; 390 initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_SEND_BUFFER_ID; 391 392 /* Send the gpadl notification request */ 393 ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, 394 initPacket, sizeof(struct nvsp_message), 395 (unsigned long)initPacket, 396 VmbusPacketTypeDataInBand, 397 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 398 if (ret != 0) { 399 DPRINT_ERR(NETVSC, 400 "unable to send receive buffer's gpadl to netvsp"); 401 goto Cleanup; 402 } 403 404 osd_WaitEventWait(netDevice->ChannelInitEvent); 405 406 /* Check the response */ 407 if (initPacket->Messages.Version1Messages.SendSendBufferComplete.Status != NvspStatusSuccess) { 408 DPRINT_ERR(NETVSC, "Unable to complete send buffer " 409 "initialzation with NetVsp - status %d", 410 initPacket->Messages.Version1Messages.SendSendBufferComplete.Status); 411 ret = -1; 412 goto Cleanup; 413 } 414 415 netDevice->SendSectionSize = initPacket->Messages.Version1Messages.SendSendBufferComplete.SectionSize; 416 417 goto Exit; 418 419Cleanup: 420 NetVscDestroySendBuffer(netDevice); 421 422Exit: 423 PutNetDevice(Device); 424 return ret; 425} 426 427static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice) 428{ 429 struct nvsp_message *revokePacket; 430 int ret = 0; 431 432 /* 433 * If we got a section count, it means we received a 434 * SendReceiveBufferComplete msg (ie sent 435 * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need 436 * to send a revoke msg here 437 */ 438 if (NetDevice->ReceiveSectionCount) { 439 DPRINT_INFO(NETVSC, 440 "Sending NvspMessage1TypeRevokeReceiveBuffer..."); 441 442 /* Send the revoke receive buffer */ 443 revokePacket = &NetDevice->RevokePacket; 444 memset(revokePacket, 0, sizeof(struct nvsp_message)); 445 446 revokePacket->Header.MessageType = NvspMessage1TypeRevokeReceiveBuffer; 447 revokePacket->Messages.Version1Messages.RevokeReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; 448 449 ret = NetDevice->Device->Driver->VmbusChannelInterface.SendPacket( 450 NetDevice->Device, 451 revokePacket, 452 sizeof(struct nvsp_message), 453 (unsigned long)revokePacket, 454 VmbusPacketTypeDataInBand, 0); 455 /* 456 * If we failed here, we might as well return and 457 * have a leak rather than continue and a bugchk 458 */ 459 if (ret != 0) { 460 DPRINT_ERR(NETVSC, "unable to send revoke receive " 461 "buffer to netvsp"); 462 return -1; 463 } 464 } 465 466 /* Teardown the gpadl on the vsp end */ 467 if (NetDevice->ReceiveBufferGpadlHandle) { 468 DPRINT_INFO(NETVSC, "Tearing down receive buffer's GPADL..."); 469 470 ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl( 471 NetDevice->Device, 472 NetDevice->ReceiveBufferGpadlHandle); 473 474 /* If we failed here, we might as well return and have a leak rather than continue and a bugchk */ 475 if (ret != 0) { 476 DPRINT_ERR(NETVSC, 477 "unable to teardown receive buffer's gpadl"); 478 return -1; 479 } 480 NetDevice->ReceiveBufferGpadlHandle = 0; 481 } 482 483 if (NetDevice->ReceiveBuffer) { 484 DPRINT_INFO(NETVSC, "Freeing up receive buffer..."); 485 486 /* Free up the receive buffer */ 487 osd_PageFree(NetDevice->ReceiveBuffer, 488 NetDevice->ReceiveBufferSize >> PAGE_SHIFT); 489 NetDevice->ReceiveBuffer = NULL; 490 } 491 492 if (NetDevice->ReceiveSections) { 493 NetDevice->ReceiveSectionCount = 0; 494 kfree(NetDevice->ReceiveSections); 495 NetDevice->ReceiveSections = NULL; 496 } 497 498 return ret; 499} 500 501static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice) 502{ 503 struct nvsp_message *revokePacket; 504 int ret = 0; 505 506 /* 507 * If we got a section count, it means we received a 508 * SendReceiveBufferComplete msg (ie sent 509 * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need 510 * to send a revoke msg here 511 */ 512 if (NetDevice->SendSectionSize) { 513 DPRINT_INFO(NETVSC, 514 "Sending NvspMessage1TypeRevokeSendBuffer..."); 515 516 /* Send the revoke send buffer */ 517 revokePacket = &NetDevice->RevokePacket; 518 memset(revokePacket, 0, sizeof(struct nvsp_message)); 519 520 revokePacket->Header.MessageType = NvspMessage1TypeRevokeSendBuffer; 521 revokePacket->Messages.Version1Messages.RevokeSendBuffer.Id = NETVSC_SEND_BUFFER_ID; 522 523 ret = NetDevice->Device->Driver->VmbusChannelInterface.SendPacket(NetDevice->Device, 524 revokePacket, 525 sizeof(struct nvsp_message), 526 (unsigned long)revokePacket, 527 VmbusPacketTypeDataInBand, 0); 528 /* 529 * If we failed here, we might as well return and have a leak 530 * rather than continue and a bugchk 531 */ 532 if (ret != 0) { 533 DPRINT_ERR(NETVSC, "unable to send revoke send buffer " 534 "to netvsp"); 535 return -1; 536 } 537 } 538 539 /* Teardown the gpadl on the vsp end */ 540 if (NetDevice->SendBufferGpadlHandle) { 541 DPRINT_INFO(NETVSC, "Tearing down send buffer's GPADL..."); 542 543 ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl(NetDevice->Device, NetDevice->SendBufferGpadlHandle); 544 545 /* 546 * If we failed here, we might as well return and have a leak 547 * rather than continue and a bugchk 548 */ 549 if (ret != 0) { 550 DPRINT_ERR(NETVSC, "unable to teardown send buffer's " 551 "gpadl"); 552 return -1; 553 } 554 NetDevice->SendBufferGpadlHandle = 0; 555 } 556 557 if (NetDevice->SendBuffer) { 558 DPRINT_INFO(NETVSC, "Freeing up send buffer..."); 559 560 /* Free up the receive buffer */ 561 osd_PageFree(NetDevice->SendBuffer, 562 NetDevice->SendBufferSize >> PAGE_SHIFT); 563 NetDevice->SendBuffer = NULL; 564 } 565 566 return ret; 567} 568 569 570static int NetVscConnectToVsp(struct hv_device *Device) 571{ 572 int ret; 573 struct netvsc_device *netDevice; 574 struct nvsp_message *initPacket; 575 int ndisVersion; 576 577 netDevice = GetOutboundNetDevice(Device); 578 if (!netDevice) { 579 DPRINT_ERR(NETVSC, "unable to get net device..." 580 "device being destroyed?"); 581 return -1; 582 } 583 584 initPacket = &netDevice->ChannelInitPacket; 585 586 memset(initPacket, 0, sizeof(struct nvsp_message)); 587 initPacket->Header.MessageType = NvspMessageTypeInit; 588 initPacket->Messages.InitMessages.Init.MinProtocolVersion = NVSP_MIN_PROTOCOL_VERSION; 589 initPacket->Messages.InitMessages.Init.MaxProtocolVersion = NVSP_MAX_PROTOCOL_VERSION; 590 591 DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit..."); 592 593 /* Send the init request */ 594 ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, 595 initPacket, 596 sizeof(struct nvsp_message), 597 (unsigned long)initPacket, 598 VmbusPacketTypeDataInBand, 599 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 600 601 if (ret != 0) { 602 DPRINT_ERR(NETVSC, "unable to send NvspMessageTypeInit"); 603 goto Cleanup; 604 } 605 606 osd_WaitEventWait(netDevice->ChannelInitEvent); 607 608 /* Now, check the response */ 609 /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */ 610 DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)", 611 initPacket->Messages.InitMessages.InitComplete.Status, 612 initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength); 613 614 if (initPacket->Messages.InitMessages.InitComplete.Status != 615 NvspStatusSuccess) { 616 DPRINT_ERR(NETVSC, 617 "unable to initialize with netvsp (status 0x%x)", 618 initPacket->Messages.InitMessages.InitComplete.Status); 619 ret = -1; 620 goto Cleanup; 621 } 622 623 if (initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion != NVSP_PROTOCOL_VERSION_1) { 624 DPRINT_ERR(NETVSC, "unable to initialize with netvsp " 625 "(version expected 1 got %d)", 626 initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion); 627 ret = -1; 628 goto Cleanup; 629 } 630 DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion..."); 631 632 /* Send the ndis version */ 633 memset(initPacket, 0, sizeof(struct nvsp_message)); 634 635 ndisVersion = 0x00050000; 636 637 initPacket->Header.MessageType = NvspMessage1TypeSendNdisVersion; 638 initPacket->Messages.Version1Messages.SendNdisVersion.NdisMajorVersion = 639 (ndisVersion & 0xFFFF0000) >> 16; 640 initPacket->Messages.Version1Messages.SendNdisVersion.NdisMinorVersion = 641 ndisVersion & 0xFFFF; 642 643 /* Send the init request */ 644 ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, 645 initPacket, 646 sizeof(struct nvsp_message), 647 (unsigned long)initPacket, 648 VmbusPacketTypeDataInBand, 0); 649 if (ret != 0) { 650 DPRINT_ERR(NETVSC, 651 "unable to send NvspMessage1TypeSendNdisVersion"); 652 ret = -1; 653 goto Cleanup; 654 } 655 /* 656 * BUGBUG - We have to wait for the above msg since the 657 * netvsp uses KMCL which acknowledges packet (completion 658 * packet) since our Vmbus always set the 659 * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag 660 */ 661 /* osd_WaitEventWait(NetVscChannel->ChannelInitEvent); */ 662 663 /* Post the big receive buffer to NetVSP */ 664 ret = NetVscInitializeReceiveBufferWithNetVsp(Device); 665 if (ret == 0) 666 ret = NetVscInitializeSendBufferWithNetVsp(Device); 667 668Cleanup: 669 PutNetDevice(Device); 670 return ret; 671} 672 673static void NetVscDisconnectFromVsp(struct netvsc_device *NetDevice) 674{ 675 NetVscDestroyReceiveBuffer(NetDevice); 676 NetVscDestroySendBuffer(NetDevice); 677} 678 679/* 680 * NetVscOnDeviceAdd - Callback when the device belonging to this driver is added 681 */ 682static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) 683{ 684 int ret = 0; 685 int i; 686 struct netvsc_device *netDevice; 687 struct hv_netvsc_packet *packet, *pos; 688 struct netvsc_driver *netDriver = 689 (struct netvsc_driver *)Device->Driver; 690 691 netDevice = AllocNetDevice(Device); 692 if (!netDevice) { 693 ret = -1; 694 goto Cleanup; 695 } 696 697 DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", netDevice); 698 699 /* Initialize the NetVSC channel extension */ 700 netDevice->ReceiveBufferSize = NETVSC_RECEIVE_BUFFER_SIZE; 701 spin_lock_init(&netDevice->receive_packet_list_lock); 702 703 netDevice->SendBufferSize = NETVSC_SEND_BUFFER_SIZE; 704 705 INIT_LIST_HEAD(&netDevice->ReceivePacketList); 706 707 for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) { 708 packet = kzalloc(sizeof(struct hv_netvsc_packet) + 709 (NETVSC_RECEIVE_SG_COUNT * 710 sizeof(struct hv_page_buffer)), GFP_KERNEL); 711 if (!packet) { 712 DPRINT_DBG(NETVSC, "unable to allocate netvsc pkts " 713 "for receive pool (wanted %d got %d)", 714 NETVSC_RECEIVE_PACKETLIST_COUNT, i); 715 break; 716 } 717 list_add_tail(&packet->ListEntry, 718 &netDevice->ReceivePacketList); 719 } 720 netDevice->ChannelInitEvent = osd_WaitEventCreate(); 721 if (!netDevice->ChannelInitEvent) { 722 ret = -ENOMEM; 723 goto Cleanup; 724 } 725 726 /* Open the channel */ 727 ret = Device->Driver->VmbusChannelInterface.Open(Device, 728 netDriver->RingBufferSize, 729 netDriver->RingBufferSize, 730 NULL, 0, 731 NetVscOnChannelCallback, 732 Device); 733 734 if (ret != 0) { 735 DPRINT_ERR(NETVSC, "unable to open channel: %d", ret); 736 ret = -1; 737 goto Cleanup; 738 } 739 740 /* Channel is opened */ 741 DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***"); 742 743 /* Connect with the NetVsp */ 744 ret = NetVscConnectToVsp(Device); 745 if (ret != 0) { 746 DPRINT_ERR(NETVSC, "unable to connect to NetVSP - %d", ret); 747 ret = -1; 748 goto Close; 749 } 750 751 DPRINT_INFO(NETVSC, "*** NetVSC channel handshake result - %d ***", 752 ret); 753 754 return ret; 755 756Close: 757 /* Now, we can close the channel safely */ 758 Device->Driver->VmbusChannelInterface.Close(Device); 759 760Cleanup: 761 762 if (netDevice) { 763 kfree(netDevice->ChannelInitEvent); 764 765 list_for_each_entry_safe(packet, pos, 766 &netDevice->ReceivePacketList, 767 ListEntry) { 768 list_del(&packet->ListEntry); 769 kfree(packet); 770 } 771 772 ReleaseOutboundNetDevice(Device); 773 ReleaseInboundNetDevice(Device); 774 775 FreeNetDevice(netDevice); 776 } 777 778 return ret; 779} 780 781/* 782 * NetVscOnDeviceRemove - Callback when the root bus device is removed 783 */ 784static int NetVscOnDeviceRemove(struct hv_device *Device) 785{ 786 struct netvsc_device *netDevice; 787 struct hv_netvsc_packet *netvscPacket, *pos; 788 789 DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...", 790 Device->Extension); 791 792 /* Stop outbound traffic ie sends and receives completions */ 793 netDevice = ReleaseOutboundNetDevice(Device); 794 if (!netDevice) { 795 DPRINT_ERR(NETVSC, "No net device present!!"); 796 return -1; 797 } 798 799 /* Wait for all send completions */ 800 while (atomic_read(&netDevice->NumOutstandingSends)) { 801 DPRINT_INFO(NETVSC, "waiting for %d requests to complete...", 802 atomic_read(&netDevice->NumOutstandingSends)); 803 udelay(100); 804 } 805 806 DPRINT_INFO(NETVSC, "Disconnecting from netvsp..."); 807 808 NetVscDisconnectFromVsp(netDevice); 809 810 DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...", 811 Device->Extension); 812 813 /* Stop inbound traffic ie receives and sends completions */ 814 netDevice = ReleaseInboundNetDevice(Device); 815 816 /* At this point, no one should be accessing netDevice except in here */ 817 DPRINT_INFO(NETVSC, "net device (%p) safe to remove", netDevice); 818 819 /* Now, we can close the channel safely */ 820 Device->Driver->VmbusChannelInterface.Close(Device); 821 822 /* Release all resources */ 823 list_for_each_entry_safe(netvscPacket, pos, 824 &netDevice->ReceivePacketList, ListEntry) { 825 list_del(&netvscPacket->ListEntry); 826 kfree(netvscPacket); 827 } 828 829 kfree(netDevice->ChannelInitEvent); 830 FreeNetDevice(netDevice); 831 return 0; 832} 833 834/* 835 * NetVscOnCleanup - Perform any cleanup when the driver is removed 836 */ 837static void NetVscOnCleanup(struct hv_driver *drv) 838{ 839} 840 841static void NetVscOnSendCompletion(struct hv_device *Device, 842 struct vmpacket_descriptor *Packet) 843{ 844 struct netvsc_device *netDevice; 845 struct nvsp_message *nvspPacket; 846 struct hv_netvsc_packet *nvscPacket; 847 848 netDevice = GetInboundNetDevice(Device); 849 if (!netDevice) { 850 DPRINT_ERR(NETVSC, "unable to get net device..." 851 "device being destroyed?"); 852 return; 853 } 854 855 nvspPacket = (struct nvsp_message *)((unsigned long)Packet + (Packet->DataOffset8 << 3)); 856 857 DPRINT_DBG(NETVSC, "send completion packet - type %d", 858 nvspPacket->Header.MessageType); 859 860 if ((nvspPacket->Header.MessageType == NvspMessageTypeInitComplete) || 861 (nvspPacket->Header.MessageType == 862 NvspMessage1TypeSendReceiveBufferComplete) || 863 (nvspPacket->Header.MessageType == 864 NvspMessage1TypeSendSendBufferComplete)) { 865 /* Copy the response back */ 866 memcpy(&netDevice->ChannelInitPacket, nvspPacket, 867 sizeof(struct nvsp_message)); 868 osd_WaitEventSet(netDevice->ChannelInitEvent); 869 } else if (nvspPacket->Header.MessageType == 870 NvspMessage1TypeSendRNDISPacketComplete) { 871 /* Get the send context */ 872 nvscPacket = (struct hv_netvsc_packet *)(unsigned long)Packet->TransactionId; 873 /* ASSERT(nvscPacket); */ 874 875 /* Notify the layer above us */ 876 nvscPacket->Completion.Send.OnSendCompletion(nvscPacket->Completion.Send.SendCompletionContext); 877 878 atomic_dec(&netDevice->NumOutstandingSends); 879 } else { 880 DPRINT_ERR(NETVSC, "Unknown send completion packet type - " 881 "%d received!!", nvspPacket->Header.MessageType); 882 } 883 884 PutNetDevice(Device); 885} 886 887static int NetVscOnSend(struct hv_device *Device, 888 struct hv_netvsc_packet *Packet) 889{ 890 struct netvsc_device *netDevice; 891 int ret = 0; 892 893 struct nvsp_message sendMessage; 894 895 netDevice = GetOutboundNetDevice(Device); 896 if (!netDevice) { 897 DPRINT_ERR(NETVSC, "net device (%p) shutting down..." 898 "ignoring outbound packets", netDevice); 899 return -2; 900 } 901 902 sendMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacket; 903 if (Packet->IsDataPacket) { 904 /* 0 is RMC_DATA; */ 905 sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0; 906 } else { 907 /* 1 is RMC_CONTROL; */ 908 sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 1; 909 } 910 911 /* Not using send buffer section */ 912 sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionIndex = 0xFFFFFFFF; 913 sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionSize = 0; 914 915 if (Packet->PageBufferCount) { 916 ret = Device->Driver->VmbusChannelInterface.SendPacketPageBuffer( 917 Device, Packet->PageBuffers, 918 Packet->PageBufferCount, 919 &sendMessage, 920 sizeof(struct nvsp_message), 921 (unsigned long)Packet); 922 } else { 923 ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, 924 &sendMessage, 925 sizeof(struct nvsp_message), 926 (unsigned long)Packet, 927 VmbusPacketTypeDataInBand, 928 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 929 930 } 931 932 if (ret != 0) 933 DPRINT_ERR(NETVSC, "Unable to send packet %p ret %d", 934 Packet, ret); 935 936 atomic_inc(&netDevice->NumOutstandingSends); 937 PutNetDevice(Device); 938 return ret; 939} 940 941static void NetVscOnReceive(struct hv_device *Device, 942 struct vmpacket_descriptor *Packet) 943{ 944 struct netvsc_device *netDevice; 945 struct vmtransfer_page_packet_header *vmxferpagePacket; 946 struct nvsp_message *nvspPacket; 947 struct hv_netvsc_packet *netvscPacket = NULL; 948 unsigned long start; 949 unsigned long end, endVirtual; 950 /* struct netvsc_driver *netvscDriver; */ 951 struct xferpage_packet *xferpagePacket = NULL; 952 int i, j; 953 int count = 0, bytesRemain = 0; 954 unsigned long flags; 955 LIST_HEAD(listHead); 956 957 netDevice = GetInboundNetDevice(Device); 958 if (!netDevice) { 959 DPRINT_ERR(NETVSC, "unable to get net device..." 960 "device being destroyed?"); 961 return; 962 } 963 964 /* 965 * All inbound packets other than send completion should be xfer page 966 * packet 967 */ 968 if (Packet->Type != VmbusPacketTypeDataUsingTransferPages) { 969 DPRINT_ERR(NETVSC, "Unknown packet type received - %d", 970 Packet->Type); 971 PutNetDevice(Device); 972 return; 973 } 974 975 nvspPacket = (struct nvsp_message *)((unsigned long)Packet + 976 (Packet->DataOffset8 << 3)); 977 978 /* Make sure this is a valid nvsp packet */ 979 if (nvspPacket->Header.MessageType != NvspMessage1TypeSendRNDISPacket) { 980 DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d", 981 nvspPacket->Header.MessageType); 982 PutNetDevice(Device); 983 return; 984 } 985 986 DPRINT_DBG(NETVSC, "NVSP packet received - type %d", 987 nvspPacket->Header.MessageType); 988 989 vmxferpagePacket = (struct vmtransfer_page_packet_header *)Packet; 990 991 if (vmxferpagePacket->TransferPageSetId != NETVSC_RECEIVE_BUFFER_ID) { 992 DPRINT_ERR(NETVSC, "Invalid xfer page set id - " 993 "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID, 994 vmxferpagePacket->TransferPageSetId); 995 PutNetDevice(Device); 996 return; 997 } 998 999 DPRINT_DBG(NETVSC, "xfer page - range count %d", 1000 vmxferpagePacket->RangeCount); 1001 1002 /* 1003 * Grab free packets (range count + 1) to represent this xfer 1004 * page packet. +1 to represent the xfer page packet itself. 1005 * We grab it here so that we know exactly how many we can 1006 * fulfil 1007 */ 1008 spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); 1009 while (!list_empty(&netDevice->ReceivePacketList)) { 1010 list_move_tail(netDevice->ReceivePacketList.next, &listHead); 1011 if (++count == vmxferpagePacket->RangeCount + 1) 1012 break; 1013 } 1014 spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags); 1015 1016 /* 1017 * We need at least 2 netvsc pkts (1 to represent the xfer 1018 * page and at least 1 for the range) i.e. we can handled 1019 * some of the xfer page packet ranges... 1020 */ 1021 if (count < 2) { 1022 DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. " 1023 "Dropping this xfer page packet completely!", 1024 count, vmxferpagePacket->RangeCount + 1); 1025 1026 /* Return it to the freelist */ 1027 spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); 1028 for (i = count; i != 0; i--) { 1029 list_move_tail(listHead.next, 1030 &netDevice->ReceivePacketList); 1031 } 1032 spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, 1033 flags); 1034 1035 NetVscSendReceiveCompletion(Device, 1036 vmxferpagePacket->d.TransactionId); 1037 1038 PutNetDevice(Device); 1039 return; 1040 } 1041 1042 /* Remove the 1st packet to represent the xfer page packet itself */ 1043 xferpagePacket = (struct xferpage_packet *)listHead.next; 1044 list_del(&xferpagePacket->ListEntry); 1045 1046 /* This is how much we can satisfy */ 1047 xferpagePacket->Count = count - 1; 1048 /* ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= */ 1049 /* vmxferpagePacket->RangeCount); */ 1050 1051 if (xferpagePacket->Count != vmxferpagePacket->RangeCount) { 1052 DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer " 1053 "page...got %d", vmxferpagePacket->RangeCount, 1054 xferpagePacket->Count); 1055 } 1056 1057 /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ 1058 for (i = 0; i < (count - 1); i++) { 1059 netvscPacket = (struct hv_netvsc_packet *)listHead.next; 1060 list_del(&netvscPacket->ListEntry); 1061 1062 /* Initialize the netvsc packet */ 1063 netvscPacket->XferPagePacket = xferpagePacket; 1064 netvscPacket->Completion.Recv.OnReceiveCompletion = 1065 NetVscOnReceiveCompletion; 1066 netvscPacket->Completion.Recv.ReceiveCompletionContext = 1067 netvscPacket; 1068 netvscPacket->Device = Device; 1069 /* Save this so that we can send it back */ 1070 netvscPacket->Completion.Recv.ReceiveCompletionTid = 1071 vmxferpagePacket->d.TransactionId; 1072 1073 netvscPacket->TotalDataBufferLength = 1074 vmxferpagePacket->Ranges[i].ByteCount; 1075 netvscPacket->PageBufferCount = 1; 1076 1077 /* ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + */ 1078 /* vmxferpagePacket->Ranges[i].ByteCount < */ 1079 /* netDevice->ReceiveBufferSize); */ 1080 1081 netvscPacket->PageBuffers[0].Length = 1082 vmxferpagePacket->Ranges[i].ByteCount; 1083 1084 start = virt_to_phys((void *)((unsigned long)netDevice->ReceiveBuffer + vmxferpagePacket->Ranges[i].ByteOffset)); 1085 1086 netvscPacket->PageBuffers[0].Pfn = start >> PAGE_SHIFT; 1087 endVirtual = (unsigned long)netDevice->ReceiveBuffer 1088 + vmxferpagePacket->Ranges[i].ByteOffset 1089 + vmxferpagePacket->Ranges[i].ByteCount - 1; 1090 end = virt_to_phys((void *)endVirtual); 1091 1092 /* Calculate the page relative offset */ 1093 netvscPacket->PageBuffers[0].Offset = 1094 vmxferpagePacket->Ranges[i].ByteOffset & (PAGE_SIZE - 1); 1095 if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) { 1096 /* Handle frame across multiple pages: */ 1097 netvscPacket->PageBuffers[0].Length = 1098 (netvscPacket->PageBuffers[0].Pfn << PAGE_SHIFT) 1099 + PAGE_SIZE - start; 1100 bytesRemain = netvscPacket->TotalDataBufferLength - 1101 netvscPacket->PageBuffers[0].Length; 1102 for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) { 1103 netvscPacket->PageBuffers[j].Offset = 0; 1104 if (bytesRemain <= PAGE_SIZE) { 1105 netvscPacket->PageBuffers[j].Length = bytesRemain; 1106 bytesRemain = 0; 1107 } else { 1108 netvscPacket->PageBuffers[j].Length = PAGE_SIZE; 1109 bytesRemain -= PAGE_SIZE; 1110 } 1111 netvscPacket->PageBuffers[j].Pfn = 1112 virt_to_phys((void *)(endVirtual - bytesRemain)) >> PAGE_SHIFT; 1113 netvscPacket->PageBufferCount++; 1114 if (bytesRemain == 0) 1115 break; 1116 } 1117 /* ASSERT(bytesRemain == 0); */ 1118 } 1119 DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => " 1120 "(pfn %llx, offset %u, len %u)", i, 1121 vmxferpagePacket->Ranges[i].ByteOffset, 1122 vmxferpagePacket->Ranges[i].ByteCount, 1123 netvscPacket->PageBuffers[0].Pfn, 1124 netvscPacket->PageBuffers[0].Offset, 1125 netvscPacket->PageBuffers[0].Length); 1126 1127 /* Pass it to the upper layer */ 1128 ((struct netvsc_driver *)Device->Driver)->OnReceiveCallback(Device, netvscPacket); 1129 1130 NetVscOnReceiveCompletion(netvscPacket->Completion.Recv.ReceiveCompletionContext); 1131 } 1132 1133 /* ASSERT(list_empty(&listHead)); */ 1134 1135 PutNetDevice(Device); 1136} 1137 1138static void NetVscSendReceiveCompletion(struct hv_device *Device, 1139 u64 TransactionId) 1140{ 1141 struct nvsp_message recvcompMessage; 1142 int retries = 0; 1143 int ret; 1144 1145 DPRINT_DBG(NETVSC, "Sending receive completion pkt - %llx", 1146 TransactionId); 1147 1148 recvcompMessage.Header.MessageType = 1149 NvspMessage1TypeSendRNDISPacketComplete; 1150 1151 recvcompMessage.Messages.Version1Messages.SendRNDISPacketComplete.Status = NvspStatusSuccess; 1152 1153retry_send_cmplt: 1154 /* Send the completion */ 1155 ret = Device->Driver->VmbusChannelInterface.SendPacket(Device, 1156 &recvcompMessage, 1157 sizeof(struct nvsp_message), 1158 TransactionId, 1159 VmbusPacketTypeCompletion, 0); 1160 if (ret == 0) { 1161 /* success */ 1162 /* no-op */ 1163 } else if (ret == -1) { 1164 /* no more room...wait a bit and attempt to retry 3 times */ 1165 retries++; 1166 DPRINT_ERR(NETVSC, "unable to send receive completion pkt " 1167 "(tid %llx)...retrying %d", TransactionId, retries); 1168 1169 if (retries < 4) { 1170 udelay(100); 1171 goto retry_send_cmplt; 1172 } else { 1173 DPRINT_ERR(NETVSC, "unable to send receive completion " 1174 "pkt (tid %llx)...give up retrying", 1175 TransactionId); 1176 } 1177 } else { 1178 DPRINT_ERR(NETVSC, "unable to send receive completion pkt - " 1179 "%llx", TransactionId); 1180 } 1181} 1182 1183/* Send a receive completion packet to RNDIS device (ie NetVsp) */ 1184static void NetVscOnReceiveCompletion(void *Context) 1185{ 1186 struct hv_netvsc_packet *packet = Context; 1187 struct hv_device *device = (struct hv_device *)packet->Device; 1188 struct netvsc_device *netDevice; 1189 u64 transactionId = 0; 1190 bool fSendReceiveComp = false; 1191 unsigned long flags; 1192 1193 /* ASSERT(packet->XferPagePacket); */ 1194 1195 /* 1196 * Even though it seems logical to do a GetOutboundNetDevice() here to 1197 * send out receive completion, we are using GetInboundNetDevice() 1198 * since we may have disable outbound traffic already. 1199 */ 1200 netDevice = GetInboundNetDevice(device); 1201 if (!netDevice) { 1202 DPRINT_ERR(NETVSC, "unable to get net device..." 1203 "device being destroyed?"); 1204 return; 1205 } 1206 1207 /* Overloading use of the lock. */ 1208 spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); 1209 1210 /* ASSERT(packet->XferPagePacket->Count > 0); */ 1211 packet->XferPagePacket->Count--; 1212 1213 /* 1214 * Last one in the line that represent 1 xfer page packet. 1215 * Return the xfer page packet itself to the freelist 1216 */ 1217 if (packet->XferPagePacket->Count == 0) { 1218 fSendReceiveComp = true; 1219 transactionId = packet->Completion.Recv.ReceiveCompletionTid; 1220 list_add_tail(&packet->XferPagePacket->ListEntry, 1221 &netDevice->ReceivePacketList); 1222 1223 } 1224 1225 /* Put the packet back */ 1226 list_add_tail(&packet->ListEntry, &netDevice->ReceivePacketList); 1227 spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags); 1228 1229 /* Send a receive completion for the xfer page packet */ 1230 if (fSendReceiveComp) 1231 NetVscSendReceiveCompletion(device, transactionId); 1232 1233 PutNetDevice(device); 1234} 1235 1236static void NetVscOnChannelCallback(void *Context) 1237{ 1238 int ret; 1239 struct hv_device *device = Context; 1240 struct netvsc_device *netDevice; 1241 u32 bytesRecvd; 1242 u64 requestId; 1243 unsigned char *packet; 1244 struct vmpacket_descriptor *desc; 1245 unsigned char *buffer; 1246 int bufferlen = NETVSC_PACKET_SIZE; 1247 1248 /* ASSERT(device); */ 1249 1250 packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char), 1251 GFP_ATOMIC); 1252 if (!packet) 1253 return; 1254 buffer = packet; 1255 1256 netDevice = GetInboundNetDevice(device); 1257 if (!netDevice) { 1258 DPRINT_ERR(NETVSC, "net device (%p) shutting down..." 1259 "ignoring inbound packets", netDevice); 1260 goto out; 1261 } 1262 1263 do { 1264 ret = device->Driver->VmbusChannelInterface.RecvPacketRaw( 1265 device, buffer, bufferlen, 1266 &bytesRecvd, &requestId); 1267 if (ret == 0) { 1268 if (bytesRecvd > 0) { 1269 DPRINT_DBG(NETVSC, "receive %d bytes, tid %llx", 1270 bytesRecvd, requestId); 1271 1272 desc = (struct vmpacket_descriptor *)buffer; 1273 switch (desc->Type) { 1274 case VmbusPacketTypeCompletion: 1275 NetVscOnSendCompletion(device, desc); 1276 break; 1277 1278 case VmbusPacketTypeDataUsingTransferPages: 1279 NetVscOnReceive(device, desc); 1280 break; 1281 1282 default: 1283 DPRINT_ERR(NETVSC, 1284 "unhandled packet type %d, " 1285 "tid %llx len %d\n", 1286 desc->Type, requestId, 1287 bytesRecvd); 1288 break; 1289 } 1290 1291 /* reset */ 1292 if (bufferlen > NETVSC_PACKET_SIZE) { 1293 kfree(buffer); 1294 buffer = packet; 1295 bufferlen = NETVSC_PACKET_SIZE; 1296 } 1297 } else { 1298 /* reset */ 1299 if (bufferlen > NETVSC_PACKET_SIZE) { 1300 kfree(buffer); 1301 buffer = packet; 1302 bufferlen = NETVSC_PACKET_SIZE; 1303 } 1304 1305 break; 1306 } 1307 } else if (ret == -2) { 1308 /* Handle large packet */ 1309 buffer = kmalloc(bytesRecvd, GFP_ATOMIC); 1310 if (buffer == NULL) { 1311 /* Try again next time around */ 1312 DPRINT_ERR(NETVSC, 1313 "unable to allocate buffer of size " 1314 "(%d)!!", bytesRecvd); 1315 break; 1316 } 1317 1318 bufferlen = bytesRecvd; 1319 } 1320 } while (1); 1321 1322 PutNetDevice(device); 1323out: 1324 kfree(buffer); 1325 return; 1326} 1327