/** @file
  Provides basic function upon network adapter card.

Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Undi32.h"

UINT8 basic_config_cmd[22] = {
                    22,        0x08,
                    0,           0,
                    0, (UINT8)0x80,
                    0x32,        0x03,
                    1,            0,
                    0x2E,           0,
                    0x60,           0,
                    (UINT8)0xf2,        0x48,
                    0,        0x40,
                    (UINT8)0xf2, (UINT8)0x80, // 0x40=Force full-duplex
                    0x3f,       0x05,
};

//
// How to wait for the command unit to accept a command.
// Typically this takes 0 ticks.
//
#define wait_for_cmd_done(cmd_ioaddr) \
{                      \
  INT16 wait_count = 2000;              \
  while ((InByte (AdapterInfo, cmd_ioaddr) != 0) && --wait_count >= 0)  \
    DelayIt (AdapterInfo, 10);  \
  if (wait_count == 0) \
    DelayIt (AdapterInfo, 50);    \
}


/**
  This function calls the MemIo callback to read a byte from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
  to make undi3.0 a special case

  @param  Port                            Which port to read from.

  @retval Results                         The data read from the port.

**/
// TODO:    AdapterInfo - add argument and description to function comment
UINT8
InByte (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT32            Port
  )
{
  UINT8 Results;

  (*AdapterInfo->Mem_Io) (
    AdapterInfo->Unique_ID,
    PXE_MEM_READ,
    1,
    (UINT64)Port,
    (UINT64) (UINTN) &Results
    );
  return Results;
}


/**
  This function calls the MemIo callback to read a word from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
  to make undi3.0 a special case

  @param  Port                            Which port to read from.

  @retval Results                         The data read from the port.

**/
// TODO:    AdapterInfo - add argument and description to function comment
UINT16
InWord (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT32            Port
  )
{
  UINT16  Results;

  (*AdapterInfo->Mem_Io) (
    AdapterInfo->Unique_ID,
    PXE_MEM_READ,
    2,
    (UINT64)Port,
    (UINT64)(UINTN)&Results
    );
  return Results;
}


/**
  This function calls the MemIo callback to read a dword from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
  to make undi3.0 a special case

  @param  Port                            Which port to read from.

  @retval Results                         The data read from the port.

**/
// TODO:    AdapterInfo - add argument and description to function comment
UINT32
InLong (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT32            Port
  )
{
  UINT32  Results;

  (*AdapterInfo->Mem_Io) (
    AdapterInfo->Unique_ID,
    PXE_MEM_READ,
    4,
    (UINT64)Port,
    (UINT64)(UINTN)&Results
    );
  return Results;
}


/**
  This function calls the MemIo callback to write a byte from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
  to make undi3.0 a special case

  @param  Data                            Data to write to Port.
  @param  Port                            Which port to write to.

  @return none

**/
// TODO:    AdapterInfo - add argument and description to function comment
VOID
OutByte (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT8             Data,
  IN UINT32            Port
  )
{
  UINT8 Val;

  Val = Data;
  (*AdapterInfo->Mem_Io) (
     AdapterInfo->Unique_ID,
     PXE_MEM_WRITE,
     1,
     (UINT64)Port,
     (UINT64)(UINTN)(UINTN)&Val
     );
  return ;
}


/**
  This function calls the MemIo callback to write a word from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
  to make undi3.0 a special case

  @param  Data                            Data to write to Port.
  @param  Port                            Which port to write to.

  @return none

**/
// TODO:    AdapterInfo - add argument and description to function comment
VOID
OutWord (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT16            Data,
  IN UINT32            Port
  )
{
  UINT16  Val;

  Val = Data;
  (*AdapterInfo->Mem_Io) (
     AdapterInfo->Unique_ID,
     PXE_MEM_WRITE,
     2,
     (UINT64)Port,
     (UINT64)(UINTN)&Val
     );
  return ;
}


