/** @file
  Implementation of Managed Network Protocol private services.

Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "MnpImpl.h"
#include "MnpVlan.h"

EFI_SERVICE_BINDING_PROTOCOL  mMnpServiceBindingProtocol = {
  MnpServiceBindingCreateChild,
  MnpServiceBindingDestroyChild
};

EFI_MANAGED_NETWORK_PROTOCOL  mMnpProtocolTemplate = {
  MnpGetModeData,
  MnpConfigure,
  MnpMcastIpToMac,
  MnpGroups,
  MnpTransmit,
  MnpReceive,
  MnpCancel,
  MnpPoll
};

EFI_MANAGED_NETWORK_CONFIG_DATA  mMnpDefaultConfigData = {
  10000000,
  10000000,
  0,
  FALSE,
  FALSE,
  FALSE,
  FALSE,
  FALSE,
  FALSE,
  FALSE
};

/**
  Add Count of net buffers to MnpDeviceData->FreeNbufQue. The length of the net
  buffer is specified by MnpDeviceData->BufferLength.

  @param[in, out]  MnpDeviceData         Pointer to the MNP_DEVICE_DATA.
  @param[in]       Count                 Number of NET_BUFFERs to add.

  @retval EFI_SUCCESS           The specified amount of NET_BUFs are allocated
                                and added to MnpDeviceData->FreeNbufQue.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate a NET_BUF structure.

**/
EFI_STATUS
MnpAddFreeNbuf (
  IN OUT MNP_DEVICE_DATA  *MnpDeviceData,
  IN     UINTN            Count
  )
{
  EFI_STATUS  Status;
  UINTN       Index;
  NET_BUF     *Nbuf;

  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  ASSERT ((Count > 0) && (MnpDeviceData->BufferLength > 0));

  Status = EFI_SUCCESS;
  for (Index = 0; Index < Count; Index++) {
    Nbuf = NetbufAlloc (MnpDeviceData->BufferLength + MnpDeviceData->PaddingSize);
    if (Nbuf == NULL) {
      DEBUG ((DEBUG_ERROR, "MnpAddFreeNbuf: NetBufAlloc failed.\n"));

      Status = EFI_OUT_OF_RESOURCES;
      break;
    }

    if (MnpDeviceData->PaddingSize > 0) {
      //
      // Pad padding bytes before the media header
      //
      NetbufAllocSpace (Nbuf, MnpDeviceData->PaddingSize, NET_BUF_TAIL);
      NetbufTrim (Nbuf, MnpDeviceData->PaddingSize, NET_BUF_HEAD);
    }

    NetbufQueAppend (&MnpDeviceData->FreeNbufQue, Nbuf);
  }

  MnpDeviceData->NbufCnt += Index;
  return Status;
}

/**
  Allocate a free NET_BUF from MnpDeviceData->FreeNbufQue. If there is none
  in the queue, first try to allocate some and add them into the queue, then
  fetch the NET_BUF from the updated FreeNbufQue.

  @param[in, out]  MnpDeviceData        Pointer to the MNP_DEVICE_DATA.

  @return     Pointer to the allocated free NET_BUF structure, if NULL the
              operation is failed.

**/
NET_BUF *
MnpAllocNbuf (
  IN OUT MNP_DEVICE_DATA  *MnpDeviceData
  )
{
  EFI_STATUS     Status;
  NET_BUF_QUEUE  *FreeNbufQue;
  NET_BUF        *Nbuf;
  EFI_TPL        OldTpl;

  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);

  FreeNbufQue = &MnpDeviceData->FreeNbufQue;
  OldTpl      = gBS->RaiseTPL (TPL_NOTIFY);

  //
  // Check whether there are available buffers, or else try to add some.
  //
  if (FreeNbufQue->BufNum == 0) {
    if ((MnpDeviceData->NbufCnt + MNP_NET_BUFFER_INCREASEMENT) > MNP_MAX_NET_BUFFER_NUM) {
      DEBUG (
        (DEBUG_ERROR,
         "MnpAllocNbuf: The maximum NET_BUF size is reached for MNP driver instance %p.\n",
         MnpDeviceData)
        );

      Nbuf = NULL;
      goto ON_EXIT;
    }

    Status = MnpAddFreeNbuf (MnpDeviceData, MNP_NET_BUFFER_INCREASEMENT);
    if (EFI_ERROR (Status)) {
      DEBUG (
        (DEBUG_ERROR,
         "MnpAllocNbuf: Failed to add NET_BUFs into the FreeNbufQue, %r.\n",
         Status)
        );

      //
      // Don't return NULL, perhaps MnpAddFreeNbuf does add some NET_BUFs but
      // the amount is less than MNP_NET_BUFFER_INCREASEMENT.
      //
    }
  }

  Nbuf = NetbufQueRemove (FreeNbufQue);

  //
  // Increase the RefCnt.
  //
  if (Nbuf != NULL) {
    NET_GET_REF (Nbuf);
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);

  return Nbuf;
}

/**
  Try to reclaim the Nbuf into the buffer pool.

  @param[in, out]  MnpDeviceData         Pointer to the mnp device context data.
  @param[in, out]  Nbuf                  Pointer to the NET_BUF to free.

**/
VOID
MnpFreeNbuf (
  IN OUT MNP_DEVICE_DATA  *MnpDeviceData,
  IN OUT NET_BUF          *Nbuf
  )
{
  EFI_TPL  OldTpl;

  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  ASSERT (Nbuf->RefCnt > 1);

  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);

  NET_PUT_REF (Nbuf);

  if (Nbuf->RefCnt == 1) {
    //
    // Trim all buffer contained in the Nbuf, then append it to the NbufQue.
    //
    NetbufTrim (Nbuf, Nbuf->TotalSize, NET_BUF_TAIL);

    if (NetbufAllocSpace (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_HEAD) != NULL) {
      //
      // There is space reserved for vlan tag in the head, reclaim it
      //
      NetbufTrim (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_TAIL);
    }

    NetbufQueAppend (&MnpDeviceData->FreeNbufQue, Nbuf);
  }

  gBS->RestoreTPL (OldTpl);
}

