/** @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;
}