/**
  This function calls the MemIo callback to write a dword from the device's
  address space
  Since UNDI3.0 uses the TmpMemIo function (instead of the callback routine)
  which also takes the UniqueId parameter (as in UNDI3.1 spec) we don't have
  to make undi3.0 a special case

  @param  Data                            Data to write to Port.
  @param  Port                            Which port to write to.

  @return none

**/
// TODO:    AdapterInfo - add argument and description to function comment
VOID
OutLong (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT32            Data,
  IN UINT32            Port
  )
{
  UINT32  Val;

  Val = Data;
  (*AdapterInfo->Mem_Io) (
     AdapterInfo->Unique_ID,
     PXE_MEM_WRITE,
     4,
     (UINT64)Port,
     (UINT64)(UINTN)&Val
     );
  return ;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description
  @param  MemAddr                         TODO: add argument description
  @param  Size                            TODO: add argument description
  @param  Direction                       TODO: add argument description
  @param  MappedAddr                      TODO: add argument description

  @return TODO: add return values

**/
UINTN
MapIt (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT64            MemAddr,
  IN UINT32            Size,
  IN UINT32            Direction,
  OUT UINT64           MappedAddr
  )
{
  UINT64  *PhyAddr;

  PhyAddr = (UINT64 *) (UINTN) MappedAddr;
  //
  // mapping is different for theold and new NII protocols
  //
  if (AdapterInfo->VersionFlag == 0x30) {
    if (AdapterInfo->Virt2Phys_30 == (VOID *) NULL) {
      *PhyAddr = (UINT64) AdapterInfo->MemoryPtr;
    } else {
      (*AdapterInfo->Virt2Phys_30) (MemAddr, (UINT64) (UINTN) PhyAddr);
    }

    if (*PhyAddr > FOUR_GIGABYTE) {
      return PXE_STATCODE_INVALID_PARAMETER;
    }
  } else {
    if (AdapterInfo->Map_Mem == (VOID *) NULL) {
      //
      // this UNDI cannot handle addresses beyond 4 GB without a map routine
      //
      if (MemAddr > FOUR_GIGABYTE) {
        return PXE_STATCODE_INVALID_PARAMETER;
      } else {
        *PhyAddr = MemAddr;
      }
    } else {
      (*AdapterInfo->Map_Mem) (
        AdapterInfo->Unique_ID,
        MemAddr,
        Size,
        Direction,
        MappedAddr
        );
    }
  }

  return PXE_STATCODE_SUCCESS;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description
  @param  MemAddr                         TODO: add argument description
  @param  Size                            TODO: add argument description
  @param  Direction                       TODO: add argument description
  @param  MappedAddr                      TODO: add argument description

  @return TODO: add return values

**/
VOID
UnMapIt (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT64            MemAddr,
  IN UINT32            Size,
  IN UINT32            Direction,
  IN UINT64            MappedAddr
  )
{
  if (AdapterInfo->VersionFlag > 0x30) {
    //
    // no mapping service
    //
    if (AdapterInfo->UnMap_Mem != (VOID *) NULL) {
      (*AdapterInfo->UnMap_Mem) (
        AdapterInfo->Unique_ID,
        MemAddr,
        Size,
        Direction,
        MappedAddr
        );

    }
  }

  return ;
}


/**

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on..


**/
// TODO:    MicroSeconds - add argument and description to function comment
VOID
DelayIt (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  UINT16               MicroSeconds
  )
{
  if (AdapterInfo->VersionFlag == 0x30) {
    (*AdapterInfo->Delay_30) (MicroSeconds);
  } else {
    (*AdapterInfo->Delay) (AdapterInfo->Unique_ID, MicroSeconds);
  }
}


/**

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on..


**/
// TODO:    flag - add argument and description to function comment
VOID
BlockIt (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  UINT32               flag
  )
{
  if (AdapterInfo->VersionFlag == 0x30) {
    (*AdapterInfo->Block_30) (flag);
  } else {
    (*AdapterInfo->Block) (AdapterInfo->Unique_ID, flag);
  }
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
UINT8
Load_Base_Regs (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  //
  // we will use the linear (flat) memory model and fill our base registers
  // with 0's so that the entire physical address is our offset
  //
  //
  // we reset the statistics totals here because this is where we are loading stats addr
  //
  AdapterInfo->RxTotals = 0;
  AdapterInfo->TxTotals = 0;

  //
  // Load the statistics block address.
  //
  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
  OutLong (AdapterInfo, (UINT32) AdapterInfo->stat_phy_addr, AdapterInfo->ioaddr + SCBPointer);
  OutByte (AdapterInfo, CU_STATSADDR, AdapterInfo->ioaddr + SCBCmd);
  AdapterInfo->statistics->done_marker = 0;

  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
  OutLong (AdapterInfo, 0, AdapterInfo->ioaddr + SCBPointer);
  OutByte (AdapterInfo, RX_ADDR_LOAD, AdapterInfo->ioaddr + SCBCmd);

  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
  OutLong (AdapterInfo, 0, AdapterInfo->ioaddr + SCBPointer);
  OutByte (AdapterInfo, CU_CMD_BASE, AdapterInfo->ioaddr + SCBCmd);

  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description
  @param  cmd_ptr                         TODO: add argument description

  @return TODO: add return values

**/
UINT8
IssueCB (
  NIC_DATA_INSTANCE *AdapterInfo,
  TxCB              *cmd_ptr
  )
{
  UINT16  status;

  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

  //
  // read the CU status, if it is idle, write the address of cb_ptr
  // in the scbpointer and issue a cu_start,
  // if it is suspended, remove the suspend bit in the previous command
  // block and issue a resume
  //
  // Ensure that the CU Active Status bit is not on from previous CBs.
  //
  status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);

  //
  // Skip acknowledging the interrupt if it is not already set
  //

  //
  // ack only the cna the integer
  //
  if ((status & SCB_STATUS_CNA) != 0) {
    OutWord (AdapterInfo, SCB_STATUS_CNA, AdapterInfo->ioaddr + SCBStatus);

  }

  if ((status & SCB_STATUS_CU_MASK) == SCB_STATUS_CU_IDLE) {
    //
    // give a cu_start
    //
    OutLong (AdapterInfo, cmd_ptr->PhysTCBAddress, AdapterInfo->ioaddr + SCBPointer);
    OutByte (AdapterInfo, CU_START, AdapterInfo->ioaddr + SCBCmd);
  } else {
    //
    // either active or suspended, give a resume
    //

    cmd_ptr->PrevTCBVirtualLinkPtr->cb_header.command &= ~(CmdSuspend | CmdIntr);
    OutByte (AdapterInfo, CU_RESUME, AdapterInfo->ioaddr + SCBCmd);
  }

  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
UINT8
Configure (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  //
  // all command blocks are of TxCB format
  //
  TxCB  *cmd_ptr;
  UINT8 *data_ptr;
  volatile INT16 Index;
  UINT8 my_filter;

  cmd_ptr   = GetFreeCB (AdapterInfo);
  ASSERT (cmd_ptr != NULL);
  data_ptr  = (UINT8 *) cmd_ptr + sizeof (struct CB_Header);

  //
  // start the config data right after the command header
  //
  for (Index = 0; Index < sizeof (basic_config_cmd); Index++) {
    data_ptr[Index] = basic_config_cmd[Index];
  }

  my_filter = (UINT8) ((AdapterInfo->Rx_Filter & PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS) ? 1 : 0);
  my_filter = (UINT8) (my_filter | ((AdapterInfo->Rx_Filter & PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST) ? 0 : 2));

  data_ptr[15]  = (UINT8) (data_ptr[15] | my_filter);
  data_ptr[19]  = (UINT8) (AdapterInfo->Duplex ? 0xC0 : 0x80);
  data_ptr[21]  = (UINT8) ((AdapterInfo->Rx_Filter & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) ? 0x0D : 0x05);

  //
  // check if we have to use the AUI port instead
  //
  if ((AdapterInfo->PhyRecord[0] & 0x8000) != 0) {
    data_ptr[15] |= 0x80;
    data_ptr[8] = 0;
  }

  BlockIt (AdapterInfo, TRUE);
  cmd_ptr->cb_header.command = CmdSuspend | CmdConfigure;

  IssueCB (AdapterInfo, cmd_ptr);
  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

  BlockIt (AdapterInfo, FALSE);

  CommandWaitForCompletion (cmd_ptr, AdapterInfo);

  //
  // restore the cb values for tx
  //
  cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;
  cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;
  //
  // fields beyond the immediatedata are assumed to be safe
  // add the CB to the free list again
  //
  SetFreeCB (AdapterInfo, cmd_ptr);
  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
UINT8
E100bSetupIAAddr (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  //
  // all command blocks are of TxCB format
  //
  TxCB    *cmd_ptr;
  UINT16  *data_ptr;
  UINT16  *eaddrs;

  eaddrs    = (UINT16 *) AdapterInfo->CurrentNodeAddress;

  cmd_ptr   = GetFreeCB (AdapterInfo);
  ASSERT (cmd_ptr != NULL);
  data_ptr  = (UINT16 *) ((UINT8 *) cmd_ptr +sizeof (struct CB_Header));

  //
  // AVOID a bug (?!) here by marking the command already completed.
  //
  cmd_ptr->cb_header.command  = (CmdSuspend | CmdIASetup);
  cmd_ptr->cb_header.status   = 0;
  data_ptr[0]                 = eaddrs[0];
  data_ptr[1]                 = eaddrs[1];
  data_ptr[2]                 = eaddrs[2];

  BlockIt (AdapterInfo, TRUE);
  IssueCB (AdapterInfo, cmd_ptr);
  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
  BlockIt (AdapterInfo, FALSE);

  CommandWaitForCompletion (cmd_ptr, AdapterInfo);

  //
  // restore the cb values for tx
  //
  cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;
  cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;
  //
  // fields beyond the immediatedata are assumed to be safe
  // add the CB to the free list again
  //
  SetFreeCB (AdapterInfo, cmd_ptr);
  return 0;
}


/**
  Instructs the NIC to stop receiving packets.

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on..


**/
VOID
StopRU (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  if (AdapterInfo->Receive_Started) {

    //
    // Todo: verify that we must wait for previous command completion.
    //
    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

    //
    // Disable interrupts, and stop the chip's Rx process.
    //
    OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
    OutWord (AdapterInfo, INT_MASK | RX_ABORT, AdapterInfo->ioaddr + SCBCmd);

    AdapterInfo->Receive_Started = FALSE;
  }

  return ;
}


/**
  Instructs the NIC to start receiving packets.

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on..

  @retval 0                               Successful
  @retval -1                              Already Started

**/
INT8
StartRU (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{

  if (AdapterInfo->Receive_Started) {
    //
    // already started
    //
    return -1;
  }

  AdapterInfo->cur_rx_ind = 0;
  AdapterInfo->Int_Status = 0;

  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

  OutLong (AdapterInfo, (UINT32) AdapterInfo->rx_phy_addr, AdapterInfo->ioaddr + SCBPointer);
  OutByte (AdapterInfo, RX_START, AdapterInfo->ioaddr + SCBCmd);

  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

  AdapterInfo->Receive_Started = TRUE;
  return 0;
}


/**
  Configures the chip.  This routine expects the NIC_DATA_INSTANCE structure to be filled in.

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on..

  @retval 0                               Successful
  @retval PXE_STATCODE_NOT_ENOUGH_MEMORY  Insufficient length of locked memory
  @retval other                           Failure initializing chip

**/
UINTN
E100bInit (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  PCI_CONFIG_HEADER *CfgHdr;
  UINTN             stat;
  UINTN             rx_size;
  UINTN             tx_size;

  if (AdapterInfo->MemoryLength < MEMORY_NEEDED) {
    return PXE_STATCODE_NOT_ENOUGH_MEMORY;
  }

  stat = MapIt (
          AdapterInfo,
          AdapterInfo->MemoryPtr,
          AdapterInfo->MemoryLength,
          TO_AND_FROM_DEVICE,
          (UINT64)(UINTN) &AdapterInfo->Mapped_MemoryPtr
          );

  if (stat != 0) {
    return stat;
  }

  CfgHdr = (PCI_CONFIG_HEADER *) &(AdapterInfo->Config[0]);

  //
  // fill in the ioaddr, int... from the config space
  //
  AdapterInfo->int_num = CfgHdr->int_line;

  //
  // we don't need to validate integer number, what if they don't want to assign one?
  // if (AdapterInfo->int_num == 0 || AdapterInfo->int_num == 0xff)
  // return PXE_STATCODE_DEVICE_FAILURE;
  //
  AdapterInfo->ioaddr       = 0;
  AdapterInfo->VendorID     = CfgHdr->VendorID;
  AdapterInfo->DeviceID     = CfgHdr->DeviceID;
  AdapterInfo->RevID        = CfgHdr->RevID;
  AdapterInfo->SubVendorID  = CfgHdr->SubVendorID;
  AdapterInfo->SubSystemID  = CfgHdr->SubSystemID;
  AdapterInfo->flash_addr   = 0;

  //
  // Read the station address EEPROM before doing the reset.
  // Perhaps this should even be done before accepting the device,
  // then we wouldn't have a device name with which to report the error.
  //
  if (E100bReadEepromAndStationAddress (AdapterInfo) != 0) {
    return PXE_STATCODE_DEVICE_FAILURE;

  }
  //
  // ## calculate the buffer #s depending on memory given
  // ## calculate the rx and tx ring pointers
  //

  AdapterInfo->TxBufCnt       = TX_BUFFER_COUNT;
  AdapterInfo->RxBufCnt       = RX_BUFFER_COUNT;
  rx_size                     = (AdapterInfo->RxBufCnt * sizeof (RxFD));
  tx_size                     = (AdapterInfo->TxBufCnt * sizeof (TxCB));
  AdapterInfo->rx_ring        = (RxFD *) (UINTN) (AdapterInfo->MemoryPtr);
  AdapterInfo->tx_ring        = (TxCB *) (UINTN) (AdapterInfo->MemoryPtr + rx_size);
  AdapterInfo->statistics     = (struct speedo_stats *) (UINTN) (AdapterInfo->MemoryPtr + rx_size + tx_size);

  AdapterInfo->rx_phy_addr    = AdapterInfo->Mapped_MemoryPtr;
  AdapterInfo->tx_phy_addr    = AdapterInfo->Mapped_MemoryPtr + rx_size;
  AdapterInfo->stat_phy_addr  = AdapterInfo->tx_phy_addr + tx_size;

  //
  // auto detect.
  //
  AdapterInfo->PhyAddress     = 0xFF;
  AdapterInfo->Rx_Filter            = PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
  AdapterInfo->Receive_Started      = FALSE;
  AdapterInfo->mcast_list.list_len  = 0;
  return InitializeChip (AdapterInfo);
}


/**
  Sets the interrupt state for the NIC.

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on..

  @retval 0                               Successful

**/
UINT8
E100bSetInterruptState (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  //
  // don't set receive interrupt if receiver is disabled...
  //
  UINT16  cmd_word;

  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_RECEIVE) != 0) {
    cmd_word = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCmd);
    cmd_word &= ~INT_MASK;
    OutWord (AdapterInfo, cmd_word, AdapterInfo->ioaddr + SCBCmd);
  } else {
    //
    // disable ints, should not be given for SW Int.
    //
    OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);
  }

  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_SOFTWARE) != 0) {
    //
    // reset the bit in our mask, it is only one time!!
    //
    AdapterInfo->int_mask &= ~(PXE_OPFLAGS_INTERRUPT_SOFTWARE);
    cmd_word = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCmd);
    cmd_word |= DRVR_INT;
    OutWord (AdapterInfo, cmd_word, AdapterInfo->ioaddr + SCBCmd);
  }

  return 0;
}
//
// we are not going to disable broadcast for the WOL's sake!
//