/**
  Add Count of TX buffers to MnpDeviceData->AllTxBufList and MnpDeviceData->FreeTxBufList.
  The length of the buffer is specified by MnpDeviceData->BufferLength.

  @param[in, out]  MnpDeviceData         Pointer to the MNP_DEVICE_DATA.
  @param[in]       Count                 Number of TX buffers to add.

  @retval EFI_SUCCESS           The specified amount of TX buffers are allocated.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate a TX buffer.

**/
EFI_STATUS
MnpAddFreeTxBuf (
  IN OUT MNP_DEVICE_DATA  *MnpDeviceData,
  IN     UINTN            Count
  )
{
  EFI_STATUS       Status;
  UINT32           Index;
  MNP_TX_BUF_WRAP  *TxBufWrap;

  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
  ASSERT ((Count > 0) && (MnpDeviceData->BufferLength > 0));

  Status = EFI_SUCCESS;
  for (Index = 0; Index < Count; Index++) {
    TxBufWrap = (MNP_TX_BUF_WRAP *)AllocatePool (OFFSET_OF (MNP_TX_BUF_WRAP, TxBuf) + MnpDeviceData->BufferLength);
    if (TxBufWrap == NULL) {
      DEBUG ((DEBUG_ERROR, "MnpAddFreeTxBuf: TxBuf Alloc failed.\n"));

      Status = EFI_OUT_OF_RESOURCES;
      break;
    }

    DEBUG ((DEBUG_INFO, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf));
    TxBufWrap->Signature = MNP_TX_BUF_WRAP_SIGNATURE;
    TxBufWrap->InUse     = FALSE;
    InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry);
    InsertTailList (&MnpDeviceData->AllTxBufList, &TxBufWrap->AllEntry);
  }

  MnpDeviceData->TxBufCount += Index;
  return Status;
}

/**
  Allocate a free TX buffer from MnpDeviceData->FreeTxBufList. If there is none
  in the queue, first try to recycle some from SNP, then try to allocate some and add
  them into the queue, then fetch the NET_BUF from the updated FreeTxBufList.

  @param[in, out]  MnpDeviceData        Pointer to the MNP_DEVICE_DATA.

  @return     Pointer to the allocated free NET_BUF structure, if NULL the
              operation is failed.

**/
UINT8 *
MnpAllocTxBuf (
  IN OUT MNP_DEVICE_DATA  *MnpDeviceData
  )
{
  EFI_TPL          OldTpl;
  UINT8            *TxBuf;
  EFI_STATUS       Status;
  LIST_ENTRY       *Entry;
  MNP_TX_BUF_WRAP  *TxBufWrap;

  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) {
    //
    // First try to recycle some TX buffer from SNP
    //
    Status = MnpRecycleTxBuf (MnpDeviceData);
    if (EFI_ERROR (Status)) {
      TxBuf = NULL;
      goto ON_EXIT;
    }

    //
    // If still no free TX buffer, allocate more.
    //
    if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) {
      if ((MnpDeviceData->TxBufCount + MNP_TX_BUFFER_INCREASEMENT) > MNP_MAX_TX_BUFFER_NUM) {
        DEBUG (
          (DEBUG_ERROR,
           "MnpAllocTxBuf: The maximum TxBuf size is reached for MNP driver instance %p.\n",
           MnpDeviceData)
          );

        TxBuf = NULL;
        goto ON_EXIT;
      }

      Status = MnpAddFreeTxBuf (MnpDeviceData, MNP_TX_BUFFER_INCREASEMENT);
      if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) {
        DEBUG (
          (DEBUG_ERROR,
           "MnpAllocNbuf: Failed to add TxBuf into the FreeTxBufList, %r.\n",
           Status)
          );

        TxBuf = NULL;
        goto ON_EXIT;
      }
    }
  }

  ASSERT (!IsListEmpty (&MnpDeviceData->FreeTxBufList));
  Entry = MnpDeviceData->FreeTxBufList.ForwardLink;
  RemoveEntryList (MnpDeviceData->FreeTxBufList.ForwardLink);
  TxBufWrap        = NET_LIST_USER_STRUCT_S (Entry, MNP_TX_BUF_WRAP, WrapEntry, MNP_TX_BUF_WRAP_SIGNATURE);
  TxBufWrap->InUse = TRUE;
  TxBuf            = TxBufWrap->TxBuf;

ON_EXIT:
  gBS->RestoreTPL (OldTpl);

  return TxBuf;
}

/**
  Try to reclaim the TX buffer into the buffer pool.

  @param[in, out]  MnpDeviceData         Pointer to the mnp device context data.
  @param[in, out]  TxBuf                 Pointer to the TX buffer to free.

**/
VOID
MnpFreeTxBuf (
  IN OUT MNP_DEVICE_DATA  *MnpDeviceData,
  IN OUT UINT8            *TxBuf
  )
{
  MNP_TX_BUF_WRAP  *TxBufWrap;
  EFI_TPL          OldTpl;

  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);

  if (TxBuf == NULL) {
    return;
  }

  TxBufWrap = NET_LIST_USER_STRUCT (TxBuf, MNP_TX_BUF_WRAP, TxBuf);
  if (TxBufWrap->Signature != MNP_TX_BUF_WRAP_SIGNATURE) {
    DEBUG (
      (DEBUG_ERROR,
       "MnpFreeTxBuf: Signature check failed in MnpFreeTxBuf.\n")
      );
    return;
  }

  if (!TxBufWrap->InUse) {
    DEBUG (
      (DEBUG_WARN,
       "MnpFreeTxBuf: Duplicated recycle report from SNP.\n")
      );
    return;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry);
  TxBufWrap->InUse = FALSE;
  gBS->RestoreTPL (OldTpl);
}

/**
  Try to recycle all the transmitted buffer address from SNP.

  @param[in, out]  MnpDeviceData     Pointer to the mnp device context data.

  @retval EFI_SUCCESS             Successed to recyclethe transmitted buffer address.
  @retval Others                  Failed to recyclethe transmitted buffer address.

**/
EFI_STATUS
MnpRecycleTxBuf (
  IN OUT MNP_DEVICE_DATA  *MnpDeviceData
  )
{
  UINT8                        *TxBuf;
  EFI_SIMPLE_NETWORK_PROTOCOL  *Snp;
  EFI_STATUS                   Status;

  Snp = MnpDeviceData->Snp;
  ASSERT (Snp != NULL);

  do {
    TxBuf  = NULL;
    Status = Snp->GetStatus (Snp, NULL, (VOID **)&TxBuf);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (TxBuf != NULL) {
      MnpFreeTxBuf (MnpDeviceData, TxBuf);
    }
  } while (TxBuf != NULL);

  return EFI_SUCCESS;
}

