1 /** @file 2 Implementation of Managed Network Protocol private services. 3 4 Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions 7 of the BSD License which accompanies this distribution. The full 8 text of the license may be found at<BR> 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "MnpImpl.h" 17 #include "MnpVlan.h" 18 19 EFI_SERVICE_BINDING_PROTOCOL mMnpServiceBindingProtocol = { 20 MnpServiceBindingCreateChild, 21 MnpServiceBindingDestroyChild 22 }; 23 24 EFI_MANAGED_NETWORK_PROTOCOL mMnpProtocolTemplate = { 25 MnpGetModeData, 26 MnpConfigure, 27 MnpMcastIpToMac, 28 MnpGroups, 29 MnpTransmit, 30 MnpReceive, 31 MnpCancel, 32 MnpPoll 33 }; 34 35 EFI_MANAGED_NETWORK_CONFIG_DATA mMnpDefaultConfigData = { 36 10000000, 37 10000000, 38 0, 39 FALSE, 40 FALSE, 41 FALSE, 42 FALSE, 43 FALSE, 44 FALSE, 45 FALSE 46 }; 47 48 /** 49 Add Count of net buffers to MnpDeviceData->FreeNbufQue. The length of the net 50 buffer is specified by MnpDeviceData->BufferLength. 51 52 @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA. 53 @param[in] Count Number of NET_BUFFERs to add. 54 55 @retval EFI_SUCCESS The specified amount of NET_BUFs are allocated 56 and added to MnpDeviceData->FreeNbufQue. 57 @retval EFI_OUT_OF_RESOURCES Failed to allocate a NET_BUF structure. 58 59 **/ 60 EFI_STATUS 61 MnpAddFreeNbuf ( 62 IN OUT MNP_DEVICE_DATA *MnpDeviceData, 63 IN UINTN Count 64 ) 65 { 66 EFI_STATUS Status; 67 UINTN Index; 68 NET_BUF *Nbuf; 69 70 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 71 ASSERT ((Count > 0) && (MnpDeviceData->BufferLength > 0)); 72 73 Status = EFI_SUCCESS; 74 for (Index = 0; Index < Count; Index++) { 75 Nbuf = NetbufAlloc (MnpDeviceData->BufferLength + MnpDeviceData->PaddingSize); 76 if (Nbuf == NULL) { 77 DEBUG ((EFI_D_ERROR, "MnpAddFreeNbuf: NetBufAlloc failed.\n")); 78 79 Status = EFI_OUT_OF_RESOURCES; 80 break; 81 } 82 83 if (MnpDeviceData->PaddingSize > 0) { 84 // 85 // Pad padding bytes before the media header 86 // 87 NetbufAllocSpace (Nbuf, MnpDeviceData->PaddingSize, NET_BUF_TAIL); 88 NetbufTrim (Nbuf, MnpDeviceData->PaddingSize, NET_BUF_HEAD); 89 } 90 91 NetbufQueAppend (&MnpDeviceData->FreeNbufQue, Nbuf); 92 } 93 94 MnpDeviceData->NbufCnt += Index; 95 return Status; 96 } 97 98 99 /** 100 Allocate a free NET_BUF from MnpDeviceData->FreeNbufQue. If there is none 101 in the queue, first try to allocate some and add them into the queue, then 102 fetch the NET_BUF from the updated FreeNbufQue. 103 104 @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA. 105 106 @return Pointer to the allocated free NET_BUF structure, if NULL the 107 operation is failed. 108 109 **/ 110 NET_BUF * 111 MnpAllocNbuf ( 112 IN OUT MNP_DEVICE_DATA *MnpDeviceData 113 ) 114 { 115 EFI_STATUS Status; 116 NET_BUF_QUEUE *FreeNbufQue; 117 NET_BUF *Nbuf; 118 EFI_TPL OldTpl; 119 120 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 121 122 FreeNbufQue = &MnpDeviceData->FreeNbufQue; 123 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 124 125 // 126 // Check whether there are available buffers, or else try to add some. 127 // 128 if (FreeNbufQue->BufNum == 0) { 129 if ((MnpDeviceData->NbufCnt + MNP_NET_BUFFER_INCREASEMENT) > MNP_MAX_NET_BUFFER_NUM) { 130 DEBUG ( 131 (EFI_D_ERROR, 132 "MnpAllocNbuf: The maximum NET_BUF size is reached for MNP driver instance %p.\n", 133 MnpDeviceData) 134 ); 135 136 Nbuf = NULL; 137 goto ON_EXIT; 138 } 139 140 Status = MnpAddFreeNbuf (MnpDeviceData, MNP_NET_BUFFER_INCREASEMENT); 141 if (EFI_ERROR (Status)) { 142 DEBUG ( 143 (EFI_D_ERROR, 144 "MnpAllocNbuf: Failed to add NET_BUFs into the FreeNbufQue, %r.\n", 145 Status) 146 ); 147 148 // 149 // Don't return NULL, perhaps MnpAddFreeNbuf does add some NET_BUFs but 150 // the amount is less than MNP_NET_BUFFER_INCREASEMENT. 151 // 152 } 153 } 154 155 Nbuf = NetbufQueRemove (FreeNbufQue); 156 157 // 158 // Increase the RefCnt. 159 // 160 if (Nbuf != NULL) { 161 NET_GET_REF (Nbuf); 162 } 163 164 ON_EXIT: 165 gBS->RestoreTPL (OldTpl); 166 167 return Nbuf; 168 } 169 170 171 /** 172 Try to reclaim the Nbuf into the buffer pool. 173 174 @param[in, out] MnpDeviceData Pointer to the mnp device context data. 175 @param[in, out] Nbuf Pointer to the NET_BUF to free. 176 177 **/ 178 VOID 179 MnpFreeNbuf ( 180 IN OUT MNP_DEVICE_DATA *MnpDeviceData, 181 IN OUT NET_BUF *Nbuf 182 ) 183 { 184 EFI_TPL OldTpl; 185 186 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 187 ASSERT (Nbuf->RefCnt > 1); 188 189 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 190 191 NET_PUT_REF (Nbuf); 192 193 if (Nbuf->RefCnt == 1) { 194 // 195 // Trim all buffer contained in the Nbuf, then append it to the NbufQue. 196 // 197 NetbufTrim (Nbuf, Nbuf->TotalSize, NET_BUF_TAIL); 198 199 if (NetbufAllocSpace (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_HEAD) != NULL) { 200 // 201 // There is space reserved for vlan tag in the head, reclaim it 202 // 203 NetbufTrim (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_TAIL); 204 } 205 206 NetbufQueAppend (&MnpDeviceData->FreeNbufQue, Nbuf); 207 } 208 209 gBS->RestoreTPL (OldTpl); 210 } 211 212 /** 213 Add Count of TX buffers to MnpDeviceData->AllTxBufList and MnpDeviceData->FreeTxBufList. 214 The length of the buffer is specified by MnpDeviceData->BufferLength. 215 216 @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA. 217 @param[in] Count Number of TX buffers to add. 218 219 @retval EFI_SUCCESS The specified amount of TX buffers are allocated. 220 @retval EFI_OUT_OF_RESOURCES Failed to allocate a TX buffer. 221 222 **/ 223 EFI_STATUS 224 MnpAddFreeTxBuf ( 225 IN OUT MNP_DEVICE_DATA *MnpDeviceData, 226 IN UINTN Count 227 ) 228 { 229 EFI_STATUS Status; 230 UINT32 Index; 231 MNP_TX_BUF_WRAP *TxBufWrap; 232 233 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 234 ASSERT ((Count > 0) && (MnpDeviceData->BufferLength > 0)); 235 236 Status = EFI_SUCCESS; 237 for (Index = 0; Index < Count; Index++) { 238 TxBufWrap = (MNP_TX_BUF_WRAP*) AllocatePool (sizeof (MNP_TX_BUF_WRAP) + MnpDeviceData->BufferLength - 1); 239 if (TxBufWrap == NULL) { 240 DEBUG ((EFI_D_ERROR, "MnpAddFreeTxBuf: TxBuf Alloc failed.\n")); 241 242 Status = EFI_OUT_OF_RESOURCES; 243 break; 244 } 245 DEBUG ((EFI_D_INFO, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf)); 246 TxBufWrap->Signature = MNP_TX_BUF_WRAP_SIGNATURE; 247 TxBufWrap->InUse = FALSE; 248 InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry); 249 InsertTailList (&MnpDeviceData->AllTxBufList, &TxBufWrap->AllEntry); 250 } 251 252 MnpDeviceData->TxBufCount += Index; 253 return Status; 254 } 255 256 /** 257 Allocate a free TX buffer from MnpDeviceData->FreeTxBufList. If there is none 258 in the queue, first try to recycle some from SNP, then try to allocate some and add 259 them into the queue, then fetch the NET_BUF from the updated FreeTxBufList. 260 261 @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA. 262 263 @return Pointer to the allocated free NET_BUF structure, if NULL the 264 operation is failed. 265 266 **/ 267 UINT8 * 268 MnpAllocTxBuf ( 269 IN OUT MNP_DEVICE_DATA *MnpDeviceData 270 ) 271 { 272 EFI_TPL OldTpl; 273 UINT8 *TxBuf; 274 EFI_STATUS Status; 275 LIST_ENTRY *Entry; 276 MNP_TX_BUF_WRAP *TxBufWrap; 277 278 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 279 280 OldTpl = gBS->RaiseTPL (TPL_CALLBACK); 281 282 if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) { 283 // 284 // First try to recycle some TX buffer from SNP 285 // 286 Status = MnpRecycleTxBuf (MnpDeviceData); 287 if (EFI_ERROR (Status)) { 288 TxBuf = NULL; 289 goto ON_EXIT; 290 } 291 292 // 293 // If still no free TX buffer, allocate more. 294 // 295 if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) { 296 if ((MnpDeviceData->TxBufCount + MNP_TX_BUFFER_INCREASEMENT) > MNP_MAX_TX_BUFFER_NUM) { 297 DEBUG ( 298 (EFI_D_ERROR, 299 "MnpAllocTxBuf: The maximum TxBuf size is reached for MNP driver instance %p.\n", 300 MnpDeviceData) 301 ); 302 303 TxBuf = NULL; 304 goto ON_EXIT; 305 } 306 307 Status = MnpAddFreeTxBuf (MnpDeviceData, MNP_TX_BUFFER_INCREASEMENT); 308 if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) { 309 DEBUG ( 310 (EFI_D_ERROR, 311 "MnpAllocNbuf: Failed to add TxBuf into the FreeTxBufList, %r.\n", 312 Status) 313 ); 314 315 TxBuf = NULL; 316 goto ON_EXIT; 317 } 318 } 319 } 320 321 ASSERT (!IsListEmpty (&MnpDeviceData->FreeTxBufList)); 322 Entry = MnpDeviceData->FreeTxBufList.ForwardLink; 323 RemoveEntryList (MnpDeviceData->FreeTxBufList.ForwardLink); 324 TxBufWrap = NET_LIST_USER_STRUCT_S (Entry, MNP_TX_BUF_WRAP, WrapEntry, MNP_TX_BUF_WRAP_SIGNATURE); 325 TxBufWrap->InUse = TRUE; 326 TxBuf = TxBufWrap->TxBuf; 327 328 ON_EXIT: 329 gBS->RestoreTPL (OldTpl); 330 331 return TxBuf; 332 } 333 334 /** 335 Try to reclaim the TX buffer into the buffer pool. 336 337 @param[in, out] MnpDeviceData Pointer to the mnp device context data. 338 @param[in, out] TxBuf Pointer to the TX buffer to free. 339 340 **/ 341 VOID 342 MnpFreeTxBuf ( 343 IN OUT MNP_DEVICE_DATA *MnpDeviceData, 344 IN OUT UINT8 *TxBuf 345 ) 346 { 347 MNP_TX_BUF_WRAP *TxBufWrap; 348 EFI_TPL OldTpl; 349 350 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 351 352 if (TxBuf == NULL) { 353 return; 354 } 355 356 TxBufWrap = NET_LIST_USER_STRUCT (TxBuf, MNP_TX_BUF_WRAP, TxBuf); 357 if (TxBufWrap->Signature != MNP_TX_BUF_WRAP_SIGNATURE) { 358 DEBUG ( 359 (EFI_D_ERROR, 360 "MnpFreeTxBuf: Signature check failed in MnpFreeTxBuf.\n") 361 ); 362 return; 363 } 364 365 if (!TxBufWrap->InUse) { 366 DEBUG ( 367 (EFI_D_WARN, 368 "MnpFreeTxBuf: Duplicated recycle report from SNP.\n") 369 ); 370 return; 371 } 372 373 OldTpl = gBS->RaiseTPL (TPL_CALLBACK); 374 InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry); 375 TxBufWrap->InUse = FALSE; 376 gBS->RestoreTPL (OldTpl); 377 } 378 379 /** 380 Try to recycle all the transmitted buffer address from SNP. 381 382 @param[in, out] MnpDeviceData Pointer to the mnp device context data. 383 384 @retval EFI_SUCCESS Successed to recyclethe transmitted buffer address. 385 @retval Others Failed to recyclethe transmitted buffer address. 386 387 **/ 388 EFI_STATUS 389 MnpRecycleTxBuf ( 390 IN OUT MNP_DEVICE_DATA *MnpDeviceData 391 ) 392 { 393 UINT8 *TxBuf; 394 EFI_SIMPLE_NETWORK_PROTOCOL *Snp; 395 EFI_STATUS Status; 396 397 Snp = MnpDeviceData->Snp; 398 ASSERT (Snp != NULL); 399 400 do { 401 TxBuf = NULL; 402 Status = Snp->GetStatus (Snp, NULL, (VOID **) &TxBuf); 403 if (EFI_ERROR (Status)) { 404 return Status; 405 } 406 407 if (TxBuf != NULL) { 408 MnpFreeTxBuf (MnpDeviceData, TxBuf); 409 } 410 } while (TxBuf != NULL); 411 412 return EFI_SUCCESS; 413 } 414 415 /** 416 Initialize the mnp device context data. 417 418 @param[in, out] MnpDeviceData Pointer to the mnp device context data. 419 @param[in] ImageHandle The driver image handle. 420 @param[in] ControllerHandle Handle of device to bind driver to. 421 422 @retval EFI_SUCCESS The mnp service context is initialized. 423 @retval EFI_UNSUPPORTED ControllerHandle does not support Simple Network Protocol. 424 @retval Others Other errors as indicated. 425 426 **/ 427 EFI_STATUS 428 MnpInitializeDeviceData ( 429 IN OUT MNP_DEVICE_DATA *MnpDeviceData, 430 IN EFI_HANDLE ImageHandle, 431 IN EFI_HANDLE ControllerHandle 432 ) 433 { 434 EFI_STATUS Status; 435 EFI_SIMPLE_NETWORK_PROTOCOL *Snp; 436 EFI_SIMPLE_NETWORK_MODE *SnpMode; 437 438 MnpDeviceData->Signature = MNP_DEVICE_DATA_SIGNATURE; 439 MnpDeviceData->ImageHandle = ImageHandle; 440 MnpDeviceData->ControllerHandle = ControllerHandle; 441 442 // 443 // Copy the MNP Protocol interfaces from the template. 444 // 445 CopyMem (&MnpDeviceData->VlanConfig, &mVlanConfigProtocolTemplate, sizeof (EFI_VLAN_CONFIG_PROTOCOL)); 446 447 // 448 // Open the Simple Network protocol. 449 // 450 Status = gBS->OpenProtocol ( 451 ControllerHandle, 452 &gEfiSimpleNetworkProtocolGuid, 453 (VOID **) &Snp, 454 ImageHandle, 455 ControllerHandle, 456 EFI_OPEN_PROTOCOL_BY_DRIVER 457 ); 458 if (EFI_ERROR (Status)) { 459 return EFI_UNSUPPORTED; 460 } 461 462 // 463 // Get MTU from Snp. 464 // 465 SnpMode = Snp->Mode; 466 MnpDeviceData->Snp = Snp; 467 468 // 469 // Initialize the lists. 470 // 471 InitializeListHead (&MnpDeviceData->ServiceList); 472 InitializeListHead (&MnpDeviceData->GroupAddressList); 473 474 // 475 // Get the buffer length used to allocate NET_BUF to hold data received 476 // from SNP. Do this before fill the FreeNetBufQue. 477 // 478 // 479 MnpDeviceData->BufferLength = SnpMode->MediaHeaderSize + NET_VLAN_TAG_LEN + SnpMode->MaxPacketSize + NET_ETHER_FCS_SIZE; 480 481 // 482 // Make sure the protocol headers immediately following the media header 483 // 4-byte aligned, and also preserve additional space for VLAN tag 484 // 485 MnpDeviceData->PaddingSize = ((4 - SnpMode->MediaHeaderSize) & 0x3) + NET_VLAN_TAG_LEN; 486 487 // 488 // Initialize MAC string which will be used as VLAN configuration variable name 489 // 490 Status = NetLibGetMacString (ControllerHandle, ImageHandle, &MnpDeviceData->MacString); 491 if (EFI_ERROR (Status)) { 492 goto ERROR; 493 } 494 495 // 496 // Initialize the FreeNetBufQue and pre-allocate some NET_BUFs. 497 // 498 NetbufQueInit (&MnpDeviceData->FreeNbufQue); 499 Status = MnpAddFreeNbuf (MnpDeviceData, MNP_INIT_NET_BUFFER_NUM); 500 if (EFI_ERROR (Status)) { 501 DEBUG ((EFI_D_ERROR, "MnpInitializeDeviceData: MnpAddFreeNbuf failed, %r.\n", Status)); 502 503 goto ERROR; 504 } 505 506 // 507 // Get one NET_BUF from the FreeNbufQue for rx cache. 508 // 509 MnpDeviceData->RxNbufCache = MnpAllocNbuf (MnpDeviceData); 510 NetbufAllocSpace ( 511 MnpDeviceData->RxNbufCache, 512 MnpDeviceData->BufferLength, 513 NET_BUF_TAIL 514 ); 515 516 // 517 // Allocate buffer pool for tx. 518 // 519 InitializeListHead (&MnpDeviceData->FreeTxBufList); 520 InitializeListHead (&MnpDeviceData->AllTxBufList); 521 MnpDeviceData->TxBufCount = 0; 522 523 // 524 // Create the system poll timer. 525 // 526 Status = gBS->CreateEvent ( 527 EVT_NOTIFY_SIGNAL | EVT_TIMER, 528 TPL_CALLBACK, 529 MnpSystemPoll, 530 MnpDeviceData, 531 &MnpDeviceData->PollTimer 532 ); 533 if (EFI_ERROR (Status)) { 534 DEBUG ((EFI_D_ERROR, "MnpInitializeDeviceData: CreateEvent for poll timer failed.\n")); 535 536 goto ERROR; 537 } 538 539 // 540 // Create the timer for packet timeout check. 541 // 542 Status = gBS->CreateEvent ( 543 EVT_NOTIFY_SIGNAL | EVT_TIMER, 544 TPL_CALLBACK, 545 MnpCheckPacketTimeout, 546 MnpDeviceData, 547 &MnpDeviceData->TimeoutCheckTimer 548 ); 549 if (EFI_ERROR (Status)) { 550 DEBUG ((EFI_D_ERROR, "MnpInitializeDeviceData: CreateEvent for packet timeout check failed.\n")); 551 552 goto ERROR; 553 } 554 555 // 556 // Create the timer for media detection. 557 // 558 Status = gBS->CreateEvent ( 559 EVT_NOTIFY_SIGNAL | EVT_TIMER, 560 TPL_CALLBACK, 561 MnpCheckMediaStatus, 562 MnpDeviceData, 563 &MnpDeviceData->MediaDetectTimer 564 ); 565 if (EFI_ERROR (Status)) { 566 DEBUG ((EFI_D_ERROR, "MnpInitializeDeviceData: CreateEvent for media detection failed.\n")); 567 568 goto ERROR; 569 } 570 571 ERROR: 572 if (EFI_ERROR (Status)) { 573 // 574 // Free the dynamic allocated resources if necessary. 575 // 576 if (MnpDeviceData->MacString != NULL) { 577 FreePool (MnpDeviceData->MacString); 578 } 579 580 if (MnpDeviceData->TimeoutCheckTimer != NULL) { 581 gBS->CloseEvent (MnpDeviceData->TimeoutCheckTimer); 582 } 583 584 if (MnpDeviceData->MediaDetectTimer != NULL) { 585 gBS->CloseEvent (MnpDeviceData->MediaDetectTimer); 586 } 587 588 if (MnpDeviceData->PollTimer != NULL) { 589 gBS->CloseEvent (MnpDeviceData->PollTimer); 590 } 591 592 if (MnpDeviceData->RxNbufCache != NULL) { 593 MnpFreeNbuf (MnpDeviceData, MnpDeviceData->RxNbufCache); 594 } 595 596 if (MnpDeviceData->FreeNbufQue.BufNum != 0) { 597 NetbufQueFlush (&MnpDeviceData->FreeNbufQue); 598 } 599 600 // 601 // Close the Simple Network Protocol. 602 // 603 gBS->CloseProtocol ( 604 ControllerHandle, 605 &gEfiSimpleNetworkProtocolGuid, 606 ImageHandle, 607 ControllerHandle 608 ); 609 } 610 611 return Status; 612 } 613 614 615 /** 616 Destroy the MNP device context data. 617 618 @param[in, out] MnpDeviceData Pointer to the mnp device context data. 619 @param[in] ImageHandle The driver image handle. 620 621 **/ 622 VOID 623 MnpDestroyDeviceData ( 624 IN OUT MNP_DEVICE_DATA *MnpDeviceData, 625 IN EFI_HANDLE ImageHandle 626 ) 627 { 628 LIST_ENTRY *Entry; 629 LIST_ENTRY *NextEntry; 630 MNP_TX_BUF_WRAP *TxBufWrap; 631 632 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 633 634 // 635 // Free Vlan Config variable name string 636 // 637 if (MnpDeviceData->MacString != NULL) { 638 FreePool (MnpDeviceData->MacString); 639 } 640 641 // 642 // The GroupAddressList must be empty. 643 // 644 ASSERT (IsListEmpty (&MnpDeviceData->GroupAddressList)); 645 646 // 647 // Close the event. 648 // 649 gBS->CloseEvent (MnpDeviceData->TimeoutCheckTimer); 650 gBS->CloseEvent (MnpDeviceData->MediaDetectTimer); 651 gBS->CloseEvent (MnpDeviceData->PollTimer); 652 653 // 654 // Free the Tx buffer pool. 655 // 656 NET_LIST_FOR_EACH_SAFE(Entry, NextEntry, &MnpDeviceData->AllTxBufList) { 657 TxBufWrap = NET_LIST_USER_STRUCT (Entry, MNP_TX_BUF_WRAP, AllEntry); 658 RemoveEntryList (Entry); 659 FreePool (TxBufWrap); 660 MnpDeviceData->TxBufCount--; 661 } 662 ASSERT (IsListEmpty (&MnpDeviceData->AllTxBufList)); 663 ASSERT (MnpDeviceData->TxBufCount == 0); 664 665 // 666 // Free the RxNbufCache. 667 // 668 MnpFreeNbuf (MnpDeviceData, MnpDeviceData->RxNbufCache); 669 670 // 671 // Flush the FreeNbufQue. 672 // 673 MnpDeviceData->NbufCnt -= MnpDeviceData->FreeNbufQue.BufNum; 674 NetbufQueFlush (&MnpDeviceData->FreeNbufQue); 675 676 // 677 // Close the Simple Network Protocol. 678 // 679 gBS->CloseProtocol ( 680 MnpDeviceData->ControllerHandle, 681 &gEfiSimpleNetworkProtocolGuid, 682 ImageHandle, 683 MnpDeviceData->ControllerHandle 684 ); 685 } 686 687 688 /** 689 Create mnp service context data. 690 691 @param[in] MnpDeviceData Pointer to the mnp device context data. 692 @param[in] VlanId The VLAN ID. 693 @param[in] Priority The VLAN priority. If VlanId is 0, 694 Priority is ignored. 695 696 @return A pointer to MNP_SERVICE_DATA or NULL if failed to create MNP service context. 697 698 **/ 699 MNP_SERVICE_DATA * 700 MnpCreateServiceData ( 701 IN MNP_DEVICE_DATA *MnpDeviceData, 702 IN UINT16 VlanId, 703 IN UINT8 Priority OPTIONAL 704 ) 705 { 706 EFI_HANDLE MnpServiceHandle; 707 MNP_SERVICE_DATA *MnpServiceData; 708 EFI_STATUS Status; 709 EFI_SIMPLE_NETWORK_MODE *SnpMode; 710 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig; 711 712 // 713 // Initialize the Mnp Service Data. 714 // 715 MnpServiceData = AllocateZeroPool (sizeof (MNP_SERVICE_DATA)); 716 if (MnpServiceData == NULL) { 717 DEBUG ((EFI_D_ERROR, "MnpCreateServiceData: Faild to allocate memory for the new Mnp Service Data.\n")); 718 719 return NULL; 720 } 721 722 // 723 // Add to MNP service list 724 // 725 InsertTailList (&MnpDeviceData->ServiceList, &MnpServiceData->Link); 726 727 MnpServiceData->Signature = MNP_SERVICE_DATA_SIGNATURE; 728 MnpServiceData->MnpDeviceData = MnpDeviceData; 729 730 // 731 // Copy the ServiceBinding structure. 732 // 733 CopyMem (&MnpServiceData->ServiceBinding, &mMnpServiceBindingProtocol, sizeof (EFI_SERVICE_BINDING_PROTOCOL)); 734 735 // 736 // Initialize the lists. 737 // 738 InitializeListHead (&MnpServiceData->ChildrenList); 739 740 SnpMode = MnpDeviceData->Snp->Mode; 741 if (VlanId != 0) { 742 // 743 // Create VLAN child handle 744 // 745 MnpServiceHandle = MnpCreateVlanChild ( 746 MnpDeviceData->ImageHandle, 747 MnpDeviceData->ControllerHandle, 748 VlanId, 749 &MnpServiceData->DevicePath 750 ); 751 if (MnpServiceHandle == NULL) { 752 DEBUG ((EFI_D_ERROR, "MnpCreateServiceData: Faild to create child handle.\n")); 753 754 return NULL; 755 } 756 757 // 758 // Open VLAN Config Protocol by child 759 // 760 Status = gBS->OpenProtocol ( 761 MnpDeviceData->ControllerHandle, 762 &gEfiVlanConfigProtocolGuid, 763 (VOID **) &VlanConfig, 764 MnpDeviceData->ImageHandle, 765 MnpServiceHandle, 766 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 767 ); 768 if (EFI_ERROR (Status)) { 769 goto Exit; 770 } 771 772 // 773 // Reduce MTU for VLAN device 774 // 775 MnpServiceData->Mtu = SnpMode->MaxPacketSize - NET_VLAN_TAG_LEN; 776 } else { 777 // 778 // VlanId set to 0 means rx/tx untagged frame 779 // 780 MnpServiceHandle = MnpDeviceData->ControllerHandle; 781 MnpServiceData->Mtu = SnpMode->MaxPacketSize; 782 } 783 784 MnpServiceData->ServiceHandle = MnpServiceHandle; 785 MnpServiceData->VlanId = VlanId; 786 MnpServiceData->Priority = Priority; 787 788 // 789 // Install the MNP Service Binding Protocol 790 // 791 Status = gBS->InstallMultipleProtocolInterfaces ( 792 &MnpServiceHandle, 793 &gEfiManagedNetworkServiceBindingProtocolGuid, 794 &MnpServiceData->ServiceBinding, 795 NULL 796 ); 797 798 Exit: 799 if (EFI_ERROR (Status)) { 800 MnpDestroyServiceData (MnpServiceData); 801 MnpServiceData = NULL; 802 } 803 804 return MnpServiceData; 805 } 806 807 /** 808 Destroy the MNP service context data. 809 810 @param[in, out] MnpServiceData Pointer to the mnp service context data. 811 812 @retval EFI_SUCCESS The mnp service context is destroyed. 813 @retval Others Errors as indicated. 814 815 **/ 816 EFI_STATUS 817 MnpDestroyServiceData ( 818 IN OUT MNP_SERVICE_DATA *MnpServiceData 819 ) 820 { 821 EFI_STATUS Status; 822 823 // 824 // Uninstall the MNP Service Binding Protocol 825 // 826 Status = gBS->UninstallMultipleProtocolInterfaces ( 827 MnpServiceData->ServiceHandle, 828 &gEfiManagedNetworkServiceBindingProtocolGuid, 829 &MnpServiceData->ServiceBinding, 830 NULL 831 ); 832 if (EFI_ERROR (Status)) { 833 return Status; 834 } 835 836 if (MnpServiceData->VlanId != 0) { 837 // 838 // Close VlanConfig Protocol opened by VLAN child handle 839 // 840 Status = gBS->CloseProtocol ( 841 MnpServiceData->MnpDeviceData->ControllerHandle, 842 &gEfiVlanConfigProtocolGuid, 843 MnpServiceData->MnpDeviceData->ImageHandle, 844 MnpServiceData->ServiceHandle 845 ); 846 if (EFI_ERROR (Status)) { 847 return Status; 848 } 849 850 // 851 // Uninstall Device Path Protocol to destroy the VLAN child handle 852 // 853 Status = gBS->UninstallMultipleProtocolInterfaces ( 854 MnpServiceData->ServiceHandle, 855 &gEfiDevicePathProtocolGuid, 856 MnpServiceData->DevicePath, 857 NULL 858 ); 859 if (EFI_ERROR (Status)) { 860 return Status; 861 } 862 863 if (MnpServiceData->DevicePath != NULL) { 864 FreePool (MnpServiceData->DevicePath); 865 } 866 } 867 868 // 869 // Remove from MnpDeviceData service list 870 // 871 RemoveEntryList (&MnpServiceData->Link); 872 873 FreePool (MnpServiceData); 874 875 return Status; 876 } 877 878 /** 879 Callback function which provided by user to remove one node in NetDestroyLinkList process. 880 881 @param[in] Entry The entry to be removed. 882 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. 883 884 @retval EFI_SUCCESS The entry has been removed successfully. 885 @retval Others Fail to remove the entry. 886 887 **/ 888 EFI_STATUS 889 EFIAPI 890 MnpDestoryChildEntry ( 891 IN LIST_ENTRY *Entry, 892 IN VOID *Context 893 ) 894 { 895 MNP_INSTANCE_DATA *Instance; 896 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; 897 898 ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context; 899 Instance = CR (Entry, MNP_INSTANCE_DATA, InstEntry, MNP_INSTANCE_DATA_SIGNATURE); 900 return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); 901 } 902 903 /** 904 Destroy all child of the MNP service data. 905 906 @param[in, out] MnpServiceData Pointer to the mnp service context data. 907 908 @retval EFI_SUCCESS All child are destroyed. 909 @retval Others Failed to destroy all child. 910 911 **/ 912 EFI_STATUS 913 MnpDestroyServiceChild ( 914 IN OUT MNP_SERVICE_DATA *MnpServiceData 915 ) 916 { 917 LIST_ENTRY *List; 918 EFI_STATUS Status; 919 UINTN ListLength; 920 921 List = &MnpServiceData->ChildrenList; 922 923 Status = NetDestroyLinkList ( 924 List, 925 MnpDestoryChildEntry, 926 &MnpServiceData->ServiceBinding, 927 &ListLength 928 ); 929 if (EFI_ERROR (Status) || ListLength != 0) { 930 return EFI_DEVICE_ERROR; 931 } 932 933 return EFI_SUCCESS; 934 } 935 936 /** 937 Find the MNP Service Data for given VLAN ID. 938 939 @param[in] MnpDeviceData Pointer to the mnp device context data. 940 @param[in] VlanId The VLAN ID. 941 942 @return A pointer to MNP_SERVICE_DATA or NULL if not found. 943 944 **/ 945 MNP_SERVICE_DATA * 946 MnpFindServiceData ( 947 IN MNP_DEVICE_DATA *MnpDeviceData, 948 IN UINT16 VlanId 949 ) 950 { 951 LIST_ENTRY *Entry; 952 MNP_SERVICE_DATA *MnpServiceData; 953 954 NET_LIST_FOR_EACH (Entry, &MnpDeviceData->ServiceList) { 955 // 956 // Check VLAN ID of each Mnp Service Data 957 // 958 MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry); 959 if (MnpServiceData->VlanId == VlanId) { 960 return MnpServiceData; 961 } 962 } 963 964 return NULL; 965 } 966 967 /** 968 Initialize the mnp instance context data. 969 970 @param[in] MnpServiceData Pointer to the mnp service context data. 971 @param[in, out] Instance Pointer to the mnp instance context data 972 to initialize. 973 974 **/ 975 VOID 976 MnpInitializeInstanceData ( 977 IN MNP_SERVICE_DATA *MnpServiceData, 978 IN OUT MNP_INSTANCE_DATA *Instance 979 ) 980 { 981 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE); 982 ASSERT (Instance != NULL); 983 984 // 985 // Set the signature. 986 // 987 Instance->Signature = MNP_INSTANCE_DATA_SIGNATURE; 988 989 // 990 // Copy the MNP Protocol interfaces from the template. 991 // 992 CopyMem (&Instance->ManagedNetwork, &mMnpProtocolTemplate, sizeof (Instance->ManagedNetwork)); 993 994 // 995 // Copy the default config data. 996 // 997 CopyMem (&Instance->ConfigData, &mMnpDefaultConfigData, sizeof (Instance->ConfigData)); 998 999 // 1000 // Initialize the lists. 1001 // 1002 InitializeListHead (&Instance->GroupCtrlBlkList); 1003 InitializeListHead (&Instance->RcvdPacketQueue); 1004 InitializeListHead (&Instance->RxDeliveredPacketQueue); 1005 1006 // 1007 // Initialize the RxToken Map. 1008 // 1009 NetMapInit (&Instance->RxTokenMap); 1010 1011 // 1012 // Save the MnpServiceData info. 1013 // 1014 Instance->MnpServiceData = MnpServiceData; 1015 } 1016 1017 1018 /** 1019 Check whether the token specified by Arg matches the token in Item. 1020 1021 @param[in] Map Pointer to the NET_MAP. 1022 @param[in] Item Pointer to the NET_MAP_ITEM. 1023 @param[in] Arg Pointer to the Arg, it's a pointer to the token to 1024 check. 1025 1026 @retval EFI_SUCCESS The token specified by Arg is different from the 1027 token in Item. 1028 @retval EFI_ACCESS_DENIED The token specified by Arg is the same as that in 1029 Item. 1030 1031 **/ 1032 EFI_STATUS 1033 EFIAPI 1034 MnpTokenExist ( 1035 IN NET_MAP *Map, 1036 IN NET_MAP_ITEM *Item, 1037 IN VOID *Arg 1038 ) 1039 { 1040 EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token; 1041 EFI_MANAGED_NETWORK_COMPLETION_TOKEN *TokenInItem; 1042 1043 Token = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *) Arg; 1044 TokenInItem = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *) Item->Key; 1045 1046 if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) { 1047 // 1048 // The token is the same either the two tokens equals or the Events in 1049 // the two tokens are the same. 1050 // 1051 return EFI_ACCESS_DENIED; 1052 } 1053 1054 return EFI_SUCCESS; 1055 } 1056 1057 /** 1058 Cancel the token specified by Arg if it matches the token in Item. 1059 1060 @param[in, out] Map Pointer to the NET_MAP. 1061 @param[in, out] Item Pointer to the NET_MAP_ITEM. 1062 @param[in] Arg Pointer to the Arg, it's a pointer to the 1063 token to cancel. 1064 1065 @retval EFI_SUCCESS The Arg is NULL, and the token in Item is cancelled, 1066 or the Arg isn't NULL, and the token in Item is 1067 different from the Arg. 1068 @retval EFI_ABORTED The Arg isn't NULL, the token in Item mathces the 1069 Arg, and the token is cancelled. 1070 1071 **/ 1072 EFI_STATUS 1073 EFIAPI 1074 MnpCancelTokens ( 1075 IN OUT NET_MAP *Map, 1076 IN OUT NET_MAP_ITEM *Item, 1077 IN VOID *Arg 1078 ) 1079 { 1080 EFI_MANAGED_NETWORK_COMPLETION_TOKEN *TokenToCancel; 1081 1082 if ((Arg != NULL) && (Item->Key != Arg)) { 1083 // 1084 // The token in Item is not the token specified by Arg. 1085 // 1086 return EFI_SUCCESS; 1087 } 1088 1089 TokenToCancel = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *) Item->Key; 1090 1091 // 1092 // Remove the item from the map. 1093 // 1094 NetMapRemoveItem (Map, Item, NULL); 1095 1096 // 1097 // Cancel this token with status set to EFI_ABORTED. 1098 // 1099 TokenToCancel->Status = EFI_ABORTED; 1100 gBS->SignalEvent (TokenToCancel->Event); 1101 1102 if (Arg != NULL) { 1103 // 1104 // Only abort the token specified by Arg if Arg isn't NULL. 1105 // 1106 return EFI_ABORTED; 1107 } 1108 1109 return EFI_SUCCESS; 1110 } 1111 1112 1113 /** 1114 Start and initialize the simple network. 1115 1116 @param[in] Snp Pointer to the simple network protocol. 1117 1118 @retval EFI_SUCCESS The simple network protocol is started. 1119 @retval Others Other errors as indicated. 1120 1121 **/ 1122 EFI_STATUS 1123 MnpStartSnp ( 1124 IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp 1125 ) 1126 { 1127 EFI_STATUS Status; 1128 1129 ASSERT (Snp != NULL); 1130 1131 // 1132 // Start the simple network. 1133 // 1134 Status = Snp->Start (Snp); 1135 1136 if (!EFI_ERROR (Status)) { 1137 // 1138 // Initialize the simple network. 1139 // 1140 Status = Snp->Initialize (Snp, 0, 0); 1141 } 1142 1143 return Status; 1144 } 1145 1146 1147 /** 1148 Stop the simple network. 1149 1150 @param[in] MnpDeviceData Pointer to the MNP_DEVICE_DATA. 1151 1152 @retval EFI_SUCCESS The simple network is stopped. 1153 @retval Others Other errors as indicated. 1154 1155 **/ 1156 EFI_STATUS 1157 MnpStopSnp ( 1158 IN MNP_DEVICE_DATA *MnpDeviceData 1159 ) 1160 { 1161 EFI_STATUS Status; 1162 EFI_SIMPLE_NETWORK_PROTOCOL *Snp; 1163 1164 Snp = MnpDeviceData->Snp; 1165 ASSERT (Snp != NULL); 1166 1167 // 1168 // Recycle all the transmit buffer from SNP. 1169 // 1170 Status = MnpRecycleTxBuf (MnpDeviceData); 1171 if (EFI_ERROR (Status)) { 1172 return Status; 1173 } 1174 1175 // 1176 // Shut down the simple network. 1177 // 1178 Status = Snp->Shutdown (Snp); 1179 if (!EFI_ERROR (Status)) { 1180 // 1181 // Stop the simple network. 1182 // 1183 Status = Snp->Stop (Snp); 1184 } 1185 1186 return Status; 1187 } 1188 1189 1190 /** 1191 Start the managed network, this function is called when one instance is configured 1192 or reconfigured. 1193 1194 @param[in, out] MnpServiceData Pointer to the mnp service context data. 1195 @param[in] IsConfigUpdate The instance is reconfigured or it's the first 1196 time the instanced is configured. 1197 @param[in] EnableSystemPoll Enable the system polling or not. 1198 1199 @retval EFI_SUCCESS The managed network is started and some 1200 configuration is updated. 1201 @retval Others Other errors as indicated. 1202 1203 **/ 1204 EFI_STATUS 1205 MnpStart ( 1206 IN OUT MNP_SERVICE_DATA *MnpServiceData, 1207 IN BOOLEAN IsConfigUpdate, 1208 IN BOOLEAN EnableSystemPoll 1209 ) 1210 { 1211 EFI_STATUS Status; 1212 EFI_TIMER_DELAY TimerOpType; 1213 MNP_DEVICE_DATA *MnpDeviceData; 1214 1215 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE); 1216 1217 Status = EFI_SUCCESS; 1218 MnpDeviceData = MnpServiceData->MnpDeviceData; 1219 1220 if (!IsConfigUpdate) { 1221 // 1222 // If it's not a configuration update, increase the configured children number. 1223 // 1224 MnpDeviceData->ConfiguredChildrenNumber++; 1225 1226 if (MnpDeviceData->ConfiguredChildrenNumber == 1) { 1227 // 1228 // It's the first configured child, start the simple network. 1229 // 1230 Status = MnpStartSnp (MnpDeviceData->Snp); 1231 if (EFI_ERROR (Status)) { 1232 DEBUG ((EFI_D_ERROR, "MnpStart: MnpStartSnp failed, %r.\n", Status)); 1233 1234 goto ErrorExit; 1235 } 1236 1237 // 1238 // Start the timeout timer. 1239 // 1240 Status = gBS->SetTimer ( 1241 MnpDeviceData->TimeoutCheckTimer, 1242 TimerPeriodic, 1243 MNP_TIMEOUT_CHECK_INTERVAL 1244 ); 1245 if (EFI_ERROR (Status)) { 1246 DEBUG ( 1247 (EFI_D_ERROR, 1248 "MnpStart, gBS->SetTimer for TimeoutCheckTimer %r.\n", 1249 Status) 1250 ); 1251 1252 goto ErrorExit; 1253 } 1254 1255 // 1256 // Start the media detection timer. 1257 // 1258 Status = gBS->SetTimer ( 1259 MnpDeviceData->MediaDetectTimer, 1260 TimerPeriodic, 1261 MNP_MEDIA_DETECT_INTERVAL 1262 ); 1263 if (EFI_ERROR (Status)) { 1264 DEBUG ( 1265 (EFI_D_ERROR, 1266 "MnpStart, gBS->SetTimer for MediaDetectTimer %r.\n", 1267 Status) 1268 ); 1269 1270 goto ErrorExit; 1271 } 1272 } 1273 } 1274 1275 if (MnpDeviceData->EnableSystemPoll ^ EnableSystemPoll) { 1276 // 1277 // The EnableSystemPoll differs with the current state, disable or enable 1278 // the system poll. 1279 // 1280 TimerOpType = EnableSystemPoll ? TimerPeriodic : TimerCancel; 1281 1282 Status = gBS->SetTimer (MnpDeviceData->PollTimer, TimerOpType, MNP_SYS_POLL_INTERVAL); 1283 if (EFI_ERROR (Status)) { 1284 DEBUG ((EFI_D_ERROR, "MnpStart: gBS->SetTimer for PollTimer failed, %r.\n", Status)); 1285 1286 goto ErrorExit; 1287 } 1288 1289 MnpDeviceData->EnableSystemPoll = EnableSystemPoll; 1290 } 1291 1292 // 1293 // Change the receive filters if need. 1294 // 1295 Status = MnpConfigReceiveFilters (MnpDeviceData); 1296 1297 ErrorExit: 1298 return Status; 1299 } 1300 1301 1302 /** 1303 Stop the managed network. 1304 1305 @param[in, out] MnpServiceData Pointer to the mnp service context data. 1306 1307 @retval EFI_SUCCESS The managed network is stopped. 1308 @retval Others Other errors as indicated. 1309 1310 **/ 1311 EFI_STATUS 1312 MnpStop ( 1313 IN OUT MNP_SERVICE_DATA *MnpServiceData 1314 ) 1315 { 1316 EFI_STATUS Status; 1317 MNP_DEVICE_DATA *MnpDeviceData; 1318 1319 NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE); 1320 MnpDeviceData = MnpServiceData->MnpDeviceData; 1321 ASSERT (MnpDeviceData->ConfiguredChildrenNumber > 0); 1322 1323 // 1324 // Configure the receive filters. 1325 // 1326 MnpConfigReceiveFilters (MnpDeviceData); 1327 1328 // 1329 // Decrease the children number. 1330 // 1331 MnpDeviceData->ConfiguredChildrenNumber--; 1332 1333 if (MnpDeviceData->ConfiguredChildrenNumber > 0) { 1334 // 1335 // If there are other configured chilren, return and keep the timers and 1336 // simple network unchanged. 1337 // 1338 return EFI_SUCCESS; 1339 } 1340 1341 // 1342 // No configured children now. 1343 // 1344 if (MnpDeviceData->EnableSystemPoll) { 1345 // 1346 // The system poll in on, cancel the poll timer. 1347 // 1348 Status = gBS->SetTimer (MnpDeviceData->PollTimer, TimerCancel, 0); 1349 MnpDeviceData->EnableSystemPoll = FALSE; 1350 } 1351 1352 // 1353 // Cancel the timeout timer. 1354 // 1355 Status = gBS->SetTimer (MnpDeviceData->TimeoutCheckTimer, TimerCancel, 0); 1356 1357 // 1358 // Cancel the media detect timer. 1359 // 1360 Status = gBS->SetTimer (MnpDeviceData->MediaDetectTimer, TimerCancel, 0); 1361 1362 // 1363 // Stop the simple network. 1364 // 1365 Status = MnpStopSnp (MnpDeviceData); 1366 return Status; 1367 } 1368 1369 1370 /** 1371 Flush the instance's received data. 1372 1373 @param[in, out] Instance Pointer to the mnp instance context data. 1374 1375 **/ 1376 VOID 1377 MnpFlushRcvdDataQueue ( 1378 IN OUT MNP_INSTANCE_DATA *Instance 1379 ) 1380 { 1381 EFI_TPL OldTpl; 1382 MNP_RXDATA_WRAP *RxDataWrap; 1383 1384 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE); 1385 1386 OldTpl = gBS->RaiseTPL (TPL_NOTIFY); 1387 1388 while (!IsListEmpty (&Instance->RcvdPacketQueue)) { 1389 // 1390 // Remove all the Wraps. 1391 // 1392 RxDataWrap = NET_LIST_HEAD (&Instance->RcvdPacketQueue, MNP_RXDATA_WRAP, WrapEntry); 1393 1394 // 1395 // Recycle the RxDataWrap. 1396 // 1397 MnpRecycleRxData (NULL, (VOID *) RxDataWrap); 1398 Instance->RcvdPacketQueueSize--; 1399 } 1400 1401 ASSERT (Instance->RcvdPacketQueueSize == 0); 1402 1403 gBS->RestoreTPL (OldTpl); 1404 } 1405 1406 1407 /** 1408 Configure the Instance using ConfigData. 1409 1410 @param[in, out] Instance Pointer to the mnp instance context data. 1411 @param[in] ConfigData Pointer to the configuration data used to configure 1412 the isntance. 1413 1414 @retval EFI_SUCCESS The Instance is configured. 1415 @retval EFI_UNSUPPORTED EnableReceiveTimestamps is on and the 1416 implementation doesn't support it. 1417 @retval Others Other errors as indicated. 1418 1419 **/ 1420 EFI_STATUS 1421 MnpConfigureInstance ( 1422 IN OUT MNP_INSTANCE_DATA *Instance, 1423 IN EFI_MANAGED_NETWORK_CONFIG_DATA *ConfigData OPTIONAL 1424 ) 1425 { 1426 EFI_STATUS Status; 1427 MNP_SERVICE_DATA *MnpServiceData; 1428 MNP_DEVICE_DATA *MnpDeviceData; 1429 EFI_MANAGED_NETWORK_CONFIG_DATA *OldConfigData; 1430 EFI_MANAGED_NETWORK_CONFIG_DATA *NewConfigData; 1431 BOOLEAN IsConfigUpdate; 1432 1433 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE); 1434 1435 if ((ConfigData != NULL) && ConfigData->EnableReceiveTimestamps) { 1436 // 1437 // Don't support timestamp. 1438 // 1439 return EFI_UNSUPPORTED; 1440 } 1441 1442 Status = EFI_SUCCESS; 1443 1444 MnpServiceData = Instance->MnpServiceData; 1445 MnpDeviceData = MnpServiceData->MnpDeviceData; 1446 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 1447 1448 IsConfigUpdate = (BOOLEAN) ((Instance->Configured) && (ConfigData != NULL)); 1449 1450 OldConfigData = &Instance->ConfigData; 1451 NewConfigData = ConfigData; 1452 if (NewConfigData == NULL) { 1453 // 1454 // Restore back the default config data if a reset of this instance 1455 // is required. 1456 // 1457 NewConfigData = &mMnpDefaultConfigData; 1458 } 1459 1460 // 1461 // Reset the instance's receive filter. 1462 // 1463 Instance->ReceiveFilter = 0; 1464 1465 // 1466 // Clear the receive counters according to the old ConfigData. 1467 // 1468 if (OldConfigData->EnableUnicastReceive) { 1469 MnpDeviceData->UnicastCount--; 1470 } 1471 1472 if (OldConfigData->EnableMulticastReceive) { 1473 MnpDeviceData->MulticastCount--; 1474 } 1475 1476 if (OldConfigData->EnableBroadcastReceive) { 1477 MnpDeviceData->BroadcastCount--; 1478 } 1479 1480 if (OldConfigData->EnablePromiscuousReceive) { 1481 MnpDeviceData->PromiscuousCount--; 1482 } 1483 1484 // 1485 // Set the receive filter counters and the receive filter of the 1486 // instance according to the new ConfigData. 1487 // 1488 if (NewConfigData->EnableUnicastReceive) { 1489 MnpDeviceData->UnicastCount++; 1490 Instance->ReceiveFilter |= MNP_RECEIVE_UNICAST; 1491 } 1492 1493 if (NewConfigData->EnableMulticastReceive) { 1494 MnpDeviceData->MulticastCount++; 1495 } 1496 1497 if (NewConfigData->EnableBroadcastReceive) { 1498 MnpDeviceData->BroadcastCount++; 1499 Instance->ReceiveFilter |= MNP_RECEIVE_BROADCAST; 1500 } 1501 1502 if (NewConfigData->EnablePromiscuousReceive) { 1503 MnpDeviceData->PromiscuousCount++; 1504 } 1505 1506 if (OldConfigData->FlushQueuesOnReset) { 1507 MnpFlushRcvdDataQueue (Instance); 1508 } 1509 1510 if (ConfigData == NULL) { 1511 Instance->ManagedNetwork.Cancel (&Instance->ManagedNetwork, NULL); 1512 } 1513 1514 if (!NewConfigData->EnableMulticastReceive) { 1515 MnpGroupOp (Instance, FALSE, NULL, NULL); 1516 } 1517 1518 // 1519 // Save the new configuration data. 1520 // 1521 CopyMem (OldConfigData, NewConfigData, sizeof (*OldConfigData)); 1522 1523 Instance->Configured = (BOOLEAN) (ConfigData != NULL); 1524 if (Instance->Configured) { 1525 // 1526 // The instance is configured, start the Mnp. 1527 // 1528 Status = MnpStart ( 1529 MnpServiceData, 1530 IsConfigUpdate, 1531 (BOOLEAN) !NewConfigData->DisableBackgroundPolling 1532 ); 1533 } else { 1534 // 1535 // The instance is changed to the unconfigured state, stop the Mnp. 1536 // 1537 Status = MnpStop (MnpServiceData); 1538 } 1539 1540 return Status; 1541 } 1542 1543 /** 1544 Configure the Snp receive filters according to the instances' receive filter 1545 settings. 1546 1547 @param[in] MnpDeviceData Pointer to the mnp device context data. 1548 1549 @retval EFI_SUCCESS The receive filters is configured. 1550 @retval EFI_OUT_OF_RESOURCES The receive filters can't be configured due 1551 to lack of memory resource. 1552 1553 **/ 1554 EFI_STATUS 1555 MnpConfigReceiveFilters ( 1556 IN MNP_DEVICE_DATA *MnpDeviceData 1557 ) 1558 { 1559 EFI_STATUS Status; 1560 EFI_SIMPLE_NETWORK_PROTOCOL *Snp; 1561 EFI_MAC_ADDRESS *MCastFilter; 1562 UINT32 MCastFilterCnt; 1563 UINT32 EnableFilterBits; 1564 UINT32 DisableFilterBits; 1565 BOOLEAN ResetMCastFilters; 1566 LIST_ENTRY *Entry; 1567 UINT32 Index; 1568 MNP_GROUP_ADDRESS *GroupAddress; 1569 1570 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 1571 1572 Snp = MnpDeviceData->Snp; 1573 1574 // 1575 // Initialize the enable filter and disable filter. 1576 // 1577 EnableFilterBits = 0; 1578 DisableFilterBits = Snp->Mode->ReceiveFilterMask; 1579 1580 if (MnpDeviceData->UnicastCount != 0) { 1581 // 1582 // Enable unicast if any instance wants to receive unicast. 1583 // 1584 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST; 1585 } 1586 1587 if (MnpDeviceData->BroadcastCount != 0) { 1588 // 1589 // Enable broadcast if any instance wants to receive broadcast. 1590 // 1591 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST; 1592 } 1593 1594 MCastFilter = NULL; 1595 MCastFilterCnt = 0; 1596 ResetMCastFilters = TRUE; 1597 1598 if ((MnpDeviceData->MulticastCount != 0) && (MnpDeviceData->GroupAddressCount != 0)) { 1599 // 1600 // There are instances configured to receive multicast and already some group 1601 // addresses are joined. 1602 // 1603 1604 ResetMCastFilters = FALSE; 1605 1606 if (MnpDeviceData->GroupAddressCount <= Snp->Mode->MaxMCastFilterCount) { 1607 // 1608 // The joind group address is less than simple network's maximum count. 1609 // Just configure the snp to do the multicast filtering. 1610 // 1611 1612 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST; 1613 1614 // 1615 // Allocate pool for the mulicast addresses. 1616 // 1617 MCastFilterCnt = MnpDeviceData->GroupAddressCount; 1618 MCastFilter = AllocatePool (sizeof (EFI_MAC_ADDRESS) * MCastFilterCnt); 1619 if (MCastFilter == NULL) { 1620 DEBUG ((EFI_D_ERROR, "MnpConfigReceiveFilters: Failed to allocate memory resource for MCastFilter.\n")); 1621 1622 return EFI_OUT_OF_RESOURCES; 1623 } 1624 1625 // 1626 // Fill the multicast HW address buffer. 1627 // 1628 Index = 0; 1629 NET_LIST_FOR_EACH (Entry, &MnpDeviceData->GroupAddressList) { 1630 1631 GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry); 1632 CopyMem (MCastFilter + Index, &GroupAddress->Address, sizeof (*(MCastFilter + Index))); 1633 Index++; 1634 1635 ASSERT (Index <= MCastFilterCnt); 1636 } 1637 } else { 1638 // 1639 // The maximum multicast is reached, set the filter to be promiscuous 1640 // multicast. 1641 // 1642 1643 if ((Snp->Mode->ReceiveFilterMask & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) { 1644 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST; 1645 } else { 1646 // 1647 // Either MULTICAST or PROMISCUOUS_MULTICAST is not supported by Snp, 1648 // set the NIC to be promiscuous although this will tremendously degrade 1649 // the performance. 1650 // 1651 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS; 1652 } 1653 } 1654 } 1655 1656 if (MnpDeviceData->PromiscuousCount != 0) { 1657 // 1658 // Enable promiscuous if any instance wants to receive promiscuous. 1659 // 1660 EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS; 1661 } 1662 1663 // 1664 // Set the disable filter. 1665 // 1666 DisableFilterBits ^= EnableFilterBits; 1667 1668 // 1669 // Configure the receive filters of SNP. 1670 // 1671 Status = Snp->ReceiveFilters ( 1672 Snp, 1673 EnableFilterBits, 1674 DisableFilterBits, 1675 ResetMCastFilters, 1676 MCastFilterCnt, 1677 MCastFilter 1678 ); 1679 DEBUG_CODE ( 1680 if (EFI_ERROR (Status)) { 1681 DEBUG ( 1682 (EFI_D_ERROR, 1683 "MnpConfigReceiveFilters: Snp->ReceiveFilters failed, %r.\n", 1684 Status) 1685 ); 1686 } 1687 ); 1688 1689 if (MCastFilter != NULL) { 1690 // 1691 // Free the buffer used to hold the group addresses. 1692 // 1693 FreePool (MCastFilter); 1694 } 1695 1696 return Status; 1697 } 1698 1699 1700 /** 1701 Add a group address control block which controls the MacAddress for 1702 this instance. 1703 1704 @param[in, out] Instance Pointer to the mnp instance context data. 1705 @param[in, out] CtrlBlk Pointer to the group address control block. 1706 @param[in, out] GroupAddress Pointer to the group adress. 1707 @param[in] MacAddress Pointer to the mac address. 1708 @param[in] HwAddressSize The hardware address size. 1709 1710 @retval EFI_SUCCESS The group address control block is added. 1711 @retval EFI_OUT_OF_RESOURCES Failed due to lack of memory resources. 1712 1713 **/ 1714 EFI_STATUS 1715 MnpGroupOpAddCtrlBlk ( 1716 IN OUT MNP_INSTANCE_DATA *Instance, 1717 IN OUT MNP_GROUP_CONTROL_BLOCK *CtrlBlk, 1718 IN OUT MNP_GROUP_ADDRESS *GroupAddress OPTIONAL, 1719 IN EFI_MAC_ADDRESS *MacAddress, 1720 IN UINT32 HwAddressSize 1721 ) 1722 { 1723 MNP_DEVICE_DATA *MnpDeviceData; 1724 1725 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE); 1726 1727 MnpDeviceData = Instance->MnpServiceData->MnpDeviceData; 1728 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 1729 1730 if (GroupAddress == NULL) { 1731 ASSERT (MacAddress != NULL); 1732 1733 // 1734 // Allocate a new GroupAddress to be added into MNP's GroupAddressList. 1735 // 1736 GroupAddress = AllocatePool (sizeof (MNP_GROUP_ADDRESS)); 1737 if (GroupAddress == NULL) { 1738 1739 DEBUG ((EFI_D_ERROR, "MnpGroupOpFormCtrlBlk: Failed to allocate memory resource.\n")); 1740 1741 return EFI_OUT_OF_RESOURCES; 1742 } 1743 1744 CopyMem (&GroupAddress->Address, MacAddress, sizeof (GroupAddress->Address)); 1745 GroupAddress->RefCnt = 0; 1746 InsertTailList ( 1747 &MnpDeviceData->GroupAddressList, 1748 &GroupAddress->AddrEntry 1749 ); 1750 MnpDeviceData->GroupAddressCount++; 1751 } 1752 1753 // 1754 // Increase the RefCnt. 1755 // 1756 GroupAddress->RefCnt++; 1757 1758 // 1759 // Add the CtrlBlk into the instance's GroupCtrlBlkList. 1760 // 1761 CtrlBlk->GroupAddress = GroupAddress; 1762 InsertTailList (&Instance->GroupCtrlBlkList, &CtrlBlk->CtrlBlkEntry); 1763 1764 return EFI_SUCCESS; 1765 } 1766 1767 1768 /** 1769 Delete a group control block from the instance. If the controlled group address's 1770 reference count reaches zero, the group address is removed too. 1771 1772 @param[in] Instance Pointer to the instance context data. 1773 @param[in] CtrlBlk Pointer to the group control block to delete. 1774 1775 @return The group address controlled by the control block is no longer used or not. 1776 1777 **/ 1778 BOOLEAN 1779 MnpGroupOpDelCtrlBlk ( 1780 IN MNP_INSTANCE_DATA *Instance, 1781 IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk 1782 ) 1783 { 1784 MNP_DEVICE_DATA *MnpDeviceData; 1785 MNP_GROUP_ADDRESS *GroupAddress; 1786 1787 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE); 1788 1789 MnpDeviceData = Instance->MnpServiceData->MnpDeviceData; 1790 NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); 1791 1792 // 1793 // Remove and free the CtrlBlk. 1794 // 1795 GroupAddress = CtrlBlk->GroupAddress; 1796 RemoveEntryList (&CtrlBlk->CtrlBlkEntry); 1797 FreePool (CtrlBlk); 1798 1799 ASSERT (GroupAddress->RefCnt > 0); 1800 1801 // 1802 // Count down the RefCnt. 1803 // 1804 GroupAddress->RefCnt--; 1805 1806 if (GroupAddress->RefCnt == 0) { 1807 // 1808 // Free this GroupAddress entry if no instance uses it. 1809 // 1810 MnpDeviceData->GroupAddressCount--; 1811 RemoveEntryList (&GroupAddress->AddrEntry); 1812 FreePool (GroupAddress); 1813 1814 return TRUE; 1815 } 1816 1817 return FALSE; 1818 } 1819 1820 1821 /** 1822 Do the group operations for this instance. 1823 1824 @param[in, out] Instance Pointer to the instance context data. 1825 @param[in] JoinFlag Set to TRUE to join a group. Set to TRUE to 1826 leave a group/groups. 1827 @param[in] MacAddress Pointer to the group address to join or leave. 1828 @param[in] CtrlBlk Pointer to the group control block if JoinFlag 1829 is FALSE. 1830 1831 @retval EFI_SUCCESS The group operation finished. 1832 @retval EFI_OUT_OF_RESOURCES Failed due to lack of memory resources. 1833 @retval Others Other errors as indicated. 1834 1835 **/ 1836 EFI_STATUS 1837 MnpGroupOp ( 1838 IN OUT MNP_INSTANCE_DATA *Instance, 1839 IN BOOLEAN JoinFlag, 1840 IN EFI_MAC_ADDRESS *MacAddress OPTIONAL, 1841 IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk OPTIONAL 1842 ) 1843 { 1844 MNP_DEVICE_DATA *MnpDeviceData; 1845 LIST_ENTRY *Entry; 1846 LIST_ENTRY *NextEntry; 1847 MNP_GROUP_ADDRESS *GroupAddress; 1848 EFI_SIMPLE_NETWORK_MODE *SnpMode; 1849 MNP_GROUP_CONTROL_BLOCK *NewCtrlBlk; 1850 EFI_STATUS Status; 1851 BOOLEAN AddressExist; 1852 BOOLEAN NeedUpdate; 1853 1854 NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE); 1855 1856 MnpDeviceData = Instance->MnpServiceData->MnpDeviceData; 1857 SnpMode = MnpDeviceData->Snp->Mode; 1858 1859 if (JoinFlag) { 1860 // 1861 // A new gropu address is to be added. 1862 // 1863 GroupAddress = NULL; 1864 AddressExist = FALSE; 1865 1866 // 1867 // Allocate memory for the control block. 1868 // 1869 NewCtrlBlk = AllocatePool (sizeof (MNP_GROUP_CONTROL_BLOCK)); 1870 if (NewCtrlBlk == NULL) { 1871 DEBUG ((EFI_D_ERROR, "MnpGroupOp: Failed to allocate memory resource.\n")); 1872 1873 return EFI_OUT_OF_RESOURCES; 1874 } 1875 1876 NET_LIST_FOR_EACH (Entry, &MnpDeviceData->GroupAddressList) { 1877 // 1878 // Check whether the MacAddress is already joined by other instances. 1879 // 1880 GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry); 1881 if (CompareMem (MacAddress, &GroupAddress->Address, SnpMode->HwAddressSize) == 0) { 1882 AddressExist = TRUE; 1883 break; 1884 } 1885 } 1886 1887 if (!AddressExist) { 1888 GroupAddress = NULL; 1889 } 1890 1891 // 1892 // Add the GroupAddress for this instance. 1893 // 1894 Status = MnpGroupOpAddCtrlBlk ( 1895 Instance, 1896 NewCtrlBlk, 1897 GroupAddress, 1898 MacAddress, 1899 SnpMode->HwAddressSize 1900 ); 1901 if (EFI_ERROR (Status)) { 1902 return Status; 1903 } 1904 1905 NeedUpdate = TRUE; 1906 } else { 1907 if (MacAddress != NULL) { 1908 ASSERT (CtrlBlk != NULL); 1909 1910 // 1911 // Leave the specific multicast mac address. 1912 // 1913 NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, CtrlBlk); 1914 } else { 1915 // 1916 // Leave all multicast mac addresses. 1917 // 1918 NeedUpdate = FALSE; 1919 1920 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->GroupCtrlBlkList) { 1921 1922 NewCtrlBlk = NET_LIST_USER_STRUCT ( 1923 Entry, 1924 MNP_GROUP_CONTROL_BLOCK, 1925 CtrlBlkEntry 1926 ); 1927 // 1928 // Update is required if the group address left is no longer used 1929 // by other instances. 1930 // 1931 NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, NewCtrlBlk); 1932 } 1933 } 1934 } 1935 1936 Status = EFI_SUCCESS; 1937 1938 if (NeedUpdate) { 1939 // 1940 // Reconfigure the receive filters if necessary. 1941 // 1942 Status = MnpConfigReceiveFilters (MnpDeviceData); 1943 } 1944 1945 return Status; 1946 } 1947