/**
  Instructs the NIC to start receiving packets.

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on.. new_filter
                                              - cpb                             -
                                          cpbsize                         -

  @retval 0                               Successful
  @retval -1                              Already Started

**/
UINTN
E100bSetfilter (
  NIC_DATA_INSTANCE *AdapterInfo,
  UINT16            new_filter,
  UINT64            cpb,
  UINT32            cpbsize
  )
{
  PXE_CPB_RECEIVE_FILTERS *mc_list = (PXE_CPB_RECEIVE_FILTERS *) (UINTN)cpb;
  UINT16                  cfg_flt;
  UINT16                  old_filter;
  UINT16                  Index;
  UINT16                  Index2;
  UINT16                  mc_count;
  TxCB                    *cmd_ptr;
  struct MC_CB_STRUCT     *data_ptr;
  UINT16                  mc_byte_cnt;

  old_filter  = AdapterInfo->Rx_Filter;

  //
  // only these bits need a change in the configuration
  // actually change in bcast requires configure but we ignore that change
  //
  cfg_flt = PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS |
            PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;

  if ((old_filter & cfg_flt) != (new_filter & cfg_flt)) {
    XmitWaitForCompletion (AdapterInfo);

    if (AdapterInfo->Receive_Started) {
      StopRU (AdapterInfo);
    }

    AdapterInfo->Rx_Filter = (UINT8) (new_filter | PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST);
    Configure (AdapterInfo);
  }

  //
  // check if mcast setting changed
  //
  if ( ((new_filter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) !=
       (old_filter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) ) ||
       (mc_list != NULL) ) {


    if (mc_list != NULL) {
      mc_count = AdapterInfo->mcast_list.list_len = (UINT16) (cpbsize / PXE_MAC_LENGTH);

      for (Index = 0; (Index < mc_count && Index < MAX_MCAST_ADDRESS_CNT); Index++) {
        for (Index2 = 0; Index2 < PXE_MAC_LENGTH; Index2++) {
          AdapterInfo->mcast_list.mc_list[Index][Index2] = mc_list->MCastList[Index][Index2];
        }
      }
    }

    //
    // are we setting the list or resetting??
    //
    if ((new_filter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
      //
      // we are setting a new list!
      //
      mc_count = AdapterInfo->mcast_list.list_len;
      //
      // count should be the actual # of bytes in the list
      // so multiply this with 6
      //
      mc_byte_cnt = (UINT16) ((mc_count << 2) + (mc_count << 1));
      AdapterInfo->Rx_Filter |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
    } else {
      //
      // disabling the list in the NIC.
      //
      mc_byte_cnt = mc_count = 0;
      AdapterInfo->Rx_Filter &= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);
    }

    //
    // before issuing any new command!
    //
    XmitWaitForCompletion (AdapterInfo);

    if (AdapterInfo->Receive_Started) {
      StopRU (AdapterInfo);

    }

    cmd_ptr = GetFreeCB (AdapterInfo);
    if (cmd_ptr == NULL) {
      return PXE_STATCODE_QUEUE_FULL;
    }
    //
    // fill the command structure and issue
    //
    data_ptr = (struct MC_CB_STRUCT *) (&cmd_ptr->PhysTBDArrayAddres);
    //
    // first 2 bytes are the count;
    //
    data_ptr->count = mc_byte_cnt;
    for (Index = 0; Index < mc_count; Index++) {
      for (Index2 = 0; Index2 < PXE_HWADDR_LEN_ETHER; Index2++) {
        data_ptr->m_list[Index][Index2] = AdapterInfo->mcast_list.mc_list[Index][Index2];
      }
    }

    cmd_ptr->cb_header.command  = CmdSuspend | CmdMulticastList;
    cmd_ptr->cb_header.status   = 0;

    BlockIt (AdapterInfo, TRUE);
    IssueCB (AdapterInfo, cmd_ptr);
    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

    BlockIt (AdapterInfo, FALSE);

    CommandWaitForCompletion (cmd_ptr, AdapterInfo);

    cmd_ptr->PhysTBDArrayAddres = cmd_ptr->PhysArrayAddr;
    cmd_ptr->ByteCount = cmd_ptr->Threshold = cmd_ptr->TBDCount = 0;
    //
    // fields beyond the immediatedata are assumed to be safe
    // add the CB to the free list again
    //
    SetFreeCB (AdapterInfo, cmd_ptr);
  }

  if (new_filter != 0) {
    //
    // enable unicast and start the RU
    //
    AdapterInfo->Rx_Filter = (UINT8) (AdapterInfo->Rx_Filter | (new_filter | PXE_OPFLAGS_RECEIVE_FILTER_UNICAST));
    StartRU (AdapterInfo);
  } else {
    //
    // may be disabling everything!
    //
    if (AdapterInfo->Receive_Started) {
      StopRU (AdapterInfo);
    }

    AdapterInfo->Rx_Filter |= (~PXE_OPFLAGS_RECEIVE_FILTER_UNICAST);
  }

  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description
  @param  cpb                             TODO: add argument description
  @param  opflags                         TODO: add argument description

  @return TODO: add return values

**/
UINTN
E100bTransmit (
  NIC_DATA_INSTANCE *AdapterInfo,
  UINT64            cpb,
  UINT16            opflags
  )
{
  PXE_CPB_TRANSMIT_FRAGMENTS  *tx_ptr_f;
  PXE_CPB_TRANSMIT            *tx_ptr_1;
  TxCB                        *tcb_ptr;
  UINT64                      Tmp_ptr;
  UINTN                       stat;
  INT32                       Index;
  UINT16                      wait_sec;

  tx_ptr_1  = (PXE_CPB_TRANSMIT *) (UINTN) cpb;
  tx_ptr_f  = (PXE_CPB_TRANSMIT_FRAGMENTS *) (UINTN) cpb;
  Tmp_ptr = 0;

  //
  // stop reentrancy here
  //
  if (AdapterInfo->in_transmit) {
    return PXE_STATCODE_BUSY;

  }

  AdapterInfo->in_transmit = TRUE;

  //
  // Prevent interrupts from changing the Tx ring from underneath us.
  //
  // Calculate the Tx descriptor entry.
  //
  if ((tcb_ptr = GetFreeCB (AdapterInfo)) == NULL) {
    AdapterInfo->in_transmit = FALSE;
    return PXE_STATCODE_QUEUE_FULL;
  }

  AdapterInfo->TxTotals++;

  tcb_ptr->cb_header.command  = (CmdSuspend | CmdTx | CmdTxFlex);
  tcb_ptr->cb_header.status   = 0;

  //
  // no immediate data, set EOF in the ByteCount
  //
  tcb_ptr->ByteCount = 0x8000;

  //
  // The data region is always in one buffer descriptor, Tx FIFO
  // threshold of 256.
  // 82557 multiplies the threashold value by 8, so give 256/8
  //
  tcb_ptr->Threshold = 32;
  if ((opflags & PXE_OPFLAGS_TRANSMIT_FRAGMENTED) != 0) {

    if (tx_ptr_f->FragCnt > MAX_XMIT_FRAGMENTS) {
      SetFreeCB (AdapterInfo, tcb_ptr);
      AdapterInfo->in_transmit = FALSE;
      return PXE_STATCODE_INVALID_PARAMETER;
    }

    tcb_ptr->TBDCount = (UINT8) tx_ptr_f->FragCnt;

    for (Index = 0; Index < tx_ptr_f->FragCnt; Index++) {
      stat = MapIt (
              AdapterInfo,
              tx_ptr_f->FragDesc[Index].FragAddr,
              tx_ptr_f->FragDesc[Index].FragLen,
              TO_DEVICE,
              (UINT64)(UINTN) &Tmp_ptr
              );
      if (stat != 0) {
        SetFreeCB (AdapterInfo, tcb_ptr);
        AdapterInfo->in_transmit = FALSE;
        return PXE_STATCODE_INVALID_PARAMETER;
      }

      tcb_ptr->TBDArray[Index].phys_buf_addr  = (UINT32) Tmp_ptr;
      tcb_ptr->TBDArray[Index].buf_len        = tx_ptr_f->FragDesc[Index].FragLen;
    }

    tcb_ptr->free_data_ptr = tx_ptr_f->FragDesc[0].FragAddr;

  } else {
    //
    // non fragmented case
    //
    tcb_ptr->TBDCount = 1;
    stat = MapIt (
            AdapterInfo,
            tx_ptr_1->FrameAddr,
            tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen,
            TO_DEVICE,
            (UINT64)(UINTN) &Tmp_ptr
            );
    if (stat != 0) {
      SetFreeCB (AdapterInfo, tcb_ptr);
      AdapterInfo->in_transmit = FALSE;
      return PXE_STATCODE_INVALID_PARAMETER;
    }

    tcb_ptr->TBDArray[0].phys_buf_addr  = (UINT32) (Tmp_ptr);
    tcb_ptr->TBDArray[0].buf_len        = tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen;
    tcb_ptr->free_data_ptr              = tx_ptr_1->FrameAddr;
  }

  //
  // must wait for previous command completion only if it was a non-transmit
  //
  BlockIt (AdapterInfo, TRUE);
  IssueCB (AdapterInfo, tcb_ptr);
  BlockIt (AdapterInfo, FALSE);

  //
  // see if we need to wait for completion here
  //
  if ((opflags & PXE_OPFLAGS_TRANSMIT_BLOCK) != 0) {
    //
    // don't wait for more than 1 second!!!
    //
    wait_sec = 1000;
    while (tcb_ptr->cb_header.status == 0) {
      DelayIt (AdapterInfo, 10);
      wait_sec--;
      if (wait_sec == 0) {
        break;
      }
    }
    //
    // we need to un-map any mapped buffers here
    //
    if ((opflags & PXE_OPFLAGS_TRANSMIT_FRAGMENTED) != 0) {

      for (Index = 0; Index < tx_ptr_f->FragCnt; Index++) {
        Tmp_ptr = tcb_ptr->TBDArray[Index].phys_buf_addr;
        UnMapIt (
          AdapterInfo,
          tx_ptr_f->FragDesc[Index].FragAddr,
          tx_ptr_f->FragDesc[Index].FragLen,
          TO_DEVICE,
          (UINT64) Tmp_ptr
          );
      }
    } else {
      Tmp_ptr = tcb_ptr->TBDArray[0].phys_buf_addr;
      UnMapIt (
        AdapterInfo,
        tx_ptr_1->FrameAddr,
        tx_ptr_1->DataLen + tx_ptr_1->MediaheaderLen,
        TO_DEVICE,
        (UINT64) Tmp_ptr
        );
    }

    if (tcb_ptr->cb_header.status == 0) {
      SetFreeCB (AdapterInfo, tcb_ptr);
      AdapterInfo->in_transmit = FALSE;
      return PXE_STATCODE_DEVICE_FAILURE;
    }

    SetFreeCB (AdapterInfo, tcb_ptr);
  }
  //
  // CB will be set free later in get_status (or when we run out of xmit buffers
  //
  AdapterInfo->in_transmit = FALSE;

  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description
  @param  cpb                             TODO: add argument description
  @param  db                              TODO: add argument description

  @return TODO: add return values

**/
UINTN
E100bReceive (
  NIC_DATA_INSTANCE *AdapterInfo,
  UINT64            cpb,
  UINT64            db
  )
{
  PXE_CPB_RECEIVE *rx_cpbptr;
  PXE_DB_RECEIVE  *rx_dbptr;
  RxFD            *rx_ptr;
  INT32           status;
  INT32           Index;
  UINT16          pkt_len;
  UINT16          ret_code;
  PXE_FRAME_TYPE  pkt_type;
  UINT16          Tmp_len;
  EtherHeader     *hdr_ptr;
  ret_code  = PXE_STATCODE_NO_DATA;
  pkt_type  = PXE_FRAME_TYPE_NONE;
  status    = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
  AdapterInfo->Int_Status = (UINT16) (AdapterInfo->Int_Status | status);
  //
  // acknoledge the interrupts
  //
  OutWord (AdapterInfo, (UINT16) (status & 0xfc00), (UINT32) (AdapterInfo->ioaddr + SCBStatus));

  //
  // include the prev ints as well
  //
  status = AdapterInfo->Int_Status;
  rx_cpbptr = (PXE_CPB_RECEIVE *) (UINTN) cpb;
  rx_dbptr  = (PXE_DB_RECEIVE *) (UINTN) db;

  rx_ptr    = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];

  //
  // be in a loop just in case (we may drop a pkt)
  //
  while ((status = rx_ptr->cb_header.status) & RX_COMPLETE) {

    AdapterInfo->RxTotals++;
    //
    // If we own the next entry, it's a new packet. Send it up.
    //
    if (rx_ptr->forwarded) {
      goto FreeRFD;

    }

    //
    // discard bad frames
    //

    //
    // crc, align, dma overrun, too short, receive error (v22 no coll)
    //
    if ((status & 0x0D90) != 0) {
      goto FreeRFD;

    }

    //
    // make sure the status is OK
    //
    if ((status & 0x02000) == 0) {
      goto FreeRFD;
    }

    pkt_len = (UINT16) (rx_ptr->ActualCount & 0x3fff);

    if (pkt_len != 0) {

      Tmp_len = pkt_len;
      if (pkt_len > rx_cpbptr->BufferLen) {
        Tmp_len = (UINT16) rx_cpbptr->BufferLen;
      }

      CopyMem ((INT8 *) (UINTN) rx_cpbptr->BufferAddr, (INT8 *) &rx_ptr->RFDBuffer, Tmp_len);

      hdr_ptr = (EtherHeader *) &rx_ptr->RFDBuffer;
      //
      // fill the CDB and break the loop
      //

      //
      // includes header
      //
      rx_dbptr->FrameLen = pkt_len;
      rx_dbptr->MediaHeaderLen = PXE_MAC_HEADER_LEN_ETHER;

      for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
        if (hdr_ptr->dest_addr[Index] != AdapterInfo->CurrentNodeAddress[Index]) {
          break;
        }
      }

      if (Index >= PXE_HWADDR_LEN_ETHER) {
        pkt_type = PXE_FRAME_TYPE_UNICAST;
      } else {
        for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
          if (hdr_ptr->dest_addr[Index] != AdapterInfo->BroadcastNodeAddress[Index]) {
            break;
          }
        }

        if (Index >= PXE_HWADDR_LEN_ETHER) {
          pkt_type = PXE_FRAME_TYPE_BROADCAST;
        } else {
          if ((hdr_ptr->dest_addr[0] & 1) == 1) {
            //
            // mcast
            //

            pkt_type = PXE_FRAME_TYPE_FILTERED_MULTICAST;
          } else {
            pkt_type = PXE_FRAME_TYPE_PROMISCUOUS;
          }
        }
      }

      rx_dbptr->Type      = pkt_type;
      rx_dbptr->Protocol  = hdr_ptr->type;

      for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
        rx_dbptr->SrcAddr[Index]  = hdr_ptr->src_addr[Index];
        rx_dbptr->DestAddr[Index] = hdr_ptr->dest_addr[Index];
      }

      rx_ptr->forwarded = TRUE;
      //
      // success
      //
      ret_code          = 0;
      Recycle_RFD (AdapterInfo, AdapterInfo->cur_rx_ind);
      AdapterInfo->cur_rx_ind++;
      if (AdapterInfo->cur_rx_ind == AdapterInfo->RxBufCnt) {
        AdapterInfo->cur_rx_ind = 0;
      }
      break;
    }