/**
  Initialize the mnp device context data.

  @param[in, out]  MnpDeviceData      Pointer to the mnp device context data.
  @param[in]       ImageHandle        The driver image handle.
  @param[in]       ControllerHandle   Handle of device to bind driver to.

  @retval EFI_SUCCESS           The mnp service context is initialized.
  @retval EFI_UNSUPPORTED       ControllerHandle does not support Simple Network Protocol.
  @retval Others                Other errors as indicated.

**/
EFI_STATUS
MnpInitializeDeviceData (
  IN OUT MNP_DEVICE_DATA  *MnpDeviceData,
  IN     EFI_HANDLE       ImageHandle,
  IN     EFI_HANDLE       ControllerHandle
  )
{
  EFI_STATUS                   Status;
  EFI_SIMPLE_NETWORK_PROTOCOL  *Snp;
  EFI_SIMPLE_NETWORK_MODE      *SnpMode;

  MnpDeviceData->Signature        = MNP_DEVICE_DATA_SIGNATURE;
  MnpDeviceData->ImageHandle      = ImageHandle;
  MnpDeviceData->ControllerHandle = ControllerHandle;

  //
  // Copy the MNP Protocol interfaces from the template.
  //
  CopyMem (&MnpDeviceData->VlanConfig, &mVlanConfigProtocolTemplate, sizeof (EFI_VLAN_CONFIG_PROTOCOL));

  //
  // Open the Simple Network protocol.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiSimpleNetworkProtocolGuid,
                  (VOID **)&Snp,
                  ImageHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  //
  // Get MTU from Snp.
  //
  SnpMode            = Snp->Mode;
  MnpDeviceData->Snp = Snp;

  //
  // Initialize the lists.
  //
  InitializeListHead (&MnpDeviceData->ServiceList);
  InitializeListHead (&MnpDeviceData->GroupAddressList);

  //
  // Get the buffer length used to allocate NET_BUF to hold data received
  // from SNP. Do this before fill the FreeNetBufQue.
  //
  //
  MnpDeviceData->BufferLength = SnpMode->MediaHeaderSize + NET_VLAN_TAG_LEN + SnpMode->MaxPacketSize + NET_ETHER_FCS_SIZE;

  //
  // Make sure the protocol headers immediately following the media header
  // 4-byte aligned, and also preserve additional space for VLAN tag
  //
  MnpDeviceData->PaddingSize = ((4 - SnpMode->MediaHeaderSize) & 0x3) + NET_VLAN_TAG_LEN;

  //
  // Initialize MAC string which will be used as VLAN configuration variable name
  //
  Status = NetLibGetMacString (ControllerHandle, ImageHandle, &MnpDeviceData->MacString);
  if (EFI_ERROR (Status)) {
    goto ERROR;
  }

  //
  // Initialize the FreeNetBufQue and pre-allocate some NET_BUFs.
  //
  NetbufQueInit (&MnpDeviceData->FreeNbufQue);
  Status = MnpAddFreeNbuf (MnpDeviceData, MNP_INIT_NET_BUFFER_NUM);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: MnpAddFreeNbuf failed, %r.\n", Status));

    goto ERROR;
  }

  //
  // Get one NET_BUF from the FreeNbufQue for rx cache.
  //
  MnpDeviceData->RxNbufCache = MnpAllocNbuf (MnpDeviceData);
  NetbufAllocSpace (
    MnpDeviceData->RxNbufCache,
    MnpDeviceData->BufferLength,
    NET_BUF_TAIL
    );

  //
  // Allocate buffer pool for tx.
  //
  InitializeListHead (&MnpDeviceData->FreeTxBufList);
  InitializeListHead (&MnpDeviceData->AllTxBufList);
  MnpDeviceData->TxBufCount = 0;

  //
  // Create the system poll timer.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
                  TPL_CALLBACK,
                  MnpSystemPoll,
                  MnpDeviceData,
                  &MnpDeviceData->PollTimer
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: CreateEvent for poll timer failed.\n"));

    goto ERROR;
  }

  //
  // Create the timer for packet timeout check.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
                  TPL_CALLBACK,
                  MnpCheckPacketTimeout,
                  MnpDeviceData,
                  &MnpDeviceData->TimeoutCheckTimer
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: CreateEvent for packet timeout check failed.\n"));

    goto ERROR;
  }

  //
  // Create the timer for media detection.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL | EVT_TIMER,
                  TPL_CALLBACK,
                  MnpCheckMediaStatus,
                  MnpDeviceData,
                  &MnpDeviceData->MediaDetectTimer
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "MnpInitializeDeviceData: CreateEvent for media detection failed.\n"));

    goto ERROR;
  }

ERROR:
  if (EFI_ERROR (Status)) {
    //
    // Free the dynamic allocated resources if necessary.
    //
    if (MnpDeviceData->MacString != NULL) {
      FreePool (MnpDeviceData->MacString);
    }

    if (MnpDeviceData->TimeoutCheckTimer != NULL) {
      gBS->CloseEvent (MnpDeviceData->TimeoutCheckTimer);
    }

    if (MnpDeviceData->MediaDetectTimer != NULL) {
      gBS->CloseEvent (MnpDeviceData->MediaDetectTimer);
    }

    if (MnpDeviceData->PollTimer != NULL) {
      gBS->CloseEvent (MnpDeviceData->PollTimer);
    }

    if (MnpDeviceData->RxNbufCache != NULL) {
      MnpFreeNbuf (MnpDeviceData, MnpDeviceData->RxNbufCache);
    }

    if (MnpDeviceData->FreeNbufQue.BufNum != 0) {
      NetbufQueFlush (&MnpDeviceData->FreeNbufQue);
    }

    //
    // Close the Simple Network Protocol.
    //
    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiSimpleNetworkProtocolGuid,
           ImageHandle,
           ControllerHandle
           );
  }

  return Status;
}

/**
  Destroy the MNP device context data.

  @param[in, out]  MnpDeviceData      Pointer to the mnp device context data.
  @param[in]       ImageHandle        The driver image handle.

**/
VOID
MnpDestroyDeviceData (
  IN OUT MNP_DEVICE_DATA  *MnpDeviceData,
  IN     EFI_HANDLE       ImageHandle
  )
{
  LIST_ENTRY       *Entry;
  LIST_ENTRY       *NextEntry;
  MNP_TX_BUF_WRAP  *TxBufWrap;

  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);

  //
  // Free Vlan Config variable name string
  //
  if (MnpDeviceData->MacString != NULL) {
    FreePool (MnpDeviceData->MacString);
  }

  //
  // The GroupAddressList must be empty.
  //
  ASSERT (IsListEmpty (&MnpDeviceData->GroupAddressList));

  //
  // Close the event.
  //
  gBS->CloseEvent (MnpDeviceData->TimeoutCheckTimer);
  gBS->CloseEvent (MnpDeviceData->MediaDetectTimer);
  gBS->CloseEvent (MnpDeviceData->PollTimer);

  //
  // Free the Tx buffer pool.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &MnpDeviceData->AllTxBufList) {
    TxBufWrap = NET_LIST_USER_STRUCT (Entry, MNP_TX_BUF_WRAP, AllEntry);
    RemoveEntryList (Entry);
    FreePool (TxBufWrap);
    MnpDeviceData->TxBufCount--;
  }
  ASSERT (IsListEmpty (&MnpDeviceData->AllTxBufList));
  ASSERT (MnpDeviceData->TxBufCount == 0);

  //
  // Free the RxNbufCache.
  //
  MnpFreeNbuf (MnpDeviceData, MnpDeviceData->RxNbufCache);

  //
  // Flush the FreeNbufQue.
  //
  MnpDeviceData->NbufCnt -= MnpDeviceData->FreeNbufQue.BufNum;
  NetbufQueFlush (&MnpDeviceData->FreeNbufQue);

  //
  // Close the Simple Network Protocol.
  //
  gBS->CloseProtocol (
         MnpDeviceData->ControllerHandle,
         &gEfiSimpleNetworkProtocolGuid,
         ImageHandle,
         MnpDeviceData->ControllerHandle
         );
}

