/** @file
  This file contains code for UNDI command based on UEFI specification.

  Copyright (c) 2023, American Megatrends International LLC. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include "DriverBinding.h"

// API table, defined in UEFI specification
API_FUNC  gUndiApiTable[] = {
  UndiGetState,
  UndiStart,
  UndiStop,
  UndiGetInitInfo,
  UndiGetConfigInfo,
  UndiInitialize,
  UndiReset,
  UndiShutdown,
  UndiInterruptEnable,
  UndiReceiveFilter,
  UndiStationAddress,
  UndiStatistics,
  UndiMcastIp2Mac,
  UndiNvData,
  UndiGetStatus,
  UndiFillHeader,
  UndiTransmit,
  UndiReceive
};

/**
   Callback function for enable Rate Limiter.

   @param[in] Event           Event whose notification function is being invoked
   @param[in] Context         Pointer to the notification function's context

**/
VOID
EFIAPI
UndiRateLimiterCallback (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  NIC_DATA  *Nic;

  Nic = Context;

  if (Nic->RateLimitingCreditCount < Nic->RateLimitingCredit) {
    Nic->RateLimitingCreditCount++;
  }
}

/**
  This command is used to determine the operational state of the UNDI.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiGetState (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  EFI_STATUS  Status;

  if ((Cdb->OpCode != PXE_OPCODE_GET_STATE) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != PXE_CPBSIZE_NOT_USED) ||
      (Cdb->CPBaddr != PXE_CPBADDR_NOT_USED) ||
      (Cdb->DBsize != PXE_DBSIZE_NOT_USED) ||
      (Cdb->DBaddr != PXE_DBADDR_NOT_USED) ||
      (Cdb->OpFlags != PXE_OPFLAGS_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  Cdb->StatFlags = Cdb->StatFlags | Nic->State;

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiGetState != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiGetState (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  This command is used to change the UNDI operational state from stopped to started.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiStart (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  PXE_CPB_START_31  *Cpb;
  EFI_STATUS        Status;
  BOOLEAN           EventError;

  if ((Cdb->OpCode != PXE_OPCODE_START) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != sizeof (PXE_CPB_START_31)) ||
      (Cdb->DBsize != PXE_DBSIZE_NOT_USED) ||
      (Cdb->DBaddr != PXE_DBADDR_NOT_USED) ||
      (Cdb->OpFlags != PXE_OPFLAGS_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_STOPPED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_ALREADY_STARTED;
    return;
  }

  Cpb = (PXE_CPB_START_31 *)(UINTN)Cdb->CPBaddr;

  Nic->PxeStart.Delay     = Cpb->Delay;
  Nic->PxeStart.Virt2Phys = Cpb->Virt2Phys;
  Nic->PxeStart.Block     = Cpb->Block;
  Nic->PxeStart.Map_Mem   = 0;
  Nic->PxeStart.UnMap_Mem = 0;
  Nic->PxeStart.Sync_Mem  = Cpb->Sync_Mem;
  Nic->PxeStart.Unique_ID = Cpb->Unique_ID;
  EventError              = FALSE;
  Status                  = EFI_SUCCESS;
  if (Nic->RateLimitingEnable == TRUE) {
    Status = gBS->CreateEvent (
                    EVT_TIMER | EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    UndiRateLimiterCallback,
                    Nic,
                    &Nic->RateLimiter
                    );
    if (!EFI_ERROR (Status)) {
      Status = gBS->SetTimer (
                      Nic->RateLimiter,
                      TimerPeriodic,
                      Nic->RateLimitingPollTimer * 10000
                      );
      if (EFI_ERROR (Status)) {
        EventError = TRUE;
      }
    }
  }

  if ((Nic->UsbEth->UsbEthUndi.UsbEthUndiStart != NULL) && (EventError == FALSE)) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiStart (Cdb, Nic);
  }

  if (!EFI_ERROR (Status)) {
    // Initial the state for UNDI start.
    Nic->State     = PXE_STATFLAGS_GET_STATE_STARTED;
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  } else {
    if (Nic->RateLimitingEnable == TRUE) {
      if (!EventError) {
        gBS->SetTimer (&Nic->RateLimiter, TimerCancel, 0);
      }

      if (Nic->RateLimiter) {
        gBS->CloseEvent (&Nic->RateLimiter);
        Nic->RateLimiter = 0;
      }
    }

    // Initial the state when UNDI start is fail
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_DEVICE_FAILURE;
  }
}

/**
  This command is used to change the UNDI operational state from started to stopped.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiStop (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  EFI_STATUS  Status;

  if ((Cdb->OpCode != PXE_OPCODE_STOP) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != PXE_CPBSIZE_NOT_USED) ||
      (Cdb->CPBaddr != PXE_CPBADDR_NOT_USED) ||
      (Cdb->DBsize != PXE_DBSIZE_NOT_USED) ||
      (Cdb->DBaddr != PXE_DBADDR_NOT_USED) ||
      (Cdb->OpFlags != PXE_OPFLAGS_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State == PXE_STATFLAGS_GET_STATE_STOPPED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_NOT_STARTED;
    return;
  }

  if (Nic->State == PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_NOT_SHUTDOWN;
    return;
  }

  Nic->PxeStart.Delay     = 0;
  Nic->PxeStart.Virt2Phys = 0;
  Nic->PxeStart.Block     = 0;
  Nic->PxeStart.Map_Mem   = 0;
  Nic->PxeStart.UnMap_Mem = 0;
  Nic->PxeStart.Sync_Mem  = 0;
  Nic->State              = PXE_STATFLAGS_GET_STATE_STOPPED;

  if (Nic->RateLimitingEnable == TRUE) {
    gBS->SetTimer (&Nic->RateLimiter, TimerCancel, 0);
    gBS->CloseEvent (&Nic->RateLimiter);
  }

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiStop != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiStop (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  This command is used to retrieve initialization information that is
  needed by drivers and applications to initialized UNDI.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiGetInitInfo (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  PXE_DB_GET_INIT_INFO  *Db;
  EFI_STATUS            Status;

  if ((Cdb->OpCode != PXE_OPCODE_GET_INIT_INFO) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != PXE_CPBSIZE_NOT_USED) ||
      (Cdb->CPBaddr != PXE_CPBADDR_NOT_USED) ||
      (Cdb->DBsize != sizeof (PXE_DB_GET_INIT_INFO)) ||
      (Cdb->OpFlags != PXE_OPFLAGS_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State == PXE_STATFLAGS_GET_STATE_STOPPED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_NOT_STARTED;
    return;
  }

  Db = (PXE_DB_GET_INIT_INFO *)(UINTN)Cdb->DBaddr;

  Db->MemoryRequired         = MEMORY_REQUIRE;
  Db->FrameDataLen           = PXE_MAX_TXRX_UNIT_ETHER;
  Db->LinkSpeeds[0]          = 10;
  Db->LinkSpeeds[1]          = 100;
  Db->LinkSpeeds[2]          = 1000;
  Db->LinkSpeeds[3]          = 0;
  Db->MediaHeaderLen         = PXE_MAC_HEADER_LEN_ETHER;
  Db->HWaddrLen              = PXE_HWADDR_LEN_ETHER;
  Db->MCastFilterCnt         = MAX_MCAST_ADDRESS_CNT;
  Db->TxBufCnt               = Nic->PxeInit.TxBufCnt;
  Db->TxBufSize              = Nic->PxeInit.TxBufSize;
  Db->RxBufCnt               = Nic->PxeInit.RxBufCnt;
  Db->RxBufSize              = Nic->PxeInit.RxBufSize;
  Db->IFtype                 = PXE_IFTYPE_ETHERNET;
  Db->SupportedDuplexModes   = PXE_DUPLEX_DEFAULT;
  Db->SupportedLoopBackModes = LOOPBACK_NORMAL;

  Cdb->StatFlags |= (PXE_STATFLAGS_CABLE_DETECT_SUPPORTED |
                     PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED);

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiGetInitInfo != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiGetInitInfo (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  This command is used to retrieve configuration information about
  the NIC being controlled by the UNDI.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiGetConfigInfo (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  PXE_DB_GET_CONFIG_INFO  *Db;
  EFI_STATUS              Status;

  if ((Cdb->OpCode != PXE_OPCODE_GET_CONFIG_INFO) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != PXE_CPBSIZE_NOT_USED) ||
      (Cdb->CPBaddr != PXE_CPBADDR_NOT_USED) ||
      (Cdb->DBsize != sizeof (PXE_DB_GET_CONFIG_INFO)) ||
      (Cdb->OpFlags != PXE_OPFLAGS_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State == PXE_STATFLAGS_GET_STATE_STOPPED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_NOT_STARTED;
    return;
  }

  Db = (PXE_DB_GET_CONFIG_INFO *)(UINTN)Cdb->DBaddr;

  Db->pci.BusType = PXE_BUSTYPE_USB;

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiGetConfigInfo != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiGetConfigInfo (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  This command resets the network adapter and initializes UNDI using
  the parameters supplied in the CPB.

  @param[in]      Cdb  A pointer to the command descriptor block.
  @param[in, out] Nic  A pointer to the Network interface controller data.

**/
VOID
UndiInitialize (
  IN      PXE_CDB   *Cdb,
  IN OUT  NIC_DATA  *Nic
  )
{
  PXE_CPB_INITIALIZE  *Cpb;
  PXE_DB_INITIALIZE   *Db;
  EFI_STATUS          Status;

  if ((Cdb->OpCode != PXE_OPCODE_INITIALIZE) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != sizeof (PXE_CPB_INITIALIZE)))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
  }

  if (Nic->State == PXE_STATFLAGS_GET_STATE_STOPPED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_NOT_STARTED;
    return;
  }

  if ((Cdb->OpFlags != PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) &&
      (Cdb->OpFlags != PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  }

  if (Nic->State == PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_ALREADY_INITIALIZED;
    return;
  }

  Cpb = (PXE_CPB_INITIALIZE *)(UINTN)Cdb->CPBaddr;
  Db  = (PXE_DB_INITIALIZE *)(UINTN)Cdb->DBaddr;

  Nic->PxeInit.LinkSpeed    = Cpb->LinkSpeed;
  Nic->PxeInit.DuplexMode   = Cpb->DuplexMode;
  Nic->PxeInit.LoopBackMode = Cpb->LoopBackMode;
  Nic->PxeInit.MemoryAddr   = Cpb->MemoryAddr;
  Nic->PxeInit.MemoryLength = Cpb->MemoryLength;
  Nic->PxeInit.TxBufCnt     = TX_BUFFER_COUNT;
  Nic->PxeInit.TxBufSize    = Nic->MaxSegmentSize;
  Nic->PxeInit.RxBufCnt     = RX_BUFFER_COUNT;
  Nic->PxeInit.RxBufSize    = Nic->MaxSegmentSize;

  Cdb->StatCode = Initialize (Cdb, Nic);

  Db->MemoryUsed = MEMORY_REQUIRE;
  Db->TxBufCnt   = Nic->PxeInit.TxBufCnt;
  Db->TxBufSize  = Nic->PxeInit.TxBufSize;
  Db->RxBufCnt   = Nic->PxeInit.RxBufCnt;
  Db->RxBufSize  = Nic->PxeInit.RxBufSize;

  Nic->RxFilter    = PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
  Nic->CanTransmit = FALSE;

  if (Cdb->OpFlags == PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) {
    if ((Nic->Request.Request == USB_CDC_NETWORK_CONNECTION) && (Nic->Request.Value == NETWORK_DISCONNECT)) {
      Nic->CableDetect = 0;
    } else if ((Nic->Request.Request == USB_CDC_NETWORK_CONNECTION) && (Nic->Request.Value == NETWORK_CONNECTED)) {
      Nic->CableDetect = 1;
    }

    if (Nic->CableDetect == 0) {
      Cdb->StatFlags |= PXE_STATFLAGS_INITIALIZED_NO_MEDIA;
    }
  }

  if (Cdb->StatCode != PXE_STATCODE_SUCCESS) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
  } else {
    Nic->State = PXE_STATFLAGS_GET_STATE_INITIALIZED;
  }

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiInitialize != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiInitialize (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  Initialize Network interface controller data.

  @param[in]      Cdb     A pointer to the command descriptor block.
  @param[in, out] Nic     A pointer to the Network interface controller data.

  @retval Status  A value of Pxe statcode.

**/
UINT16
Initialize (
  IN      PXE_CDB   *Cdb,
  IN OUT  NIC_DATA  *Nic
  )
{
  UINTN       Status;
  UINT32      Index;
  EFI_STATUS  EfiStatus;

  Status = MapIt (
             Nic,
             Nic->PxeInit.MemoryAddr,
             Nic->PxeInit.MemoryLength,
             TO_AND_FROM_DEVICE,
             (UINT64)(UINTN)&Nic->MappedAddr
             );

  if (Status != 0) {
    return (UINT16)Status;
  }

  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
    Nic->PermNodeAddress[Index] = Nic->MacAddr.Addr[Index];
  }

  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
    Nic->CurrentNodeAddress[Index] = Nic->PermNodeAddress[Index];
  }

  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
    Nic->BroadcastNodeAddress[Index] = 0xFF;
  }

  for (Index = PXE_HWADDR_LEN_ETHER; Index < PXE_MAC_LENGTH; Index++) {
    Nic->CurrentNodeAddress[Index]   = 0;
    Nic->PermNodeAddress[Index]      = 0;
    Nic->BroadcastNodeAddress[Index] = 0;
  }

  if (Nic->UsbEth->UsbEthInitialize != NULL) {
    EfiStatus = Nic->UsbEth->UsbEthInitialize (Cdb, Nic);
    if (EFI_ERROR (EfiStatus)) {
      return PXE_STATFLAGS_COMMAND_FAILED;
    }
  }

  return (UINT16)Status;
}