FreeRFD:
    Recycle_RFD (AdapterInfo, AdapterInfo->cur_rx_ind);
    AdapterInfo->cur_rx_ind++;
    if (AdapterInfo->cur_rx_ind == AdapterInfo->RxBufCnt) {
      AdapterInfo->cur_rx_ind = 0;
    }

    rx_ptr = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];
  }

  if (pkt_type == PXE_FRAME_TYPE_NONE) {
    AdapterInfo->Int_Status &= (~SCB_STATUS_FR);
  }

  status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
  if ((status & SCB_RUS_NO_RESOURCES) != 0) {
    //
    // start the receive unit here!
    // leave all the filled frames,
    //
    SetupReceiveQueues (AdapterInfo);
    OutLong (AdapterInfo, (UINT32) AdapterInfo->rx_phy_addr, AdapterInfo->ioaddr + SCBPointer);
    OutWord (AdapterInfo, RX_START, AdapterInfo->ioaddr + SCBCmd);
    AdapterInfo->cur_rx_ind = 0;
  }

  return ret_code;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
INT16
E100bReadEepromAndStationAddress (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  INT32   Index;
  INT32   Index2;
  UINT16  sum;
  UINT16  eeprom_len;
  UINT8   addr_len;
  UINT16  *eedata;

  eedata    = (UINT16 *) (&AdapterInfo->NVData[0]);

  sum       = 0;
  addr_len  = E100bGetEepromAddrLen (AdapterInfo);

  //
  // in words
  //
  AdapterInfo->NVData_Len = eeprom_len = (UINT16) (1 << addr_len);
  for (Index2 = 0, Index = 0; ((Index2 < PXE_MAC_LENGTH - 1) && (Index < eeprom_len)); Index++) {
    UINT16  value;
    value         = E100bReadEeprom (AdapterInfo, Index, addr_len);
    eedata[Index] = value;
    sum           = (UINT16) (sum + value);
    if (Index < 3) {
      AdapterInfo->PermNodeAddress[Index2++]  = (UINT8) value;
      AdapterInfo->PermNodeAddress[Index2++]  = (UINT8) (value >> 8);
    }
  }

  if (sum != 0xBABA) {
    return -1;
  }

  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
    AdapterInfo->CurrentNodeAddress[Index] = AdapterInfo->PermNodeAddress[Index];
  }

  for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
    AdapterInfo->BroadcastNodeAddress[Index] = 0xff;
  }

  for (Index = PXE_HWADDR_LEN_ETHER; Index < PXE_MAC_LENGTH; Index++) {
    AdapterInfo->CurrentNodeAddress[Index]    = 0;
    AdapterInfo->PermNodeAddress[Index]       = 0;
    AdapterInfo->BroadcastNodeAddress[Index]  = 0;
  }

  return 0;
}

//
//  CBList is a circular linked list
//  1) When all are free, Tail->next == Head and FreeCount == # allocated
//  2) When none are free, Tail == Head and FreeCount == 0
//  3) when one is free, Tail == Head and Freecount == 1
//  4) First non-Free frame is always at Tail->next
//

/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
UINT8
SetupCBlink (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  TxCB  *head_ptr;
  TxCB  *tail_ptr;
  TxCB  *cur_ptr;
  INT32 Index;
  UINTN array_off;

  cur_ptr   = &(AdapterInfo->tx_ring[0]);
  array_off = (UINTN) (&cur_ptr->TBDArray) - (UINTN) cur_ptr;
  for (Index = 0; Index < AdapterInfo->TxBufCnt; Index++) {
    cur_ptr[Index].cb_header.status   = 0;
    cur_ptr[Index].cb_header.command  = 0;

    cur_ptr[Index].PhysTCBAddress     =
    (UINT32) AdapterInfo->tx_phy_addr + (Index * sizeof (TxCB));

    cur_ptr[Index].PhysArrayAddr      = (UINT32)(cur_ptr[Index].PhysTCBAddress + array_off);
    cur_ptr[Index].PhysTBDArrayAddres = (UINT32)(cur_ptr[Index].PhysTCBAddress + array_off);

    cur_ptr->free_data_ptr = (UINT64) 0;

    if (Index < AdapterInfo->TxBufCnt - 1) {
      cur_ptr[Index].cb_header.link             = cur_ptr[Index].PhysTCBAddress + sizeof (TxCB);
      cur_ptr[Index].NextTCBVirtualLinkPtr      = &cur_ptr[Index + 1];
      cur_ptr[Index + 1].PrevTCBVirtualLinkPtr  = &cur_ptr[Index];
    }
  }

  head_ptr                        = &cur_ptr[0];
  tail_ptr                        = &cur_ptr[AdapterInfo->TxBufCnt - 1];
  tail_ptr->cb_header.link        = head_ptr->PhysTCBAddress;
  tail_ptr->NextTCBVirtualLinkPtr = head_ptr;
  head_ptr->PrevTCBVirtualLinkPtr = tail_ptr;

  AdapterInfo->FreeCBCount        = AdapterInfo->TxBufCnt;
  AdapterInfo->FreeTxHeadPtr      = head_ptr;
  //
  // set tail of the free list, next to this would be either in use
  // or the head itself
  //
  AdapterInfo->FreeTxTailPtr  = tail_ptr;

  AdapterInfo->xmit_done_head = AdapterInfo->xmit_done_tail = 0;

  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
TxCB *
GetFreeCB (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  TxCB  *free_cb_ptr;

  //
  // claim any hanging free CBs
  //
  if (AdapterInfo->FreeCBCount <= 1) {
    CheckCBList (AdapterInfo);
  }

  //
  // don't use up the last CB problem if the previous CB that the CU used
  // becomes the last CB we submit because of the SUSPEND bit we set.
  // the CU thinks it was never cleared.
  //

  if (AdapterInfo->FreeCBCount <= 1) {
    return NULL;
  }

  BlockIt (AdapterInfo, TRUE);
  free_cb_ptr                 = AdapterInfo->FreeTxHeadPtr;
  AdapterInfo->FreeTxHeadPtr  = free_cb_ptr->NextTCBVirtualLinkPtr;
  --AdapterInfo->FreeCBCount;
  BlockIt (AdapterInfo, FALSE);
  return free_cb_ptr;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description
  @param  cb_ptr                          TODO: add argument description

  @return TODO: add return values

**/
VOID
SetFreeCB (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN TxCB              *cb_ptr
  )
{
  //
  // here we assume cb are returned in the order they are taken out
  // and we link the newly freed cb at the tail of free cb list
  //
  cb_ptr->cb_header.status    = 0;
  cb_ptr->free_data_ptr       = (UINT64) 0;

  AdapterInfo->FreeTxTailPtr  = cb_ptr;
  ++AdapterInfo->FreeCBCount;
  return ;
}


/**
  TODO: Add function description

  @param  ind                             TODO: add argument description

  @return TODO: add return values

**/
UINT16
next (
  IN UINT16 ind
  )
{
  UINT16  Tmp;

  Tmp = (UINT16) (ind + 1);
  if (Tmp >= (TX_BUFFER_COUNT << 1)) {
    Tmp = 0;
  }

  return Tmp;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
UINT16
CheckCBList (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  TxCB    *Tmp_ptr;
  UINT16  cnt;

  cnt = 0;
  while (1) {
    Tmp_ptr = AdapterInfo->FreeTxTailPtr->NextTCBVirtualLinkPtr;
    if ((Tmp_ptr->cb_header.status & CMD_STATUS_MASK) != 0) {
      //
      // check if Q is full
      //
      if (next (AdapterInfo->xmit_done_tail) != AdapterInfo->xmit_done_head) {
        ASSERT (AdapterInfo->xmit_done_tail < TX_BUFFER_COUNT << 1);
        AdapterInfo->xmit_done[AdapterInfo->xmit_done_tail] = Tmp_ptr->free_data_ptr;

        UnMapIt (
          AdapterInfo,
          Tmp_ptr->free_data_ptr,
          Tmp_ptr->TBDArray[0].buf_len,
          TO_DEVICE,
          (UINT64) Tmp_ptr->TBDArray[0].phys_buf_addr
          );

        AdapterInfo->xmit_done_tail = next (AdapterInfo->xmit_done_tail);
      }

      SetFreeCB (AdapterInfo, Tmp_ptr);
    } else {
      break;
    }
  }

  return cnt;
}
//
// Description : Initialize the RFD list list by linking each element together
//               in a circular list.  The simplified memory model is used.
//               All data is in the RFD.  The RFDs are linked together and the
//               last one points back to the first one.  When the current RFD
//               is processed (frame received), its EL bit is set and the EL
//               bit in the previous RXFD is cleared.
//               Allocation done during INIT, this is making linked list.
//

/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
UINT8
SetupReceiveQueues (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  RxFD    *rx_ptr;
  RxFD    *tail_ptr;
  UINT16  Index;

  AdapterInfo->cur_rx_ind = 0;
  rx_ptr                  = (&AdapterInfo->rx_ring[0]);

  for (Index = 0; Index < AdapterInfo->RxBufCnt; Index++) {
    rx_ptr[Index].cb_header.status  = 0;
    rx_ptr[Index].cb_header.command = 0;
    rx_ptr[Index].RFDSize           = RX_BUFFER_SIZE;
    rx_ptr[Index].ActualCount       = 0;
    //
    // RBDs not used, simple memory model
    //
    rx_ptr[Index].rx_buf_addr       = (UINT32) (-1);

    //
    // RBDs not used, simple memory model
    //
    rx_ptr[Index].forwarded = FALSE;

    //
    // don't use Tmp_ptr if it is beyond the last one
    //
    if (Index < AdapterInfo->RxBufCnt - 1) {
      rx_ptr[Index].cb_header.link = (UINT32) AdapterInfo->rx_phy_addr + ((Index + 1) * sizeof (RxFD));
    }
  }

  tail_ptr                    = (&AdapterInfo->rx_ring[AdapterInfo->RxBufCnt - 1]);
  tail_ptr->cb_header.link    = (UINT32) AdapterInfo->rx_phy_addr;

  //
  // set the EL bit
  //
  tail_ptr->cb_header.command = 0xC000;
  AdapterInfo->RFDTailPtr = tail_ptr;
  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description
  @param  rx_index                        TODO: add argument description

  @return TODO: add return values

**/
VOID
Recycle_RFD (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT16            rx_index
  )
{
  RxFD  *rx_ptr;
  RxFD  *tail_ptr;
  //
  // change the EL bit and change the AdapterInfo->RxTailPtr
  // rx_ptr is assumed to be the head of the Q
  // AdapterInfo->rx_forwarded[rx_index] = FALSE;
  //
  rx_ptr                    = &AdapterInfo->rx_ring[rx_index];
  tail_ptr                  = AdapterInfo->RFDTailPtr;
  //
  // set el_bit and suspend bit
  //
  rx_ptr->cb_header.command = 0xc000;
  rx_ptr->cb_header.status    = 0;
  rx_ptr->ActualCount         = 0;
  rx_ptr->forwarded           = FALSE;
  AdapterInfo->RFDTailPtr     = rx_ptr;
  //
  // resetting the el_bit.
  //
  tail_ptr->cb_header.command = 0;
  //
  // check the receive unit, fix if there is any problem
  //
  return ;
}
//
// Serial EEPROM section.
//
//  EEPROM_Ctrl bits.
//
#define EE_SHIFT_CLK  0x01  /* EEPROM shift clock. */
#define EE_CS         0x02  /* EEPROM chip select. */
#define EE_DI         0x04  /* EEPROM chip data in. */
#define EE_WRITE_0    0x01
#define EE_WRITE_1    0x05
#define EE_DO         0x08  /* EEPROM chip data out. */
#define EE_ENB        (0x4800 | EE_CS)

//
// Delay between EEPROM clock transitions.
// This will actually work with no delay on 33Mhz PCI.
//
#define eeprom_delay(nanosec) DelayIt (AdapterInfo, nanosec);

//
// The EEPROM commands include the alway-set leading bit.
//
#define EE_WRITE_CMD  5 // 101b
#define EE_READ_CMD   6 // 110b
#define EE_ERASE_CMD  (7 << 6)

VOID
shift_bits_out (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT16            val,
  IN UINT8             num_bits
  )
/*++

Routine Description:

  TODO: Add function description

Arguments:

  AdapterInfo - TODO: add argument description
  val         - TODO: add argument description
  num_bits    - TODO: add argument description

Returns:

  TODO: add return values

--*/
{
  INT32   Index;
  UINT8   Tmp;
  UINT32  EEAddr;

  EEAddr = AdapterInfo->ioaddr + SCBeeprom;

  for (Index = num_bits; Index >= 0; Index--) {
    INT16 dataval;

    //
    // will be 0 or 4
    //
    dataval = (INT16) ((val & (1 << Index)) ? EE_DI : 0);

    //
    // mask off the data_in bit
    //
    Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) &~EE_DI);
    Tmp = (UINT8) (Tmp | dataval);
    OutByte (AdapterInfo, Tmp, EEAddr);
    eeprom_delay (100);
    //
    // raise the eeprom clock
    //
    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
    eeprom_delay (150);
    //
    // lower the eeprom clock
    //
    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
    eeprom_delay (150);
  }
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
UINT16
shift_bits_in (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  UINT8   Tmp;
  INT32   Index;
  UINT16  retval;
  UINT32  EEAddr;

  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;

  retval  = 0;
  for (Index = 15; Index >= 0; Index--) {
    //
    // raise the clock
    //

    //
    // mask off the data_in bit
    //
    Tmp = InByte (AdapterInfo, EEAddr);
    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
    eeprom_delay (100);
    Tmp     = InByte (AdapterInfo, EEAddr);
    retval  = (UINT16) ((retval << 1) | ((Tmp & EE_DO) ? 1 : 0));
    //
    // lower the clock
    //
    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
    eeprom_delay (100);
  }

  return retval;
}


/**
  This routine sets the EEPROM lockout bit to gain exclusive access to the
  eeprom. the access bit is the most significant bit in the General Control
  Register 2 in the SCB space.

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on..

  @retval TRUE                            if it got the access
  @retval FALSE                           if it fails to get the exclusive access

**/
BOOLEAN
E100bSetEepromLockOut (
  IN NIC_DATA_INSTANCE  *AdapterInfo
  )
{
  UINTN wait;
  UINT8 tmp;

  if ((AdapterInfo->DeviceID == D102_DEVICE_ID) ||
      (AdapterInfo->RevID >= D102_REVID)) {

    wait = 500;

    while (wait--) {

      tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);
      tmp |= GCR2_EEPROM_ACCESS_SEMAPHORE;
      OutByte (AdapterInfo, tmp, AdapterInfo->ioaddr + SCBGenCtrl2);

      DelayIt (AdapterInfo, 50);
      tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);

      if (tmp & GCR2_EEPROM_ACCESS_SEMAPHORE) {
        return TRUE;
      }
    }

    return FALSE;
  }

  return TRUE;
}


/**
  This routine Resets the EEPROM lockout bit to giveup access to the
  eeprom. the access bit is the most significant bit in the General Control
  Register 2 in the SCB space.

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on..

  @return None

**/
VOID
E100bReSetEepromLockOut (
  IN NIC_DATA_INSTANCE  *AdapterInfo
  )
{
  UINT8 tmp;

  if ((AdapterInfo->DeviceID == D102_DEVICE_ID) ||
      (AdapterInfo->RevID >= D102_REVID)) {

    tmp = InByte (AdapterInfo, AdapterInfo->ioaddr + SCBGenCtrl2);
    tmp &= ~(GCR2_EEPROM_ACCESS_SEMAPHORE);
    OutByte (AdapterInfo, tmp, AdapterInfo->ioaddr + SCBGenCtrl2);

    DelayIt (AdapterInfo, 50);
  }
}


/**
  Using the NIC data structure information, read the EEPROM to get a Word of data for the MAC address.

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on..
  @param  Location                        Word offset into the MAC address to read.
  @param  AddrLen                         Number of bits of address length.

  @retval RetVal                          The word read from the EEPROM.

**/
UINT16
E100bReadEeprom (
  IN NIC_DATA_INSTANCE  *AdapterInfo,
  IN INT32              Location,
  IN UINT8              AddrLen
  )
{
  UINT16  RetVal;
  UINT8   Tmp;

  UINT32  EEAddr;
  UINT16  ReadCmd;

  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;
  ReadCmd = (UINT16) (Location | (EE_READ_CMD << AddrLen));

  RetVal  = 0;

  //
  // get exclusive access to the eeprom first!
  //
  E100bSetEepromLockOut (AdapterInfo);

  //
  // eeprom control reg bits: x,x,x,x,DO,DI,CS,SK
  // to write the opcode+data value out one bit at a time in DI starting at msb
  // and then out a 1 to sk, wait, out 0 to SK and wait
  // repeat this for all the bits to be written
  //

  //
  // 11110010b
  //
  Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) & 0xF2);
  OutByte (AdapterInfo, (UINT8) (Tmp | EE_CS), EEAddr);

  //
  // 3 for the read opcode 110b
  //
  shift_bits_out (AdapterInfo, ReadCmd, (UINT8) (3 + AddrLen));

  //
  // read the eeprom word one bit at a time
  //
  RetVal = shift_bits_in (AdapterInfo);

  //
  // Terminate the EEPROM access and leave eeprom in a clean state.
  //
  Tmp = InByte (AdapterInfo, EEAddr);
  Tmp &= ~(EE_CS | EE_DI);
  OutByte (AdapterInfo, Tmp, EEAddr);

  //
  // raise the clock and lower the eeprom shift clock
  //
  OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
  eeprom_delay (100);

  OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
  eeprom_delay (100);

  //
  // giveup access to the eeprom
  //
  E100bReSetEepromLockOut (AdapterInfo);

  return RetVal;
}