/**
  Create mnp service context data.

  @param[in]       MnpDeviceData      Pointer to the mnp device context data.
  @param[in]       VlanId             The VLAN ID.
  @param[in]       Priority           The VLAN priority. If VlanId is 0,
                                      Priority is ignored.

  @return A pointer to MNP_SERVICE_DATA or NULL if failed to create MNP service context.

**/
MNP_SERVICE_DATA *
MnpCreateServiceData (
  IN MNP_DEVICE_DATA  *MnpDeviceData,
  IN UINT16           VlanId,
  IN UINT8            Priority OPTIONAL
  )
{
  EFI_HANDLE                MnpServiceHandle;
  MNP_SERVICE_DATA          *MnpServiceData;
  EFI_STATUS                Status;
  EFI_SIMPLE_NETWORK_MODE   *SnpMode;
  EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;

  //
  // Initialize the Mnp Service Data.
  //
  MnpServiceData = AllocateZeroPool (sizeof (MNP_SERVICE_DATA));
  if (MnpServiceData == NULL) {
    DEBUG ((DEBUG_ERROR, "MnpCreateServiceData: Failed to allocate memory for the new Mnp Service Data.\n"));

    return NULL;
  }

  //
  // Add to MNP service list
  //
  InsertTailList (&MnpDeviceData->ServiceList, &MnpServiceData->Link);

  MnpServiceData->Signature     = MNP_SERVICE_DATA_SIGNATURE;
  MnpServiceData->MnpDeviceData = MnpDeviceData;

  //
  // Copy the ServiceBinding structure.
  //
  CopyMem (&MnpServiceData->ServiceBinding, &mMnpServiceBindingProtocol, sizeof (EFI_SERVICE_BINDING_PROTOCOL));

  //
  // Initialize the lists.
  //
  InitializeListHead (&MnpServiceData->ChildrenList);

  SnpMode = MnpDeviceData->Snp->Mode;
  if (VlanId != 0) {
    //
    // Create VLAN child handle
    //
    MnpServiceHandle = MnpCreateVlanChild (
                         MnpDeviceData->ImageHandle,
                         MnpDeviceData->ControllerHandle,
                         VlanId,
                         &MnpServiceData->DevicePath
                         );
    if (MnpServiceHandle == NULL) {
      DEBUG ((DEBUG_ERROR, "MnpCreateServiceData: Failed to create child handle.\n"));

      return NULL;
    }

    //
    // Open VLAN Config Protocol by child
    //
    Status = gBS->OpenProtocol (
                    MnpDeviceData->ControllerHandle,
                    &gEfiVlanConfigProtocolGuid,
                    (VOID **)&VlanConfig,
                    MnpDeviceData->ImageHandle,
                    MnpServiceHandle,
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                    );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    //
    // Reduce MTU for VLAN device
    //
    MnpServiceData->Mtu = SnpMode->MaxPacketSize - NET_VLAN_TAG_LEN;
  } else {
    //
    // VlanId set to 0 means rx/tx untagged frame
    //
    MnpServiceHandle    = MnpDeviceData->ControllerHandle;
    MnpServiceData->Mtu = SnpMode->MaxPacketSize;
  }

  MnpServiceData->ServiceHandle = MnpServiceHandle;
  MnpServiceData->VlanId        = VlanId;
  MnpServiceData->Priority      = Priority;

  //
  // Install the MNP Service Binding Protocol
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &MnpServiceHandle,
                  &gEfiManagedNetworkServiceBindingProtocolGuid,
                  &MnpServiceData->ServiceBinding,
                  NULL
                  );

Exit:
  if (EFI_ERROR (Status)) {
    MnpDestroyServiceData (MnpServiceData);
    MnpServiceData = NULL;
  }

  return MnpServiceData;
}

/**
  Destroy the MNP service context data.

  @param[in, out]  MnpServiceData    Pointer to the mnp service context data.

  @retval EFI_SUCCESS           The mnp service context is destroyed.
  @retval Others                Errors as indicated.

**/
EFI_STATUS
MnpDestroyServiceData (
  IN OUT MNP_SERVICE_DATA  *MnpServiceData
  )
{
  EFI_STATUS  Status;

  //
  // Uninstall the MNP Service Binding Protocol
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  MnpServiceData->ServiceHandle,
                  &gEfiManagedNetworkServiceBindingProtocolGuid,
                  &MnpServiceData->ServiceBinding,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (MnpServiceData->VlanId != 0) {
    //
    // Close VlanConfig Protocol opened by VLAN child handle
    //
    Status = gBS->CloseProtocol (
                    MnpServiceData->MnpDeviceData->ControllerHandle,
                    &gEfiVlanConfigProtocolGuid,
                    MnpServiceData->MnpDeviceData->ImageHandle,
                    MnpServiceData->ServiceHandle
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Uninstall Device Path Protocol to destroy the VLAN child handle
    //
    Status = gBS->UninstallMultipleProtocolInterfaces (
                    MnpServiceData->ServiceHandle,
                    &gEfiDevicePathProtocolGuid,
                    MnpServiceData->DevicePath,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    if (MnpServiceData->DevicePath != NULL) {
      FreePool (MnpServiceData->DevicePath);
    }
  }

  //
  // Remove from MnpDeviceData service list
  //
  RemoveEntryList (&MnpServiceData->Link);

  FreePool (MnpServiceData);

  return Status;
}

/**
  Callback function which provided by user to remove one node in NetDestroyLinkList process.

  @param[in]    Entry           The entry to be removed.
  @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.

  @retval EFI_SUCCESS           The entry has been removed successfully.
  @retval Others                Fail to remove the entry.

**/
EFI_STATUS
EFIAPI
MnpDestoryChildEntry (
  IN LIST_ENTRY  *Entry,
  IN VOID        *Context
  )
{
  MNP_INSTANCE_DATA             *Instance;
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;

  ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *)Context;
  Instance       = CR (Entry, MNP_INSTANCE_DATA, InstEntry, MNP_INSTANCE_DATA_SIGNATURE);
  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
}

/**
  Destroy all child of the MNP service data.

  @param[in, out]  MnpServiceData    Pointer to the mnp service context data.

  @retval EFI_SUCCESS           All child are destroyed.
  @retval Others                Failed to destroy all child.

**/
EFI_STATUS
MnpDestroyServiceChild (
  IN OUT MNP_SERVICE_DATA  *MnpServiceData
  )
{
  LIST_ENTRY  *List;
  EFI_STATUS  Status;
  UINTN       ListLength;

  List = &MnpServiceData->ChildrenList;

  Status = NetDestroyLinkList (
             List,
             MnpDestoryChildEntry,
             &MnpServiceData->ServiceBinding,
             &ListLength
             );
  if (EFI_ERROR (Status) || (ListLength != 0)) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Find the MNP Service Data for given VLAN ID.

  @param[in]  MnpDeviceData      Pointer to the mnp device context data.
  @param[in]  VlanId             The VLAN ID.

  @return A pointer to MNP_SERVICE_DATA or NULL if not found.

**/
MNP_SERVICE_DATA *
MnpFindServiceData (
  IN MNP_DEVICE_DATA  *MnpDeviceData,
  IN UINT16           VlanId
  )
{
  LIST_ENTRY        *Entry;
  MNP_SERVICE_DATA  *MnpServiceData;

  NET_LIST_FOR_EACH (Entry, &MnpDeviceData->ServiceList) {
    //
    // Check VLAN ID of each Mnp Service Data
    //
    MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (Entry);
    if (MnpServiceData->VlanId == VlanId) {
      return MnpServiceData;
    }
  }

  return NULL;
}

/**
  Initialize the mnp instance context data.

  @param[in]       MnpServiceData   Pointer to the mnp service context data.
  @param[in, out]  Instance         Pointer to the mnp instance context data
                                    to initialize.

**/
VOID
MnpInitializeInstanceData (
  IN     MNP_SERVICE_DATA   *MnpServiceData,
  IN OUT MNP_INSTANCE_DATA  *Instance
  )
{
  NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
  ASSERT (Instance != NULL);

  //
  // Set the signature.
  //
  Instance->Signature = MNP_INSTANCE_DATA_SIGNATURE;

  //
  // Copy the MNP Protocol interfaces from the template.
  //
  CopyMem (&Instance->ManagedNetwork, &mMnpProtocolTemplate, sizeof (Instance->ManagedNetwork));

  //
  // Copy the default config data.
  //
  CopyMem (&Instance->ConfigData, &mMnpDefaultConfigData, sizeof (Instance->ConfigData));

  //
  // Initialize the lists.
  //
  InitializeListHead (&Instance->GroupCtrlBlkList);
  InitializeListHead (&Instance->RcvdPacketQueue);
  InitializeListHead (&Instance->RxDeliveredPacketQueue);

  //
  // Initialize the RxToken Map.
  //
  NetMapInit (&Instance->RxTokenMap);

  //
  // Save the MnpServiceData info.
  //
  Instance->MnpServiceData = MnpServiceData;
}

/**
  Check whether the token specified by Arg matches the token in Item.

  @param[in]  Map               Pointer to the NET_MAP.
  @param[in]  Item              Pointer to the NET_MAP_ITEM.
  @param[in]  Arg               Pointer to the Arg, it's a pointer to the token to
                                check.

  @retval EFI_SUCCESS           The token specified by Arg is different from the
                                token in Item.
  @retval EFI_ACCESS_DENIED     The token specified by Arg is the same as that in
                                Item.

**/
EFI_STATUS
EFIAPI
MnpTokenExist (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Arg
  )
{
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *Token;
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *TokenInItem;

  Token       = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *)Arg;
  TokenInItem = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *)Item->Key;

  if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) {
    //
    // The token is the same either the two tokens equals or the Events in
    // the two tokens are the same.
    //
    return EFI_ACCESS_DENIED;
  }

  return EFI_SUCCESS;
}