/**
  This command resets the network adapter and reinitializes the UNDI
  with the same parameters provided in the Initialize command.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiReset (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  EFI_STATUS  Status;

  if ((Cdb->OpCode != PXE_OPCODE_RESET) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != PXE_CPBSIZE_NOT_USED) ||
      (Cdb->CPBaddr != PXE_CPBADDR_NOT_USED) ||
      (Cdb->DBsize != PXE_DBSIZE_NOT_USED) ||
      (Cdb->DBaddr != PXE_DBADDR_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    return;
  }

  if ((Cdb->OpFlags != PXE_OPFLAGS_NOT_USED) &&
      (Cdb->OpFlags != PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS) &&
      (Cdb->OpFlags != PXE_OPFLAGS_RESET_DISABLE_FILTERS))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  }

  if ((Cdb->OpFlags & PXE_OPFLAGS_RESET_DISABLE_FILTERS) == 0) {
    Nic->RxFilter = PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
  }

  if ((Cdb->OpFlags & PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS) != 0) {
    Nic->InterrupOpFlag = 0;
  }

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiReset != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiReset (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  The Shutdown command resets the network adapter and leaves it in a
  safe state for another driver to initialize.

  @param[in]      Cdb  A pointer to the command descriptor block.
  @param[in, out] Nic  A pointer to the Network interface controller data.

**/
VOID
UndiShutdown (
  IN      PXE_CDB   *Cdb,
  IN OUT  NIC_DATA  *Nic
  )
{
  EFI_STATUS  Status;

  if ((Cdb->OpCode != PXE_OPCODE_SHUTDOWN) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != PXE_CPBSIZE_NOT_USED) ||
      (Cdb->CPBaddr != PXE_CPBADDR_NOT_USED) ||
      (Cdb->DBsize != PXE_DBSIZE_NOT_USED) ||
      (Cdb->DBaddr != PXE_DBADDR_NOT_USED) ||
      (Cdb->OpFlags != PXE_OPFLAGS_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    return;
  }

  Nic->CanTransmit = FALSE;

  Nic->State = PXE_STATFLAGS_GET_STATE_STARTED;

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiShutdown != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiShutdown (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  The Interrupt Enables command can be used to read and/or change
  the current external interrupt enable settings.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiInterruptEnable (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  EFI_STATUS  Status;

  Cdb->StatCode = PXE_STATCODE_UNSUPPORTED;
  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiInterruptEnable != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiInterruptEnable (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    } else {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
      Cdb->StatCode  = PXE_STATCODE_SUCCESS;
    }
  }
}

/**
  This command is used to read and change receive filters and,
  if supported, read and change the multicast MAC address filter list.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiReceiveFilter (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  UINT16                  NewFilter;
  PXE_DB_RECEIVE_FILTERS  *Db;
  EFI_STATUS              Status;

  if ((Cdb->OpCode != PXE_OPCODE_RECEIVE_FILTERS) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    return;
  }

  NewFilter = (UINT16)(Cdb->OpFlags & 0x1F);

  switch (Cdb->OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_OPMASK) {
    case PXE_OPFLAGS_RECEIVE_FILTER_READ:
      if (Cdb->CPBsize != PXE_CPBSIZE_NOT_USED) {
        Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
        Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
      }

      if ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) == 0) {
        if ((Cdb->DBsize != 0)) {
          Db = (PXE_DB_RECEIVE_FILTERS *)(UINTN)Cdb->DBaddr;
          CopyMem (Db, &Nic->McastList, Nic->McastCount);
        }
      }

      break;

    case PXE_OPFLAGS_RECEIVE_FILTER_ENABLE:
      if (NewFilter == 0) {
        Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
      }

      if (Cdb->CPBsize != 0) {
        if (((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) == 0) ||
            ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) ||
            ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) ||
            ((Cdb->CPBsize % sizeof (PXE_MAC_ADDR)) != 0))
        {
          Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
        }
      }

      if ((Cdb->OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
        if (((Cdb->OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) ||
            ((Cdb->OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0))
        {
          Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
        }

        if (Cdb->CPBsize == 0) {
          Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
        }
      }

      Cdb->StatCode = SetFilter (Nic, NewFilter, Cdb->CPBaddr, Cdb->CPBsize);
      break;

    case PXE_OPFLAGS_RECEIVE_FILTER_DISABLE:
      if (Cdb->CPBsize != PXE_CPBSIZE_NOT_USED) {
        Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
        Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
      }

      break;

    default:
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
      Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
  }

  Cdb->StatFlags = (PXE_STATFLAGS)(Cdb->StatFlags | Nic->RxFilter);

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiReceiveFilter != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiReceiveFilter (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  Set PXE receive filter.

  @param[in]  Nic         A pointer to the Network interface controller data.
  @param[in]  SetFilter   PXE receive filter
  @param[in]  CpbAddr     Command Parameter Block Address
  @param[in]  CpbSize     Command Parameter Block Size

**/
UINT16
SetFilter (
  IN  NIC_DATA  *Nic,
  IN  UINT16    SetFilter,
  IN  UINT64    CpbAddr,
  IN  UINT32    CpbSize
  )
{
  EFI_STATUS                   Status;
  UINT8                        *McastList;
  UINT8                        Count;
  UINT8                        Index1;
  UINT8                        Index2;
  PXE_CPB_RECEIVE_FILTERS      *Cpb;
  USB_ETHERNET_FUN_DESCRIPTOR  UsbEthFunDescriptor;

  Count = 0;
  Cpb   = (PXE_CPB_RECEIVE_FILTERS *)(UINTN)CpbAddr;

  // The Cpb could be NULL.(ref:PXE_CPBADDR_NOT_USED)
  Nic->RxFilter = (UINT8)SetFilter;

  if (((SetFilter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) || (Cpb != NULL)) {
    if (Cpb != NULL) {
      Nic->McastCount = (UINT8)(CpbSize / PXE_MAC_LENGTH);
      CopyMem (&Nic->McastList, Cpb, Nic->McastCount);
    }

    Nic->UsbEth->UsbEthFunDescriptor (Nic->UsbEth, &UsbEthFunDescriptor);
    if ((UsbEthFunDescriptor.NumberMcFilters & MAC_FILTERS_MASK) == 0) {
      Nic->RxFilter |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
      Nic->UsbEth->SetUsbEthPacketFilter (Nic->UsbEth, Nic->RxFilter);
    } else {
      Status = gBS->AllocatePool (EfiBootServicesData, Nic->McastCount * 6, (VOID **)&McastList);
      if (EFI_ERROR (Status)) {
        return PXE_STATCODE_INVALID_PARAMETER;
      }

      if (Cpb != NULL) {
        for (Index1 = 0; Index1 < Nic->McastCount; Index1++) {
          for (Index2 = 0; Index2 < 6; Index2++) {
            McastList[Count++] = Cpb->MCastList[Index1][Index2];
          }
        }
      }

      Nic->RxFilter |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
      if (Cpb != NULL) {
        Nic->UsbEth->SetUsbEthMcastFilter (Nic->UsbEth, Nic->McastCount, McastList);
      }

      Nic->UsbEth->SetUsbEthPacketFilter (Nic->UsbEth, Nic->RxFilter);
      FreePool (McastList);
    }
  }

  return PXE_STATCODE_SUCCESS;
}

/**
  This command is used to get current station and broadcast MAC addresses
  and, if supported, to change the current station MAC address.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiStationAddress (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  PXE_CPB_STATION_ADDRESS  *Cpb;
  PXE_DB_STATION_ADDRESS   *Db;
  UINT16                   Index;
  EFI_STATUS               Status;

  if ((Cdb->OpCode != PXE_OPCODE_STATION_ADDRESS) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->DBsize != sizeof (PXE_DB_STATION_ADDRESS)))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    return;
  }

  if (Cdb->OpFlags == PXE_OPFLAGS_STATION_ADDRESS_RESET) {
    if (CompareMem (&Nic->CurrentNodeAddress[0], &Nic->PermNodeAddress[0], PXE_MAC_LENGTH) != 0) {
      for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
        Nic->CurrentNodeAddress[Index] = Nic->PermNodeAddress[Index];
      }
    }
  }

  if (Cdb->CPBaddr != 0) {
    Cpb = (PXE_CPB_STATION_ADDRESS *)(UINTN)Cdb->CPBaddr;
    for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
      Nic->CurrentNodeAddress[Index] = Cpb->StationAddr[Index];
    }
  }

  if (Cdb->DBaddr != 0) {
    Db = (PXE_DB_STATION_ADDRESS *)(UINTN)Cdb->DBaddr;
    for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
      Db->StationAddr[Index]   = Nic->CurrentNodeAddress[Index];
      Db->BroadcastAddr[Index] = Nic->BroadcastNodeAddress[Index];
      Db->PermanentAddr[Index] = Nic->PermNodeAddress[Index];
    }
  }

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiStationAddress != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiStationAddress (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  This command is used to read and clear the NIC traffic statistics.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiStatistics (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  EFI_STATUS  Status;

  if ((Cdb->OpCode != PXE_OPCODE_STATISTICS) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != PXE_CPBSIZE_NOT_USED) ||
      (Cdb->CPBaddr != PXE_CPBADDR_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    return;
  }

  if ((Cdb->OpFlags != PXE_OPFLAGS_STATISTICS_RESET) &&
      (Cdb->OpFlags != PXE_OPFLAGS_STATISTICS_READ))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  }

  Cdb->StatCode = Statistics (Nic, Cdb->DBaddr, Cdb->DBsize);

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiStatistics != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiStatistics (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  Return data for DB data.

  @param[in]  Nic      A pointer to the Network interface controller data.
  @param[in]  DbAddr   Data Block Address.
  @param[in]  DbSize   Data Block Size.

**/
UINT16
Statistics (
  IN NIC_DATA  *Nic,
  IN UINT64    DbAddr,
  IN UINT16    DbSize
  )
{
  PXE_DB_STATISTICS  *DbStatistic;
  EFI_STATUS         Status;

  DbStatistic = (PXE_DB_STATISTICS *)(UINTN)DbAddr;

  if (DbSize == 0) {
    return PXE_STATCODE_SUCCESS;
  }

  DbStatistic->Supported  = 0x802;
  DbStatistic->Data[0x01] = Nic->RxFrame;
  DbStatistic->Data[0x0B] = Nic->TxFrame;

  if (Nic->UsbEth->UsbEthStatistics != NULL) {
    Status = Nic->UsbEth->UsbEthStatistics (Nic, DbAddr, DbSize);
    if (EFI_ERROR (Status)) {
      return PXE_STATFLAGS_COMMAND_FAILED;
    }
  }

  return PXE_STATCODE_SUCCESS;
}

/**
  Translate a multicast IPv4 or IPv6 address to a multicast MAC address.

  @param[in, out] Cdb  A pointer to the command descriptor block.
  @param[in]      Nic  A pointer to the Network interface controller data.

**/
VOID
UndiMcastIp2Mac (
  IN OUT  PXE_CDB   *Cdb,
  IN      NIC_DATA  *Nic
  )
{
  PXE_CPB_MCAST_IP_TO_MAC  *Cpb;
  PXE_DB_MCAST_IP_TO_MAC   *Db;
  UINT8                    *Tmp;
  EFI_STATUS               Status;

  if ((Cdb->OpCode != PXE_OPCODE_MCAST_IP_TO_MAC) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != sizeof (PXE_CPB_MCAST_IP_TO_MAC)) ||
      (Cdb->DBsize != sizeof (PXE_DB_MCAST_IP_TO_MAC)))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    return;
  }

  Cpb = (PXE_CPB_MCAST_IP_TO_MAC *)(UINTN)Cdb->CPBaddr;
  Db  = (PXE_DB_MCAST_IP_TO_MAC *)(UINTN)Cdb->DBaddr;

  if ((Cdb->OpFlags & PXE_OPFLAGS_MCAST_IPV6_TO_MAC) != 0) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_UNSUPPORTED;
    return;
  }

  Tmp = (UINT8 *)(&Cpb->IP.IPv4);

  if ((Tmp[0] & 0xF0) != 0xE0) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CPB;
  }

  Db->MAC[0] = 0x01;
  Db->MAC[1] = 0x00;
  Db->MAC[2] = 0x5E;
  Db->MAC[3] = Tmp[1] & 0x7F;
  Db->MAC[4] = Tmp[2];
  Db->MAC[5] = Tmp[3];

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiMcastIp2Mac != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiMcastIp2Mac (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  This command is used to read and write (if supported by NIC H/W)
  nonvolatile storage on the NIC.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiNvData (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  EFI_STATUS  Status;

  Cdb->StatCode = PXE_STATCODE_UNSUPPORTED;
  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiNvData != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiNvData (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    } else {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
      Cdb->StatCode  = PXE_STATCODE_SUCCESS;
    }
  }
}