/**
  Using the NIC data structure information, read the EEPROM to determine how many bits of address length
  this EEPROM is in Words.

  @param  AdapterInfo                     Pointer to the NIC data structure
                                          information which the UNDI driver is
                                          layering on..

  @retval RetVal                          The word read from the EEPROM.

**/
UINT8
E100bGetEepromAddrLen (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  UINT8   Tmp;
  UINT8   AddrLen;
  UINT32  EEAddr;
  //
  // assume 64word eeprom (so,6 bits of address_length)
  //
  UINT16  ReadCmd;

  EEAddr  = AdapterInfo->ioaddr + SCBeeprom;
  ReadCmd = (EE_READ_CMD << 6);

  //
  // get exclusive access to the eeprom first!
  //
  E100bSetEepromLockOut (AdapterInfo);

  //
  // address we are trying to read is 0
  // eeprom control reg bits: x,x,x,x,DO,,DI,,CS,SK
  // to write the opcode+data value out one bit at a time in DI starting at msb
  // and then out a 1 to sk, wait, out 0 to SK and wait
  // repeat this for all the bits to be written
  //
  Tmp = (UINT8) (InByte (AdapterInfo, EEAddr) & 0xF2);

  //
  // enable eeprom access
  //
  OutByte (AdapterInfo, (UINT8) (Tmp | EE_CS), EEAddr);

  //
  // 3 for opcode, 6 for the default address len
  //
  shift_bits_out (AdapterInfo, ReadCmd, (UINT8) (3 + 6));

  //
  // (in case of a 64 word eeprom).
  // read the "dummy zero" from EE_DO to say that the address we wrote
  // (six 0s) is accepted, write more zeros (until 8) to get a "dummy zero"
  //

  //
  // assume the smallest
  //
  AddrLen = 6;
  Tmp     = InByte (AdapterInfo, EEAddr);
  while ((AddrLen < 8) && ((Tmp & EE_DO) != 0)) {
    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_DI), EEAddr);
    eeprom_delay (100);

    //
    // raise the eeprom clock
    //
    OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
    eeprom_delay (150);

    //
    // lower the eeprom clock
    //
    OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
    eeprom_delay (150);
    Tmp = InByte (AdapterInfo, EEAddr);
    AddrLen++;
  }

  //
  // read the eeprom word, even though we don't need this
  //
  shift_bits_in (AdapterInfo);

  //
  // Terminate the EEPROM access.
  //
  Tmp = InByte (AdapterInfo, EEAddr);
  Tmp &= ~(EE_CS | EE_DI);
  OutByte (AdapterInfo, Tmp, EEAddr);

  //
  // raise the clock and lower the eeprom shift clock
  //
  OutByte (AdapterInfo, (UINT8) (Tmp | EE_SHIFT_CLK), EEAddr);
  eeprom_delay (100);

  OutByte (AdapterInfo, (UINT8) (Tmp &~EE_SHIFT_CLK), EEAddr);
  eeprom_delay (100);

  //
  // giveup access to the eeprom!
  //
  E100bReSetEepromLockOut (AdapterInfo);

  return AddrLen;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description
  @param  DBaddr                          TODO: add argument description
  @param  DBsize                          TODO: add argument description

  @return TODO: add return values

**/
UINTN
E100bStatistics (
  NIC_DATA_INSTANCE *AdapterInfo,
  UINT64            DBaddr,
  UINT16            DBsize
  )
{
  PXE_DB_STATISTICS db;
  //
  // wait upto one second (each wait is 100 micro s)
  //
  UINT32            Wait;
  Wait = 10000;
  wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);

  //
  // Clear statistics done marker.
  //
  AdapterInfo->statistics->done_marker = 0;

  //
  // Issue statistics dump (or dump w/ reset) command.
  //
  OutByte (
    AdapterInfo,
    (UINT8) (DBsize ? CU_SHOWSTATS : CU_DUMPSTATS),
    (UINT32) (AdapterInfo->ioaddr + SCBCmd)
    );

  //
  // Wait for command to complete.
  //
  // zero the db here just to chew up a little more time.
  //

  ZeroMem ((VOID *) &db, sizeof db);

  while (Wait != 0) {
    //
    // Wait a bit before checking.
    //

    DelayIt (AdapterInfo, 100);

    //
    // Look for done marker at end of statistics.
    //

    switch (AdapterInfo->statistics->done_marker) {
    case 0xA005:
    case 0xA007:
      break;

    default:
      Wait--;
      continue;
    }

    //
    // if we did not "continue" from the above switch, we are done,
    //
    break;
  }

  //
  // If this is a reset, we are out of here!
  //
  if (DBsize == 0) {
    return PXE_STATCODE_SUCCESS;
  }

  //
  // Convert NIC statistics counter format to EFI/UNDI
  // specification statistics counter format.
  //

  //
  //                54 3210 fedc ba98 7654 3210
  // db.Supported = 01 0000 0100 1101 0001 0111;
  //
  db.Supported = 0x104D17;

  //
  // Statistics from the NIC
  //

  db.Data[0x01] = AdapterInfo->statistics->rx_good_frames;

  db.Data[0x02] = AdapterInfo->statistics->rx_runt_errs;

  db.Data[0x08] = AdapterInfo->statistics->rx_crc_errs +
                  AdapterInfo->statistics->rx_align_errs;

  db.Data[0x04] = db.Data[0x02] +
                  db.Data[0x08] +
                  AdapterInfo->statistics->rx_resource_errs +
                  AdapterInfo->statistics->rx_overrun_errs;

  db.Data[0x00] = db.Data[0x01] + db.Data[0x04];

  db.Data[0x0B] = AdapterInfo->statistics->tx_good_frames;

  db.Data[0x0E] = AdapterInfo->statistics->tx_coll16_errs +
    AdapterInfo->statistics->tx_late_colls +
    AdapterInfo->statistics->tx_underruns +
    AdapterInfo->statistics->tx_one_colls +
    AdapterInfo->statistics->tx_multi_colls;

  db.Data[0x14] = AdapterInfo->statistics->tx_total_colls;

  db.Data[0x0A] = db.Data[0x0B] +
                  db.Data[0x0E] +
                  AdapterInfo->statistics->tx_lost_carrier;

  if (DBsize > sizeof db) {
    DBsize = (UINT16) sizeof (db);
  }

  CopyMem ((VOID *) (UINTN) DBaddr, (VOID *) &db, (UINTN) DBsize);

  return PXE_STATCODE_SUCCESS;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description
  @param  OpFlags                         TODO: add argument description

  @return TODO: add return values

