/** @file
  Implementation of Managed Network Protocol public services.

Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "MnpImpl.h"

/**
  Returns the operational parameters for the current MNP child driver. May also
  support returning the underlying SNP driver mode data.

  The GetModeData() function is used to read the current mode data (operational
  parameters) from the MNP or the underlying SNP.

  @param[in]  This          Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
  @param[out] MnpConfigData Pointer to storage for MNP operational parameters. Type
                            EFI_MANAGED_NETWORK_CONFIG_DATA is defined in "Related
                            Definitions" below.
  @param[out] SnpModeData   Pointer to storage for SNP operational parameters. This
                            feature may be unsupported. Type EFI_SIMPLE_NETWORK_MODE
                            is defined in the EFI_SIMPLE_NETWORK_PROTOCOL.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval EFI_INVALID_PARAMETER This is NULL.
  @retval EFI_UNSUPPORTED       The requested feature is unsupported in this
                                MNP implementation.
  @retval EFI_NOT_STARTED       This MNP child driver instance has not been
                                configured. The default values are returned in
                                MnpConfigData if it is not NULL.
  @retval Others                The mode data could not be read.

**/
EFI_STATUS
EFIAPI
MnpGetModeData (
  IN     EFI_MANAGED_NETWORK_PROTOCOL      *This,
     OUT EFI_MANAGED_NETWORK_CONFIG_DATA   *MnpConfigData OPTIONAL,
     OUT EFI_SIMPLE_NETWORK_MODE           *SnpModeData OPTIONAL
  )
{
  MNP_INSTANCE_DATA           *Instance;
  EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
  EFI_TPL                     OldTpl;
  EFI_STATUS                  Status;
  UINT32                      InterruptStatus;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = MNP_INSTANCE_DATA_FROM_THIS (This);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (MnpConfigData != NULL) {
    //
    // Copy the instance configuration data.
    //
    CopyMem (MnpConfigData, &Instance->ConfigData, sizeof (*MnpConfigData));
  }

  if (SnpModeData != NULL) {
    //
    // Copy the underlayer Snp mode data.
    //
    Snp = Instance->MnpServiceData->MnpDeviceData->Snp;

    //
    // Upon successful return of GetStatus(), the Snp->Mode->MediaPresent
    // will be updated to reflect any change of media status
    //
    Snp->GetStatus (Snp, &InterruptStatus, NULL);
    CopyMem (SnpModeData, Snp->Mode, sizeof (*SnpModeData));
  }

  if (!Instance->Configured) {
    Status = EFI_NOT_STARTED;
  } else {
    Status = EFI_SUCCESS;
  }

  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  Sets or clears the operational parameters for the MNP child driver.

  The Configure() function is used to set, change, or reset the operational
  parameters for the MNP child driver instance. Until the operational parameters
  have been set, no network traffic can be sent or received by this MNP child
  driver instance. Once the operational parameters have been reset, no more
  traffic can be sent or received until the operational parameters have been set
  again.
  Each MNP child driver instance can be started and stopped independently of
  each other by setting or resetting their receive filter settings with the
  Configure() function.
  After any successful call to Configure(), the MNP child driver instance is
  started. The internal periodic timer (if supported) is enabled. Data can be
  transmitted and may be received if the receive filters have also been enabled.
  Note: If multiple MNP child driver instances will receive the same packet
  because of overlapping receive filter settings, then the first MNP child
  driver instance will receive the original packet and additional instances will
  receive copies of the original packet.
  Note: Warning: Receive filter settings that overlap will consume extra
  processor and/or DMA resources and degrade system and network performance.

  @param[in]  This           Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
  @param[in]  MnpConfigData  Pointer to configuration data that will be assigned
                             to the MNP child driver instance. If NULL, the MNP
                             child driver instance is reset to startup defaults
                             and all pending transmit and receive requests are
                             flushed. Type EFI_MANAGED_NETWORK_CONFIG_DATA is
                             defined in EFI_MANAGED_NETWORK_PROTOCOL.GetModeData().

  @retval EFI_SUCCESS            The operation completed successfully.
  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is
                                 TRUE:
                                 * This is NULL.
                                 * MnpConfigData.ProtocolTypeFilter is not
                                   valid.
                                 The operational data for the MNP child driver
                                 instance is unchanged.
  @retval EFI_OUT_OF_RESOURCES   Required system resources (usually memory)
                                 could not be allocated.
                                 The MNP child driver instance has been reset to
                                 startup defaults.
  @retval EFI_UNSUPPORTED        The requested feature is unsupported in
                                 this [MNP] implementation. The operational data
                                 for the MNP child driver instance is unchanged.
  @retval EFI_DEVICE_ERROR       An unexpected network or system error
                                 occurred. The MNP child driver instance has
                                 been reset to startup defaults.
  @retval Others                 The MNP child driver instance has been reset to
                                 startup defaults.

**/
EFI_STATUS
EFIAPI
MnpConfigure (
  IN EFI_MANAGED_NETWORK_PROTOCOL        *This,
  IN EFI_MANAGED_NETWORK_CONFIG_DATA     *MnpConfigData OPTIONAL
  )
{
  MNP_INSTANCE_DATA  *Instance;
  EFI_TPL            OldTpl;
  EFI_STATUS         Status;

  if ((This == NULL) ||
      ((MnpConfigData != NULL) &&
       (MnpConfigData->ProtocolTypeFilter > 0) &&
       (MnpConfigData->ProtocolTypeFilter <= 1500))
     ) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = MNP_INSTANCE_DATA_FROM_THIS (This);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if ((MnpConfigData == NULL) && (!Instance->Configured)) {
    //
    // If the instance is not configured and a reset is requested, just return.
    //
    Status = EFI_SUCCESS;
    goto ON_EXIT;
  }

  //
  // Configure the instance.
  //
  Status = MnpConfigureInstance (Instance, MnpConfigData);

ON_EXIT:
  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  Translates an IP multicast address to a hardware (MAC) multicast address. This
  function may be unsupported in some MNP implementations.

  The McastIpToMac() function translates an IP multicast address to a hardware
  (MAC) multicast address. This function may be implemented by calling the
  underlying EFI_SIMPLE_NETWORK. MCastIpToMac() function, which may also be
  unsupported in some MNP implementations.

  @param[in]  This        Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
  @param[in]  Ipv6Flag    Set to TRUE to if IpAddress is an IPv6 multicast address.
                          Set to FALSE if IpAddress is an IPv4 multicast address.
  @param[in]  IpAddress   Pointer to the multicast IP address (in network byte
                          order) to convert.
  @param[out] MacAddress  Pointer to the resulting multicast MAC address.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval EFI_INVALID_PARAMETER One of the following conditions is TRUE:
                                 * This is NULL.
                                 * IpAddress is NULL.
                                 * IpAddress is not a valid multicast IP
                                   address.
                                 * MacAddress is NULL.
  @retval EFI_NOT_STARTED       This MNP child driver instance has not been
                                configured.
  @retval EFI_UNSUPPORTED       The requested feature is unsupported in this
                                MNP implementation.
  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.
  @retval Others                The address could not be converted.
**/
EFI_STATUS
EFIAPI
MnpMcastIpToMac (
  IN     EFI_MANAGED_NETWORK_PROTOCOL    *This,
  IN     BOOLEAN                         Ipv6Flag,
  IN     EFI_IP_ADDRESS                  *IpAddress,
     OUT EFI_MAC_ADDRESS                 *MacAddress
  )
{
  EFI_STATUS                  Status;
  MNP_INSTANCE_DATA           *Instance;
  EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
  EFI_TPL                     OldTpl;
  EFI_IPv6_ADDRESS            *Ip6Address;

  if ((This == NULL) || (IpAddress == NULL) || (MacAddress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Ip6Address = &IpAddress->v6;

  if ((Ipv6Flag && !IP6_IS_MULTICAST (Ip6Address)) ||
      (!Ipv6Flag && !IP4_IS_MULTICAST (EFI_NTOHL (*IpAddress)))
      ) {
    //
    // The IP address passed in is not a multicast address.
    //
    return EFI_INVALID_PARAMETER;
  }

  Instance = MNP_INSTANCE_DATA_FROM_THIS (This);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (!Instance->Configured) {

    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  Snp = Instance->MnpServiceData->MnpDeviceData->Snp;
  ASSERT (Snp != NULL);

  ZeroMem (MacAddress, sizeof (EFI_MAC_ADDRESS));

  if (Snp->Mode->IfType == NET_IFTYPE_ETHERNET) {
    if (!Ipv6Flag) {
      //
      // Translate the IPv4 address into a multicast MAC address if the NIC is an
      // ethernet NIC according to RFC1112..
      //
      MacAddress->Addr[0] = 0x01;
      MacAddress->Addr[1] = 0x00;
      MacAddress->Addr[2] = 0x5E;
      MacAddress->Addr[3] = (UINT8) (IpAddress->v4.Addr[1] & 0x7F);
      MacAddress->Addr[4] = IpAddress->v4.Addr[2];
      MacAddress->Addr[5] = IpAddress->v4.Addr[3];
    } else {
      //
      // Translate the IPv6 address into a multicast MAC address if the NIC is an
      // ethernet NIC according to RFC2464.
      //

      MacAddress->Addr[0] = 0x33;
      MacAddress->Addr[1] = 0x33;
      MacAddress->Addr[2] = Ip6Address->Addr[12];
      MacAddress->Addr[3] = Ip6Address->Addr[13];
      MacAddress->Addr[4] = Ip6Address->Addr[14];
      MacAddress->Addr[5] = Ip6Address->Addr[15];
    }

    Status = EFI_SUCCESS;
  } else {
    //
    // Invoke Snp to translate the multicast IP address.
    //
    Status = Snp->MCastIpToMac (
                    Snp,
                    Ipv6Flag,
                    IpAddress,
                    MacAddress
                    );
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Enables and disables receive filters for multicast address. This function may
  be unsupported in some MNP implementations.

  The Groups() function only adds and removes multicast MAC addresses from the
  filter list. The MNP driver does not transmit or process Internet Group
  Management Protocol (IGMP) packets. If JoinFlag is FALSE and MacAddress is
  NULL, then all joined groups are left.

  @param[in]  This        Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
  @param[in]  JoinFlag    Set to TRUE to join this multicast group.
                          Set to FALSE to leave this multicast group.
  @param[in]  MacAddress  Pointer to the multicast MAC group (address) to join or
                          leave.

  @retval EFI_SUCCESS           The requested operation completed successfully.
  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
                                * This is NULL.
                                * JoinFlag is TRUE and MacAddress is NULL.
                                * MacAddress is not a valid multicast MAC
                                  address.
                                * The MNP multicast group settings are
                                  unchanged.
  @retval EFI_NOT_STARTED       This MNP child driver instance has not been
                                configured.
  @retval EFI_ALREADY_STARTED   The supplied multicast group is already joined.
  @retval EFI_NOT_FOUND         The supplied multicast group is not joined.
  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.
                                The MNP child driver instance has been reset to
                                startup defaults.
  @retval EFI_UNSUPPORTED       The requested feature is unsupported in this MNP
                                implementation.
  @retval Others                The requested operation could not be completed.
                                The MNP multicast group settings are unchanged.

**/
EFI_STATUS
EFIAPI
MnpGroups (
  IN EFI_MANAGED_NETWORK_PROTOCOL    *This,
  IN BOOLEAN                         JoinFlag,
  IN EFI_MAC_ADDRESS                 *MacAddress OPTIONAL
  )
{
  MNP_INSTANCE_DATA       *Instance;
  EFI_SIMPLE_NETWORK_MODE *SnpMode;
  MNP_GROUP_CONTROL_BLOCK *GroupCtrlBlk;
  MNP_GROUP_ADDRESS       *GroupAddress;
  LIST_ENTRY              *ListEntry;
  BOOLEAN                 AddressExist;
  EFI_TPL                 OldTpl;
  EFI_STATUS              Status;

  if (This == NULL || (JoinFlag && (MacAddress == NULL))) {
    //
    // This is NULL, or it's a join operation but MacAddress is NULL.
    //
    return EFI_INVALID_PARAMETER;
  }

  Instance  = MNP_INSTANCE_DATA_FROM_THIS (This);
  SnpMode   = Instance->MnpServiceData->MnpDeviceData->Snp->Mode;

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (!Instance->Configured) {
    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  if ((!Instance->ConfigData.EnableMulticastReceive) ||
    ((MacAddress != NULL) && !NET_MAC_IS_MULTICAST (MacAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize))) {
    //
    // The instance isn't configured to do multicast receive. OR
    // the passed in MacAddress is not a multicast mac address.
    //
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  Status       = EFI_SUCCESS;
  AddressExist = FALSE;
  GroupCtrlBlk = NULL;

  if (MacAddress != NULL) {
    //
    // Search the instance's GroupCtrlBlkList to find the specific address.
    //
    NET_LIST_FOR_EACH (ListEntry, &Instance->GroupCtrlBlkList) {

      GroupCtrlBlk = NET_LIST_USER_STRUCT (
                      ListEntry,
                      MNP_GROUP_CONTROL_BLOCK,
                      CtrlBlkEntry
                      );
      GroupAddress = GroupCtrlBlk->GroupAddress;
      if (0 == CompareMem (
                MacAddress,
                &GroupAddress->Address,
                SnpMode->HwAddressSize
                )) {
        //
        // There is already the same multicast mac address configured.
        //
        AddressExist = TRUE;
        break;
      }
    }

    if (JoinFlag && AddressExist) {
      //
      // The multicast mac address to join already exists.
      //
      Status = EFI_ALREADY_STARTED;
    }

    if (!JoinFlag && !AddressExist) {
      //
      // The multicast mac address to leave doesn't exist in this instance.
      //
      Status = EFI_NOT_FOUND;
    }

    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  } else if (IsListEmpty (&Instance->GroupCtrlBlkList)) {
    //
    // The MacAddress is NULL and there is no configured multicast mac address,
    // just return.
    //
    goto ON_EXIT;
  }

  //
  // OK, it is time to take action.
  //
  Status = MnpGroupOp (Instance, JoinFlag, MacAddress, GroupCtrlBlk);

ON_EXIT:
  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Places asynchronous outgoing data packets into the transmit queue.

  The Transmit() function places a completion token into the transmit packet
  queue. This function is always asynchronous.
  The caller must fill in the Token.Event and Token.TxData fields in the
  completion token, and these fields cannot be NULL. When the transmit operation
  completes, the MNP updates the Token.Status field and the Token.Event is
  signaled.
  Note: There may be a performance penalty if the packet needs to be
  defragmented before it can be transmitted by the network device. Systems in
  which performance is critical should review the requirements and features of
  the underlying communications device and drivers.


  @param[in]  This    Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
  @param[in]  Token   Pointer to a token associated with the transmit data
                      descriptor. Type EFI_MANAGED_NETWORK_COMPLETION_TOKEN
                      is defined in "Related Definitions" below.

  @retval EFI_SUCCESS            The transmit completion token was cached.
  @retval EFI_NOT_STARTED        This MNP child driver instance has not been
                                 configured.
  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is
                                 TRUE:
                                 * This is NULL.
                                 * Token is NULL.
                                 * Token.Event is NULL.
                                 * Token.TxData is NULL.
                                 * Token.TxData.DestinationAddress is not
                                   NULL and Token.TxData.HeaderLength is zero.
                                 * Token.TxData.FragmentCount is zero.
                                 * (Token.TxData.HeaderLength +
                                   Token.TxData.DataLength) is not equal to the
                                   sum of the
                                   Token.TxData.FragmentTable[].FragmentLength
                                   fields.
                                 * One or more of the
                                   Token.TxData.FragmentTable[].FragmentLength
                                   fields is zero.
                                 * One or more of the
                                   Token.TxData.FragmentTable[].FragmentBufferfields
                                   is NULL.
                                 * Token.TxData.DataLength is greater than MTU.
  @retval EFI_ACCESS_DENIED      The transmit completion token is already in the
                                 transmit queue.
  @retval EFI_OUT_OF_RESOURCES   The transmit data could not be queued due to a
                                 lack of system resources (usually memory).
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
                                 The MNP child driver instance has been reset to
                                 startup defaults.
  @retval EFI_NOT_READY          The transmit request could not be queued because
                                 the transmit queue is full.

**/
EFI_STATUS
EFIAPI
MnpTransmit (
  IN EFI_MANAGED_NETWORK_PROTOCOL            *This,
  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN    *Token
  )
{
  EFI_STATUS        Status;
  MNP_INSTANCE_DATA *Instance;
  MNP_SERVICE_DATA  *MnpServiceData;
  UINT8             *PktBuf;
  UINT32            PktLen;
  EFI_TPL           OldTpl;

  if ((This == NULL) || (Token == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = MNP_INSTANCE_DATA_FROM_THIS (This);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (!Instance->Configured) {

    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  if (!MnpIsValidTxToken (Instance, Token)) {
    //
    // The Token is invalid.
    //
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  MnpServiceData = Instance->MnpServiceData;
  NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);

  //
  // Build the tx packet
  //
  Status = MnpBuildTxPacket (MnpServiceData, Token->Packet.TxData, &PktBuf, &PktLen);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  //  OK, send the packet synchronously.
  //
  Status = MnpSyncSendPacket (MnpServiceData, PktBuf, PktLen, Token);

ON_EXIT:
  gBS->RestoreTPL (OldTpl);

  return Status;
}


/**
  Places an asynchronous receiving request into the receiving queue.

  The Receive() function places a completion token into the receive packet
  queue. This function is always asynchronous.
  The caller must fill in the Token.Event field in the completion token, and
  this field cannot be NULL. When the receive operation completes, the MNP
  updates the Token.Status and Token.RxData fields and the Token.Event is
  signaled.

  @param[in]  This      Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
  @param[in]  Token     Pointer to a token associated with the receive
                        data descriptor. Type
                        EFI_MANAGED_NETWORK_COMPLETION_TOKEN is defined in
                        EFI_MANAGED_NETWORK_PROTOCOL.Transmit().

  @retval EFI_SUCCESS            The receive completion token was cached.
  @retval EFI_NOT_STARTED        This MNP child driver instance has not been
                                 configured.
  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is
                                 TRUE:
                                 * This is NULL.
                                 * Token is NULL.
                                 * Token.Event is NULL
  @retval EFI_OUT_OF_RESOURCES   The transmit data could not be queued due to a
                                 lack of system resources (usually memory).
  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
                                 The MNP child driver instance has been reset to
                                 startup defaults.
  @retval EFI_ACCESS_DENIED      The receive completion token was already in the
                                 receive queue.
  @retval EFI_NOT_READY          The receive request could not be queued because
                                 the receive queue is full.

**/
EFI_STATUS
EFIAPI
MnpReceive (
  IN EFI_MANAGED_NETWORK_PROTOCOL            *This,
  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN    *Token
  )
{
  EFI_STATUS         Status;
  MNP_INSTANCE_DATA  *Instance;
  EFI_TPL            OldTpl;

  if ((This == NULL) || (Token == NULL) || (Token->Event == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = MNP_INSTANCE_DATA_FROM_THIS (This);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (!Instance->Configured) {
    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  //
  // Check whether this token(event) is already in the rx token queue.
  //
  Status = NetMapIterate (&Instance->RxTokenMap, MnpTokenExist, (VOID *) Token);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Insert the Token into the RxTokenMap.
  //
  Status = NetMapInsertTail (&Instance->RxTokenMap, (VOID *) Token, NULL);
  if (!EFI_ERROR (Status)) {
    //
    // Try to deliver any buffered packets.
    //
    Status = MnpInstanceDeliverPacket (Instance);

    //
    // Dispatch the DPC queued by the NotifyFunction of Token->Event.
    //
    DispatchDpc ();
  }

ON_EXIT:
  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Aborts an asynchronous transmit or receive request.

  The Cancel() function is used to abort a pending transmit or receive request.
  If the token is in the transmit or receive request queues, after calling this
  function, Token.Status will be set to EFI_ABORTED and then Token.Event will be
  signaled. If the token is not in one of the queues, which usually means that
  the asynchronous operation has completed, this function will not signal the
  token and EFI_NOT_FOUND is returned.

  @param[in]  This     Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
  @param[in]  Token    Pointer to a token that has been issued by
                       EFI_MANAGED_NETWORK_PROTOCOL.Transmit() or
                       EFI_MANAGED_NETWORK_PROTOCOL.Receive(). If NULL, all
                       pending tokens are aborted.

  @retval EFI_SUCCESS            The asynchronous I/O request was aborted and
                                 Token.Event was signaled. When Token is NULL,
                                 all pending requests were aborted and their
                                 events were signaled.
  @retval EFI_NOT_STARTED        This MNP child driver instance has not been
                                 configured.
  @retval EFI_INVALID_PARAMETER  This is NULL.
  @retval EFI_NOT_FOUND          When Token is not NULL, the asynchronous I/O
                                 request was not found in the transmit or
                                 receive queue. It has either completed or was
                                 not issued by Transmit() and Receive().

**/
EFI_STATUS
EFIAPI
MnpCancel (
  IN EFI_MANAGED_NETWORK_PROTOCOL            *This,
  IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN    *Token OPTIONAL
  )
{
  EFI_STATUS         Status;
  MNP_INSTANCE_DATA  *Instance;
  EFI_TPL            OldTpl;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = MNP_INSTANCE_DATA_FROM_THIS (This);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (!Instance->Configured) {
    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  //
  // Iterate the RxTokenMap to cancel the specified Token.
  //
  Status = NetMapIterate (&Instance->RxTokenMap, MnpCancelTokens, (VOID *) Token);
  if (Token != NULL) {
    Status = (Status == EFI_ABORTED) ? EFI_SUCCESS : EFI_NOT_FOUND;
  }

  //
  // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.
  //
  DispatchDpc ();

ON_EXIT:
  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Polls for incoming data packets and processes outgoing data packets.

  The Poll() function can be used by network drivers and applications to
  increase the rate that data packets are moved between the communications
  device and the transmit and receive queues.
  Normally, a periodic timer event internally calls the Poll() function. But, in
  some systems, the periodic timer event may not call Poll() fast enough to
  transmit and/or receive all data packets without missing packets. Drivers and
  applications that are experiencing packet loss should try calling the Poll()
  function more often.

  @param[in]  This         Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.

  @retval EFI_SUCCESS      Incoming or outgoing data was processed.
  @retval EFI_NOT_STARTED  This MNP child driver instance has not been
                           configured.
  @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The
                           MNP child driver instance has been reset to startup
                           defaults.
  @retval EFI_NOT_READY    No incoming or outgoing data was processed. Consider
                           increasing the polling rate.
  @retval EFI_TIMEOUT      Data was dropped out of the transmit and/or receive
                           queue. Consider increasing the polling rate.

**/
EFI_STATUS
EFIAPI
MnpPoll (
  IN EFI_MANAGED_NETWORK_PROTOCOL    *This
  )
{
  EFI_STATUS         Status;
  MNP_INSTANCE_DATA  *Instance;
  EFI_TPL            OldTpl;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Instance = MNP_INSTANCE_DATA_FROM_THIS (This);

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  if (!Instance->Configured) {
    Status = EFI_NOT_STARTED;
    goto ON_EXIT;
  }

  //
  // Try to receive packets.
  //
  Status = MnpReceivePacket (Instance->MnpServiceData->MnpDeviceData);

  //
  // Dispatch the DPC queued by the NotifyFunction of rx token's events.
  //
  DispatchDpc ();

ON_EXIT:
  gBS->RestoreTPL (OldTpl);

  return Status;
}