/**
  This command returns the current interrupt status and/or the
  transmitted buffer addresses and the current media status.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiGetStatus (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  PXE_DB_GET_STATUS  *Db;
  PXE_DB_GET_STATUS  TmpGetStatus;
  UINT16             NumEntries;
  UINTN              Index;
  EFI_STATUS         Status;

  if ((Cdb->OpCode != PXE_OPCODE_GET_STATUS) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != PXE_CPBSIZE_NOT_USED) ||
      (Cdb->CPBaddr != PXE_CPBADDR_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    return;
  }

  TmpGetStatus.RxFrameLen = 0;
  TmpGetStatus.reserved   = 0;
  Db                      = (PXE_DB_GET_STATUS *)(UINTN)Cdb->DBaddr;

  if ((Cdb->DBsize > 0) && (Cdb->DBsize < sizeof (UINT32) * 2)) {
    CopyMem (Db, &TmpGetStatus, Cdb->DBsize);
  } else {
    CopyMem (Db, &TmpGetStatus, sizeof (UINT32) * 2);
  }

  if ((Cdb->OpFlags & PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS) != 0) {
    if (Cdb->DBsize == 0) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
      Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
      return;
    }

    NumEntries  = Cdb->DBsize - sizeof (UINT64);
    Cdb->DBsize = sizeof (UINT32) * 2;

    for (Index = 0; NumEntries >= sizeof (UINT64); Index++, NumEntries -= sizeof (UINT64)) {
      if (Nic->TxBufferCount > 0) {
        Nic->TxBufferCount--;
        Db->TxBuffer[Index] = Nic->MediaHeader[Nic->TxBufferCount];
      }
    }
  }

  if ((Cdb->OpFlags & PXE_OPFLAGS_GET_INTERRUPT_STATUS) != 0) {
    if (Nic->ReceiveStatus != 0) {
      Cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_RECEIVE;
    }
  }

  if ((Nic->Request.Request == USB_CDC_NETWORK_CONNECTION) && (Nic->Request.Value == NETWORK_DISCONNECT)) {
    Nic->CableDetect = 0;
  } else if ((Nic->Request.Request == USB_CDC_NETWORK_CONNECTION) && (Nic->Request.Value == NETWORK_CONNECTED)) {
    Nic->CableDetect = 1;
  }

  if ((Cdb->OpFlags & PXE_OPFLAGS_GET_MEDIA_STATUS) != 0) {
    if (Nic->CableDetect == 0) {
      Cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_MEDIA;
    }
  }

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiGetStatus != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiGetStatus (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  This command is used to fill the media header(s) in transmit packet(s).

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiFillHeader (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  PXE_CPB_FILL_HEADER             *CpbFillHeader;
  PXE_CPB_FILL_HEADER_FRAGMENTED  *CpbFill;
  ETHERNET_HEADER                 *MacHeader;
  UINTN                           Index;
  EFI_STATUS                      Status;

  if ((Cdb->OpCode != PXE_OPCODE_FILL_HEADER) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED)) ||
      (Cdb->DBsize != PXE_DBSIZE_NOT_USED) ||
      (Cdb->DBaddr != PXE_DBADDR_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    return;
  }

  if (Cdb->CPBsize == PXE_CPBSIZE_NOT_USED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  }

  if ((Cdb->OpFlags & PXE_OPFLAGS_FILL_HEADER_FRAGMENTED) != 0) {
    CpbFill = (PXE_CPB_FILL_HEADER_FRAGMENTED *)(UINTN)Cdb->CPBaddr;

    if ((CpbFill->FragCnt == 0) || (CpbFill->FragDesc[0].FragLen < PXE_MAC_HEADER_LEN_ETHER)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
      Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
      return;
    }

    MacHeader           = (ETHERNET_HEADER *)(UINTN)CpbFill->FragDesc[0].FragAddr;
    MacHeader->Protocol = CpbFill->Protocol;

    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
      MacHeader->DestAddr[Index] = CpbFill->DestAddr[Index];
      MacHeader->SrcAddr[Index]  = CpbFill->SrcAddr[Index];
    }
  } else {
    CpbFillHeader = (PXE_CPB_FILL_HEADER *)(UINTN)Cdb->CPBaddr;

    MacHeader           = (ETHERNET_HEADER *)(UINTN)CpbFillHeader->MediaHeader;
    MacHeader->Protocol = CpbFillHeader->Protocol;

    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
      MacHeader->DestAddr[Index] = CpbFillHeader->DestAddr[Index];
      MacHeader->SrcAddr[Index]  = CpbFillHeader->SrcAddr[Index];
    }
  }

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiFillHeader != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiFillHeader (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }
  }
}

/**
  The Transmit command is used to place a packet into the transmit queue.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiTransmit (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  EFI_STATUS  Status;

  if ((Cdb->OpCode != PXE_OPCODE_TRANSMIT) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != sizeof (PXE_CPB_TRANSMIT)) ||
      (Cdb->DBsize != PXE_DBSIZE_NOT_USED) ||
      (Cdb->DBaddr != PXE_DBADDR_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    return;
  }

  if (Cdb->CPBsize == PXE_CPBSIZE_NOT_USED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  }

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiTransmit != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiTransmit (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }

    return;
  }

  Cdb->StatCode = Transmit (Cdb, Nic, Cdb->CPBaddr, Cdb->OpFlags);

  if (Cdb->StatCode != PXE_STATCODE_SUCCESS) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
  }
}

/**
  Use USB Ethernet Protocol Bulk out command to transmit data.

  @param[in]      Cdb      A pointer to the command descriptor block.
  @param[in, out] Nic      A pointer to the Network interface controller data.
  @param[in]      CpbAddr  Command Parameter Block Address.
  @param[in]      OpFlags  Operation Flags.

**/
UINT16
Transmit (
  IN      PXE_CDB   *Cdb,
  IN OUT  NIC_DATA  *Nic,
  IN      UINT64    CpbAddr,
  IN      UINT16    OpFlags
  )
{
  EFI_STATUS        Status;
  PXE_CPB_TRANSMIT  *Cpb;
  UINT64            BulkOutData;
  UINTN             DataLength;
  UINTN             TransmitLength;
  UINTN             Map;
  UINT32            Counter;
  UINT16            StatCode;

  BulkOutData = 0;
  Counter     = 0;
  Cpb         = (PXE_CPB_TRANSMIT *)(UINTN)CpbAddr;

  if (Nic->CanTransmit) {
    return PXE_STATCODE_BUSY;
  }

  Nic->CanTransmit = TRUE;

  if ((OpFlags & PXE_OPFLAGS_TRANSMIT_FRAGMENTED) != 0) {
    return PXE_STATCODE_INVALID_PARAMETER;
  }

  Map = MapIt (
          Nic,
          Cpb->FrameAddr,
          Cpb->DataLen + (UINT32)Cpb->MediaheaderLen,
          TO_DEVICE,
          (UINT64)(UINTN)&BulkOutData
          );

  if (Map != 0) {
    Nic->CanTransmit = FALSE;
    return PXE_STATCODE_INVALID_PARAMETER;
  }

  if (Nic->TxBufferCount < MAX_XMIT_BUFFERS) {
    Nic->MediaHeader[Nic->TxBufferCount] = Cpb->FrameAddr;
    Nic->TxBufferCount++;
  }

  DataLength = (UINTN)(Cpb->DataLen + (UINT32)Cpb->MediaheaderLen);

  while (1) {
    if (Counter >= 3) {
      StatCode = PXE_STATCODE_BUSY;
      break;
    }

    TransmitLength = DataLength;

    Status = Nic->UsbEth->UsbEthTransmit (Cdb, Nic->UsbEth, (VOID *)(UINTN)BulkOutData, &TransmitLength);
    if (EFI_ERROR (Status)) {
      StatCode =  PXE_STATFLAGS_COMMAND_FAILED;
    }

    if (Status == EFI_INVALID_PARAMETER) {
      StatCode = PXE_STATCODE_INVALID_PARAMETER;
      break;
    }

    if (Status == EFI_DEVICE_ERROR) {
      StatCode = PXE_STATCODE_DEVICE_FAILURE;
      break;
    }

    if (!EFI_ERROR (Status)) {
      Nic->TxFrame++;
      StatCode = PXE_STATCODE_SUCCESS;
      break;
    }

    Counter++;
  }

  UnMapIt (
    Nic,
    Cpb->FrameAddr,
    Cpb->DataLen + (UINT32)Cpb->MediaheaderLen,
    TO_DEVICE,
    BulkOutData
    );

  Nic->CanTransmit = FALSE;

  return StatCode;
}

