2 Implementation of Managed Network Protocol private services.
4 Copyright (c) 2005 - 2012, 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
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.
19 EFI_SERVICE_BINDING_PROTOCOL mMnpServiceBindingProtocol
= {
20 MnpServiceBindingCreateChild
,
21 MnpServiceBindingDestroyChild
24 EFI_MANAGED_NETWORK_PROTOCOL mMnpProtocolTemplate
= {
35 EFI_MANAGED_NETWORK_CONFIG_DATA mMnpDefaultConfigData
= {
49 Add Count of net buffers to MnpDeviceData->FreeNbufQue. The length of the net
50 buffer is specified by MnpDeviceData->BufferLength.
52 @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
53 @param[in] Count Number of NET_BUFFERs to add.
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.
62 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
,
70 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
71 ASSERT ((Count
> 0) && (MnpDeviceData
->BufferLength
> 0));
74 for (Index
= 0; Index
< Count
; Index
++) {
75 Nbuf
= NetbufAlloc (MnpDeviceData
->BufferLength
+ MnpDeviceData
->PaddingSize
);
77 DEBUG ((EFI_D_ERROR
, "MnpAddFreeNbuf: NetBufAlloc failed.\n"));
79 Status
= EFI_OUT_OF_RESOURCES
;
83 if (MnpDeviceData
->PaddingSize
> 0) {
85 // Pad padding bytes before the media header
87 NetbufAllocSpace (Nbuf
, MnpDeviceData
->PaddingSize
, NET_BUF_TAIL
);
88 NetbufTrim (Nbuf
, MnpDeviceData
->PaddingSize
, NET_BUF_HEAD
);
91 NetbufQueAppend (&MnpDeviceData
->FreeNbufQue
, Nbuf
);
94 MnpDeviceData
->NbufCnt
+= Index
;
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.
104 @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
106 @return Pointer to the allocated free NET_BUF structure, if NULL the
112 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
116 NET_BUF_QUEUE
*FreeNbufQue
;
120 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
122 FreeNbufQue
= &MnpDeviceData
->FreeNbufQue
;
123 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
126 // Check whether there are available buffers, or else try to add some.
128 if (FreeNbufQue
->BufNum
== 0) {
129 if ((MnpDeviceData
->NbufCnt
+ MNP_NET_BUFFER_INCREASEMENT
) > MNP_MAX_NET_BUFFER_NUM
) {
132 "MnpAllocNbuf: The maximum NET_BUF size is reached for MNP driver instance %p.\n",
140 Status
= MnpAddFreeNbuf (MnpDeviceData
, MNP_NET_BUFFER_INCREASEMENT
);
141 if (EFI_ERROR (Status
)) {
144 "MnpAllocNbuf: Failed to add NET_BUFs into the FreeNbufQue, %r.\n",
149 // Don't return NULL, perhaps MnpAddFreeNbuf does add some NET_BUFs but
150 // the amount is less than MNP_NET_BUFFER_INCREASEMENT.
155 Nbuf
= NetbufQueRemove (FreeNbufQue
);
158 // Increase the RefCnt.
165 gBS
->RestoreTPL (OldTpl
);
172 Try to reclaim the Nbuf into the buffer pool.
174 @param[in, out] MnpDeviceData Pointer to the mnp device context data.
175 @param[in, out] Nbuf Pointer to the NET_BUF to free.
180 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
,
186 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
187 ASSERT (Nbuf
->RefCnt
> 1);
189 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
193 if (Nbuf
->RefCnt
== 1) {
195 // Trim all buffer contained in the Nbuf, then append it to the NbufQue.
197 NetbufTrim (Nbuf
, Nbuf
->TotalSize
, NET_BUF_TAIL
);
199 if (NetbufAllocSpace (Nbuf
, NET_VLAN_TAG_LEN
, NET_BUF_HEAD
) != NULL
) {
201 // There is space reserved for vlan tag in the head, reclaim it
203 NetbufTrim (Nbuf
, NET_VLAN_TAG_LEN
, NET_BUF_TAIL
);
206 NetbufQueAppend (&MnpDeviceData
->FreeNbufQue
, Nbuf
);
209 gBS
->RestoreTPL (OldTpl
);
214 Initialize the mnp device context data.
216 @param[in, out] MnpDeviceData Pointer to the mnp device context data.
217 @param[in] ImageHandle The driver image handle.
218 @param[in] ControllerHandle Handle of device to bind driver to.
220 @retval EFI_SUCCESS The mnp service context is initialized.
221 @retval EFI_UNSUPPORTED ControllerHandle does not support Simple Network Protocol.
222 @retval Others Other errors as indicated.
226 MnpInitializeDeviceData (
227 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
,
228 IN EFI_HANDLE ImageHandle
,
229 IN EFI_HANDLE ControllerHandle
233 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
234 EFI_SIMPLE_NETWORK_MODE
*SnpMode
;
236 MnpDeviceData
->Signature
= MNP_DEVICE_DATA_SIGNATURE
;
237 MnpDeviceData
->ImageHandle
= ImageHandle
;
238 MnpDeviceData
->ControllerHandle
= ControllerHandle
;
241 // Copy the MNP Protocol interfaces from the template.
243 CopyMem (&MnpDeviceData
->VlanConfig
, &mVlanConfigProtocolTemplate
, sizeof (EFI_VLAN_CONFIG_PROTOCOL
));
246 // Open the Simple Network protocol.
248 Status
= gBS
->OpenProtocol (
250 &gEfiSimpleNetworkProtocolGuid
,
254 EFI_OPEN_PROTOCOL_BY_DRIVER
256 if (EFI_ERROR (Status
)) {
257 return EFI_UNSUPPORTED
;
264 MnpDeviceData
->Snp
= Snp
;
267 // Initialize the lists.
269 InitializeListHead (&MnpDeviceData
->ServiceList
);
270 InitializeListHead (&MnpDeviceData
->GroupAddressList
);
273 // Get the buffer length used to allocate NET_BUF to hold data received
274 // from SNP. Do this before fill the FreeNetBufQue.
277 MnpDeviceData
->BufferLength
= SnpMode
->MediaHeaderSize
+ NET_VLAN_TAG_LEN
+ SnpMode
->MaxPacketSize
+ NET_ETHER_FCS_SIZE
;
280 // Make sure the protocol headers immediately following the media header
281 // 4-byte aligned, and also preserve additional space for VLAN tag
283 MnpDeviceData
->PaddingSize
= ((4 - SnpMode
->MediaHeaderSize
) & 0x3) + NET_VLAN_TAG_LEN
;
286 // Initialize MAC string which will be used as VLAN configuration variable name
288 Status
= NetLibGetMacString (ControllerHandle
, ImageHandle
, &MnpDeviceData
->MacString
);
289 if (EFI_ERROR (Status
)) {
294 // Initialize the FreeNetBufQue and pre-allocate some NET_BUFs.
296 NetbufQueInit (&MnpDeviceData
->FreeNbufQue
);
297 Status
= MnpAddFreeNbuf (MnpDeviceData
, MNP_INIT_NET_BUFFER_NUM
);
298 if (EFI_ERROR (Status
)) {
299 DEBUG ((EFI_D_ERROR
, "MnpInitializeDeviceData: MnpAddFreeNbuf failed, %r.\n", Status
));
305 // Get one NET_BUF from the FreeNbufQue for rx cache.
307 MnpDeviceData
->RxNbufCache
= MnpAllocNbuf (MnpDeviceData
);
309 MnpDeviceData
->RxNbufCache
,
310 MnpDeviceData
->BufferLength
,
315 // Allocate buffer pool for tx.
317 MnpDeviceData
->TxBuf
= AllocatePool (MnpDeviceData
->BufferLength
);
318 if (MnpDeviceData
->TxBuf
== NULL
) {
319 DEBUG ((EFI_D_ERROR
, "MnpInitializeDeviceData: AllocatePool failed.\n"));
321 Status
= EFI_OUT_OF_RESOURCES
;
326 // Create the system poll timer.
328 Status
= gBS
->CreateEvent (
329 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
333 &MnpDeviceData
->PollTimer
335 if (EFI_ERROR (Status
)) {
336 DEBUG ((EFI_D_ERROR
, "MnpInitializeDeviceData: CreateEvent for poll timer failed.\n"));
342 // Create the timer for packet timeout check.
344 Status
= gBS
->CreateEvent (
345 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
347 MnpCheckPacketTimeout
,
349 &MnpDeviceData
->TimeoutCheckTimer
351 if (EFI_ERROR (Status
)) {
352 DEBUG ((EFI_D_ERROR
, "MnpInitializeDeviceData: CreateEvent for packet timeout check failed.\n"));
358 // Create the timer for media detection.
360 Status
= gBS
->CreateEvent (
361 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
365 &MnpDeviceData
->MediaDetectTimer
367 if (EFI_ERROR (Status
)) {
368 DEBUG ((EFI_D_ERROR
, "MnpInitializeDeviceData: CreateEvent for media detection failed.\n"));
374 // Create the timer for tx timeout check.
376 Status
= gBS
->CreateEvent (
381 &MnpDeviceData
->TxTimeoutEvent
383 if (EFI_ERROR (Status
)) {
384 DEBUG ((EFI_D_ERROR
, "MnpInitializeDeviceData: CreateEvent for tx timeout event failed.\n"));
388 if (EFI_ERROR (Status
)) {
390 // Free the dynamic allocated resources if necessary.
392 if (MnpDeviceData
->MacString
!= NULL
) {
393 FreePool (MnpDeviceData
->MacString
);
396 if (MnpDeviceData
->TimeoutCheckTimer
!= NULL
) {
397 gBS
->CloseEvent (MnpDeviceData
->TimeoutCheckTimer
);
400 if (MnpDeviceData
->MediaDetectTimer
!= NULL
) {
401 gBS
->CloseEvent (MnpDeviceData
->MediaDetectTimer
);
404 if (MnpDeviceData
->PollTimer
!= NULL
) {
405 gBS
->CloseEvent (MnpDeviceData
->PollTimer
);
408 if (MnpDeviceData
->TxBuf
!= NULL
) {
409 FreePool (MnpDeviceData
->TxBuf
);
412 if (MnpDeviceData
->RxNbufCache
!= NULL
) {
413 MnpFreeNbuf (MnpDeviceData
, MnpDeviceData
->RxNbufCache
);
416 if (MnpDeviceData
->FreeNbufQue
.BufNum
!= 0) {
417 NetbufQueFlush (&MnpDeviceData
->FreeNbufQue
);
421 // Close the Simple Network Protocol.
425 &gEfiSimpleNetworkProtocolGuid
,
436 Destroy the MNP device context data.
438 @param[in, out] MnpDeviceData Pointer to the mnp device context data.
439 @param[in] ImageHandle The driver image handle.
443 MnpDestroyDeviceData (
444 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
,
445 IN EFI_HANDLE ImageHandle
448 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
451 // Free Vlan Config variable name string
453 if (MnpDeviceData
->MacString
!= NULL
) {
454 FreePool (MnpDeviceData
->MacString
);
458 // The GroupAddressList must be empty.
460 ASSERT (IsListEmpty (&MnpDeviceData
->GroupAddressList
));
465 gBS
->CloseEvent (MnpDeviceData
->TxTimeoutEvent
);
466 gBS
->CloseEvent (MnpDeviceData
->TimeoutCheckTimer
);
467 gBS
->CloseEvent (MnpDeviceData
->MediaDetectTimer
);
468 gBS
->CloseEvent (MnpDeviceData
->PollTimer
);
471 // Free the tx buffer.
473 FreePool (MnpDeviceData
->TxBuf
);
476 // Free the RxNbufCache.
478 MnpFreeNbuf (MnpDeviceData
, MnpDeviceData
->RxNbufCache
);
481 // Flush the FreeNbufQue.
483 MnpDeviceData
->NbufCnt
-= MnpDeviceData
->FreeNbufQue
.BufNum
;
484 NetbufQueFlush (&MnpDeviceData
->FreeNbufQue
);
487 // Close the Simple Network Protocol.
490 MnpDeviceData
->ControllerHandle
,
491 &gEfiSimpleNetworkProtocolGuid
,
493 MnpDeviceData
->ControllerHandle
499 Create mnp service context data.
501 @param[in] MnpDeviceData Pointer to the mnp device context data.
502 @param[in] VlanId The VLAN ID.
503 @param[in] Priority The VLAN priority. If VlanId is 0,
506 @return A pointer to MNP_SERVICE_DATA or NULL if failed to create MNP service context.
510 MnpCreateServiceData (
511 IN MNP_DEVICE_DATA
*MnpDeviceData
,
513 IN UINT8 Priority OPTIONAL
516 EFI_HANDLE MnpServiceHandle
;
517 MNP_SERVICE_DATA
*MnpServiceData
;
519 EFI_SIMPLE_NETWORK_MODE
*SnpMode
;
520 EFI_VLAN_CONFIG_PROTOCOL
*VlanConfig
;
523 // Initialize the Mnp Service Data.
525 MnpServiceData
= AllocateZeroPool (sizeof (MNP_SERVICE_DATA
));
526 if (MnpServiceData
== NULL
) {
527 DEBUG ((EFI_D_ERROR
, "MnpCreateServiceData: Faild to allocate memory for the new Mnp Service Data.\n"));
533 // Add to MNP service list
535 InsertTailList (&MnpDeviceData
->ServiceList
, &MnpServiceData
->Link
);
537 MnpServiceData
->Signature
= MNP_SERVICE_DATA_SIGNATURE
;
538 MnpServiceData
->MnpDeviceData
= MnpDeviceData
;
541 // Copy the ServiceBinding structure.
543 CopyMem (&MnpServiceData
->ServiceBinding
, &mMnpServiceBindingProtocol
, sizeof (EFI_SERVICE_BINDING_PROTOCOL
));
546 // Initialize the lists.
548 InitializeListHead (&MnpServiceData
->ChildrenList
);
550 SnpMode
= MnpDeviceData
->Snp
->Mode
;
553 // Create VLAN child handle
555 MnpServiceHandle
= MnpCreateVlanChild (
556 MnpDeviceData
->ImageHandle
,
557 MnpDeviceData
->ControllerHandle
,
559 &MnpServiceData
->DevicePath
561 if (MnpServiceHandle
== NULL
) {
562 DEBUG ((EFI_D_ERROR
, "MnpCreateServiceData: Faild to create child handle.\n"));
568 // Open VLAN Config Protocol by child
570 Status
= gBS
->OpenProtocol (
571 MnpDeviceData
->ControllerHandle
,
572 &gEfiVlanConfigProtocolGuid
,
573 (VOID
**) &VlanConfig
,
574 MnpDeviceData
->ImageHandle
,
576 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
578 if (EFI_ERROR (Status
)) {
583 // Reduce MTU for VLAN device
585 MnpServiceData
->Mtu
= SnpMode
->MaxPacketSize
- NET_VLAN_TAG_LEN
;
588 // VlanId set to 0 means rx/tx untagged frame
590 MnpServiceHandle
= MnpDeviceData
->ControllerHandle
;
591 MnpServiceData
->Mtu
= SnpMode
->MaxPacketSize
;
594 MnpServiceData
->ServiceHandle
= MnpServiceHandle
;
595 MnpServiceData
->VlanId
= VlanId
;
596 MnpServiceData
->Priority
= Priority
;
599 // Install the MNP Service Binding Protocol
601 Status
= gBS
->InstallMultipleProtocolInterfaces (
603 &gEfiManagedNetworkServiceBindingProtocolGuid
,
604 &MnpServiceData
->ServiceBinding
,
609 if (EFI_ERROR (Status
)) {
610 MnpDestroyServiceData (MnpServiceData
);
611 MnpServiceData
= NULL
;
614 return MnpServiceData
;
618 Destroy the MNP service context data.
620 @param[in, out] MnpServiceData Pointer to the mnp service context data.
622 @retval EFI_SUCCESS The mnp service context is destroyed.
623 @retval Others Errors as indicated.
627 MnpDestroyServiceData (
628 IN OUT MNP_SERVICE_DATA
*MnpServiceData
634 // Uninstall the MNP Service Binding Protocol
636 Status
= gBS
->UninstallMultipleProtocolInterfaces (
637 MnpServiceData
->ServiceHandle
,
638 &gEfiManagedNetworkServiceBindingProtocolGuid
,
639 &MnpServiceData
->ServiceBinding
,
642 if (EFI_ERROR (Status
)) {
646 if (MnpServiceData
->VlanId
!= 0) {
648 // Close VlanConfig Protocol opened by VLAN child handle
650 Status
= gBS
->CloseProtocol (
651 MnpServiceData
->MnpDeviceData
->ControllerHandle
,
652 &gEfiVlanConfigProtocolGuid
,
653 MnpServiceData
->MnpDeviceData
->ImageHandle
,
654 MnpServiceData
->ServiceHandle
656 if (EFI_ERROR (Status
)) {
661 // Uninstall Device Path Protocol to destroy the VLAN child handle
663 Status
= gBS
->UninstallMultipleProtocolInterfaces (
664 MnpServiceData
->ServiceHandle
,
665 &gEfiDevicePathProtocolGuid
,
666 MnpServiceData
->DevicePath
,
669 if (EFI_ERROR (Status
)) {
673 if (MnpServiceData
->DevicePath
!= NULL
) {
674 FreePool (MnpServiceData
->DevicePath
);
679 // Remove from MnpDeviceData service list
681 RemoveEntryList (&MnpServiceData
->Link
);
683 FreePool (MnpServiceData
);
689 Callback function which provided by user to remove one node in NetDestroyLinkList process.
691 @param[in] Entry The entry to be removed.
692 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
694 @retval EFI_SUCCESS The entry has been removed successfully.
695 @retval Others Fail to remove the entry.
700 MnpDestoryChildEntry (
701 IN LIST_ENTRY
*Entry
,
705 MNP_INSTANCE_DATA
*Instance
;
706 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
708 ServiceBinding
= (EFI_SERVICE_BINDING_PROTOCOL
*) Context
;
709 Instance
= CR (Entry
, MNP_INSTANCE_DATA
, InstEntry
, MNP_INSTANCE_DATA_SIGNATURE
);
710 return ServiceBinding
->DestroyChild (ServiceBinding
, Instance
->Handle
);
714 Destroy all child of the MNP service data.
716 @param[in, out] MnpServiceData Pointer to the mnp service context data.
718 @retval EFI_SUCCESS All child are destroyed.
719 @retval Others Failed to destroy all child.
723 MnpDestroyServiceChild (
724 IN OUT MNP_SERVICE_DATA
*MnpServiceData
731 List
= &MnpServiceData
->ChildrenList
;
733 Status
= NetDestroyLinkList (
735 MnpDestoryChildEntry
,
736 &MnpServiceData
->ServiceBinding
,
739 if (EFI_ERROR (Status
) || ListLength
!= 0) {
740 return EFI_DEVICE_ERROR
;
747 Find the MNP Service Data for given VLAN ID.
749 @param[in] MnpDeviceData Pointer to the mnp device context data.
750 @param[in] VlanId The VLAN ID.
752 @return A pointer to MNP_SERVICE_DATA or NULL if not found.
757 IN MNP_DEVICE_DATA
*MnpDeviceData
,
762 MNP_SERVICE_DATA
*MnpServiceData
;
764 NET_LIST_FOR_EACH (Entry
, &MnpDeviceData
->ServiceList
) {
766 // Check VLAN ID of each Mnp Service Data
768 MnpServiceData
= MNP_SERVICE_DATA_FROM_LINK (Entry
);
769 if (MnpServiceData
->VlanId
== VlanId
) {
770 return MnpServiceData
;
778 Initialize the mnp instance context data.
780 @param[in] MnpServiceData Pointer to the mnp service context data.
781 @param[in, out] Instance Pointer to the mnp instance context data
786 MnpInitializeInstanceData (
787 IN MNP_SERVICE_DATA
*MnpServiceData
,
788 IN OUT MNP_INSTANCE_DATA
*Instance
791 NET_CHECK_SIGNATURE (MnpServiceData
, MNP_SERVICE_DATA_SIGNATURE
);
792 ASSERT (Instance
!= NULL
);
795 // Set the signature.
797 Instance
->Signature
= MNP_INSTANCE_DATA_SIGNATURE
;
800 // Copy the MNP Protocol interfaces from the template.
802 CopyMem (&Instance
->ManagedNetwork
, &mMnpProtocolTemplate
, sizeof (Instance
->ManagedNetwork
));
805 // Copy the default config data.
807 CopyMem (&Instance
->ConfigData
, &mMnpDefaultConfigData
, sizeof (Instance
->ConfigData
));
810 // Initialize the lists.
812 InitializeListHead (&Instance
->GroupCtrlBlkList
);
813 InitializeListHead (&Instance
->RcvdPacketQueue
);
814 InitializeListHead (&Instance
->RxDeliveredPacketQueue
);
817 // Initialize the RxToken Map.
819 NetMapInit (&Instance
->RxTokenMap
);
822 // Save the MnpServiceData info.
824 Instance
->MnpServiceData
= MnpServiceData
;
829 Check whether the token specified by Arg matches the token in Item.
831 @param[in] Map Pointer to the NET_MAP.
832 @param[in] Item Pointer to the NET_MAP_ITEM.
833 @param[in] Arg Pointer to the Arg, it's a pointer to the token to
836 @retval EFI_SUCCESS The token specified by Arg is different from the
838 @retval EFI_ACCESS_DENIED The token specified by Arg is the same as that in
846 IN NET_MAP_ITEM
*Item
,
850 EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*Token
;
851 EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*TokenInItem
;
853 Token
= (EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*) Arg
;
854 TokenInItem
= (EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*) Item
->Key
;
856 if ((Token
== TokenInItem
) || (Token
->Event
== TokenInItem
->Event
)) {
858 // The token is the same either the two tokens equals or the Events in
859 // the two tokens are the same.
861 return EFI_ACCESS_DENIED
;
868 Cancel the token specified by Arg if it matches the token in Item.
870 @param[in, out] Map Pointer to the NET_MAP.
871 @param[in, out] Item Pointer to the NET_MAP_ITEM.
872 @param[in] Arg Pointer to the Arg, it's a pointer to the
875 @retval EFI_SUCCESS The Arg is NULL, and the token in Item is cancelled,
876 or the Arg isn't NULL, and the token in Item is
877 different from the Arg.
878 @retval EFI_ABORTED The Arg isn't NULL, the token in Item mathces the
879 Arg, and the token is cancelled.
886 IN OUT NET_MAP_ITEM
*Item
,
890 EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*TokenToCancel
;
892 if ((Arg
!= NULL
) && (Item
->Key
!= Arg
)) {
894 // The token in Item is not the token specified by Arg.
899 TokenToCancel
= (EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*) Item
->Key
;
902 // Remove the item from the map.
904 NetMapRemoveItem (Map
, Item
, NULL
);
907 // Cancel this token with status set to EFI_ABORTED.
909 TokenToCancel
->Status
= EFI_ABORTED
;
910 gBS
->SignalEvent (TokenToCancel
->Event
);
914 // Only abort the token specified by Arg if Arg isn't NULL.
924 Start and initialize the simple network.
926 @param[in] Snp Pointer to the simple network protocol.
928 @retval EFI_SUCCESS The simple network protocol is started.
929 @retval Others Other errors as indicated.
934 IN EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
939 ASSERT (Snp
!= NULL
);
942 // Start the simple network.
944 Status
= Snp
->Start (Snp
);
946 if (!EFI_ERROR (Status
)) {
948 // Initialize the simple network.
950 Status
= Snp
->Initialize (Snp
, 0, 0);
958 Stop the simple network.
960 @param[in] Snp Pointer to the simple network protocol.
962 @retval EFI_SUCCESS The simple network is stopped.
963 @retval Others Other errors as indicated.
968 IN EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
973 ASSERT (Snp
!= NULL
);
976 // Shut down the simple network.
978 Status
= Snp
->Shutdown (Snp
);
979 if (!EFI_ERROR (Status
)) {
981 // Stop the simple network.
983 Status
= Snp
->Stop (Snp
);
991 Start the managed network, this function is called when one instance is configured
994 @param[in, out] MnpServiceData Pointer to the mnp service context data.
995 @param[in] IsConfigUpdate The instance is reconfigured or it's the first
996 time the instanced is configured.
997 @param[in] EnableSystemPoll Enable the system polling or not.
999 @retval EFI_SUCCESS The managed network is started and some
1000 configuration is updated.
1001 @retval Others Other errors as indicated.
1006 IN OUT MNP_SERVICE_DATA
*MnpServiceData
,
1007 IN BOOLEAN IsConfigUpdate
,
1008 IN BOOLEAN EnableSystemPoll
1012 EFI_TIMER_DELAY TimerOpType
;
1013 MNP_DEVICE_DATA
*MnpDeviceData
;
1015 NET_CHECK_SIGNATURE (MnpServiceData
, MNP_SERVICE_DATA_SIGNATURE
);
1017 Status
= EFI_SUCCESS
;
1018 MnpDeviceData
= MnpServiceData
->MnpDeviceData
;
1020 if (!IsConfigUpdate
) {
1022 // If it's not a configuration update, increase the configured children number.
1024 MnpDeviceData
->ConfiguredChildrenNumber
++;
1026 if (MnpDeviceData
->ConfiguredChildrenNumber
== 1) {
1028 // It's the first configured child, start the simple network.
1030 Status
= MnpStartSnp (MnpDeviceData
->Snp
);
1031 if (EFI_ERROR (Status
)) {
1032 DEBUG ((EFI_D_ERROR
, "MnpStart: MnpStartSnp failed, %r.\n", Status
));
1038 // Start the timeout timer.
1040 Status
= gBS
->SetTimer (
1041 MnpDeviceData
->TimeoutCheckTimer
,
1043 MNP_TIMEOUT_CHECK_INTERVAL
1045 if (EFI_ERROR (Status
)) {
1048 "MnpStart, gBS->SetTimer for TimeoutCheckTimer %r.\n",
1056 // Start the media detection timer.
1058 Status
= gBS
->SetTimer (
1059 MnpDeviceData
->MediaDetectTimer
,
1061 MNP_MEDIA_DETECT_INTERVAL
1063 if (EFI_ERROR (Status
)) {
1066 "MnpStart, gBS->SetTimer for MediaDetectTimer %r.\n",
1075 if (MnpDeviceData
->EnableSystemPoll
^ EnableSystemPoll
) {
1077 // The EnableSystemPoll differs with the current state, disable or enable
1080 TimerOpType
= EnableSystemPoll
? TimerPeriodic
: TimerCancel
;
1082 Status
= gBS
->SetTimer (MnpDeviceData
->PollTimer
, TimerOpType
, MNP_SYS_POLL_INTERVAL
);
1083 if (EFI_ERROR (Status
)) {
1084 DEBUG ((EFI_D_ERROR
, "MnpStart: gBS->SetTimer for PollTimer failed, %r.\n", Status
));
1089 MnpDeviceData
->EnableSystemPoll
= EnableSystemPoll
;
1093 // Change the receive filters if need.
1095 Status
= MnpConfigReceiveFilters (MnpDeviceData
);
1103 Stop the managed network.
1105 @param[in, out] MnpServiceData Pointer to the mnp service context data.
1107 @retval EFI_SUCCESS The managed network is stopped.
1108 @retval Others Other errors as indicated.
1113 IN OUT MNP_SERVICE_DATA
*MnpServiceData
1117 MNP_DEVICE_DATA
*MnpDeviceData
;
1119 NET_CHECK_SIGNATURE (MnpServiceData
, MNP_SERVICE_DATA_SIGNATURE
);
1120 MnpDeviceData
= MnpServiceData
->MnpDeviceData
;
1121 ASSERT (MnpDeviceData
->ConfiguredChildrenNumber
> 0);
1124 // Configure the receive filters.
1126 MnpConfigReceiveFilters (MnpDeviceData
);
1129 // Decrease the children number.
1131 MnpDeviceData
->ConfiguredChildrenNumber
--;
1133 if (MnpDeviceData
->ConfiguredChildrenNumber
> 0) {
1135 // If there are other configured chilren, return and keep the timers and
1136 // simple network unchanged.
1142 // No configured children now.
1144 if (MnpDeviceData
->EnableSystemPoll
) {
1146 // The system poll in on, cancel the poll timer.
1148 Status
= gBS
->SetTimer (MnpDeviceData
->PollTimer
, TimerCancel
, 0);
1149 MnpDeviceData
->EnableSystemPoll
= FALSE
;
1153 // Cancel the timeout timer.
1155 Status
= gBS
->SetTimer (MnpDeviceData
->TimeoutCheckTimer
, TimerCancel
, 0);
1158 // Cancel the media detect timer.
1160 Status
= gBS
->SetTimer (MnpDeviceData
->MediaDetectTimer
, TimerCancel
, 0);
1163 // Stop the simple network.
1165 Status
= MnpStopSnp (MnpDeviceData
->Snp
);
1171 Flush the instance's received data.
1173 @param[in, out] Instance Pointer to the mnp instance context data.
1177 MnpFlushRcvdDataQueue (
1178 IN OUT MNP_INSTANCE_DATA
*Instance
1182 MNP_RXDATA_WRAP
*RxDataWrap
;
1184 NET_CHECK_SIGNATURE (Instance
, MNP_INSTANCE_DATA_SIGNATURE
);
1186 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1188 while (!IsListEmpty (&Instance
->RcvdPacketQueue
)) {
1190 // Remove all the Wraps.
1192 RxDataWrap
= NET_LIST_HEAD (&Instance
->RcvdPacketQueue
, MNP_RXDATA_WRAP
, WrapEntry
);
1195 // Recycle the RxDataWrap.
1197 MnpRecycleRxData (NULL
, (VOID
*) RxDataWrap
);
1198 Instance
->RcvdPacketQueueSize
--;
1201 ASSERT (Instance
->RcvdPacketQueueSize
== 0);
1203 gBS
->RestoreTPL (OldTpl
);
1208 Configure the Instance using ConfigData.
1210 @param[in, out] Instance Pointer to the mnp instance context data.
1211 @param[in] ConfigData Pointer to the configuration data used to configure
1214 @retval EFI_SUCCESS The Instance is configured.
1215 @retval EFI_UNSUPPORTED EnableReceiveTimestamps is on and the
1216 implementation doesn't support it.
1217 @retval Others Other errors as indicated.
1221 MnpConfigureInstance (
1222 IN OUT MNP_INSTANCE_DATA
*Instance
,
1223 IN EFI_MANAGED_NETWORK_CONFIG_DATA
*ConfigData OPTIONAL
1227 MNP_SERVICE_DATA
*MnpServiceData
;
1228 MNP_DEVICE_DATA
*MnpDeviceData
;
1229 EFI_MANAGED_NETWORK_CONFIG_DATA
*OldConfigData
;
1230 EFI_MANAGED_NETWORK_CONFIG_DATA
*NewConfigData
;
1231 BOOLEAN IsConfigUpdate
;
1233 NET_CHECK_SIGNATURE (Instance
, MNP_INSTANCE_DATA_SIGNATURE
);
1235 if ((ConfigData
!= NULL
) && ConfigData
->EnableReceiveTimestamps
) {
1237 // Don't support timestamp.
1239 return EFI_UNSUPPORTED
;
1242 Status
= EFI_SUCCESS
;
1244 MnpServiceData
= Instance
->MnpServiceData
;
1245 MnpDeviceData
= MnpServiceData
->MnpDeviceData
;
1246 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
1248 IsConfigUpdate
= (BOOLEAN
) ((Instance
->Configured
) && (ConfigData
!= NULL
));
1250 OldConfigData
= &Instance
->ConfigData
;
1251 NewConfigData
= ConfigData
;
1252 if (NewConfigData
== NULL
) {
1254 // Restore back the default config data if a reset of this instance
1257 NewConfigData
= &mMnpDefaultConfigData
;
1261 // Reset the instance's receive filter.
1263 Instance
->ReceiveFilter
= 0;
1266 // Clear the receive counters according to the old ConfigData.
1268 if (OldConfigData
->EnableUnicastReceive
) {
1269 MnpDeviceData
->UnicastCount
--;
1272 if (OldConfigData
->EnableMulticastReceive
) {
1273 MnpDeviceData
->MulticastCount
--;
1276 if (OldConfigData
->EnableBroadcastReceive
) {
1277 MnpDeviceData
->BroadcastCount
--;
1280 if (OldConfigData
->EnablePromiscuousReceive
) {
1281 MnpDeviceData
->PromiscuousCount
--;
1285 // Set the receive filter counters and the receive filter of the
1286 // instance according to the new ConfigData.
1288 if (NewConfigData
->EnableUnicastReceive
) {
1289 MnpDeviceData
->UnicastCount
++;
1290 Instance
->ReceiveFilter
|= MNP_RECEIVE_UNICAST
;
1293 if (NewConfigData
->EnableMulticastReceive
) {
1294 MnpDeviceData
->MulticastCount
++;
1297 if (NewConfigData
->EnableBroadcastReceive
) {
1298 MnpDeviceData
->BroadcastCount
++;
1299 Instance
->ReceiveFilter
|= MNP_RECEIVE_BROADCAST
;
1302 if (NewConfigData
->EnablePromiscuousReceive
) {
1303 MnpDeviceData
->PromiscuousCount
++;
1306 if (OldConfigData
->FlushQueuesOnReset
) {
1307 MnpFlushRcvdDataQueue (Instance
);
1310 if (ConfigData
== NULL
) {
1311 Instance
->ManagedNetwork
.Cancel (&Instance
->ManagedNetwork
, NULL
);
1314 if (!NewConfigData
->EnableMulticastReceive
) {
1315 MnpGroupOp (Instance
, FALSE
, NULL
, NULL
);
1319 // Save the new configuration data.
1321 CopyMem (OldConfigData
, NewConfigData
, sizeof (*OldConfigData
));
1323 Instance
->Configured
= (BOOLEAN
) (ConfigData
!= NULL
);
1324 if (Instance
->Configured
) {
1326 // The instance is configured, start the Mnp.
1331 (BOOLEAN
) !NewConfigData
->DisableBackgroundPolling
1335 // The instance is changed to the unconfigured state, stop the Mnp.
1337 Status
= MnpStop (MnpServiceData
);
1344 Configure the Snp receive filters according to the instances' receive filter
1347 @param[in] MnpDeviceData Pointer to the mnp device context data.
1349 @retval EFI_SUCCESS The receive filters is configured.
1350 @retval EFI_OUT_OF_RESOURCES The receive filters can't be configured due
1351 to lack of memory resource.
1355 MnpConfigReceiveFilters (
1356 IN MNP_DEVICE_DATA
*MnpDeviceData
1360 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1361 EFI_MAC_ADDRESS
*MCastFilter
;
1362 UINT32 MCastFilterCnt
;
1363 UINT32 EnableFilterBits
;
1364 UINT32 DisableFilterBits
;
1365 BOOLEAN ResetMCastFilters
;
1368 MNP_GROUP_ADDRESS
*GroupAddress
;
1370 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
1372 Snp
= MnpDeviceData
->Snp
;
1375 // Initialize the enable filter and disable filter.
1377 EnableFilterBits
= 0;
1378 DisableFilterBits
= Snp
->Mode
->ReceiveFilterMask
;
1380 if (MnpDeviceData
->UnicastCount
!= 0) {
1382 // Enable unicast if any instance wants to receive unicast.
1384 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
1387 if (MnpDeviceData
->BroadcastCount
!= 0) {
1389 // Enable broadcast if any instance wants to receive broadcast.
1391 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
1396 ResetMCastFilters
= TRUE
;
1398 if ((MnpDeviceData
->MulticastCount
!= 0) && (MnpDeviceData
->GroupAddressCount
!= 0)) {
1400 // There are instances configured to receive multicast and already some group
1401 // addresses are joined.
1404 ResetMCastFilters
= FALSE
;
1406 if (MnpDeviceData
->GroupAddressCount
<= Snp
->Mode
->MaxMCastFilterCount
) {
1408 // The joind group address is less than simple network's maximum count.
1409 // Just configure the snp to do the multicast filtering.
1412 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
;
1415 // Allocate pool for the mulicast addresses.
1417 MCastFilterCnt
= MnpDeviceData
->GroupAddressCount
;
1418 MCastFilter
= AllocatePool (sizeof (EFI_MAC_ADDRESS
) * MCastFilterCnt
);
1419 if (MCastFilter
== NULL
) {
1420 DEBUG ((EFI_D_ERROR
, "MnpConfigReceiveFilters: Failed to allocate memory resource for MCastFilter.\n"));
1422 return EFI_OUT_OF_RESOURCES
;
1426 // Fill the multicast HW address buffer.
1429 NET_LIST_FOR_EACH (Entry
, &MnpDeviceData
->GroupAddressList
) {
1431 GroupAddress
= NET_LIST_USER_STRUCT (Entry
, MNP_GROUP_ADDRESS
, AddrEntry
);
1432 CopyMem (MCastFilter
+ Index
, &GroupAddress
->Address
, sizeof (*(MCastFilter
+ Index
)));
1435 ASSERT (Index
<= MCastFilterCnt
);
1439 // The maximum multicast is reached, set the filter to be promiscuous
1443 if ((Snp
->Mode
->ReceiveFilterMask
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
) != 0) {
1444 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
1447 // Either MULTICAST or PROMISCUOUS_MULTICAST is not supported by Snp,
1448 // set the NIC to be promiscuous although this will tremendously degrade
1451 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
1456 if (MnpDeviceData
->PromiscuousCount
!= 0) {
1458 // Enable promiscuous if any instance wants to receive promiscuous.
1460 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
1464 // Set the disable filter.
1466 DisableFilterBits
^= EnableFilterBits
;
1469 // Configure the receive filters of SNP.
1471 Status
= Snp
->ReceiveFilters (
1480 if (EFI_ERROR (Status
)) {
1483 "MnpConfigReceiveFilters: Snp->ReceiveFilters failed, %r.\n",
1489 if (MCastFilter
!= NULL
) {
1491 // Free the buffer used to hold the group addresses.
1493 FreePool (MCastFilter
);
1501 Add a group address control block which controls the MacAddress for
1504 @param[in, out] Instance Pointer to the mnp instance context data.
1505 @param[in, out] CtrlBlk Pointer to the group address control block.
1506 @param[in, out] GroupAddress Pointer to the group adress.
1507 @param[in] MacAddress Pointer to the mac address.
1508 @param[in] HwAddressSize The hardware address size.
1510 @retval EFI_SUCCESS The group address control block is added.
1511 @retval EFI_OUT_OF_RESOURCES Failed due to lack of memory resources.
1515 MnpGroupOpAddCtrlBlk (
1516 IN OUT MNP_INSTANCE_DATA
*Instance
,
1517 IN OUT MNP_GROUP_CONTROL_BLOCK
*CtrlBlk
,
1518 IN OUT MNP_GROUP_ADDRESS
*GroupAddress OPTIONAL
,
1519 IN EFI_MAC_ADDRESS
*MacAddress
,
1520 IN UINT32 HwAddressSize
1523 MNP_DEVICE_DATA
*MnpDeviceData
;
1525 NET_CHECK_SIGNATURE (Instance
, MNP_INSTANCE_DATA_SIGNATURE
);
1527 MnpDeviceData
= Instance
->MnpServiceData
->MnpDeviceData
;
1528 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
1530 if (GroupAddress
== NULL
) {
1531 ASSERT (MacAddress
!= NULL
);
1534 // Allocate a new GroupAddress to be added into MNP's GroupAddressList.
1536 GroupAddress
= AllocatePool (sizeof (MNP_GROUP_ADDRESS
));
1537 if (GroupAddress
== NULL
) {
1539 DEBUG ((EFI_D_ERROR
, "MnpGroupOpFormCtrlBlk: Failed to allocate memory resource.\n"));
1541 return EFI_OUT_OF_RESOURCES
;
1544 CopyMem (&GroupAddress
->Address
, MacAddress
, sizeof (GroupAddress
->Address
));
1545 GroupAddress
->RefCnt
= 0;
1547 &MnpDeviceData
->GroupAddressList
,
1548 &GroupAddress
->AddrEntry
1550 MnpDeviceData
->GroupAddressCount
++;
1554 // Increase the RefCnt.
1556 GroupAddress
->RefCnt
++;
1559 // Add the CtrlBlk into the instance's GroupCtrlBlkList.
1561 CtrlBlk
->GroupAddress
= GroupAddress
;
1562 InsertTailList (&Instance
->GroupCtrlBlkList
, &CtrlBlk
->CtrlBlkEntry
);
1569 Delete a group control block from the instance. If the controlled group address's
1570 reference count reaches zero, the group address is removed too.
1572 @param[in] Instance Pointer to the instance context data.
1573 @param[in] CtrlBlk Pointer to the group control block to delete.
1575 @return The group address controlled by the control block is no longer used or not.
1579 MnpGroupOpDelCtrlBlk (
1580 IN MNP_INSTANCE_DATA
*Instance
,
1581 IN MNP_GROUP_CONTROL_BLOCK
*CtrlBlk
1584 MNP_DEVICE_DATA
*MnpDeviceData
;
1585 MNP_GROUP_ADDRESS
*GroupAddress
;
1587 NET_CHECK_SIGNATURE (Instance
, MNP_INSTANCE_DATA_SIGNATURE
);
1589 MnpDeviceData
= Instance
->MnpServiceData
->MnpDeviceData
;
1590 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
1593 // Remove and free the CtrlBlk.
1595 GroupAddress
= CtrlBlk
->GroupAddress
;
1596 RemoveEntryList (&CtrlBlk
->CtrlBlkEntry
);
1599 ASSERT (GroupAddress
->RefCnt
> 0);
1602 // Count down the RefCnt.
1604 GroupAddress
->RefCnt
--;
1606 if (GroupAddress
->RefCnt
== 0) {
1608 // Free this GroupAddress entry if no instance uses it.
1610 MnpDeviceData
->GroupAddressCount
--;
1611 RemoveEntryList (&GroupAddress
->AddrEntry
);
1612 FreePool (GroupAddress
);
1622 Do the group operations for this instance.
1624 @param[in, out] Instance Pointer to the instance context data.
1625 @param[in] JoinFlag Set to TRUE to join a group. Set to TRUE to
1626 leave a group/groups.
1627 @param[in] MacAddress Pointer to the group address to join or leave.
1628 @param[in] CtrlBlk Pointer to the group control block if JoinFlag
1631 @retval EFI_SUCCESS The group operation finished.
1632 @retval EFI_OUT_OF_RESOURCES Failed due to lack of memory resources.
1633 @retval Others Other errors as indicated.
1638 IN OUT MNP_INSTANCE_DATA
*Instance
,
1639 IN BOOLEAN JoinFlag
,
1640 IN EFI_MAC_ADDRESS
*MacAddress OPTIONAL
,
1641 IN MNP_GROUP_CONTROL_BLOCK
*CtrlBlk OPTIONAL
1644 MNP_DEVICE_DATA
*MnpDeviceData
;
1646 LIST_ENTRY
*NextEntry
;
1647 MNP_GROUP_ADDRESS
*GroupAddress
;
1648 EFI_SIMPLE_NETWORK_MODE
*SnpMode
;
1649 MNP_GROUP_CONTROL_BLOCK
*NewCtrlBlk
;
1651 BOOLEAN AddressExist
;
1654 NET_CHECK_SIGNATURE (Instance
, MNP_INSTANCE_DATA_SIGNATURE
);
1656 MnpDeviceData
= Instance
->MnpServiceData
->MnpDeviceData
;
1657 SnpMode
= MnpDeviceData
->Snp
->Mode
;
1661 // A new gropu address is to be added.
1663 GroupAddress
= NULL
;
1664 AddressExist
= FALSE
;
1667 // Allocate memory for the control block.
1669 NewCtrlBlk
= AllocatePool (sizeof (MNP_GROUP_CONTROL_BLOCK
));
1670 if (NewCtrlBlk
== NULL
) {
1671 DEBUG ((EFI_D_ERROR
, "MnpGroupOp: Failed to allocate memory resource.\n"));
1673 return EFI_OUT_OF_RESOURCES
;
1676 NET_LIST_FOR_EACH (Entry
, &MnpDeviceData
->GroupAddressList
) {
1678 // Check whether the MacAddress is already joined by other instances.
1680 GroupAddress
= NET_LIST_USER_STRUCT (Entry
, MNP_GROUP_ADDRESS
, AddrEntry
);
1681 if (CompareMem (MacAddress
, &GroupAddress
->Address
, SnpMode
->HwAddressSize
) == 0) {
1682 AddressExist
= TRUE
;
1687 if (!AddressExist
) {
1688 GroupAddress
= NULL
;
1692 // Add the GroupAddress for this instance.
1694 Status
= MnpGroupOpAddCtrlBlk (
1699 SnpMode
->HwAddressSize
1701 if (EFI_ERROR (Status
)) {
1707 if (MacAddress
!= NULL
) {
1708 ASSERT (CtrlBlk
!= NULL
);
1711 // Leave the specific multicast mac address.
1713 NeedUpdate
= MnpGroupOpDelCtrlBlk (Instance
, CtrlBlk
);
1716 // Leave all multicast mac addresses.
1720 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &Instance
->GroupCtrlBlkList
) {
1722 NewCtrlBlk
= NET_LIST_USER_STRUCT (
1724 MNP_GROUP_CONTROL_BLOCK
,
1728 // Update is required if the group address left is no longer used
1729 // by other instances.
1731 NeedUpdate
= MnpGroupOpDelCtrlBlk (Instance
, NewCtrlBlk
);
1736 Status
= EFI_SUCCESS
;
1740 // Reconfigure the receive filters if necessary.
1742 Status
= MnpConfigReceiveFilters (MnpDeviceData
);