2 Implementation of Managed Network Protocol private services.
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
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
);
213 Add Count of TX buffers to MnpDeviceData->AllTxBufList and MnpDeviceData->FreeTxBufList.
214 The length of the buffer is specified by MnpDeviceData->BufferLength.
216 @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
217 @param[in] Count Number of TX buffers to add.
219 @retval EFI_SUCCESS The specified amount of TX buffers are allocated.
220 @retval EFI_OUT_OF_RESOURCES Failed to allocate a TX buffer.
225 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
,
231 MNP_TX_BUF_WRAP
*TxBufWrap
;
233 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
234 ASSERT ((Count
> 0) && (MnpDeviceData
->BufferLength
> 0));
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"));
242 Status
= EFI_OUT_OF_RESOURCES
;
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
);
252 MnpDeviceData
->TxBufCount
+= Index
;
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.
261 @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
263 @return Pointer to the allocated free NET_BUF structure, if NULL the
269 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
276 MNP_TX_BUF_WRAP
*TxBufWrap
;
278 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
280 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
282 if (IsListEmpty (&MnpDeviceData
->FreeTxBufList
)) {
284 // First try to recycle some TX buffer from SNP
286 Status
= MnpRecycleTxBuf (MnpDeviceData
);
287 if (EFI_ERROR (Status
)) {
293 // If still no free TX buffer, allocate more.
295 if (IsListEmpty (&MnpDeviceData
->FreeTxBufList
)) {
296 if ((MnpDeviceData
->TxBufCount
+ MNP_TX_BUFFER_INCREASEMENT
) > MNP_MAX_TX_BUFFER_NUM
) {
299 "MnpAllocTxBuf: The maximum TxBuf size is reached for MNP driver instance %p.\n",
307 Status
= MnpAddFreeTxBuf (MnpDeviceData
, MNP_TX_BUFFER_INCREASEMENT
);
308 if (IsListEmpty (&MnpDeviceData
->FreeTxBufList
)) {
311 "MnpAllocNbuf: Failed to add TxBuf into the FreeTxBufList, %r.\n",
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
;
329 gBS
->RestoreTPL (OldTpl
);
335 Try to reclaim the TX buffer into the buffer pool.
337 @param[in, out] MnpDeviceData Pointer to the mnp device context data.
338 @param[in, out] TxBuf Pointer to the TX buffer to free.
343 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
,
347 MNP_TX_BUF_WRAP
*TxBufWrap
;
350 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
356 TxBufWrap
= NET_LIST_USER_STRUCT (TxBuf
, MNP_TX_BUF_WRAP
, TxBuf
);
357 if (TxBufWrap
->Signature
!= MNP_TX_BUF_WRAP_SIGNATURE
) {
360 "MnpFreeTxBuf: Signature check failed in MnpFreeTxBuf.\n")
365 if (!TxBufWrap
->InUse
) {
368 "MnpFreeTxBuf: Duplicated recycle report from SNP.\n")
373 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
374 InsertTailList (&MnpDeviceData
->FreeTxBufList
, &TxBufWrap
->WrapEntry
);
375 TxBufWrap
->InUse
= FALSE
;
376 gBS
->RestoreTPL (OldTpl
);
380 Try to recycle all the transmitted buffer address from SNP.
382 @param[in, out] MnpDeviceData Pointer to the mnp device context data.
384 @retval EFI_SUCCESS Successed to recyclethe transmitted buffer address.
385 @retval Others Failed to recyclethe transmitted buffer address.
390 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
394 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
397 Snp
= MnpDeviceData
->Snp
;
398 ASSERT (Snp
!= NULL
);
402 Status
= Snp
->GetStatus (Snp
, NULL
, (VOID
**) &TxBuf
);
403 if (EFI_ERROR (Status
)) {
408 MnpFreeTxBuf (MnpDeviceData
, TxBuf
);
410 } while (TxBuf
!= NULL
);
416 Initialize the mnp device context data.
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.
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.
428 MnpInitializeDeviceData (
429 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
,
430 IN EFI_HANDLE ImageHandle
,
431 IN EFI_HANDLE ControllerHandle
435 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
436 EFI_SIMPLE_NETWORK_MODE
*SnpMode
;
438 MnpDeviceData
->Signature
= MNP_DEVICE_DATA_SIGNATURE
;
439 MnpDeviceData
->ImageHandle
= ImageHandle
;
440 MnpDeviceData
->ControllerHandle
= ControllerHandle
;
443 // Copy the MNP Protocol interfaces from the template.
445 CopyMem (&MnpDeviceData
->VlanConfig
, &mVlanConfigProtocolTemplate
, sizeof (EFI_VLAN_CONFIG_PROTOCOL
));
448 // Open the Simple Network protocol.
450 Status
= gBS
->OpenProtocol (
452 &gEfiSimpleNetworkProtocolGuid
,
456 EFI_OPEN_PROTOCOL_BY_DRIVER
458 if (EFI_ERROR (Status
)) {
459 return EFI_UNSUPPORTED
;
466 MnpDeviceData
->Snp
= Snp
;
469 // Initialize the lists.
471 InitializeListHead (&MnpDeviceData
->ServiceList
);
472 InitializeListHead (&MnpDeviceData
->GroupAddressList
);
475 // Get the buffer length used to allocate NET_BUF to hold data received
476 // from SNP. Do this before fill the FreeNetBufQue.
479 MnpDeviceData
->BufferLength
= SnpMode
->MediaHeaderSize
+ NET_VLAN_TAG_LEN
+ SnpMode
->MaxPacketSize
+ NET_ETHER_FCS_SIZE
;
482 // Make sure the protocol headers immediately following the media header
483 // 4-byte aligned, and also preserve additional space for VLAN tag
485 MnpDeviceData
->PaddingSize
= ((4 - SnpMode
->MediaHeaderSize
) & 0x3) + NET_VLAN_TAG_LEN
;
488 // Initialize MAC string which will be used as VLAN configuration variable name
490 Status
= NetLibGetMacString (ControllerHandle
, ImageHandle
, &MnpDeviceData
->MacString
);
491 if (EFI_ERROR (Status
)) {
496 // Initialize the FreeNetBufQue and pre-allocate some NET_BUFs.
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
));
507 // Get one NET_BUF from the FreeNbufQue for rx cache.
509 MnpDeviceData
->RxNbufCache
= MnpAllocNbuf (MnpDeviceData
);
511 MnpDeviceData
->RxNbufCache
,
512 MnpDeviceData
->BufferLength
,
517 // Allocate buffer pool for tx.
519 InitializeListHead (&MnpDeviceData
->FreeTxBufList
);
520 InitializeListHead (&MnpDeviceData
->AllTxBufList
);
521 MnpDeviceData
->TxBufCount
= 0;
524 // Create the system poll timer.
526 Status
= gBS
->CreateEvent (
527 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
531 &MnpDeviceData
->PollTimer
533 if (EFI_ERROR (Status
)) {
534 DEBUG ((EFI_D_ERROR
, "MnpInitializeDeviceData: CreateEvent for poll timer failed.\n"));
540 // Create the timer for packet timeout check.
542 Status
= gBS
->CreateEvent (
543 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
545 MnpCheckPacketTimeout
,
547 &MnpDeviceData
->TimeoutCheckTimer
549 if (EFI_ERROR (Status
)) {
550 DEBUG ((EFI_D_ERROR
, "MnpInitializeDeviceData: CreateEvent for packet timeout check failed.\n"));
556 // Create the timer for media detection.
558 Status
= gBS
->CreateEvent (
559 EVT_NOTIFY_SIGNAL
| EVT_TIMER
,
563 &MnpDeviceData
->MediaDetectTimer
565 if (EFI_ERROR (Status
)) {
566 DEBUG ((EFI_D_ERROR
, "MnpInitializeDeviceData: CreateEvent for media detection failed.\n"));
572 if (EFI_ERROR (Status
)) {
574 // Free the dynamic allocated resources if necessary.
576 if (MnpDeviceData
->MacString
!= NULL
) {
577 FreePool (MnpDeviceData
->MacString
);
580 if (MnpDeviceData
->TimeoutCheckTimer
!= NULL
) {
581 gBS
->CloseEvent (MnpDeviceData
->TimeoutCheckTimer
);
584 if (MnpDeviceData
->MediaDetectTimer
!= NULL
) {
585 gBS
->CloseEvent (MnpDeviceData
->MediaDetectTimer
);
588 if (MnpDeviceData
->PollTimer
!= NULL
) {
589 gBS
->CloseEvent (MnpDeviceData
->PollTimer
);
592 if (MnpDeviceData
->RxNbufCache
!= NULL
) {
593 MnpFreeNbuf (MnpDeviceData
, MnpDeviceData
->RxNbufCache
);
596 if (MnpDeviceData
->FreeNbufQue
.BufNum
!= 0) {
597 NetbufQueFlush (&MnpDeviceData
->FreeNbufQue
);
601 // Close the Simple Network Protocol.
605 &gEfiSimpleNetworkProtocolGuid
,
616 Destroy the MNP device context data.
618 @param[in, out] MnpDeviceData Pointer to the mnp device context data.
619 @param[in] ImageHandle The driver image handle.
623 MnpDestroyDeviceData (
624 IN OUT MNP_DEVICE_DATA
*MnpDeviceData
,
625 IN EFI_HANDLE ImageHandle
629 LIST_ENTRY
*NextEntry
;
630 MNP_TX_BUF_WRAP
*TxBufWrap
;
632 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
635 // Free Vlan Config variable name string
637 if (MnpDeviceData
->MacString
!= NULL
) {
638 FreePool (MnpDeviceData
->MacString
);
642 // The GroupAddressList must be empty.
644 ASSERT (IsListEmpty (&MnpDeviceData
->GroupAddressList
));
649 gBS
->CloseEvent (MnpDeviceData
->TimeoutCheckTimer
);
650 gBS
->CloseEvent (MnpDeviceData
->MediaDetectTimer
);
651 gBS
->CloseEvent (MnpDeviceData
->PollTimer
);
654 // Free the Tx buffer pool.
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
--;
662 ASSERT (IsListEmpty (&MnpDeviceData
->AllTxBufList
));
663 ASSERT (MnpDeviceData
->TxBufCount
== 0);
666 // Free the RxNbufCache.
668 MnpFreeNbuf (MnpDeviceData
, MnpDeviceData
->RxNbufCache
);
671 // Flush the FreeNbufQue.
673 MnpDeviceData
->NbufCnt
-= MnpDeviceData
->FreeNbufQue
.BufNum
;
674 NetbufQueFlush (&MnpDeviceData
->FreeNbufQue
);
677 // Close the Simple Network Protocol.
680 MnpDeviceData
->ControllerHandle
,
681 &gEfiSimpleNetworkProtocolGuid
,
683 MnpDeviceData
->ControllerHandle
689 Create mnp service context data.
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,
696 @return A pointer to MNP_SERVICE_DATA or NULL if failed to create MNP service context.
700 MnpCreateServiceData (
701 IN MNP_DEVICE_DATA
*MnpDeviceData
,
703 IN UINT8 Priority OPTIONAL
706 EFI_HANDLE MnpServiceHandle
;
707 MNP_SERVICE_DATA
*MnpServiceData
;
709 EFI_SIMPLE_NETWORK_MODE
*SnpMode
;
710 EFI_VLAN_CONFIG_PROTOCOL
*VlanConfig
;
713 // Initialize the Mnp Service Data.
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"));
723 // Add to MNP service list
725 InsertTailList (&MnpDeviceData
->ServiceList
, &MnpServiceData
->Link
);
727 MnpServiceData
->Signature
= MNP_SERVICE_DATA_SIGNATURE
;
728 MnpServiceData
->MnpDeviceData
= MnpDeviceData
;
731 // Copy the ServiceBinding structure.
733 CopyMem (&MnpServiceData
->ServiceBinding
, &mMnpServiceBindingProtocol
, sizeof (EFI_SERVICE_BINDING_PROTOCOL
));
736 // Initialize the lists.
738 InitializeListHead (&MnpServiceData
->ChildrenList
);
740 SnpMode
= MnpDeviceData
->Snp
->Mode
;
743 // Create VLAN child handle
745 MnpServiceHandle
= MnpCreateVlanChild (
746 MnpDeviceData
->ImageHandle
,
747 MnpDeviceData
->ControllerHandle
,
749 &MnpServiceData
->DevicePath
751 if (MnpServiceHandle
== NULL
) {
752 DEBUG ((EFI_D_ERROR
, "MnpCreateServiceData: Faild to create child handle.\n"));
758 // Open VLAN Config Protocol by child
760 Status
= gBS
->OpenProtocol (
761 MnpDeviceData
->ControllerHandle
,
762 &gEfiVlanConfigProtocolGuid
,
763 (VOID
**) &VlanConfig
,
764 MnpDeviceData
->ImageHandle
,
766 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
768 if (EFI_ERROR (Status
)) {
773 // Reduce MTU for VLAN device
775 MnpServiceData
->Mtu
= SnpMode
->MaxPacketSize
- NET_VLAN_TAG_LEN
;
778 // VlanId set to 0 means rx/tx untagged frame
780 MnpServiceHandle
= MnpDeviceData
->ControllerHandle
;
781 MnpServiceData
->Mtu
= SnpMode
->MaxPacketSize
;
784 MnpServiceData
->ServiceHandle
= MnpServiceHandle
;
785 MnpServiceData
->VlanId
= VlanId
;
786 MnpServiceData
->Priority
= Priority
;
789 // Install the MNP Service Binding Protocol
791 Status
= gBS
->InstallMultipleProtocolInterfaces (
793 &gEfiManagedNetworkServiceBindingProtocolGuid
,
794 &MnpServiceData
->ServiceBinding
,
799 if (EFI_ERROR (Status
)) {
800 MnpDestroyServiceData (MnpServiceData
);
801 MnpServiceData
= NULL
;
804 return MnpServiceData
;
808 Destroy the MNP service context data.
810 @param[in, out] MnpServiceData Pointer to the mnp service context data.
812 @retval EFI_SUCCESS The mnp service context is destroyed.
813 @retval Others Errors as indicated.
817 MnpDestroyServiceData (
818 IN OUT MNP_SERVICE_DATA
*MnpServiceData
824 // Uninstall the MNP Service Binding Protocol
826 Status
= gBS
->UninstallMultipleProtocolInterfaces (
827 MnpServiceData
->ServiceHandle
,
828 &gEfiManagedNetworkServiceBindingProtocolGuid
,
829 &MnpServiceData
->ServiceBinding
,
832 if (EFI_ERROR (Status
)) {
836 if (MnpServiceData
->VlanId
!= 0) {
838 // Close VlanConfig Protocol opened by VLAN child handle
840 Status
= gBS
->CloseProtocol (
841 MnpServiceData
->MnpDeviceData
->ControllerHandle
,
842 &gEfiVlanConfigProtocolGuid
,
843 MnpServiceData
->MnpDeviceData
->ImageHandle
,
844 MnpServiceData
->ServiceHandle
846 if (EFI_ERROR (Status
)) {
851 // Uninstall Device Path Protocol to destroy the VLAN child handle
853 Status
= gBS
->UninstallMultipleProtocolInterfaces (
854 MnpServiceData
->ServiceHandle
,
855 &gEfiDevicePathProtocolGuid
,
856 MnpServiceData
->DevicePath
,
859 if (EFI_ERROR (Status
)) {
863 if (MnpServiceData
->DevicePath
!= NULL
) {
864 FreePool (MnpServiceData
->DevicePath
);
869 // Remove from MnpDeviceData service list
871 RemoveEntryList (&MnpServiceData
->Link
);
873 FreePool (MnpServiceData
);
879 Callback function which provided by user to remove one node in NetDestroyLinkList process.
881 @param[in] Entry The entry to be removed.
882 @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList.
884 @retval EFI_SUCCESS The entry has been removed successfully.
885 @retval Others Fail to remove the entry.
890 MnpDestoryChildEntry (
891 IN LIST_ENTRY
*Entry
,
895 MNP_INSTANCE_DATA
*Instance
;
896 EFI_SERVICE_BINDING_PROTOCOL
*ServiceBinding
;
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
);
904 Destroy all child of the MNP service data.
906 @param[in, out] MnpServiceData Pointer to the mnp service context data.
908 @retval EFI_SUCCESS All child are destroyed.
909 @retval Others Failed to destroy all child.
913 MnpDestroyServiceChild (
914 IN OUT MNP_SERVICE_DATA
*MnpServiceData
921 List
= &MnpServiceData
->ChildrenList
;
923 Status
= NetDestroyLinkList (
925 MnpDestoryChildEntry
,
926 &MnpServiceData
->ServiceBinding
,
929 if (EFI_ERROR (Status
) || ListLength
!= 0) {
930 return EFI_DEVICE_ERROR
;
937 Find the MNP Service Data for given VLAN ID.
939 @param[in] MnpDeviceData Pointer to the mnp device context data.
940 @param[in] VlanId The VLAN ID.
942 @return A pointer to MNP_SERVICE_DATA or NULL if not found.
947 IN MNP_DEVICE_DATA
*MnpDeviceData
,
952 MNP_SERVICE_DATA
*MnpServiceData
;
954 NET_LIST_FOR_EACH (Entry
, &MnpDeviceData
->ServiceList
) {
956 // Check VLAN ID of each Mnp Service Data
958 MnpServiceData
= MNP_SERVICE_DATA_FROM_LINK (Entry
);
959 if (MnpServiceData
->VlanId
== VlanId
) {
960 return MnpServiceData
;
968 Initialize the mnp instance context data.
970 @param[in] MnpServiceData Pointer to the mnp service context data.
971 @param[in, out] Instance Pointer to the mnp instance context data
976 MnpInitializeInstanceData (
977 IN MNP_SERVICE_DATA
*MnpServiceData
,
978 IN OUT MNP_INSTANCE_DATA
*Instance
981 NET_CHECK_SIGNATURE (MnpServiceData
, MNP_SERVICE_DATA_SIGNATURE
);
982 ASSERT (Instance
!= NULL
);
985 // Set the signature.
987 Instance
->Signature
= MNP_INSTANCE_DATA_SIGNATURE
;
990 // Copy the MNP Protocol interfaces from the template.
992 CopyMem (&Instance
->ManagedNetwork
, &mMnpProtocolTemplate
, sizeof (Instance
->ManagedNetwork
));
995 // Copy the default config data.
997 CopyMem (&Instance
->ConfigData
, &mMnpDefaultConfigData
, sizeof (Instance
->ConfigData
));
1000 // Initialize the lists.
1002 InitializeListHead (&Instance
->GroupCtrlBlkList
);
1003 InitializeListHead (&Instance
->RcvdPacketQueue
);
1004 InitializeListHead (&Instance
->RxDeliveredPacketQueue
);
1007 // Initialize the RxToken Map.
1009 NetMapInit (&Instance
->RxTokenMap
);
1012 // Save the MnpServiceData info.
1014 Instance
->MnpServiceData
= MnpServiceData
;
1019 Check whether the token specified by Arg matches the token in Item.
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
1026 @retval EFI_SUCCESS The token specified by Arg is different from the
1028 @retval EFI_ACCESS_DENIED The token specified by Arg is the same as that in
1036 IN NET_MAP_ITEM
*Item
,
1040 EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*Token
;
1041 EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*TokenInItem
;
1043 Token
= (EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*) Arg
;
1044 TokenInItem
= (EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*) Item
->Key
;
1046 if ((Token
== TokenInItem
) || (Token
->Event
== TokenInItem
->Event
)) {
1048 // The token is the same either the two tokens equals or the Events in
1049 // the two tokens are the same.
1051 return EFI_ACCESS_DENIED
;
1058 Cancel the token specified by Arg if it matches the token in Item.
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
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.
1075 IN OUT NET_MAP
*Map
,
1076 IN OUT NET_MAP_ITEM
*Item
,
1080 EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*TokenToCancel
;
1082 if ((Arg
!= NULL
) && (Item
->Key
!= Arg
)) {
1084 // The token in Item is not the token specified by Arg.
1089 TokenToCancel
= (EFI_MANAGED_NETWORK_COMPLETION_TOKEN
*) Item
->Key
;
1092 // Remove the item from the map.
1094 NetMapRemoveItem (Map
, Item
, NULL
);
1097 // Cancel this token with status set to EFI_ABORTED.
1099 TokenToCancel
->Status
= EFI_ABORTED
;
1100 gBS
->SignalEvent (TokenToCancel
->Event
);
1104 // Only abort the token specified by Arg if Arg isn't NULL.
1114 Start and initialize the simple network.
1116 @param[in] Snp Pointer to the simple network protocol.
1118 @retval EFI_SUCCESS The simple network protocol is started.
1119 @retval Others Other errors as indicated.
1124 IN EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
1129 ASSERT (Snp
!= NULL
);
1132 // Start the simple network.
1134 Status
= Snp
->Start (Snp
);
1136 if (!EFI_ERROR (Status
)) {
1138 // Initialize the simple network.
1140 Status
= Snp
->Initialize (Snp
, 0, 0);
1148 Stop the simple network.
1150 @param[in] MnpDeviceData Pointer to the MNP_DEVICE_DATA.
1152 @retval EFI_SUCCESS The simple network is stopped.
1153 @retval Others Other errors as indicated.
1158 IN MNP_DEVICE_DATA
*MnpDeviceData
1162 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1164 Snp
= MnpDeviceData
->Snp
;
1165 ASSERT (Snp
!= NULL
);
1168 // Recycle all the transmit buffer from SNP.
1170 Status
= MnpRecycleTxBuf (MnpDeviceData
);
1171 if (EFI_ERROR (Status
)) {
1176 // Shut down the simple network.
1178 Status
= Snp
->Shutdown (Snp
);
1179 if (!EFI_ERROR (Status
)) {
1181 // Stop the simple network.
1183 Status
= Snp
->Stop (Snp
);
1191 Start the managed network, this function is called when one instance is configured
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.
1199 @retval EFI_SUCCESS The managed network is started and some
1200 configuration is updated.
1201 @retval Others Other errors as indicated.
1206 IN OUT MNP_SERVICE_DATA
*MnpServiceData
,
1207 IN BOOLEAN IsConfigUpdate
,
1208 IN BOOLEAN EnableSystemPoll
1212 EFI_TIMER_DELAY TimerOpType
;
1213 MNP_DEVICE_DATA
*MnpDeviceData
;
1215 NET_CHECK_SIGNATURE (MnpServiceData
, MNP_SERVICE_DATA_SIGNATURE
);
1217 Status
= EFI_SUCCESS
;
1218 MnpDeviceData
= MnpServiceData
->MnpDeviceData
;
1220 if (!IsConfigUpdate
) {
1222 // If it's not a configuration update, increase the configured children number.
1224 MnpDeviceData
->ConfiguredChildrenNumber
++;
1226 if (MnpDeviceData
->ConfiguredChildrenNumber
== 1) {
1228 // It's the first configured child, start the simple network.
1230 Status
= MnpStartSnp (MnpDeviceData
->Snp
);
1231 if (EFI_ERROR (Status
)) {
1232 DEBUG ((EFI_D_ERROR
, "MnpStart: MnpStartSnp failed, %r.\n", Status
));
1238 // Start the timeout timer.
1240 Status
= gBS
->SetTimer (
1241 MnpDeviceData
->TimeoutCheckTimer
,
1243 MNP_TIMEOUT_CHECK_INTERVAL
1245 if (EFI_ERROR (Status
)) {
1248 "MnpStart, gBS->SetTimer for TimeoutCheckTimer %r.\n",
1256 // Start the media detection timer.
1258 Status
= gBS
->SetTimer (
1259 MnpDeviceData
->MediaDetectTimer
,
1261 MNP_MEDIA_DETECT_INTERVAL
1263 if (EFI_ERROR (Status
)) {
1266 "MnpStart, gBS->SetTimer for MediaDetectTimer %r.\n",
1275 if (MnpDeviceData
->EnableSystemPoll
^ EnableSystemPoll
) {
1277 // The EnableSystemPoll differs with the current state, disable or enable
1280 TimerOpType
= EnableSystemPoll
? TimerPeriodic
: TimerCancel
;
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
));
1289 MnpDeviceData
->EnableSystemPoll
= EnableSystemPoll
;
1293 // Change the receive filters if need.
1295 Status
= MnpConfigReceiveFilters (MnpDeviceData
);
1303 Stop the managed network.
1305 @param[in, out] MnpServiceData Pointer to the mnp service context data.
1307 @retval EFI_SUCCESS The managed network is stopped.
1308 @retval Others Other errors as indicated.
1313 IN OUT MNP_SERVICE_DATA
*MnpServiceData
1317 MNP_DEVICE_DATA
*MnpDeviceData
;
1319 NET_CHECK_SIGNATURE (MnpServiceData
, MNP_SERVICE_DATA_SIGNATURE
);
1320 MnpDeviceData
= MnpServiceData
->MnpDeviceData
;
1321 ASSERT (MnpDeviceData
->ConfiguredChildrenNumber
> 0);
1324 // Configure the receive filters.
1326 MnpConfigReceiveFilters (MnpDeviceData
);
1329 // Decrease the children number.
1331 MnpDeviceData
->ConfiguredChildrenNumber
--;
1333 if (MnpDeviceData
->ConfiguredChildrenNumber
> 0) {
1335 // If there are other configured chilren, return and keep the timers and
1336 // simple network unchanged.
1342 // No configured children now.
1344 if (MnpDeviceData
->EnableSystemPoll
) {
1346 // The system poll in on, cancel the poll timer.
1348 Status
= gBS
->SetTimer (MnpDeviceData
->PollTimer
, TimerCancel
, 0);
1349 MnpDeviceData
->EnableSystemPoll
= FALSE
;
1353 // Cancel the timeout timer.
1355 Status
= gBS
->SetTimer (MnpDeviceData
->TimeoutCheckTimer
, TimerCancel
, 0);
1358 // Cancel the media detect timer.
1360 Status
= gBS
->SetTimer (MnpDeviceData
->MediaDetectTimer
, TimerCancel
, 0);
1363 // Stop the simple network.
1365 Status
= MnpStopSnp (MnpDeviceData
);
1371 Flush the instance's received data.
1373 @param[in, out] Instance Pointer to the mnp instance context data.
1377 MnpFlushRcvdDataQueue (
1378 IN OUT MNP_INSTANCE_DATA
*Instance
1382 MNP_RXDATA_WRAP
*RxDataWrap
;
1384 NET_CHECK_SIGNATURE (Instance
, MNP_INSTANCE_DATA_SIGNATURE
);
1386 OldTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1388 while (!IsListEmpty (&Instance
->RcvdPacketQueue
)) {
1390 // Remove all the Wraps.
1392 RxDataWrap
= NET_LIST_HEAD (&Instance
->RcvdPacketQueue
, MNP_RXDATA_WRAP
, WrapEntry
);
1395 // Recycle the RxDataWrap.
1397 MnpRecycleRxData (NULL
, (VOID
*) RxDataWrap
);
1398 Instance
->RcvdPacketQueueSize
--;
1401 ASSERT (Instance
->RcvdPacketQueueSize
== 0);
1403 gBS
->RestoreTPL (OldTpl
);
1408 Configure the Instance using ConfigData.
1410 @param[in, out] Instance Pointer to the mnp instance context data.
1411 @param[in] ConfigData Pointer to the configuration data used to configure
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.
1421 MnpConfigureInstance (
1422 IN OUT MNP_INSTANCE_DATA
*Instance
,
1423 IN EFI_MANAGED_NETWORK_CONFIG_DATA
*ConfigData OPTIONAL
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
;
1433 NET_CHECK_SIGNATURE (Instance
, MNP_INSTANCE_DATA_SIGNATURE
);
1435 if ((ConfigData
!= NULL
) && ConfigData
->EnableReceiveTimestamps
) {
1437 // Don't support timestamp.
1439 return EFI_UNSUPPORTED
;
1442 Status
= EFI_SUCCESS
;
1444 MnpServiceData
= Instance
->MnpServiceData
;
1445 MnpDeviceData
= MnpServiceData
->MnpDeviceData
;
1446 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
1448 IsConfigUpdate
= (BOOLEAN
) ((Instance
->Configured
) && (ConfigData
!= NULL
));
1450 OldConfigData
= &Instance
->ConfigData
;
1451 NewConfigData
= ConfigData
;
1452 if (NewConfigData
== NULL
) {
1454 // Restore back the default config data if a reset of this instance
1457 NewConfigData
= &mMnpDefaultConfigData
;
1461 // Reset the instance's receive filter.
1463 Instance
->ReceiveFilter
= 0;
1466 // Clear the receive counters according to the old ConfigData.
1468 if (OldConfigData
->EnableUnicastReceive
) {
1469 MnpDeviceData
->UnicastCount
--;
1472 if (OldConfigData
->EnableMulticastReceive
) {
1473 MnpDeviceData
->MulticastCount
--;
1476 if (OldConfigData
->EnableBroadcastReceive
) {
1477 MnpDeviceData
->BroadcastCount
--;
1480 if (OldConfigData
->EnablePromiscuousReceive
) {
1481 MnpDeviceData
->PromiscuousCount
--;
1485 // Set the receive filter counters and the receive filter of the
1486 // instance according to the new ConfigData.
1488 if (NewConfigData
->EnableUnicastReceive
) {
1489 MnpDeviceData
->UnicastCount
++;
1490 Instance
->ReceiveFilter
|= MNP_RECEIVE_UNICAST
;
1493 if (NewConfigData
->EnableMulticastReceive
) {
1494 MnpDeviceData
->MulticastCount
++;
1497 if (NewConfigData
->EnableBroadcastReceive
) {
1498 MnpDeviceData
->BroadcastCount
++;
1499 Instance
->ReceiveFilter
|= MNP_RECEIVE_BROADCAST
;
1502 if (NewConfigData
->EnablePromiscuousReceive
) {
1503 MnpDeviceData
->PromiscuousCount
++;
1506 if (OldConfigData
->FlushQueuesOnReset
) {
1507 MnpFlushRcvdDataQueue (Instance
);
1510 if (ConfigData
== NULL
) {
1511 Instance
->ManagedNetwork
.Cancel (&Instance
->ManagedNetwork
, NULL
);
1514 if (!NewConfigData
->EnableMulticastReceive
) {
1515 MnpGroupOp (Instance
, FALSE
, NULL
, NULL
);
1519 // Save the new configuration data.
1521 CopyMem (OldConfigData
, NewConfigData
, sizeof (*OldConfigData
));
1523 Instance
->Configured
= (BOOLEAN
) (ConfigData
!= NULL
);
1524 if (Instance
->Configured
) {
1526 // The instance is configured, start the Mnp.
1531 (BOOLEAN
) !NewConfigData
->DisableBackgroundPolling
1535 // The instance is changed to the unconfigured state, stop the Mnp.
1537 Status
= MnpStop (MnpServiceData
);
1544 Configure the Snp receive filters according to the instances' receive filter
1547 @param[in] MnpDeviceData Pointer to the mnp device context data.
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.
1555 MnpConfigReceiveFilters (
1556 IN MNP_DEVICE_DATA
*MnpDeviceData
1560 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1561 EFI_MAC_ADDRESS
*MCastFilter
;
1562 UINT32 MCastFilterCnt
;
1563 UINT32 EnableFilterBits
;
1564 UINT32 DisableFilterBits
;
1565 BOOLEAN ResetMCastFilters
;
1568 MNP_GROUP_ADDRESS
*GroupAddress
;
1570 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
1572 Snp
= MnpDeviceData
->Snp
;
1575 // Initialize the enable filter and disable filter.
1577 EnableFilterBits
= 0;
1578 DisableFilterBits
= Snp
->Mode
->ReceiveFilterMask
;
1580 if (MnpDeviceData
->UnicastCount
!= 0) {
1582 // Enable unicast if any instance wants to receive unicast.
1584 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
1587 if (MnpDeviceData
->BroadcastCount
!= 0) {
1589 // Enable broadcast if any instance wants to receive broadcast.
1591 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
1596 ResetMCastFilters
= TRUE
;
1598 if ((MnpDeviceData
->MulticastCount
!= 0) && (MnpDeviceData
->GroupAddressCount
!= 0)) {
1600 // There are instances configured to receive multicast and already some group
1601 // addresses are joined.
1604 ResetMCastFilters
= FALSE
;
1606 if (MnpDeviceData
->GroupAddressCount
<= Snp
->Mode
->MaxMCastFilterCount
) {
1608 // The joind group address is less than simple network's maximum count.
1609 // Just configure the snp to do the multicast filtering.
1612 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
;
1615 // Allocate pool for the mulicast addresses.
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"));
1622 return EFI_OUT_OF_RESOURCES
;
1626 // Fill the multicast HW address buffer.
1629 NET_LIST_FOR_EACH (Entry
, &MnpDeviceData
->GroupAddressList
) {
1631 GroupAddress
= NET_LIST_USER_STRUCT (Entry
, MNP_GROUP_ADDRESS
, AddrEntry
);
1632 CopyMem (MCastFilter
+ Index
, &GroupAddress
->Address
, sizeof (*(MCastFilter
+ Index
)));
1635 ASSERT (Index
<= MCastFilterCnt
);
1639 // The maximum multicast is reached, set the filter to be promiscuous
1643 if ((Snp
->Mode
->ReceiveFilterMask
& EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
) != 0) {
1644 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
1647 // Either MULTICAST or PROMISCUOUS_MULTICAST is not supported by Snp,
1648 // set the NIC to be promiscuous although this will tremendously degrade
1651 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
1656 if (MnpDeviceData
->PromiscuousCount
!= 0) {
1658 // Enable promiscuous if any instance wants to receive promiscuous.
1660 EnableFilterBits
|= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
;
1664 // Set the disable filter.
1666 DisableFilterBits
^= EnableFilterBits
;
1669 // Configure the receive filters of SNP.
1671 Status
= Snp
->ReceiveFilters (
1680 if (EFI_ERROR (Status
)) {
1683 "MnpConfigReceiveFilters: Snp->ReceiveFilters failed, %r.\n",
1689 if (MCastFilter
!= NULL
) {
1691 // Free the buffer used to hold the group addresses.
1693 FreePool (MCastFilter
);
1701 Add a group address control block which controls the MacAddress for
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.
1710 @retval EFI_SUCCESS The group address control block is added.
1711 @retval EFI_OUT_OF_RESOURCES Failed due to lack of memory resources.
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
1723 MNP_DEVICE_DATA
*MnpDeviceData
;
1725 NET_CHECK_SIGNATURE (Instance
, MNP_INSTANCE_DATA_SIGNATURE
);
1727 MnpDeviceData
= Instance
->MnpServiceData
->MnpDeviceData
;
1728 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
1730 if (GroupAddress
== NULL
) {
1731 ASSERT (MacAddress
!= NULL
);
1734 // Allocate a new GroupAddress to be added into MNP's GroupAddressList.
1736 GroupAddress
= AllocatePool (sizeof (MNP_GROUP_ADDRESS
));
1737 if (GroupAddress
== NULL
) {
1739 DEBUG ((EFI_D_ERROR
, "MnpGroupOpFormCtrlBlk: Failed to allocate memory resource.\n"));
1741 return EFI_OUT_OF_RESOURCES
;
1744 CopyMem (&GroupAddress
->Address
, MacAddress
, sizeof (GroupAddress
->Address
));
1745 GroupAddress
->RefCnt
= 0;
1747 &MnpDeviceData
->GroupAddressList
,
1748 &GroupAddress
->AddrEntry
1750 MnpDeviceData
->GroupAddressCount
++;
1754 // Increase the RefCnt.
1756 GroupAddress
->RefCnt
++;
1759 // Add the CtrlBlk into the instance's GroupCtrlBlkList.
1761 CtrlBlk
->GroupAddress
= GroupAddress
;
1762 InsertTailList (&Instance
->GroupCtrlBlkList
, &CtrlBlk
->CtrlBlkEntry
);
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.
1772 @param[in] Instance Pointer to the instance context data.
1773 @param[in] CtrlBlk Pointer to the group control block to delete.
1775 @return The group address controlled by the control block is no longer used or not.
1779 MnpGroupOpDelCtrlBlk (
1780 IN MNP_INSTANCE_DATA
*Instance
,
1781 IN MNP_GROUP_CONTROL_BLOCK
*CtrlBlk
1784 MNP_DEVICE_DATA
*MnpDeviceData
;
1785 MNP_GROUP_ADDRESS
*GroupAddress
;
1787 NET_CHECK_SIGNATURE (Instance
, MNP_INSTANCE_DATA_SIGNATURE
);
1789 MnpDeviceData
= Instance
->MnpServiceData
->MnpDeviceData
;
1790 NET_CHECK_SIGNATURE (MnpDeviceData
, MNP_DEVICE_DATA_SIGNATURE
);
1793 // Remove and free the CtrlBlk.
1795 GroupAddress
= CtrlBlk
->GroupAddress
;
1796 RemoveEntryList (&CtrlBlk
->CtrlBlkEntry
);
1799 ASSERT (GroupAddress
->RefCnt
> 0);
1802 // Count down the RefCnt.
1804 GroupAddress
->RefCnt
--;
1806 if (GroupAddress
->RefCnt
== 0) {
1808 // Free this GroupAddress entry if no instance uses it.
1810 MnpDeviceData
->GroupAddressCount
--;
1811 RemoveEntryList (&GroupAddress
->AddrEntry
);
1812 FreePool (GroupAddress
);
1822 Do the group operations for this instance.
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
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.
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
1844 MNP_DEVICE_DATA
*MnpDeviceData
;
1846 LIST_ENTRY
*NextEntry
;
1847 MNP_GROUP_ADDRESS
*GroupAddress
;
1848 EFI_SIMPLE_NETWORK_MODE
*SnpMode
;
1849 MNP_GROUP_CONTROL_BLOCK
*NewCtrlBlk
;
1851 BOOLEAN AddressExist
;
1854 NET_CHECK_SIGNATURE (Instance
, MNP_INSTANCE_DATA_SIGNATURE
);
1856 MnpDeviceData
= Instance
->MnpServiceData
->MnpDeviceData
;
1857 SnpMode
= MnpDeviceData
->Snp
->Mode
;
1861 // A new gropu address is to be added.
1863 GroupAddress
= NULL
;
1864 AddressExist
= FALSE
;
1867 // Allocate memory for the control block.
1869 NewCtrlBlk
= AllocatePool (sizeof (MNP_GROUP_CONTROL_BLOCK
));
1870 if (NewCtrlBlk
== NULL
) {
1871 DEBUG ((EFI_D_ERROR
, "MnpGroupOp: Failed to allocate memory resource.\n"));
1873 return EFI_OUT_OF_RESOURCES
;
1876 NET_LIST_FOR_EACH (Entry
, &MnpDeviceData
->GroupAddressList
) {
1878 // Check whether the MacAddress is already joined by other instances.
1880 GroupAddress
= NET_LIST_USER_STRUCT (Entry
, MNP_GROUP_ADDRESS
, AddrEntry
);
1881 if (CompareMem (MacAddress
, &GroupAddress
->Address
, SnpMode
->HwAddressSize
) == 0) {
1882 AddressExist
= TRUE
;
1887 if (!AddressExist
) {
1888 GroupAddress
= NULL
;
1892 // Add the GroupAddress for this instance.
1894 Status
= MnpGroupOpAddCtrlBlk (
1899 SnpMode
->HwAddressSize
1901 if (EFI_ERROR (Status
)) {
1907 if (MacAddress
!= NULL
) {
1908 ASSERT (CtrlBlk
!= NULL
);
1911 // Leave the specific multicast mac address.
1913 NeedUpdate
= MnpGroupOpDelCtrlBlk (Instance
, CtrlBlk
);
1916 // Leave all multicast mac addresses.
1920 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, &Instance
->GroupCtrlBlkList
) {
1922 NewCtrlBlk
= NET_LIST_USER_STRUCT (
1924 MNP_GROUP_CONTROL_BLOCK
,
1928 // Update is required if the group address left is no longer used
1929 // by other instances.
1931 NeedUpdate
= MnpGroupOpDelCtrlBlk (Instance
, NewCtrlBlk
);
1936 Status
= EFI_SUCCESS
;
1940 // Reconfigure the receive filters if necessary.
1942 Status
= MnpConfigReceiveFilters (MnpDeviceData
);