**/
UINTN
E100bReset (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN INT32             OpFlags
  )
{

  UINT16  save_filter;
  //
  // disable the interrupts
  //
  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);

  //
  // wait for the tx queue to complete
  //
  CheckCBList (AdapterInfo);

  XmitWaitForCompletion (AdapterInfo);

  if (AdapterInfo->Receive_Started) {
    StopRU (AdapterInfo);
  }

  InitializeChip (AdapterInfo);

  //
  // check the opflags and restart receive filters
  //
  if ((OpFlags & PXE_OPFLAGS_RESET_DISABLE_FILTERS) == 0) {

    save_filter = AdapterInfo->Rx_Filter;
    //
    // if we give the filter same as Rx_Filter,
    // this routine will not set mcast list (it thinks there is no change)
    // to force it, we will reset that flag in the Rx_Filter
    //
    AdapterInfo->Rx_Filter &= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);
    E100bSetfilter (AdapterInfo, save_filter, (UINT64) 0, (UINT32) 0);
  }

  if ((OpFlags & PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS) != 0) {
    //
    // disable the interrupts
    //
    AdapterInfo->int_mask = 0;
  }
  //
  // else leave the interrupt in the pre-set state!!!
  //
  E100bSetInterruptState (AdapterInfo);

  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
UINTN
E100bShutdown (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  //
  // disable the interrupts
  //
  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);

  //
  // stop the receive unit
  //
  if (AdapterInfo->Receive_Started) {
    StopRU (AdapterInfo);
  }

  //
  // wait for the tx queue to complete
  //
  CheckCBList (AdapterInfo);
  if (AdapterInfo->FreeCBCount != AdapterInfo->TxBufCnt) {
    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
  }

  //
  // we do not want to reset the phy, it takes a long time to renegotiate the
  // link after that (3-4 seconds)
  //
  InitializeChip (AdapterInfo);
  SelectiveReset (AdapterInfo);
  return 0;
}


/**
  This routine will write a value to the specified MII register
  of an external MDI compliant device (e.g. PHY 100).  The command will
  execute in polled mode.

  @param  AdapterInfo                     pointer to the structure that contains
                                          the NIC's context.
  @param  RegAddress                      The MII register that we are writing to
  @param  PhyAddress                      The MDI address of the Phy component.
  @param  DataValue                       The value that we are writing to the MII
                                          register.

  @return nothing

**/
VOID
MdiWrite (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT8             RegAddress,
  IN UINT8             PhyAddress,
  IN UINT16            DataValue
  )
{
  UINT32  WriteCommand;

  WriteCommand = ((UINT32) DataValue) |
                 ((UINT32)(RegAddress << 16)) |
                 ((UINT32)(PhyAddress << 21)) |
                 ((UINT32)(MDI_WRITE << 26));

  //
  // Issue the write command to the MDI control register.
  //
  OutLong (AdapterInfo, WriteCommand, AdapterInfo->ioaddr + SCBCtrlMDI);

  //
  // wait 20usec before checking status
  //
  DelayIt (AdapterInfo, 20);

  //
  // poll for the mdi write to complete
  while ((InLong (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI) &
                    MDI_PHY_READY) == 0){
    DelayIt (AdapterInfo, 20);
  }
}


/**
  This routine will read a value from the specified MII register
  of an external MDI compliant device (e.g. PHY 100), and return
  it to the calling routine.  The command will execute in polled mode.

  @param  AdapterInfo                     pointer to the structure that contains
                                          the NIC's context.
  @param  RegAddress                      The MII register that we are reading from
  @param  PhyAddress                      The MDI address of the Phy component.
  @param  DataValue                       pointer to the value that we read from
                                          the MII register.


**/
VOID
MdiRead (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT8             RegAddress,
  IN UINT8             PhyAddress,
  IN OUT UINT16        *DataValue
  )
{
  UINT32  ReadCommand;

  ReadCommand = ((UINT32) (RegAddress << 16)) |
                ((UINT32) (PhyAddress << 21)) |
                ((UINT32) (MDI_READ << 26));

  //
  // Issue the read command to the MDI control register.
  //
  OutLong (AdapterInfo, ReadCommand, AdapterInfo->ioaddr + SCBCtrlMDI);

  //
  // wait 20usec before checking status
  //
  DelayIt (AdapterInfo, 20);

  //
  // poll for the mdi read to complete
  //
  while ((InLong (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI) &
          MDI_PHY_READY) == 0) {
    DelayIt (AdapterInfo, 20);

  }

  *DataValue = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBCtrlMDI);
}


/**
  This routine will reset the PHY that the adapter is currently
  configured to use.

  @param  AdapterInfo                     pointer to the structure that contains
                                          the NIC's context.


**/
VOID
PhyReset (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  UINT16  MdiControlReg;

  MdiControlReg = (MDI_CR_AUTO_SELECT |
                  MDI_CR_RESTART_AUTO_NEG |
                  MDI_CR_RESET);

  //
  // Write the MDI control register with our new Phy configuration
  //
  MdiWrite (
    AdapterInfo,
    MDI_CONTROL_REG,
    AdapterInfo->PhyAddress,
    MdiControlReg
    );

  return ;
}


/**
  This routine will detect what phy we are using, set the line
  speed, FDX or HDX, and configure the phy if necessary.
  The following combinations are supported:
  - TX or T4 PHY alone at PHY address 1
  - T4 or TX PHY at address 1 and MII PHY at address 0
  - 82503 alone (10Base-T mode, no full duplex support)
  - 82503 and MII PHY (TX or T4) at address 0
  The sequence / priority of detection is as follows:
  - PHY 1 with cable termination
  - PHY 0 with cable termination
  - PHY 1 (if found) without cable termination
  - 503 interface
  Additionally auto-negotiation capable (NWAY) and parallel
  detection PHYs are supported. The flow-chart is described in
  the 82557 software writer's manual.
  NOTE:  1.  All PHY MDI registers are read in polled mode.
  2.  The routines assume that the 82557 has been RESET and we have
  obtained the virtual memory address of the CSR.
  3.  PhyDetect will not RESET the PHY.
  4.  If FORCEFDX is set, SPEED should also be set. The driver will
  check the values for inconsistency with the detected PHY
  technology.
  5.  PHY 1 (the PHY on the adapter) may have an address in the range
  1 through 31 inclusive. The driver will accept addresses in
  this range.
  6.  Driver ignores FORCEFDX and SPEED overrides if a 503 interface
  is detected.

  @param  AdapterInfo                     pointer to the structure that contains
                                          the NIC's context.

  @retval TRUE                            If a Phy was detected, and configured
                                          correctly.
  @retval FALSE                           If a valid phy could not be detected and
                                          configured.

**/
BOOLEAN
PhyDetect (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  UINT16  *eedata;
  UINT16  MdiControlReg;
  UINT16  MdiStatusReg;
  BOOLEAN FoundPhy1;
  UINT8   ReNegotiateTime;

  eedata          = (UINT16 *) (&AdapterInfo->NVData[0]);

  FoundPhy1       = FALSE;
  ReNegotiateTime = 35;
  //
  // EEPROM word [6] contains the Primary PHY record in which the least 3 bits
  // indicate the PHY address
  // and word [7] contains the secondary PHY record
  //
  AdapterInfo->PhyRecord[0] = eedata[6];
  AdapterInfo->PhyRecord[1] = eedata[7];
  AdapterInfo->PhyAddress   = (UINT8) (AdapterInfo->PhyRecord[0] & 7);

  //
  // Check for a phy address over-ride of 32 which indicates force use of 82503
  // not detecting the link in this case
  //
  if (AdapterInfo->PhyAddress == 32) {
    //
    // 503 interface over-ride
    // Record the current speed and duplex.  We will be in half duplex
    // mode unless the user used the force full duplex over-ride.
    //
    AdapterInfo->LinkSpeed = 10;
    return (TRUE);
  }

  //
  // If the Phy Address is between 1-31 then we must first look for phy 1,
  // at that address.
  //
  if ((AdapterInfo->PhyAddress > 0) && (AdapterInfo->PhyAddress < 32)) {

    //
    // Read the MDI control and status registers at phy 1
    // and check if we found a valid phy
    //
    MdiRead (
      AdapterInfo,
      MDI_CONTROL_REG,
      AdapterInfo->PhyAddress,
      &MdiControlReg
      );

    MdiRead (
      AdapterInfo,
      MDI_STATUS_REG,
      AdapterInfo->PhyAddress,
      &MdiStatusReg
      );

    if (!((MdiControlReg == 0xffff) ||
          ((MdiStatusReg == 0) && (MdiControlReg == 0)))) {

      //
      // we have a valid phy1
      // Read the status register again because of sticky bits
      //
      FoundPhy1 = TRUE;
      MdiRead (
        AdapterInfo,
        MDI_STATUS_REG,
        AdapterInfo->PhyAddress,
        &MdiStatusReg
        );

      //
      // If there is a valid link then use this Phy.
      //
      if (MdiStatusReg & MDI_SR_LINK_STATUS) {
        return (SetupPhy(AdapterInfo));
      }
    }
  }

  //
  // Next try to detect a PHY at address 0x00 because there was no Phy 1,
  // or Phy 1 didn't have link, or we had a phy 0 over-ride
  //

  //
  // Read the MDI control and status registers at phy 0
  //
  MdiRead (AdapterInfo, MDI_CONTROL_REG, 0, &MdiControlReg);
  MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);

  //
  // check if we found a valid phy 0
  //
  if (((MdiControlReg == 0xffff) ||
       ((MdiStatusReg == 0) && (MdiControlReg == 0)))) {

    //
    // we don't have a valid phy at address 0
    // if phy address was forced to 0, then error out because we
    // didn't find a phy at that address
    //
    if (AdapterInfo->PhyAddress == 0x0000) {
      return (FALSE);
    } else {
      //
      // at this point phy1 does not have link and there is no phy 0 at all
      // if we are forced to detect the cable, error out here!
      //
      if (AdapterInfo->CableDetect != 0) {
        return FALSE;

      }

      if (FoundPhy1) {
        //
        // no phy 0, but there is a phy 1 (no link I guess), so use phy 1
        //
        return SetupPhy (AdapterInfo);
      } else {
        //
        // didn't find phy 0 or phy 1, so assume a 503 interface
        //
        AdapterInfo->PhyAddress = 32;

        //
        // Record the current speed and duplex.  We'll be in half duplex
        // mode unless the user used the force full duplex over-ride.
        //
        AdapterInfo->LinkSpeed = 10;
        return (TRUE);
      }
    }
  } else {
    //
    // We have a valid phy at address 0.  If phy 0 has a link then we use
    // phy 0.  If Phy 0 doesn't have a link then we use Phy 1 (no link)
    // if phy 1 is present, or phy 0 if phy 1 is not present
    // If phy 1 was present, then we must isolate phy 1 before we enable
    // phy 0 to see if Phy 0 has a link.
    //
    if (FoundPhy1) {
      //
      // isolate phy 1
      //
      MdiWrite (
        AdapterInfo,
        MDI_CONTROL_REG,
        AdapterInfo->PhyAddress,
        MDI_CR_ISOLATE
        );

      //
      // wait 100 microseconds for the phy to isolate.
      //
      DelayIt (AdapterInfo, 100);
    }

    //
    // Since this Phy is at address 0, we must enable it.  So clear
    // the isolate bit, and set the auto-speed select bit
    //
    MdiWrite (
      AdapterInfo,
      MDI_CONTROL_REG,
      0,
      MDI_CR_AUTO_SELECT
      );

    //
    // wait 100 microseconds for the phy to be enabled.
    //
    DelayIt (AdapterInfo, 100);

    //
    // restart the auto-negotion process
    //
    MdiWrite (
      AdapterInfo,
      MDI_CONTROL_REG,
      0,
      MDI_CR_RESTART_AUTO_NEG | MDI_CR_AUTO_SELECT
      );

    //
    // wait no more than 3.5 seconds for auto-negotiation to complete
    //
    while (ReNegotiateTime) {
      //
      // Read the status register twice because of sticky bits
      //
      MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);
      MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);

      if (MdiStatusReg & MDI_SR_AUTO_NEG_COMPLETE) {
        break;
      }

      DelayIt (AdapterInfo, 100);
      ReNegotiateTime--;
    }

    //
    // Read the status register again because of sticky bits
    //
    MdiRead (AdapterInfo, MDI_STATUS_REG, 0, &MdiStatusReg);

    //
    // If the link was not set
    //
    if ((MdiStatusReg & MDI_SR_LINK_STATUS) == 0) {
      //
      // PHY1 does not have a link and phy 0 does not have a link
      // do not proceed if we need to detect the link!
      //
      if (AdapterInfo->CableDetect != 0) {
        return FALSE;
      }

      //
      // the link wasn't set, so use phy 1 if phy 1 was present
      //
      if (FoundPhy1) {
        //
        // isolate phy 0
        //
        MdiWrite (AdapterInfo, MDI_CONTROL_REG, 0, MDI_CR_ISOLATE);

        //
        // wait 100 microseconds for the phy to isolate.
        //
        DelayIt (AdapterInfo, 100);

        //
        // Now re-enable PHY 1
        //
        MdiWrite (
          AdapterInfo,
          MDI_CONTROL_REG,
          AdapterInfo->PhyAddress,
          MDI_CR_AUTO_SELECT
          );

        //
        // wait 100 microseconds for the phy to be enabled
        //
        DelayIt (AdapterInfo, 100);

        //
        // restart the auto-negotion process
        //
        MdiWrite (
          AdapterInfo,
          MDI_CONTROL_REG,
          AdapterInfo->PhyAddress,
          MDI_CR_RESTART_AUTO_NEG | MDI_CR_AUTO_SELECT
          );

        //
        // Don't wait for it to complete (we didn't have link earlier)
        //
        return (SetupPhy (AdapterInfo));
      }
    }

    //
    // Definitely using Phy 0
    //
    AdapterInfo->PhyAddress = 0;
    return (SetupPhy(AdapterInfo));
  }
}