/**
  When the network adapter has received a frame, this command is used
  to copy the frame into driver/application storage.

  @param[in]  Cdb  A pointer to the command descriptor block.
  @param[in]  Nic  A pointer to the Network interface controller data.

**/
VOID
UndiReceive (
  IN  PXE_CDB   *Cdb,
  IN  NIC_DATA  *Nic
  )
{
  EFI_STATUS  Status;

  if ((Cdb->OpCode != PXE_OPCODE_RECEIVE) ||
      (Cdb->StatCode != PXE_STATCODE_INITIALIZE) ||
      (Cdb->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
      (Cdb->IFnum >= (gPxe->IFcnt | gPxe->IFcntExt << 8)) ||
      (Cdb->CPBsize != sizeof (PXE_CPB_RECEIVE)) ||
      (Cdb->DBsize != sizeof (PXE_DB_RECEIVE)) ||
      (Cdb->OpFlags != PXE_OPFLAGS_NOT_USED))
  {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_INVALID_CDB;
    return;
  } else {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
    Cdb->StatCode  = PXE_STATCODE_SUCCESS;
  }

  if (Nic->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    Cdb->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
    return;
  }

  if (Nic->UsbEth->UsbEthUndi.UsbEthUndiReceive != NULL) {
    Status = Nic->UsbEth->UsbEthUndi.UsbEthUndiReceive (Cdb, Nic);
    if (EFI_ERROR (Status)) {
      Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
    }

    return;
  }

  Cdb->StatCode = Receive (Cdb, Nic, Cdb->CPBaddr, Cdb->DBaddr);

  if (Cdb->StatCode != PXE_STATCODE_SUCCESS) {
    Cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
  }
}

/**
  Use USB Ethernet Protocol Bulk in command to receive data.

  @param[in]      Cdb      A pointer to the command descriptor block.
  @param[in, out] Nic      A pointer to the Network interface controller data.
  @param[in]      CpbAddr  Command Parameter Block Address.
  @param[in, out] DbAddr   Data Block Address.

**/
UINT16
Receive (
  IN PXE_CDB       *Cdb,
  IN OUT NIC_DATA  *Nic,
  IN UINT64        CpbAddr,
  IN OUT UINT64    DbAddr
  )
{
  EFI_STATUS       Status;
  UINTN            Index;
  PXE_FRAME_TYPE   FrameType;
  PXE_CPB_RECEIVE  *Cpb;
  PXE_DB_RECEIVE   *Db;
  NIC_DEVICE       *NicDevice;
  UINT8            *BulkInData;
  UINTN            DataLength;
  ETHERNET_HEADER  *Header;
  EFI_TPL          OriginalTpl;

  FrameType  = PXE_FRAME_TYPE_NONE;
  NicDevice  = UNDI_DEV_FROM_NIC (Nic);
  BulkInData = NicDevice->ReceiveBuffer;
  DataLength = (UINTN)Nic->MaxSegmentSize;
  Cpb        = (PXE_CPB_RECEIVE *)(UINTN)CpbAddr;
  Db         = (PXE_DB_RECEIVE *)(UINTN)DbAddr;

  if (!BulkInData) {
    return PXE_STATCODE_INVALID_PARAMETER;
  }

  if ((Nic->RateLimitingCreditCount == 0) && (Nic->RateLimitingEnable == TRUE)) {
    return PXE_STATCODE_NO_DATA;
  }

  Status = Nic->UsbEth->UsbEthReceive (Cdb, Nic->UsbEth, (VOID *)BulkInData, &DataLength);
  if (EFI_ERROR (Status)) {
    Nic->ReceiveStatus = 0;
    if (Nic->RateLimitingEnable == TRUE) {
      OriginalTpl = gBS->RaiseTPL (TPL_NOTIFY);
      if (Nic->RateLimitingCreditCount != 0) {
        Nic->RateLimitingCreditCount--;
      }

      gBS->RestoreTPL (OriginalTpl);
    }

    return PXE_STATCODE_NO_DATA;
  }

  Nic->RxFrame++;

  if (DataLength != 0) {
    if (DataLength > Cpb->BufferLen) {
      DataLength = (UINTN)Cpb->BufferLen;
    }

    CopyMem ((UINT8 *)(UINTN)Cpb->BufferAddr, (UINT8 *)BulkInData, DataLength);

    Header = (ETHERNET_HEADER *)BulkInData;

    Db->FrameLen       = (UINT32)DataLength;
    Db->MediaHeaderLen = PXE_MAC_HEADER_LEN_ETHER;

    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
      if (Header->DestAddr[Index] != Nic->CurrentNodeAddress[Index]) {
        break;
      }
    }

    if (Index >= PXE_HWADDR_LEN_ETHER) {
      FrameType = PXE_FRAME_TYPE_UNICAST;
    } else {
      for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
        if (Header->DestAddr[Index] != Nic->BroadcastNodeAddress[Index]) {
          break;
        }
      }

      if (Index >= PXE_HWADDR_LEN_ETHER) {
        FrameType = PXE_FRAME_TYPE_BROADCAST;
      } else {
        if ((Header->DestAddr[0] & 1) == 1) {
          FrameType = PXE_FRAME_TYPE_FILTERED_MULTICAST;
        } else {
          FrameType = PXE_FRAME_TYPE_PROMISCUOUS;
        }
      }
    }

    Db->Type     = FrameType;
    Db->Protocol = Header->Protocol;

    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
      Db->SrcAddr[Index]  = Header->SrcAddr[Index];
      Db->DestAddr[Index] = Header->DestAddr[Index];
    }
  }

  if (FrameType == PXE_FRAME_TYPE_NONE) {
    Nic->ReceiveStatus = 0;
  } else {
    Nic->ReceiveStatus = 1;
  }

  return PXE_STATCODE_SUCCESS;
}