/**
  Cancel the token specified by Arg if it matches the token in Item.

  @param[in, out]  Map               Pointer to the NET_MAP.
  @param[in, out]  Item              Pointer to the NET_MAP_ITEM.
  @param[in]       Arg               Pointer to the Arg, it's a pointer to the
                                     token to cancel.

  @retval EFI_SUCCESS       The Arg is NULL, and the token in Item is cancelled,
                            or the Arg isn't NULL, and the token in Item is
                            different from the Arg.
  @retval EFI_ABORTED       The Arg isn't NULL, the token in Item mathces the
                            Arg, and the token is cancelled.

**/
EFI_STATUS
EFIAPI
MnpCancelTokens (
  IN OUT NET_MAP       *Map,
  IN OUT NET_MAP_ITEM  *Item,
  IN     VOID          *Arg
  )
{
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *TokenToCancel;

  if ((Arg != NULL) && (Item->Key != Arg)) {
    //
    // The token in Item is not the token specified by Arg.
    //
    return EFI_SUCCESS;
  }

  TokenToCancel = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *)Item->Key;

  //
  // Remove the item from the map.
  //
  NetMapRemoveItem (Map, Item, NULL);

  //
  // Cancel this token with status set to EFI_ABORTED.
  //
  TokenToCancel->Status = EFI_ABORTED;
  gBS->SignalEvent (TokenToCancel->Event);

  if (Arg != NULL) {
    //
    // Only abort the token specified by Arg if Arg isn't NULL.
    //
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  Start and initialize the simple network.

  @param[in]  Snp               Pointer to the simple network protocol.

  @retval EFI_SUCCESS           The simple network protocol is started.
  @retval Others                Other errors as indicated.

**/
EFI_STATUS
MnpStartSnp (
  IN EFI_SIMPLE_NETWORK_PROTOCOL  *Snp
  )
{
  EFI_STATUS  Status;

  ASSERT (Snp != NULL);

  //
  // Start the simple network.
  //
  Status = Snp->Start (Snp);

  if (!EFI_ERROR (Status)) {
    //
    // Initialize the simple network.
    //
    Status = Snp->Initialize (Snp, 0, 0);
  }

  return Status;
}

/**
  Stop the simple network.

  @param[in]  MnpDeviceData     Pointer to the MNP_DEVICE_DATA.

  @retval EFI_SUCCESS           The simple network is stopped.
  @retval Others                Other errors as indicated.

**/
EFI_STATUS
MnpStopSnp (
  IN  MNP_DEVICE_DATA  *MnpDeviceData
  )
{
  EFI_STATUS                   Status;
  EFI_SIMPLE_NETWORK_PROTOCOL  *Snp;

  Snp = MnpDeviceData->Snp;
  ASSERT (Snp != NULL);

  //
  // Recycle all the transmit buffer from SNP.
  //
  Status = MnpRecycleTxBuf (MnpDeviceData);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Shut down the simple network.
  //
  Status = Snp->Shutdown (Snp);
  if (!EFI_ERROR (Status)) {
    //
    // Stop the simple network.
    //
    Status = Snp->Stop (Snp);
  }

  return Status;
}

/**
  Start the managed network, this function is called when one instance is configured
  or reconfigured.

  @param[in, out]  MnpServiceData       Pointer to the mnp service context data.
  @param[in]       IsConfigUpdate       The instance is reconfigured or it's the first
                                        time the instanced is configured.
  @param[in]       EnableSystemPoll     Enable the system polling or not.

  @retval EFI_SUCCESS                   The managed network is started and some
                                        configuration is updated.
  @retval Others                        Other errors as indicated.

**/
EFI_STATUS
MnpStart (
  IN OUT MNP_SERVICE_DATA  *MnpServiceData,
  IN     BOOLEAN           IsConfigUpdate,
  IN     BOOLEAN           EnableSystemPoll
  )
{
  EFI_STATUS       Status;
  EFI_TIMER_DELAY  TimerOpType;
  MNP_DEVICE_DATA  *MnpDeviceData;

  NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);

  Status        = EFI_SUCCESS;
  MnpDeviceData = MnpServiceData->MnpDeviceData;

  if (!IsConfigUpdate) {
    //
    // If it's not a configuration update, increase the configured children number.
    //
    MnpDeviceData->ConfiguredChildrenNumber++;

    if (MnpDeviceData->ConfiguredChildrenNumber == 1) {
      //
      // It's the first configured child, start the simple network.
      //
      Status = MnpStartSnp (MnpDeviceData->Snp);
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "MnpStart: MnpStartSnp failed, %r.\n", Status));

        goto ErrorExit;
      }

      //
      // Start the timeout timer.
      //
      Status = gBS->SetTimer (
                      MnpDeviceData->TimeoutCheckTimer,
                      TimerPeriodic,
                      MNP_TIMEOUT_CHECK_INTERVAL
                      );
      if (EFI_ERROR (Status)) {
        DEBUG (
          (DEBUG_ERROR,
           "MnpStart, gBS->SetTimer for TimeoutCheckTimer %r.\n",
           Status)
          );

        goto ErrorExit;
      }

      //
      // Start the media detection timer.
      //
      Status = gBS->SetTimer (
                      MnpDeviceData->MediaDetectTimer,
                      TimerPeriodic,
                      MNP_MEDIA_DETECT_INTERVAL
                      );
      if (EFI_ERROR (Status)) {
        DEBUG (
          (DEBUG_ERROR,
           "MnpStart, gBS->SetTimer for MediaDetectTimer %r.\n",
           Status)
          );

        goto ErrorExit;
      }
    }
  }

  if (MnpDeviceData->EnableSystemPoll ^ EnableSystemPoll) {
    //
    // The EnableSystemPoll differs with the current state, disable or enable
    // the system poll.
    //
    TimerOpType = EnableSystemPoll ? TimerPeriodic : TimerCancel;

    Status = gBS->SetTimer (MnpDeviceData->PollTimer, TimerOpType, MNP_SYS_POLL_INTERVAL);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "MnpStart: gBS->SetTimer for PollTimer failed, %r.\n", Status));

      goto ErrorExit;
    }

    MnpDeviceData->EnableSystemPoll = EnableSystemPoll;
  }

  //
  // Change the receive filters if need.
  //
  Status = MnpConfigReceiveFilters (MnpDeviceData);