/**
  This routine will setup phy 1 or phy 0 so that it is configured
  to match a speed and duplex over-ride option.  If speed or
  duplex mode is not explicitly specified in the registry, the
  driver will skip the speed and duplex over-ride code, and
  assume the adapter is automatically setting the line speed, and
  the duplex mode.  At the end of this routine, any truly Phy
  specific code will be executed (each Phy has its own quirks,
  and some require that certain special bits are set).
  NOTE:  The driver assumes that SPEED and FORCEFDX are specified at the
  same time. If FORCEDPX is set without speed being set, the driver
  will encouter a fatal error and log a message into the event viewer.

  @param  AdapterInfo                     pointer to the structure that contains
                                          the NIC's context.

  @retval TRUE                            If the phy could be configured correctly
  @retval FALSE                           If the phy couldn't be configured
                                          correctly, because an unsupported
                                          over-ride option was used

**/
BOOLEAN
SetupPhy (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  UINT16  MdiControlReg;
  UINT16  MdiStatusReg;
  UINT16  MdiIdLowReg;
  UINT16  MdiIdHighReg;
  UINT16  MdiMiscReg;
  UINT32  PhyId;
  BOOLEAN ForcePhySetting;

  ForcePhySetting = FALSE;

  //
  // If we are NOT forcing a setting for line speed or full duplex, then
  // we won't force a link setting, and we'll jump down to the phy
  // specific code.
  //
  if (((AdapterInfo->LinkSpeedReq) || (AdapterInfo->DuplexReq))) {
    //
    // Find out what kind of technology this Phy is capable of.
    //
    MdiRead (
      AdapterInfo,
      MDI_STATUS_REG,
      AdapterInfo->PhyAddress,
      &MdiStatusReg
      );

    //
    // Read the MDI control register at our phy
    //
    MdiRead (
      AdapterInfo,
      MDI_CONTROL_REG,
      AdapterInfo->PhyAddress,
      &MdiControlReg
      );

    //
    // Now check the validity of our forced option.  If the force option is
    // valid, then force the setting.  If the force option is not valid,
    // we'll set a flag indicating that we should error out.
    //

    //
    // If speed is forced to 10mb
    //
    if (AdapterInfo->LinkSpeedReq == 10) {
      //
      // If half duplex is forced
      //
      if ((AdapterInfo->DuplexReq & PXE_FORCE_HALF_DUPLEX) != 0) {
        if (MdiStatusReg & MDI_SR_10T_HALF_DPX) {

          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);
          ForcePhySetting = TRUE;
        }
      } else if ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) != 0) {

        //
        // If full duplex is forced
        //
        if (MdiStatusReg & MDI_SR_10T_FULL_DPX) {

          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT);
          MdiControlReg |= MDI_CR_FULL_HALF;
          ForcePhySetting = TRUE;
        }
      } else {
        //
        // If auto duplex (we actually set phy to 1/2)
        //
        if (MdiStatusReg & (MDI_SR_10T_FULL_DPX | MDI_SR_10T_HALF_DPX)) {

          MdiControlReg &= ~(MDI_CR_10_100 | MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);
          ForcePhySetting = TRUE;
        }
      }
    }

    //
    // If speed is forced to 100mb
    //
    else if (AdapterInfo->LinkSpeedReq == 100) {
      //
      // If half duplex is forced
      //
      if ((AdapterInfo->DuplexReq & PXE_FORCE_HALF_DUPLEX) != 0) {
        if (MdiStatusReg & (MDI_SR_TX_HALF_DPX | MDI_SR_T4_CAPABLE)) {

          MdiControlReg &= ~(MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);
          MdiControlReg |= MDI_CR_10_100;
          ForcePhySetting = TRUE;
        }
      } else if ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) != 0) {
        //
        // If full duplex is forced
        //
        if (MdiStatusReg & MDI_SR_TX_FULL_DPX) {
          MdiControlReg &= ~MDI_CR_AUTO_SELECT;
          MdiControlReg |= (MDI_CR_10_100 | MDI_CR_FULL_HALF);
          ForcePhySetting = TRUE;
        }
      } else {
        //
        // If auto duplex (we set phy to 1/2)
        //
        if (MdiStatusReg & (MDI_SR_TX_HALF_DPX | MDI_SR_T4_CAPABLE)) {

          MdiControlReg &= ~(MDI_CR_AUTO_SELECT | MDI_CR_FULL_HALF);
          MdiControlReg |= MDI_CR_10_100;
          ForcePhySetting = TRUE;
        }
      }
    }

    if (!ForcePhySetting) {
      return (FALSE);
    }

    //
    // Write the MDI control register with our new Phy configuration
    //
    MdiWrite (
      AdapterInfo,
      MDI_CONTROL_REG,
      AdapterInfo->PhyAddress,
      MdiControlReg
      );

    //
    // wait 100 milliseconds for auto-negotiation to complete
    //
    DelayIt (AdapterInfo, 100);
  }

  //
  // Find out specifically what Phy this is.  We do this because for certain
  // phys there are specific bits that must be set so that the phy and the
  // 82557 work together properly.
  //

  MdiRead (
    AdapterInfo,
    PHY_ID_REG_1,
    AdapterInfo->PhyAddress,
    &MdiIdLowReg
    );
  MdiRead (
    AdapterInfo,
    PHY_ID_REG_2,
    AdapterInfo->PhyAddress,
    &MdiIdHighReg
    );

  PhyId = ((UINT32) MdiIdLowReg | ((UINT32) MdiIdHighReg << 16));

  //
  // And out the revsion field of the Phy ID so that we'll be able to detect
  // future revs of the same Phy.
  //
  PhyId &= PHY_MODEL_REV_ID_MASK;

  //
  // Handle the National TX
  //
  if (PhyId == PHY_NSC_TX) {

    MdiRead (
      AdapterInfo,
      NSC_CONG_CONTROL_REG,
      AdapterInfo->PhyAddress,
      &MdiMiscReg
      );

    MdiMiscReg |= (NSC_TX_CONG_TXREADY | NSC_TX_CONG_F_CONNECT);

    MdiWrite (
      AdapterInfo,
      NSC_CONG_CONTROL_REG,
      AdapterInfo->PhyAddress,
      MdiMiscReg
      );
  }

  FindPhySpeedAndDpx (AdapterInfo, PhyId);

  //
  // We put a hardware fix on to our adapters to work-around the PHY_100 errata
  // described below.  The following code is only compiled in, if we wanted
  // to attempt a software workaround to the PHY_100 A/B step problem.
  //

  return (TRUE);
}