/**
  Fill out PXE SW UNDI structure.

  @param[out]  PxeSw      A pointer to the PXE SW UNDI structure.

**/
VOID
PxeStructInit (
  OUT PXE_SW_UNDI  *PxeSw
  )
{
  PxeSw->Signature = PXE_ROMID_SIGNATURE;
  PxeSw->Len       = (UINT8)sizeof (PXE_SW_UNDI);
  PxeSw->Fudge     = 0;
  PxeSw->IFcnt     = 0;
  PxeSw->IFcntExt  = 0;
  PxeSw->Rev       = PXE_ROMID_REV;
  PxeSw->MajorVer  = PXE_ROMID_MAJORVER;
  PxeSw->MinorVer  = PXE_ROMID_MINORVER;
  PxeSw->reserved1 = 0;

  PxeSw->Implementation = PXE_ROMID_IMP_SW_VIRT_ADDR |
                          PXE_ROMID_IMP_FRAG_SUPPORTED |
                          PXE_ROMID_IMP_CMD_LINK_SUPPORTED |
                          PXE_ROMID_IMP_STATION_ADDR_SETTABLE |
                          PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED |
                          PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED |
                          PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED |
                          PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED;

  PxeSw->EntryPoint   = (UINT64)(UINTN)UndiApiEntry;
  PxeSw->reserved2[0] = 0;
  PxeSw->reserved2[1] = 0;
  PxeSw->reserved2[2] = 0;
  PxeSw->BusCnt       = 1;
  PxeSw->BusType[0]   = PXE_BUSTYPE_USB;
  PxeSw->Fudge        = PxeSw->Fudge - CalculateSum8 ((VOID *)PxeSw, PxeSw->Len);
}