ErrorExit:
  return Status;
}

/**
  Stop the managed network.

  @param[in, out]  MnpServiceData    Pointer to the mnp service context data.

  @retval EFI_SUCCESS                The managed network is stopped.
  @retval Others                     Other errors as indicated.

**/
EFI_STATUS
MnpStop (
  IN OUT MNP_SERVICE_DATA  *MnpServiceData
  )
{
  EFI_STATUS       Status;
  MNP_DEVICE_DATA  *MnpDeviceData;

  NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
  MnpDeviceData = MnpServiceData->MnpDeviceData;
  ASSERT (MnpDeviceData->ConfiguredChildrenNumber > 0);

  //
  // Configure the receive filters.
  //
  MnpConfigReceiveFilters (MnpDeviceData);

  //
  // Decrease the children number.
  //
  MnpDeviceData->ConfiguredChildrenNumber--;

  if (MnpDeviceData->ConfiguredChildrenNumber > 0) {
    //
    // If there are other configured children, return and keep the timers and
    // simple network unchanged.
    //
    return EFI_SUCCESS;
  }

  //
  // No configured children now.
  //
  if (MnpDeviceData->EnableSystemPoll) {
    //
    //  The system poll in on, cancel the poll timer.
    //
    Status                          = gBS->SetTimer (MnpDeviceData->PollTimer, TimerCancel, 0);
    MnpDeviceData->EnableSystemPoll = FALSE;
  }

  //
  // Cancel the timeout timer.
  //
  Status = gBS->SetTimer (MnpDeviceData->TimeoutCheckTimer, TimerCancel, 0);

  //
  // Cancel the media detect timer.
  //
  Status = gBS->SetTimer (MnpDeviceData->MediaDetectTimer, TimerCancel, 0);

  //
  // Stop the simple network.
  //
  Status = MnpStopSnp (MnpDeviceData);
  return Status;
}

/**
  Flush the instance's received data.

  @param[in, out]  Instance              Pointer to the mnp instance context data.

**/
VOID
MnpFlushRcvdDataQueue (
  IN OUT MNP_INSTANCE_DATA  *Instance
  )
{
  EFI_TPL          OldTpl;
  MNP_RXDATA_WRAP  *RxDataWrap;

  NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);

  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);

  while (!IsListEmpty (&Instance->RcvdPacketQueue)) {
    //
    // Remove all the Wraps.
    //
    RxDataWrap = NET_LIST_HEAD (&Instance->RcvdPacketQueue, MNP_RXDATA_WRAP, WrapEntry);

    //
    // Recycle the RxDataWrap.
    //
    MnpRecycleRxData (NULL, (VOID *)RxDataWrap);
    Instance->RcvdPacketQueueSize--;
  }

  ASSERT (Instance->RcvdPacketQueueSize == 0);

  gBS->RestoreTPL (OldTpl);
}