/**
  This routine will figure out what line speed and duplex mode
  the PHY is currently using.

  @param  AdapterInfo                     pointer to the structure that contains
                                          the NIC's context.
  @param  PhyId                           The ID of the PHY in question.

  @return NOTHING

**/
VOID
FindPhySpeedAndDpx (
  IN NIC_DATA_INSTANCE *AdapterInfo,
  IN UINT32            PhyId
  )
{
  UINT16  MdiStatusReg;
  UINT16  MdiMiscReg;
  UINT16  MdiOwnAdReg;
  UINT16  MdiLinkPartnerAdReg;

  //
  // If there was a speed and/or duplex override, then set our current
  // value accordingly
  //
  AdapterInfo->LinkSpeed  = AdapterInfo->LinkSpeedReq;
  AdapterInfo->Duplex = (UINT8) ((AdapterInfo->DuplexReq & PXE_FORCE_FULL_DUPLEX) ?
                        FULL_DUPLEX : HALF_DUPLEX);

  //
  // If speed and duplex were forced, then we know our current settings, so
  // we'll just return.  Otherwise, we'll need to figure out what NWAY set
  // us to.
  //
  if (AdapterInfo->LinkSpeed && AdapterInfo->Duplex) {
    return ;

  }
  //
  // If we didn't have a valid link, then we'll assume that our current
  // speed is 10mb half-duplex.
  //

  //
  // Read the status register twice because of sticky bits
  //
  MdiRead (
    AdapterInfo,
    MDI_STATUS_REG,
    AdapterInfo->PhyAddress,
    &MdiStatusReg
    );
  MdiRead (
    AdapterInfo,
    MDI_STATUS_REG,
    AdapterInfo->PhyAddress,
    &MdiStatusReg
    );

  //
  // If there wasn't a valid link then use default speed & duplex
  //
  if (!(MdiStatusReg & MDI_SR_LINK_STATUS)) {

    AdapterInfo->LinkSpeed  = 10;
    AdapterInfo->Duplex     = HALF_DUPLEX;
    return ;
  }

  //
  // If this is an Intel PHY (a T4 PHY_100 or a TX PHY_TX), then read bits
  // 1 and 0 of extended register 0, to get the current speed and duplex
  // settings.
  //
  if ((PhyId == PHY_100_A) || (PhyId == PHY_100_C) || (PhyId == PHY_TX_ID)) {
    //
    // Read extended register 0
    //
    MdiRead (
      AdapterInfo,
      EXTENDED_REG_0,
      AdapterInfo->PhyAddress,
      &MdiMiscReg
      );

    //
    // Get current speed setting
    //
    if (MdiMiscReg & PHY_100_ER0_SPEED_INDIC) {
      AdapterInfo->LinkSpeed = 100;
    } else {
      AdapterInfo->LinkSpeed = 10;
    }

    //
    // Get current duplex setting -- if bit is set then FDX is enabled
    //
    if (MdiMiscReg & PHY_100_ER0_FDX_INDIC) {
      AdapterInfo->Duplex = FULL_DUPLEX;
    } else {
      AdapterInfo->Duplex = HALF_DUPLEX;
    }

    return ;
  }
  //
  // Read our link partner's advertisement register
  //
  MdiRead (
    AdapterInfo,
    AUTO_NEG_LINK_PARTNER_REG,
    AdapterInfo->PhyAddress,
    &MdiLinkPartnerAdReg
    );

  //
  // See if Auto-Negotiation was complete (bit 5, reg 1)
  //
  MdiRead (
    AdapterInfo,
    MDI_STATUS_REG,
    AdapterInfo->PhyAddress,
    &MdiStatusReg
    );

  //
  // If a True NWAY connection was made, then we can detect speed/duplex by
  // ANDing our adapter's advertised abilities with our link partner's
  // advertised ablilities, and then assuming that the highest common
  // denominator was chosed by NWAY.
  //
  if ((MdiLinkPartnerAdReg & NWAY_LP_ABILITY) &&
      (MdiStatusReg & MDI_SR_AUTO_NEG_COMPLETE)) {

    //
    // Read our advertisement register
    //
    MdiRead (
      AdapterInfo,
      AUTO_NEG_ADVERTISE_REG,
      AdapterInfo->PhyAddress,
      &MdiOwnAdReg
      );

    //
    // AND the two advertisement registers together, and get rid of any
    // extraneous bits.
    //
    MdiOwnAdReg = (UINT16) (MdiOwnAdReg & (MdiLinkPartnerAdReg & NWAY_LP_ABILITY));

    //
    // Get speed setting
    //
    if (MdiOwnAdReg & (NWAY_AD_TX_HALF_DPX | NWAY_AD_TX_FULL_DPX | NWAY_AD_T4_CAPABLE)) {
      AdapterInfo->LinkSpeed = 100;
    } else {
      AdapterInfo->LinkSpeed = 10;
    }

    //
    // Get duplex setting -- use priority resolution algorithm
    //
    if (MdiOwnAdReg & (NWAY_AD_T4_CAPABLE)) {
      AdapterInfo->Duplex = HALF_DUPLEX;
      return ;
    } else if (MdiOwnAdReg & (NWAY_AD_TX_FULL_DPX)) {
      AdapterInfo->Duplex = FULL_DUPLEX;
      return ;
    } else if (MdiOwnAdReg & (NWAY_AD_TX_HALF_DPX)) {
      AdapterInfo->Duplex = HALF_DUPLEX;
      return ;
    } else if (MdiOwnAdReg & (NWAY_AD_10T_FULL_DPX)) {
      AdapterInfo->Duplex = FULL_DUPLEX;
      return ;
    } else {
      AdapterInfo->Duplex = HALF_DUPLEX;
      return ;
    }
  }

  //
  // If we are connected to a dumb (non-NWAY) repeater or hub, and the line
  // speed was determined automatically by parallel detection, then we have
  // no way of knowing exactly what speed the PHY is set to unless that PHY
  // has a propietary register which indicates speed in this situation.  The
  // NSC TX PHY does have such a register.  Also, since NWAY didn't establish
  // the connection, the duplex setting should HALF duplex.
  //
  AdapterInfo->Duplex = HALF_DUPLEX;

  if (PhyId == PHY_NSC_TX) {
    //
    // Read register 25 to get the SPEED_10 bit
    //
    MdiRead (
      AdapterInfo,
      NSC_SPEED_IND_REG,
      AdapterInfo->PhyAddress,
      &MdiMiscReg
      );

    //
    // If bit 6 was set then we're at 10mb
    //
    if (MdiMiscReg & NSC_TX_SPD_INDC_SPEED) {
      AdapterInfo->LinkSpeed = 10;
    } else {
      AdapterInfo->LinkSpeed = 100;
    }
  }

  //
  // If we don't know what line speed we are set at, then we'll default to
  // 10mbs
  //
  else {
    AdapterInfo->LinkSpeed = 10;
  }
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
VOID
XmitWaitForCompletion (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  TxCB  *TxPtr;

  if (AdapterInfo->FreeCBCount == AdapterInfo->TxBufCnt) {
    return ;
  }

  //
  // used xmit cb list starts right after the free tail (ends before the
  // free head ptr)
  //
  TxPtr = AdapterInfo->FreeTxTailPtr->NextTCBVirtualLinkPtr;
  while (TxPtr != AdapterInfo->FreeTxHeadPtr) {
    CommandWaitForCompletion (TxPtr, AdapterInfo);
    SetFreeCB (AdapterInfo, TxPtr);
    TxPtr = TxPtr->NextTCBVirtualLinkPtr;
  }
}


/**
  TODO: Add function description

  @param  cmd_ptr                         TODO: add argument description
  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
INT8
CommandWaitForCompletion (
  TxCB              *cmd_ptr,
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  INT16 wait;
  wait = 5000;
  while ((cmd_ptr->cb_header.status == 0) && (--wait > 0)) {
    DelayIt (AdapterInfo, 10);
  }

  if (cmd_ptr->cb_header.status == 0) {
    return -1;
  }

  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
INT8
SoftwareReset (
  NIC_DATA_INSTANCE *AdapterInfo
  )
{
  UINT8   tco_stat;
  UINT16  wait;

  tco_stat = 0;

  //
  // Reset the chip: stop Tx and Rx processes and clear counters.
  // This takes less than 10usec and will easily finish before the next
  // action.
  //

  OutLong (AdapterInfo, PORT_RESET, AdapterInfo->ioaddr + SCBPort);
  //
  // wait for 5 milli seconds here!
  //
  DelayIt (AdapterInfo, 5000);
  //
  // TCO Errata work around for 559s only
  // -----------------------------------------------------------------------------------
  // TCO Workaround Code
  //  haifa workaround
  // -----------------------------------------------------------------------------------
  //    1. Issue SW-RST ^^^ (already done above)
  //    2. Issue a redundant Set CU Base CMD immediately
  //       Do not set the General Pointer before the Set CU Base cycle
  //       Do not check the SCB CMD before the Set CU Base cycle
  //    3. Wait for the SCB-CMD to be cleared
  //       this indicates the transition to post-driver
  //    4. Poll the TCO-Req bit in the PMDR to be cleared
  //       this indicates the tco activity has stopped for real
  //    5. Proceed with the nominal Driver Init:
  //       Actual Set CU & RU Base ...
  //
  // Check for ICH2 device ID.  If this is an ICH2,
  // do the TCO workaround code.
  //
  if (AdapterInfo->VendorID == D102_DEVICE_ID ||
      AdapterInfo->VendorID == ICH3_DEVICE_ID_1 ||
      AdapterInfo->VendorID == ICH3_DEVICE_ID_2 ||
      AdapterInfo->VendorID == ICH3_DEVICE_ID_3 ||
      AdapterInfo->VendorID == ICH3_DEVICE_ID_4 ||
      AdapterInfo->VendorID == ICH3_DEVICE_ID_5 ||
      AdapterInfo->VendorID == ICH3_DEVICE_ID_6 ||
      AdapterInfo->VendorID == ICH3_DEVICE_ID_7 ||
      AdapterInfo->VendorID == ICH3_DEVICE_ID_8 ||
      AdapterInfo->RevID >= 8) {  // do the TCO fix
    //
    // donot load the scb pointer but just give load_cu cmd.
    //
    OutByte (AdapterInfo, CU_CMD_BASE, AdapterInfo->ioaddr + SCBCmd);
    //
    // wait for command to be accepted.
    //
    wait_for_cmd_done (AdapterInfo->ioaddr + SCBCmd);
    //
    // read PMDR register and check bit 1 in it to see if TCO is active
    //

    //
    // wait for 5 milli seconds
    //
    wait = 5000;
    while (wait) {
      tco_stat = InByte (AdapterInfo, AdapterInfo->ioaddr + 0x1b);
      if ((tco_stat & 2) == 0) {
        //
        // is the activity bit clear??
        //
        break;
      }

      wait--;
      DelayIt (AdapterInfo, 1);
    }

    if ((tco_stat & 2) != 0) {
      //
      // not zero??
      //
      return -1;
    }
  }

  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
UINT8
SelectiveReset (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  UINT16  wait;
  UINT32  stat;

  wait  = 10;
  stat  = 0;
  OutLong (AdapterInfo, POR_SELECTIVE_RESET, AdapterInfo->ioaddr + SCBPort);
  //
  // wait for this to complete
  //

  //
  // wait for 2 milli seconds here!
  //
  DelayIt (AdapterInfo, 2000);
  while (wait > 0) {
    wait--;
    stat = InLong (AdapterInfo, AdapterInfo->ioaddr + SCBPort);
    if (stat == 0) {
      break;
    }

    //
    // wait for 1 milli second
    //
    DelayIt (AdapterInfo, 1000);
  }

  if (stat != 0) {
    return PXE_STATCODE_DEVICE_FAILURE;
  }

  return 0;
}


/**
  TODO: Add function description

  @param  AdapterInfo                     TODO: add argument description

  @return TODO: add return values

**/
UINT16
InitializeChip (
  IN NIC_DATA_INSTANCE *AdapterInfo
  )
{
  UINT16  ret_val;
  if (SoftwareReset (AdapterInfo) != 0) {
    return PXE_STATCODE_DEVICE_FAILURE;
  }

  //
  // disable interrupts
  //
  OutWord (AdapterInfo, INT_MASK, AdapterInfo->ioaddr + SCBCmd);

  //
  // Load the base registers with 0s (we will give the complete address as
  // offset later when we issue any command
  //
  if ((ret_val = Load_Base_Regs (AdapterInfo)) != 0) {
    return ret_val;
  }

  if ((ret_val = SetupCBlink (AdapterInfo)) != 0) {
    return ret_val;
  }

  if ((ret_val = SetupReceiveQueues (AdapterInfo)) != 0) {
    return ret_val;
  }

  //
  // detect the PHY only if we need to detect the cable as requested by the
  // initialize parameters
  //
  AdapterInfo->PhyAddress = 0xFF;

  if (AdapterInfo->CableDetect != 0) {
    if (!PhyDetect (AdapterInfo)) {
      return PXE_STATCODE_DEVICE_FAILURE;
    }
  }

  if ((ret_val = E100bSetupIAAddr (AdapterInfo)) != 0) {
    return ret_val;
  }

  if ((ret_val = Configure (AdapterInfo)) != 0) {
    return ret_val;
  }

  return 0;
}