/**
  Update NIC number.

  @param[in]      Nic       A pointer to the Network interface controller data.
  @param[in, out] PxeSw     A pointer to the PXE SW UNDI structure.

**/
VOID
UpdateNicNum (
  IN      NIC_DATA     *Nic,
  IN OUT  PXE_SW_UNDI  *PxeSw
  )
{
  UINT16  NicNum;

  NicNum = (PxeSw->IFcnt | PxeSw->IFcntExt << 8);

  if (Nic == NULL) {
    if (NicNum > 0) {
      NicNum--;
    }

    PxeSw->IFcnt    = (UINT8)(NicNum & 0xFF);          // Get lower byte
    PxeSw->IFcntExt = (UINT8)((NicNum & 0xFF00) >> 8); // Get upper byte
    PxeSw->Fudge    = (UINT8)(PxeSw->Fudge - CalculateSum8 ((VOID *)PxeSw, PxeSw->Len));
    return;
  }

  NicNum++;

  PxeSw->IFcnt    = (UINT8)(NicNum & 0xFF);          // Get lower byte
  PxeSw->IFcntExt = (UINT8)((NicNum & 0xFF00) >> 8); // Get upper byte
  PxeSw->Fudge    = (UINT8)(PxeSw->Fudge - CalculateSum8 ((VOID *)PxeSw, PxeSw->Len));
}