/**
  Configure the Instance using ConfigData.

  @param[in, out]  Instance     Pointer to the mnp instance context data.
  @param[in]       ConfigData   Pointer to the configuration data used to configure
                                the instance.

  @retval EFI_SUCCESS           The Instance is configured.
  @retval EFI_UNSUPPORTED       EnableReceiveTimestamps is on and the
                                implementation doesn't support it.
  @retval Others                Other errors as indicated.

**/
EFI_STATUS
MnpConfigureInstance (
  IN OUT MNP_INSTANCE_DATA                *Instance,
  IN     EFI_MANAGED_NETWORK_CONFIG_DATA  *ConfigData OPTIONAL
  )
{
  EFI_STATUS                       Status;
  MNP_SERVICE_DATA                 *MnpServiceData;
  MNP_DEVICE_DATA                  *MnpDeviceData;
  EFI_MANAGED_NETWORK_CONFIG_DATA  *OldConfigData;
  EFI_MANAGED_NETWORK_CONFIG_DATA  *NewConfigData;
  BOOLEAN                          IsConfigUpdate;

  NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);

  if ((ConfigData != NULL) && ConfigData->EnableReceiveTimestamps) {
    //
    // Don't support timestamp.
    //
    return EFI_UNSUPPORTED;
  }

  Status = EFI_SUCCESS;

  MnpServiceData = Instance->MnpServiceData;
  MnpDeviceData  = MnpServiceData->MnpDeviceData;
  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);

  IsConfigUpdate = (BOOLEAN)((Instance->Configured) && (ConfigData != NULL));

  OldConfigData = &Instance->ConfigData;
  NewConfigData = ConfigData;
  if (NewConfigData == NULL) {
    //
    // Restore back the default config data if a reset of this instance
    // is required.
    //
    NewConfigData = &mMnpDefaultConfigData;
  }

  //
  // Reset the instance's receive filter.
  //
  Instance->ReceiveFilter = 0;

  //
  // Clear the receive counters according to the old ConfigData.
  //
  if (OldConfigData->EnableUnicastReceive) {
    MnpDeviceData->UnicastCount--;
  }

  if (OldConfigData->EnableMulticastReceive) {
    MnpDeviceData->MulticastCount--;
  }

  if (OldConfigData->EnableBroadcastReceive) {
    MnpDeviceData->BroadcastCount--;
  }

  if (OldConfigData->EnablePromiscuousReceive) {
    MnpDeviceData->PromiscuousCount--;
  }

  //
  // Set the receive filter counters and the receive filter of the
  // instance according to the new ConfigData.
  //
  if (NewConfigData->EnableUnicastReceive) {
    MnpDeviceData->UnicastCount++;
    Instance->ReceiveFilter |= MNP_RECEIVE_UNICAST;
  }

  if (NewConfigData->EnableMulticastReceive) {
    MnpDeviceData->MulticastCount++;
  }

  if (NewConfigData->EnableBroadcastReceive) {
    MnpDeviceData->BroadcastCount++;
    Instance->ReceiveFilter |= MNP_RECEIVE_BROADCAST;
  }

  if (NewConfigData->EnablePromiscuousReceive) {
    MnpDeviceData->PromiscuousCount++;
  }

  if (OldConfigData->FlushQueuesOnReset) {
    MnpFlushRcvdDataQueue (Instance);
  }

  if (ConfigData == NULL) {
    Instance->ManagedNetwork.Cancel (&Instance->ManagedNetwork, NULL);
  }

  if (!NewConfigData->EnableMulticastReceive) {
    MnpGroupOp (Instance, FALSE, NULL, NULL);
  }

  //
  // Save the new configuration data.
  //
  CopyMem (OldConfigData, NewConfigData, sizeof (*OldConfigData));

  Instance->Configured = (BOOLEAN)(ConfigData != NULL);
  if (Instance->Configured) {
    //
    // The instance is configured, start the Mnp.
    //
    Status = MnpStart (
               MnpServiceData,
               IsConfigUpdate,
               (BOOLEAN) !NewConfigData->DisableBackgroundPolling
               );
  } else {
    //
    // The instance is changed to the unconfigured state, stop the Mnp.
    //
    Status = MnpStop (MnpServiceData);
  }

  return Status;
}

/**
  Configure the Snp receive filters according to the instances' receive filter
  settings.

  @param[in]  MnpDeviceData         Pointer to the mnp device context data.

  @retval     EFI_SUCCESS           The receive filters is configured.
  @retval     EFI_OUT_OF_RESOURCES  The receive filters can't be configured due
                                    to lack of memory resource.

**/
EFI_STATUS
MnpConfigReceiveFilters (
  IN MNP_DEVICE_DATA  *MnpDeviceData
  )
{
  EFI_STATUS                   Status;
  EFI_SIMPLE_NETWORK_PROTOCOL  *Snp;
  EFI_MAC_ADDRESS              *MCastFilter;
  UINT32                       MCastFilterCnt;
  UINT32                       EnableFilterBits;
  UINT32                       DisableFilterBits;
  BOOLEAN                      ResetMCastFilters;
  LIST_ENTRY                   *Entry;
  UINT32                       Index;
  MNP_GROUP_ADDRESS            *GroupAddress;

  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);

  Snp = MnpDeviceData->Snp;

  //
  // Initialize the enable filter and disable filter.
  //
  EnableFilterBits  = 0;
  DisableFilterBits = Snp->Mode->ReceiveFilterMask;

  if (MnpDeviceData->UnicastCount != 0) {
    //
    // Enable unicast if any instance wants to receive unicast.
    //
    EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
  }

  if (MnpDeviceData->BroadcastCount != 0) {
    //
    // Enable broadcast if any instance wants to receive broadcast.
    //
    EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
  }

  MCastFilter       = NULL;
  MCastFilterCnt    = 0;
  ResetMCastFilters = TRUE;

  if ((MnpDeviceData->MulticastCount != 0) && (MnpDeviceData->GroupAddressCount != 0)) {
    //
    // There are instances configured to receive multicast and already some group
    // addresses are joined.
    //

    ResetMCastFilters = FALSE;

    if (MnpDeviceData->GroupAddressCount <= Snp->Mode->MaxMCastFilterCount) {
      //
      // The joind group address is less than simple network's maximum count.
      // Just configure the snp to do the multicast filtering.
      //

      EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;

      //
      // Allocate pool for the multicast addresses.
      //
      MCastFilterCnt = MnpDeviceData->GroupAddressCount;
      MCastFilter    = AllocatePool (sizeof (EFI_MAC_ADDRESS) * MCastFilterCnt);
      if (MCastFilter == NULL) {
        DEBUG ((DEBUG_ERROR, "MnpConfigReceiveFilters: Failed to allocate memory resource for MCastFilter.\n"));

        return EFI_OUT_OF_RESOURCES;
      }

      //
      // Fill the multicast HW address buffer.
      //
      Index = 0;
      NET_LIST_FOR_EACH (Entry, &MnpDeviceData->GroupAddressList) {
        GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
        CopyMem (MCastFilter + Index, &GroupAddress->Address, sizeof (*(MCastFilter + Index)));
        Index++;

        ASSERT (Index <= MCastFilterCnt);
      }
    } else {
      //
      // The maximum multicast is reached, set the filter to be promiscuous
      // multicast.
      //

      if ((Snp->Mode->ReceiveFilterMask & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
        EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
      } else {
        //
        // Either MULTICAST or PROMISCUOUS_MULTICAST is not supported by Snp,
        // set the NIC to be promiscuous although this will tremendously degrade
        // the performance.
        //
        EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
      }
    }
  }

  if (MnpDeviceData->PromiscuousCount != 0) {
    //
    // Enable promiscuous if any instance wants to receive promiscuous.
    //
    EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
  }

  //
  // Set the disable filter.
  //
  DisableFilterBits ^= EnableFilterBits;

  //
  // Configure the receive filters of SNP.
  //
  Status = Snp->ReceiveFilters (
                  Snp,
                  EnableFilterBits,
                  DisableFilterBits,
                  ResetMCastFilters,
                  MCastFilterCnt,
                  MCastFilter
                  );
  DEBUG_CODE_BEGIN ();
  if (EFI_ERROR (Status)) {
    DEBUG (
      (DEBUG_ERROR,
       "MnpConfigReceiveFilters: Snp->ReceiveFilters failed, %r.\n",
       Status)
      );
  }

  DEBUG_CODE_END ();

  if (MCastFilter != NULL) {
    //
    // Free the buffer used to hold the group addresses.
    //
    FreePool (MCastFilter);
  }

  return Status;
}

/**
  Add a group address control block which controls the MacAddress for
  this instance.

  @param[in, out]  Instance        Pointer to the mnp instance context data.
  @param[in, out]  CtrlBlk         Pointer to the group address control block.
  @param[in, out]  GroupAddress    Pointer to the group address.
  @param[in]       MacAddress      Pointer to the mac address.
  @param[in]       HwAddressSize   The hardware address size.

  @retval EFI_SUCCESS              The group address control block is added.
  @retval EFI_OUT_OF_RESOURCES     Failed due to lack of memory resources.

**/
EFI_STATUS
MnpGroupOpAddCtrlBlk (
  IN OUT MNP_INSTANCE_DATA        *Instance,
  IN OUT MNP_GROUP_CONTROL_BLOCK  *CtrlBlk,
  IN OUT MNP_GROUP_ADDRESS        *GroupAddress OPTIONAL,
  IN     EFI_MAC_ADDRESS          *MacAddress,
  IN     UINT32                   HwAddressSize
  )
{
  MNP_DEVICE_DATA  *MnpDeviceData;

  NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);

  MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;
  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);

  if (GroupAddress == NULL) {
    ASSERT (MacAddress != NULL);

    //
    // Allocate a new GroupAddress to be added into MNP's GroupAddressList.
    //
    GroupAddress = AllocatePool (sizeof (MNP_GROUP_ADDRESS));
    if (GroupAddress == NULL) {
      DEBUG ((DEBUG_ERROR, "MnpGroupOpFormCtrlBlk: Failed to allocate memory resource.\n"));

      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (&GroupAddress->Address, MacAddress, sizeof (GroupAddress->Address));
    GroupAddress->RefCnt = 0;
    InsertTailList (
      &MnpDeviceData->GroupAddressList,
      &GroupAddress->AddrEntry
      );
    MnpDeviceData->GroupAddressCount++;
  }

  //
  // Increase the RefCnt.
  //
  GroupAddress->RefCnt++;

  //
  // Add the CtrlBlk into the instance's GroupCtrlBlkList.
  //
  CtrlBlk->GroupAddress = GroupAddress;
  InsertTailList (&Instance->GroupCtrlBlkList, &CtrlBlk->CtrlBlkEntry);

  return EFI_SUCCESS;
}

/**
  Delete a group control block from the instance. If the controlled group address's
  reference count reaches zero, the group address is removed too.

  @param[in]  Instance              Pointer to the instance context data.
  @param[in]  CtrlBlk               Pointer to the group control block to delete.

  @return The group address controlled by the control block is no longer used or not.

**/
BOOLEAN
MnpGroupOpDelCtrlBlk (
  IN MNP_INSTANCE_DATA        *Instance,
  IN MNP_GROUP_CONTROL_BLOCK  *CtrlBlk
  )
{
  MNP_DEVICE_DATA    *MnpDeviceData;
  MNP_GROUP_ADDRESS  *GroupAddress;

  NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);

  MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;
  NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);

  //
  // Remove and free the CtrlBlk.
  //
  GroupAddress = CtrlBlk->GroupAddress;
  RemoveEntryList (&CtrlBlk->CtrlBlkEntry);
  FreePool (CtrlBlk);

  ASSERT (GroupAddress->RefCnt > 0);

  //
  // Count down the RefCnt.
  //
  GroupAddress->RefCnt--;

  if (GroupAddress->RefCnt == 0) {
    //
    // Free this GroupAddress entry if no instance uses it.
    //
    MnpDeviceData->GroupAddressCount--;
    RemoveEntryList (&GroupAddress->AddrEntry);
    FreePool (GroupAddress);

    return TRUE;
  }

  return FALSE;
}

/**
  Do the group operations for this instance.

  @param[in, out]  Instance        Pointer to the instance context data.
  @param[in]       JoinFlag        Set to TRUE to join a group. Set to TRUE to
                                   leave a group/groups.
  @param[in]       MacAddress      Pointer to the group address to join or leave.
  @param[in]       CtrlBlk         Pointer to the group control block if JoinFlag
                                   is FALSE.

  @retval EFI_SUCCESS              The group operation finished.
  @retval EFI_OUT_OF_RESOURCES     Failed due to lack of memory resources.
  @retval Others                   Other errors as indicated.

**/
EFI_STATUS
MnpGroupOp (
  IN OUT MNP_INSTANCE_DATA        *Instance,
  IN     BOOLEAN                  JoinFlag,
  IN     EFI_MAC_ADDRESS          *MacAddress OPTIONAL,
  IN     MNP_GROUP_CONTROL_BLOCK  *CtrlBlk OPTIONAL
  )
{
  MNP_DEVICE_DATA          *MnpDeviceData;
  LIST_ENTRY               *Entry;
  LIST_ENTRY               *NextEntry;
  MNP_GROUP_ADDRESS        *GroupAddress;
  EFI_SIMPLE_NETWORK_MODE  *SnpMode;
  MNP_GROUP_CONTROL_BLOCK  *NewCtrlBlk;
  EFI_STATUS               Status;
  BOOLEAN                  AddressExist;
  BOOLEAN                  NeedUpdate;

  NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);

  MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;
  SnpMode       = MnpDeviceData->Snp->Mode;

  if (JoinFlag) {
    //
    // A new group address is to be added.
    //
    GroupAddress = NULL;
    AddressExist = FALSE;

    //
    // Allocate memory for the control block.
    //
    NewCtrlBlk = AllocatePool (sizeof (MNP_GROUP_CONTROL_BLOCK));
    if (NewCtrlBlk == NULL) {
      DEBUG ((DEBUG_ERROR, "MnpGroupOp: Failed to allocate memory resource.\n"));

      return EFI_OUT_OF_RESOURCES;
    }

    NET_LIST_FOR_EACH (Entry, &MnpDeviceData->GroupAddressList) {
      //
      // Check whether the MacAddress is already joined by other instances.
      //
      GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
      if (CompareMem (MacAddress, &GroupAddress->Address, SnpMode->HwAddressSize) == 0) {
        AddressExist = TRUE;
        break;
      }
    }

    if (!AddressExist) {
      GroupAddress = NULL;
    }

    //
    // Add the GroupAddress for this instance.
    //
    Status = MnpGroupOpAddCtrlBlk (
               Instance,
               NewCtrlBlk,
               GroupAddress,
               MacAddress,
               SnpMode->HwAddressSize
               );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    NeedUpdate = TRUE;
  } else {
    if (MacAddress != NULL) {
      ASSERT (CtrlBlk != NULL);

      //
      // Leave the specific multicast mac address.
      //
      NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, CtrlBlk);
    } else {
      //
      // Leave all multicast mac addresses.
      //
      NeedUpdate = FALSE;

      NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->GroupCtrlBlkList) {
        NewCtrlBlk = NET_LIST_USER_STRUCT (
                       Entry,
                       MNP_GROUP_CONTROL_BLOCK,
                       CtrlBlkEntry
                       );
        //
        // Update is required if the group address left is no longer used
        // by other instances.
        //
        NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, NewCtrlBlk);
      }
    }
  }

  Status = EFI_SUCCESS;

  if (NeedUpdate) {
    //
    // Reconfigure the receive filters if necessary.
    //
    Status = MnpConfigReceiveFilters (MnpDeviceData);
  }

  return Status;
}