/**
  UNDI API table entry.

  @param[in]  Cdb  A pointer to the command descriptor block.

**/
EFI_STATUS
EFIAPI
UndiApiEntry (
  IN  UINT64  Cdb
  )
{
  PXE_CDB   *CdbPtr;
  NIC_DATA  *Nic;

  if (Cdb == 0) {
    return EFI_INVALID_PARAMETER;
  }

  CdbPtr = (PXE_CDB *)(UINTN)Cdb;
  Nic    = &(gLanDeviceList[CdbPtr->IFnum]->NicInfo);
  gUndiApiTable[CdbPtr->OpCode](CdbPtr, Nic);
  return EFI_SUCCESS;
}

/**
  Map virtual memory address for DMA. This field can be set to
  zero if there is no mapping service.

  @param[in]  Nic           A pointer to the Network interface controller data.
  @param[in]  MemAddr       Virtual address to be mapped.
  @param[in]  Size          Size of memory to be mapped.
  @param[in]  Direction     Direction of data flow for this memory's usage:
                            cpu->device, device->cpu or both ways.
  @param[out] MappedAddr    Pointer to return the mapped device address.

**/
UINTN
MapIt (
  IN NIC_DATA  *Nic,
  IN UINT64    MemAddr,
  IN UINT32    Size,
  IN UINT32    Direction,
  OUT UINT64   MappedAddr
  )
{
  UINT64  *PhyAddr;

  PhyAddr = (UINT64 *)(UINTN)MappedAddr;

  if (Nic->PxeStart.Map_Mem == 0) {
    *PhyAddr = MemAddr;
  } else {
    ((void (*)(UINT64, UINT64, UINT32, UINT32, UINT64))(UINTN) Nic->PxeStart.Map_Mem)(
  Nic->PxeStart.Unique_ID,
  MemAddr,
  Size,
  Direction,
  MappedAddr
  );
  }

  return PXE_STATCODE_SUCCESS;
}

/**
  Un-map previously mapped virtual memory address. This field can be set
  to zero only if the Map_Mem() service is also set to zero.

  @param[in]  Nic           A pointer to the Network interface controller data.
  @param[in]  MemAddr       Virtual address to be mapped.
  @param[in]  Size          Size of memory to be mapped.
  @param[in]  Direction     Direction of data flow for this memory's usage:
                            cpu->device, device->cpu or both ways.
  @param[in]  MappedAddr    Pointer to return the mapped device address.

**/
VOID
UnMapIt (
  IN NIC_DATA  *Nic,
  IN UINT64    MemAddr,
  IN UINT32    Size,
  IN UINT32    Direction,
  IN UINT64    MappedAddr
  )
{
  if (Nic->PxeStart.UnMap_Mem != 0) {
    ((void (*)(UINT64, UINT64, UINT32, UINT32, UINT64))(UINTN) Nic->PxeStart.UnMap_Mem)(
  Nic->PxeStart.Unique_ID,
  MemAddr,
  Size,
  Direction,
  MappedAddr
  );
  }

  return;
}
