151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/** @file
251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Provides the basic UNID functions.
351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
461f2ab909d473aaf6faa278424287685a2c502feQian OuyangCopyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
5ac1ca10416edf34b6700a31d0bc58d144e35974chhtianThis program and the accompanying materials
651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffare licensed and made available under the terms and conditions of the BSD License
751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffwhich accompanies this distribution.  The full text of the license may be found at
851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffhttp://opensource.org/licenses/bsd-license.php
951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
1051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
1151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
1251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
1351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
1451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
1551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff#include "Undi32.h"
1651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
1751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff//
1851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff// Global variables defined in this file
1951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff//
2051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_CALL_TABLE api_table[PXE_OPCODE_LAST_VALID+1] = { \
2151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0, (UINT16)(ANY_STATE),UNDI_GetState },\
2251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,0,(UINT16)(ANY_STATE),UNDI_Start },\
2351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0,MUST_BE_STARTED,UNDI_Stop },\
2451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {PXE_CPBSIZE_NOT_USED,sizeof(PXE_DB_GET_INIT_INFO),0,MUST_BE_STARTED, UNDI_GetInitInfo },\
2551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {PXE_CPBSIZE_NOT_USED,sizeof(PXE_DB_GET_CONFIG_INFO),0,MUST_BE_STARTED, UNDI_GetConfigInfo },\
2651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {sizeof(PXE_CPB_INITIALIZE),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),MUST_BE_STARTED,UNDI_Initialize },\
2751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED,UNDI_Reset },\
2851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,0, MUST_BE_INITIALIZED,UNDI_Shutdown },\
2951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {PXE_CPBSIZE_NOT_USED,PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED,UNDI_Interrupt },\
3051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_RecFilter },\
3151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_StnAddr },\
3251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {PXE_CPBSIZE_NOT_USED, (UINT16)(DONT_CHECK), (UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_Statistics },\
3351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {sizeof(PXE_CPB_MCAST_IP_TO_MAC),sizeof(PXE_DB_MCAST_IP_TO_MAC), (UINT16)(DONT_CHECK),MUST_BE_INITIALIZED, UNDI_ip2mac },\
3451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_NVData },\
3551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {PXE_CPBSIZE_NOT_USED,(UINT16)(DONT_CHECK),(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_Status },\
3651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_FillHeader },\
3751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {(UINT16)(DONT_CHECK),PXE_DBSIZE_NOT_USED,(UINT16)(DONT_CHECK), MUST_BE_INITIALIZED, UNDI_Transmit },\
3851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  {sizeof(PXE_CPB_RECEIVE),sizeof(PXE_DB_RECEIVE),0,MUST_BE_INITIALIZED, UNDI_Receive } \
3951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff};
4051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
4151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff//
4251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff// end of global variables
4351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff//
4451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
4551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
4651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
4751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine determines the operational state of the UNDI.  It updates the state flags in the
4851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Command Descriptor Block based on information derived from the AdapterInfo instance data.
4951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  To ensure the command has completed successfully, CdbPtr->StatCode will contain the result of
5051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  the command execution.
5151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  The CdbPtr->StatFlags will contain a STOPPED, STARTED, or INITIALIZED state once the command
5251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  has successfully completed.
5351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Keep in mind the AdapterInfo->State is the active state of the adapter (based on software
5451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  interrogation), and the CdbPtr->StateFlags is the passed back information that is reflected
5551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  to the caller of the UNDI API.
5651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
5751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
5851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
5951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
6051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
6151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
6251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
6351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
6451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
6551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_GetState (
6651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
6751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
6851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
6951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
7051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatFlags = (PXE_STATFLAGS) (CdbPtr->StatFlags | AdapterInfo->State);
7151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
7251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
7351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
7451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
7551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
7651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to change the operational state of the UNDI from stopped to started.
7751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  It will do this as long as the adapter's state is PXE_STATFLAGS_GET_STATE_STOPPED, otherwise
7851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  the CdbPtr->StatFlags will reflect a command failure, and the CdbPtr->StatCode will reflect the
7951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UNDI as having already been started.
8051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is modified to reflect the undi 1.1 specification changes. The
8151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  changes in the spec are mainly in the callback routines, the new spec adds
8251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  3 more callbacks and a unique id.
8351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Since this UNDI supports both old and new undi specifications,
8451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  The NIC's data structure is filled in with the callback routines (depending
8551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  on the version) pointed to in the caller's CpbPtr.  This seeds the Delay,
8651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Virt2Phys, Block, and Mem_IO for old and new versions and Map_Mem, UnMap_Mem
8751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  and Sync_Mem routines and a unique id variable for the new version.
8851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This is the function which an external entity (SNP, O/S, etc) would call
8951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  to provide it's I/O abstraction to the UNDI.
9051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  It's final action is to change the AdapterInfo->State to PXE_STATFLAGS_GET_STATE_STARTED.
9151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
9251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
9351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
9451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
9551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
9651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
9751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
9851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
9951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
10051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_Start (
10151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
10251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
10351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
10451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
10551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_CPB_START_30  *CpbPtr;
10651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_CPB_START_31  *CpbPtr_31;
10751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
10851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
10951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // check if it is already started.
11051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
11151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (AdapterInfo->State != PXE_STATFLAGS_GET_STATE_STOPPED) {
11251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
11351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_ALREADY_STARTED;
11451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
11551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
11651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
11751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->CPBsize != sizeof(PXE_CPB_START_30) &&
11851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->CPBsize != sizeof(PXE_CPB_START_31)) {
11951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
12051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
12151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
12251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
12351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
12451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
12551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CpbPtr    = (PXE_CPB_START_30 *) (UINTN) (CdbPtr->CPBaddr);
12651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CpbPtr_31 = (PXE_CPB_START_31 *) (UINTN) (CdbPtr->CPBaddr);
12751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
12851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (AdapterInfo->VersionFlag == 0x30) {
12951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Delay_30     = (bsptr_30) (UINTN) CpbPtr->Delay;
13051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Virt2Phys_30 = (virtphys_30) (UINTN) CpbPtr->Virt2Phys;
13151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Block_30     = (block_30) (UINTN) CpbPtr->Block;
13251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
13351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // patch for old buggy 3.0 code:
13451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // In EFI1.0 undi used to provide the full (absolute) I/O address to the
13551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // i/o calls and SNP used to provide a callback that used GlobalIoFncs and
13651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // everything worked fine! In EFI 1.1, UNDI is not using the full
13751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // i/o or memory address to access the device, The base values for the i/o
13851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // and memory address is abstracted by the device specific PciIoFncs and
13951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // UNDI only uses the offset values. Since UNDI3.0 cannot provide any
14051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // identification to SNP, SNP cannot use nic specific PciIoFncs callback!
14151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
14251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // To fix this and make undi3.0 work with SNP in EFI1.1 we
14351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // use a TmpMemIo function that is defined in init.c
14451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // This breaks the runtime driver feature of undi, but what to do
14551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // if we have to provide the 3.0 compatibility (including the 3.0 bugs)
14651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
14751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // This TmpMemIo function also takes a UniqueId parameter
14851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // (as in undi3.1 design) and so initialize the UniqueId as well here
14951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // Note: AdapterInfo->Mem_Io_30 is just filled for consistency with other
15051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // parameters but never used, we only use Mem_Io field in the In/Out routines
15151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // inside e100b.c.
15251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
15351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Mem_Io_30  = (mem_io_30) (UINTN) CpbPtr->Mem_IO;
15451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Mem_Io     = (mem_io) (UINTN) TmpMemIo;
15551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Unique_ID  = (UINT64) (UINTN) AdapterInfo;
15651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
15751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  } else {
15851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Delay      = (bsptr) (UINTN) CpbPtr_31->Delay;
15951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Virt2Phys  = (virtphys) (UINTN) CpbPtr_31->Virt2Phys;
16051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Block      = (block) (UINTN) CpbPtr_31->Block;
16151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Mem_Io     = (mem_io) (UINTN) CpbPtr_31->Mem_IO;
16251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
16351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Map_Mem    = (map_mem) (UINTN) CpbPtr_31->Map_Mem;
16451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->UnMap_Mem  = (unmap_mem) (UINTN) CpbPtr_31->UnMap_Mem;
16551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Sync_Mem   = (sync_mem) (UINTN) CpbPtr_31->Sync_Mem;
16651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Unique_ID  = CpbPtr_31->Unique_ID;
16751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
16851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
16951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->State = PXE_STATFLAGS_GET_STATE_STARTED;
17051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
17151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
17251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
17351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
17451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
17551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
17651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to change the operational state of the UNDI from started to stopped.
17751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  It will not do this if the adapter's state is PXE_STATFLAGS_GET_STATE_INITIALIZED, otherwise
17851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  the CdbPtr->StatFlags will reflect a command failure, and the CdbPtr->StatCode will reflect the
17951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UNDI as having already not been shut down.
18051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  The NIC's data structure will have the Delay, Virt2Phys, and Block, pointers zero'd out..
18151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  It's final action is to change the AdapterInfo->State to PXE_STATFLAGS_GET_STATE_STOPPED.
18251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
18351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
18451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
18551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
18651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
18751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
18851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
18951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
19051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
19151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_Stop (
19251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
19351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
19451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
19551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
19651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_INITIALIZED) {
19751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
19851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_NOT_SHUTDOWN;
19951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
20051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
20151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
20251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->Delay_30     = 0;
20351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->Virt2Phys_30 = 0;
20451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->Block_30     = 0;
20551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
20651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->Delay        = 0;
20751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->Virt2Phys    = 0;
20851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->Block        = 0;
20951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
21051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->Map_Mem      = 0;
21151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->UnMap_Mem    = 0;
21251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->Sync_Mem     = 0;
21351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
21451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->State        = PXE_STATFLAGS_GET_STATE_STOPPED;
21551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
21651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
21751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
21851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
21951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
22051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
22151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to retrieve the initialization information that is needed by drivers and
22251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  applications to initialize the UNDI.  This will fill in data in the Data Block structure that is
22351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  pointed to by the caller's CdbPtr->DBaddr.  The fields filled in are as follows:
22451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  MemoryRequired, FrameDataLen, LinkSpeeds[0-3], NvCount, NvWidth, MediaHeaderLen, HWaddrLen,
22551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  MCastFilterCnt, TxBufCnt, TxBufSize, RxBufCnt, RxBufSize, IFtype, Duplex, and LoopBack.
22651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  In addition, the CdbPtr->StatFlags ORs in that this NIC supports cable detection.  (APRIORI knowledge)
22751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
22851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
22951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
23051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
23151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
23251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
23351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
23451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
23551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
23651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_GetInitInfo (
23751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
23851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
23951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
24051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
24151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_DB_GET_INIT_INFO  *DbPtr;
24251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
24351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr = (PXE_DB_GET_INIT_INFO *) (UINTN) (CdbPtr->DBaddr);
24451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
24551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->MemoryRequired = MEMORY_NEEDED;
24651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->FrameDataLen = PXE_MAX_TXRX_UNIT_ETHER;
24751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->LinkSpeeds[0] = 10;
24851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->LinkSpeeds[1] = 100;
24951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->LinkSpeeds[2] = DbPtr->LinkSpeeds[3] = 0;
25051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->NvCount = MAX_EEPROM_LEN;
25151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->NvWidth = 4;
25251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->MediaHeaderLen = PXE_MAC_HEADER_LEN_ETHER;
25351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->HWaddrLen = PXE_HWADDR_LEN_ETHER;
25451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->MCastFilterCnt = MAX_MCAST_ADDRESS_CNT;
25551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
25651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->TxBufCnt = TX_BUFFER_COUNT;
25780448f6c1aed17ee0fbfa79bab7e7b8eeb2eb084ydong  DbPtr->TxBufSize = (UINT16) sizeof (TxCB);
25851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->RxBufCnt = RX_BUFFER_COUNT;
25980448f6c1aed17ee0fbfa79bab7e7b8eeb2eb084ydong  DbPtr->RxBufSize = (UINT16) sizeof (RxFD);
26051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
26151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->IFtype = PXE_IFTYPE_ETHERNET;
26251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->SupportedDuplexModes = PXE_DUPLEX_ENABLE_FULL_SUPPORTED |
26351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                  PXE_DUPLEX_FORCE_FULL_SUPPORTED;
26451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->SupportedLoopBackModes = PXE_LOOPBACK_INTERNAL_SUPPORTED |
26551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                    PXE_LOOPBACK_EXTERNAL_SUPPORTED;
26651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
267135ec2db42941107fc2ec69107784828a1f81e91xdu  CdbPtr->StatFlags |= (PXE_STATFLAGS_CABLE_DETECT_SUPPORTED |
268135ec2db42941107fc2ec69107784828a1f81e91xdu                        PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED);
26951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
27051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
27151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
27251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
27351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
27451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to retrieve the configuration information about the NIC being controlled by
27551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  this driver.  This will fill in data in the Data Block structure that is pointed to by the caller's CdbPtr->DBaddr.
27651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  The fields filled in are as follows:
27751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->pci.BusType, DbPtr->pci.Bus, DbPtr->pci.Device, and DbPtr->pci.
27851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  In addition, the DbPtr->pci.Config.Dword[0-63] grabs a copy of this NIC's PCI configuration space.
27951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
28051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
28151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
28251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
28351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
28451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
28551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
28651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
28751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
28851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_GetConfigInfo (
28951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
29051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
29151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
29251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
29351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT16                  Index;
29451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_DB_GET_CONFIG_INFO  *DbPtr;
29551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
29651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr               = (PXE_DB_GET_CONFIG_INFO *) (UINTN) (CdbPtr->DBaddr);
29751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
29851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->pci.BusType  = PXE_BUSTYPE_PCI;
29951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->pci.Bus      = AdapterInfo->Bus;
30051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->pci.Device   = AdapterInfo->Device;
30151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->pci.Function = AdapterInfo->Function;
30251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
30351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  for (Index = 0; Index < MAX_PCI_CONFIG_LEN; Index++) {
30451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    DbPtr->pci.Config.Dword[Index] = AdapterInfo->Config[Index];
30551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
30651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
30751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
30851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
30951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
31051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
31151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
31251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine resets the network adapter and initializes the UNDI using the parameters supplied in
31351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  the CPB.  This command must be issued before the network adapter can be setup to transmit and
31451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  receive packets.
31551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Once the memory requirements of the UNDI are obtained by using the GetInitInfo command, a block
31651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  of non-swappable memory may need to be allocated.  The address of this memory must be passed to
31751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UNDI during the Initialize in the CPB.  This memory is used primarily for transmit and receive buffers.
31851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  The fields CableDetect, LinkSpeed, Duplex, LoopBack, MemoryPtr, and MemoryLength are set with information
31951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  that was passed in the CPB and the NIC is initialized.
32051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  If the NIC initialization fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED
32151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Otherwise, AdapterInfo->State is updated with PXE_STATFLAGS_GET_STATE_INITIALIZED showing the state of
32251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  the UNDI is now initialized.
32351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
32451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
32551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
32651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
32751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
32851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
32951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
33051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
33151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
33251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_Initialize (
33351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB       *CdbPtr,
33451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  NIC_DATA_INSTANCE *AdapterInfo
33551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
33651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
33751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_CPB_INITIALIZE  *CpbPtr;
33851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
33951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((CdbPtr->OpFlags != PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) &&
34051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      (CdbPtr->OpFlags != PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE)) {
34151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
34251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
34351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
34451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
34551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
34651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
34751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // check if it is already initialized
34851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
34951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_INITIALIZED) {
35051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
35151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_ALREADY_INITIALIZED;
35251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
35351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
35451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
35551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CpbPtr  = (PXE_CPB_INITIALIZE *) (UINTN) CdbPtr->CPBaddr;
35651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
35751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CpbPtr->MemoryLength < (UINT32) MEMORY_NEEDED) {
35851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
35951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;
36051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
36151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
36251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
36351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
36451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // default behaviour is to detect the cable, if the 3rd param is 1,
36551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // do not do that
36651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
36751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->CableDetect = (UINT8) ((CdbPtr->OpFlags == (UINT16) PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE) ? (UINT8) 0 : (UINT8) 1);
36851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->LinkSpeedReq = (UINT16) CpbPtr->LinkSpeed;
36951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->DuplexReq    = CpbPtr->DuplexMode;
37051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->LoopBack     = CpbPtr->LoopBackMode;
37151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->MemoryPtr    = CpbPtr->MemoryAddr;
37251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->MemoryLength = CpbPtr->MemoryLength;
37351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
37451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatCode          = (PXE_STATCODE) E100bInit (AdapterInfo);
37551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
37651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
37751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
37851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  } else {
37951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->State = PXE_STATFLAGS_GET_STATE_INITIALIZED;
38051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
38151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
38251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
38351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
38451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
38551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
38651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
38751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine resets the network adapter and initializes the UNDI using the parameters supplied in
38851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  the CPB.  The transmit and receive queues are emptied and any pending interrupts are cleared.
38951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  If the NIC reset fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED
39051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
39151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
39251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
39351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
39451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
39551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
39651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
39751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
39851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
39951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_Reset (
40051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
40151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
40251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
40351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
40451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->OpFlags != PXE_OPFLAGS_NOT_USED &&
40551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->OpFlags != PXE_OPFLAGS_RESET_DISABLE_INTERRUPTS &&
40651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->OpFlags != PXE_OPFLAGS_RESET_DISABLE_FILTERS ) {
40751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
40851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
40951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
41051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
41151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
41251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
41351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatCode = (UINT16) E100bReset (AdapterInfo, CdbPtr->OpFlags);
41451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
41551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
41651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
41751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
41851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
41951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
42051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
42151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
42251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine resets the network adapter and leaves it in a safe state for another driver to
42351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  initialize.  Any pending transmits or receives are lost.  Receive filters and external
42451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  interrupt enables are disabled.  Once the UNDI has been shutdown, it can then be stopped
42551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  or initialized again.
42651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  If the NIC reset fails, the CdbPtr->StatFlags are updated with PXE_STATFLAGS_COMMAND_FAILED
42751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Otherwise, AdapterInfo->State is updated with PXE_STATFLAGS_GET_STATE_STARTED showing the state of
42851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  the NIC as being started.
42951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
43051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
43151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
43251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
43351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
43451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
43551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
43651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
43751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
43851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_Shutdown (
43951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
44051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
44151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
44251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
44351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
44451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // do the shutdown stuff here
44551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
44651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatCode = (UINT16) E100bShutdown (AdapterInfo);
44751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
44851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
44951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
45051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  } else {
45151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->State = PXE_STATFLAGS_GET_STATE_STARTED;
45251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
45351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
45451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
45551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
45651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
45751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
45851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
45951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine can be used to read and/or change the current external interrupt enable
46051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  settings.  Disabling an external interrupt enable prevents and external (hardware)
46151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  interrupt from being signaled by the network device.  Internally the interrupt events
46251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  can still be polled by using the UNDI_GetState command.
46351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  The resulting information on the interrupt state will be passed back in the CdbPtr->StatFlags.
46451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
46551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
46651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
46751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
46851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
46951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
47051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
47151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
47251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
47351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_Interrupt (
47451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
47551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
47651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
47751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
47851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT8 IntMask;
47951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
48051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IntMask = (UINT8)(UINTN)(CdbPtr->OpFlags & (PXE_OPFLAGS_INTERRUPT_RECEIVE |
48151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                                              PXE_OPFLAGS_INTERRUPT_TRANSMIT |
48251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                                              PXE_OPFLAGS_INTERRUPT_COMMAND |
48351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                                              PXE_OPFLAGS_INTERRUPT_SOFTWARE));
48451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
48551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  switch (CdbPtr->OpFlags & PXE_OPFLAGS_INTERRUPT_OPMASK) {
48651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  case PXE_OPFLAGS_INTERRUPT_READ:
48751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    break;
48851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
48951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  case PXE_OPFLAGS_INTERRUPT_ENABLE:
49051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (IntMask == 0) {
49151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
49251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
49351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      return ;
49451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
49551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
49651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->int_mask = IntMask;
49751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    E100bSetInterruptState (AdapterInfo);
49851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    break;
49951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
50051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  case PXE_OPFLAGS_INTERRUPT_DISABLE:
50151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (IntMask != 0) {
50251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      AdapterInfo->int_mask = (UINT16) (AdapterInfo->int_mask & ~(IntMask));
50351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      E100bSetInterruptState (AdapterInfo);
50451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      break;
50551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
50651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
50751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
50851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // else fall thru.
50951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
51051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  default:
51151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
51251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
51351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
51451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
51551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
51651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_RECEIVE) != 0) {
51751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_RECEIVE;
51851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
51951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
52051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
52151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_TRANSMIT) != 0) {
52251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_TRANSMIT;
52351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
52451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
52551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
52651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((AdapterInfo->int_mask & PXE_OPFLAGS_INTERRUPT_COMMAND) != 0) {
52751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags |= PXE_STATFLAGS_INTERRUPT_COMMAND;
52851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
52951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
53051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
53151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
53251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
53351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
53451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
53551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
53651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to read and change receive filters and, if supported, read
53751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  and change multicast MAC address filter list.
53851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
53951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
54051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
54151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
54251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
54351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
54451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
54551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
54651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
54751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_RecFilter (
54851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
54951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
55051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
55151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
55251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT16                  NewFilter;
55351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT16                  OpFlags;
55451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_DB_RECEIVE_FILTERS  *DbPtr;
55551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT8                   *MacAddr;
55651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINTN                   MacCount;
55751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT16                  Index;
55851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT16                  copy_len;
55951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT8                   *ptr1;
56051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT8                   *ptr2;
561cd4179255601b9dda32de906851f9c97fc7a8844tye  BOOLEAN                 InvalidMacAddr;
562cd4179255601b9dda32de906851f9c97fc7a8844tye
56351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  OpFlags   = CdbPtr->OpFlags;
56451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  NewFilter = (UINT16) (OpFlags & 0x1F);
56551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
56651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  switch (OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_OPMASK) {
56751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  case PXE_OPFLAGS_RECEIVE_FILTER_READ:
56851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
56951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
57051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // not expecting a cpb, not expecting any filter bits
57151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
57251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if ((NewFilter != 0) || (CdbPtr->CPBsize != 0)) {
57351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      goto BadCdb;
57451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
57551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
57651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
57751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) == 0) {
57851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      goto JustRead;
57951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
58051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
58151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
58251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    NewFilter = (UINT16) (NewFilter | AdapterInfo->Rx_Filter);
58351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
58451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // all other flags are ignored except mcast_reset
58551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
58651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    break;
58751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
58851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  case PXE_OPFLAGS_RECEIVE_FILTER_ENABLE:
58951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
59051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // there should be atleast one other filter bit set.
59151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
59251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (NewFilter == 0) {
59351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      //
59451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      // nothing to enable
59551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      //
59651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      goto BadCdb;
59751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
59851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
59951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (CdbPtr->CPBsize != 0) {
60051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      //
60151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      // this must be a multicast address list!
60251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      // don't accept the list unless selective_mcast is set
60351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      // don't accept confusing mcast settings with this
60451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      //
60551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      if (((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) == 0) ||
60651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) ||
60751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          ((NewFilter & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) ||
60851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          ((CdbPtr->CPBsize % sizeof (PXE_MAC_ADDR)) != 0) ) {
60951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        goto BadCdb;
61051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      }
61151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
61251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      MacAddr   = (UINT8 *) ((UINTN) (CdbPtr->CPBaddr));
61351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      MacCount  = CdbPtr->CPBsize / sizeof (PXE_MAC_ADDR);
61451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
615cd4179255601b9dda32de906851f9c97fc7a8844tye      //
616cd4179255601b9dda32de906851f9c97fc7a8844tye      // The format of Ethernet multicast address for IPv6 is defined in RFC2464,
617cd4179255601b9dda32de906851f9c97fc7a8844tye      // for IPv4 is defined in RFC1112. Check whether the address is valid.
618cd4179255601b9dda32de906851f9c97fc7a8844tye      //
619cd4179255601b9dda32de906851f9c97fc7a8844tye      InvalidMacAddr = FALSE;
620cd4179255601b9dda32de906851f9c97fc7a8844tye
62151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      for (; MacCount-- != 0; MacAddr += sizeof (PXE_MAC_ADDR)) {
622cd4179255601b9dda32de906851f9c97fc7a8844tye        if (MacAddr[0] == 0x01) {
623cd4179255601b9dda32de906851f9c97fc7a8844tye          //
624cd4179255601b9dda32de906851f9c97fc7a8844tye          // This multicast MAC address is mapped from IPv4 address.
625cd4179255601b9dda32de906851f9c97fc7a8844tye          //
626cd4179255601b9dda32de906851f9c97fc7a8844tye          if (MacAddr[1] != 0x00 || MacAddr[2] != 0x5E || (MacAddr[3] & 0x80) != 0) {
627cd4179255601b9dda32de906851f9c97fc7a8844tye            InvalidMacAddr = TRUE;
628cd4179255601b9dda32de906851f9c97fc7a8844tye          }
629cd4179255601b9dda32de906851f9c97fc7a8844tye        } else if (MacAddr[0] == 0x33) {
630cd4179255601b9dda32de906851f9c97fc7a8844tye          //
631cd4179255601b9dda32de906851f9c97fc7a8844tye          // This multicast MAC address is mapped from IPv6 address.
632cd4179255601b9dda32de906851f9c97fc7a8844tye          //
633cd4179255601b9dda32de906851f9c97fc7a8844tye          if (MacAddr[1] != 0x33) {
634cd4179255601b9dda32de906851f9c97fc7a8844tye            InvalidMacAddr = TRUE;
635cd4179255601b9dda32de906851f9c97fc7a8844tye          }
636cd4179255601b9dda32de906851f9c97fc7a8844tye        } else {
637cd4179255601b9dda32de906851f9c97fc7a8844tye          InvalidMacAddr = TRUE;
638cd4179255601b9dda32de906851f9c97fc7a8844tye        }
639cd4179255601b9dda32de906851f9c97fc7a8844tye
640cd4179255601b9dda32de906851f9c97fc7a8844tye        if (InvalidMacAddr) {
64151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
64251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;
64351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          return ;
64451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        }
64551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      }
64651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
64751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
64851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
64951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // check selective mcast case enable case
65051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
65151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
65251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      if (((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) ||
65351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) ) {
65451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        goto BadCdb;
65551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
65651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      }
65751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      //
65851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      // if no cpb, make sure we have an old list
65951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      //
66051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      if ((CdbPtr->CPBsize == 0) && (AdapterInfo->mcast_list.list_len == 0)) {
66151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        goto BadCdb;
66251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      }
66351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
66451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
66551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // if you want to enable anything, you got to have unicast
66651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // and you have what you already enabled!
66751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
66851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    NewFilter = (UINT16) (NewFilter | (PXE_OPFLAGS_RECEIVE_FILTER_UNICAST | AdapterInfo->Rx_Filter));
66951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
67051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    break;
67151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
67251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  case PXE_OPFLAGS_RECEIVE_FILTER_DISABLE:
67351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
67451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
67551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // mcast list not expected, i.e. no cpb here!
67651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
67751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (CdbPtr->CPBsize != PXE_CPBSIZE_NOT_USED) {
67851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      goto BadCdb;
67951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
68051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
68151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    NewFilter = (UINT16) ((~(CdbPtr->OpFlags & 0x1F)) & AdapterInfo->Rx_Filter);
68251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
68351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    break;
68451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
68551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  default:
68651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    goto BadCdb;
68751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
68851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
68951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((OpFlags & PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST) != 0) {
69051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->mcast_list.list_len = 0;
69151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    NewFilter &= (~PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST);
69251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
69351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
69451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  E100bSetfilter (AdapterInfo, NewFilter, CdbPtr->CPBaddr, CdbPtr->CPBsize);
69551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
69651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffJustRead:
69751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
69851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // give the current mcast list
69951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
70051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((CdbPtr->DBsize != 0) && (AdapterInfo->mcast_list.list_len != 0)) {
70151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
70251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // copy the mc list to db
70351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
70451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
70551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    DbPtr = (PXE_DB_RECEIVE_FILTERS *) (UINTN) CdbPtr->DBaddr;
70651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    ptr1  = (UINT8 *) (&DbPtr->MCastList[0]);
70751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
70851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
70951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // DbPtr->mc_count = AdapterInfo->mcast_list.list_len;
71051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
71151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    copy_len = (UINT16) (AdapterInfo->mcast_list.list_len * PXE_MAC_LENGTH);
71251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
71351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (copy_len > CdbPtr->DBsize) {
71451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      copy_len = CdbPtr->DBsize;
71551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
71651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
71751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
71851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    ptr2 = (UINT8 *) (&AdapterInfo->mcast_list.mc_list[0]);
71951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    for (Index = 0; Index < copy_len; Index++) {
72051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      ptr1[Index] = ptr2[Index];
72151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
72251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
72351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
72451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // give the stat flags here
72551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
72651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (AdapterInfo->Receive_Started) {
72751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = (PXE_STATFLAGS) (CdbPtr->StatFlags | AdapterInfo->Rx_Filter);
72851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
72951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
73051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
73151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
73251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
73351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffBadCdb:
73451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
73551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
73651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
73751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
73851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
73951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
74051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to get the current station and broadcast MAC addresses, and to change the
74151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  current station MAC address.
74251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
74351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
74451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
74551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
74651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
74751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
74851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
74951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
75051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
75151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_StnAddr (
75251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
75351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
75451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
75551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
75651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_CPB_STATION_ADDRESS *CpbPtr;
75751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_DB_STATION_ADDRESS  *DbPtr;
75851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT16                  Index;
75951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
76051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->OpFlags == PXE_OPFLAGS_STATION_ADDRESS_RESET) {
76151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
76251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // configure the permanent address.
76351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // change the AdapterInfo->CurrentNodeAddress field.
76451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
76551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (CompareMem (
76651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          &AdapterInfo->CurrentNodeAddress[0],
76751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          &AdapterInfo->PermNodeAddress[0],
76851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          PXE_MAC_LENGTH
76951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          ) != 0) {
77051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
77151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        AdapterInfo->CurrentNodeAddress[Index] = AdapterInfo->PermNodeAddress[Index];
77251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      }
77351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
77451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      E100bSetupIAAddr (AdapterInfo);
77551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
77651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
77751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
77851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->CPBaddr != (UINT64) 0) {
77951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CpbPtr = (PXE_CPB_STATION_ADDRESS *) (UINTN) (CdbPtr->CPBaddr);
78051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
78151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // configure the new address
78251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
78351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
78451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      AdapterInfo->CurrentNodeAddress[Index] = CpbPtr->StationAddr[Index];
78551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
78651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
78751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    E100bSetupIAAddr (AdapterInfo);
78851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
78951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
79051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->DBaddr != (UINT64) 0) {
79151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    DbPtr = (PXE_DB_STATION_ADDRESS *) (UINTN) (CdbPtr->DBaddr);
79251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
79351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // fill it with the new values
79451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
79551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    for (Index = 0; Index < PXE_MAC_LENGTH; Index++) {
79651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      DbPtr->StationAddr[Index]   = AdapterInfo->CurrentNodeAddress[Index];
79751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      DbPtr->BroadcastAddr[Index] = AdapterInfo->BroadcastNodeAddress[Index];
79851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      DbPtr->PermanentAddr[Index] = AdapterInfo->PermNodeAddress[Index];
79951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
80051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
80151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
80251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
80351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
80451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
80551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
80651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
80751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to read and clear the NIC traffic statistics.  This command is supported only
80851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if the !PXE structure's Implementation flags say so.
80951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Results will be parsed out in the following manner:
81051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->DBaddr.Data[0]   R  Total Frames (Including frames with errors and dropped frames)
81151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->DBaddr.Data[1]   R  Good Frames (All frames copied into receive buffer)
81251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->DBaddr.Data[2]   R  Undersize Frames (Frames below minimum length for media <64 for ethernet)
81351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->DBaddr.Data[4]   R  Dropped Frames (Frames that were dropped because receive buffers were full)
81451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->DBaddr.Data[8]   R  CRC Error Frames (Frames with alignment or CRC errors)
81551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->DBaddr.Data[A]   T  Total Frames (Including frames with errors and dropped frames)
81651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->DBaddr.Data[B]   T  Good Frames (All frames copied into transmit buffer)
81751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->DBaddr.Data[C]   T  Undersize Frames (Frames below minimum length for media <64 for ethernet)
81851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->DBaddr.Data[E]   T  Dropped Frames (Frames that were dropped because of collisions)
81951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->DBaddr.Data[14]  T  Total Collision Frames (Total collisions on this subnet)
82051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
82151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
82251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
82351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
82451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
82551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
82651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
82751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
82851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
82951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_Statistics (
83051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
83151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
83251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
83351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
83451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((CdbPtr->OpFlags &~(PXE_OPFLAGS_STATISTICS_RESET)) != 0) {
83551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
83651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
83751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
83851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
83951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
84051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((CdbPtr->OpFlags & PXE_OPFLAGS_STATISTICS_RESET) != 0) {
84151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
84251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // Reset the statistics
84351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
84451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode = (UINT16) E100bStatistics (AdapterInfo, 0, 0);
84551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  } else {
84651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode = (UINT16) E100bStatistics (AdapterInfo, CdbPtr->DBaddr, CdbPtr->DBsize);
84751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
84851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
84951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
85051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
85151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
85251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
85351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
85451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to translate a multicast IP address to a multicast MAC address.
85551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This results in a MAC address composed of 25 bits of fixed data with the upper 23 bits of the IP
85651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  address being appended to it.  Results passed back in the equivalent of CdbPtr->DBaddr->MAC[0-5].
85751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
85851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
85951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
86051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
86151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
86251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
86351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
86451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
86551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
86651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_ip2mac (
86751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
86851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
86951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
87051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
87151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_CPB_MCAST_IP_TO_MAC *CpbPtr;
87251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_DB_MCAST_IP_TO_MAC  *DbPtr;
87351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT8                   *TmpPtr;
87451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
87551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CpbPtr  = (PXE_CPB_MCAST_IP_TO_MAC *) (UINTN) CdbPtr->CPBaddr;
87651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr   = (PXE_DB_MCAST_IP_TO_MAC *) (UINTN) CdbPtr->DBaddr;
87751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
87851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((CdbPtr->OpFlags & PXE_OPFLAGS_MCAST_IPV6_TO_MAC) != 0) {
87951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
88051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // for now this is not supported
88151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
88251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
88351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_UNSUPPORTED;
88451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
88551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
88651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
88751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  TmpPtr = (UINT8 *) (&CpbPtr->IP.IPv4);
88851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
88951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // check if the ip given is a mcast IP
89051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
89151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((TmpPtr[0] & 0xF0) != 0xE0) {
89251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
89351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CPB;
89451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
89551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
89651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // take the last 23 bits in IP.
89751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // be very careful. accessing word on a non-word boundary will hang motherboard codenamed Big Sur
89851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // casting the mac array (in the middle) to a UINT32 pointer and accessing
89951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // the UINT32 content hung the system...
90051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
90151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->MAC[0] = 0x01;
90251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->MAC[1] = 0x00;
90351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->MAC[2] = 0x5e;
90451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->MAC[3] = (UINT8) (TmpPtr[1] & 0x7f);
90551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->MAC[4] = (UINT8) TmpPtr[2];
90651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr->MAC[5] = (UINT8) TmpPtr[3];
90751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
90851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
90951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
91051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
91151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
91251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
91351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to read and write non-volatile storage on the NIC (if supported).  The NVRAM
91451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  could be EEPROM, FLASH, or battery backed RAM.
91551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This is an optional function according to the UNDI specification  (or will be......)
91651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
91751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
91851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
91951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
92051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
92151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
92251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
92351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
92451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
92551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_NVData (
92651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
92751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
92851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
92951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
93051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_DB_NVDATA *DbPtr;
93151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT16        Index;
93251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
93351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((CdbPtr->OpFlags == PXE_OPFLAGS_NVDATA_READ) != 0) {
93451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
93551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if ((CdbPtr->DBsize == PXE_DBSIZE_NOT_USED) != 0) {
93651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
93751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
93851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      return ;
93951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
94051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
94151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    DbPtr = (PXE_DB_NVDATA *) (UINTN) CdbPtr->DBaddr;
94251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
94351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    for (Index = 0; Index < MAX_PCI_CONFIG_LEN; Index++) {
94451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      DbPtr->Data.Dword[Index] = AdapterInfo->NVData[Index];
94551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
94651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
94751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
94851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  } else {
94951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
95051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // no write for now
95151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
95251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
95351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_UNSUPPORTED;
95451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
95551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
95651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
95751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
95851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
95951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
96051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
96151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine returns the current interrupt status and/or the transmitted buffer addresses.
96251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  If the current interrupt status is returned, pending interrupts will be acknowledged by this
96351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  command.  Transmitted buffer addresses that are written to the DB are removed from the transmit
96451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  buffer queue.
96551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Normally, this command would be polled with interrupts disabled.
96651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  The transmit buffers are returned in CdbPtr->DBaddr->TxBufer[0 - NumEntries].
96751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  The interrupt status is returned in CdbPtr->StatFlags.
96851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
96951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
97051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
97151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
97251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
97351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
97451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
97551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
97651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
97751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_Status (
97851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
97951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
98051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
98151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
98251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_DB_GET_STATUS *DbPtr;
98351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_DB_GET_STATUS TmpGetStatus;
98451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT16            Index;
98551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT16            Status;
98651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINT16            NumEntries;
98751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  RxFD              *RxPtr;
98851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
98951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
99051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // Fill in temporary GetStatus storage.
99151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
99251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  RxPtr = &AdapterInfo->rx_ring[AdapterInfo->cur_rx_ind];
99351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
99451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((RxPtr->cb_header.status & RX_COMPLETE) != 0) {
99551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    TmpGetStatus.RxFrameLen = RxPtr->ActualCount & 0x3fff;
99651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  } else {
99751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    TmpGetStatus.RxFrameLen = 0;
99851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
99951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
100051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  TmpGetStatus.reserved = 0;
100151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
100251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
100351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // Fill in size of next available receive packet and
100451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // reserved field in caller's DB storage.
100551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
100651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  DbPtr = (PXE_DB_GET_STATUS *) (UINTN) CdbPtr->DBaddr;
100751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
100851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->DBsize > 0 && CdbPtr->DBsize < sizeof (UINT32) * 2) {
100951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CopyMem (DbPtr, &TmpGetStatus, CdbPtr->DBsize);
101051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  } else {
101151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CopyMem (DbPtr, &TmpGetStatus, sizeof (UINT32) * 2);
101251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
101351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
101451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
101551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
101651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
101751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS) != 0) {
101851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
101951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // DBsize of zero is invalid if Tx buffers are requested.
102051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
102151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (CdbPtr->DBsize == 0) {
102251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
102351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
102451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      return ;
102551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
102651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
102751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
102851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // remember this b4 we overwrite
102951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
103051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    NumEntries = (UINT16) (CdbPtr->DBsize - sizeof (UINT64));
103151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
103251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
103351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // We already filled in 2 UINT32s.
103451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
103580448f6c1aed17ee0fbfa79bab7e7b8eeb2eb084ydong    CdbPtr->DBsize = (UINT16) (sizeof (UINT32) * 2);
103651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
103751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
103851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // will claim any hanging free CBs
103951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
104051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CheckCBList (AdapterInfo);
104151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
104251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (AdapterInfo->xmit_done_head == AdapterInfo->xmit_done_tail) {
104351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY;
104451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    } else {
104580448f6c1aed17ee0fbfa79bab7e7b8eeb2eb084ydong      for (Index = 0; ((Index < MAX_XMIT_BUFFERS) && (NumEntries >= sizeof (UINT64))); Index++, NumEntries -= sizeof (UINT64)) {
104651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        if (AdapterInfo->xmit_done_head != AdapterInfo->xmit_done_tail) {
104751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          DbPtr->TxBuffer[Index]      = AdapterInfo->xmit_done[AdapterInfo->xmit_done_head];
104851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          AdapterInfo->xmit_done_head = next (AdapterInfo->xmit_done_head);
104951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          CdbPtr->DBsize += sizeof (UINT64);
105051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        } else {
105151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff          break;
105251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        }
105351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      }
105451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
105551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
105651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (AdapterInfo->xmit_done_head != AdapterInfo->xmit_done_tail) {
105751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatFlags |= PXE_STATFLAGS_DB_WRITE_TRUNCATED;
105851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
105951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
106051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
106151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // check for a receive buffer and give it's size in db
106251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
106351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
106451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
106551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
106651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
106751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_INTERRUPT_STATUS) != 0) {
106851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
106951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    Status = InWord (AdapterInfo, AdapterInfo->ioaddr + SCBStatus);
107051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    AdapterInfo->Int_Status = (UINT16) (AdapterInfo->Int_Status | Status);
107151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
107251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
107351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // acknoledge the interrupts
107451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
107551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    OutWord (AdapterInfo, (UINT16) (Status & 0xfc00), (UINT32) (AdapterInfo->ioaddr + SCBStatus));
107651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
107751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
107851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // report all the outstanding interrupts
107951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
108051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    Status = AdapterInfo->Int_Status;
108151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if ((Status & SCB_STATUS_FR) != 0) {
108251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_RECEIVE;
108351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
108451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
108551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if ((Status & SCB_STATUS_SWI) != 0) {
108651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_SOFTWARE;
108751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
108851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
108951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
1090135ec2db42941107fc2ec69107784828a1f81e91xdu  //
1091135ec2db42941107fc2ec69107784828a1f81e91xdu  // Return current media status
1092135ec2db42941107fc2ec69107784828a1f81e91xdu  //
1093135ec2db42941107fc2ec69107784828a1f81e91xdu  if ((CdbPtr->OpFlags & PXE_OPFLAGS_GET_MEDIA_STATUS) != 0) {
1094135ec2db42941107fc2ec69107784828a1f81e91xdu    AdapterInfo->PhyAddress = 0xFF;
1095135ec2db42941107fc2ec69107784828a1f81e91xdu    AdapterInfo->CableDetect = 1;
1096135ec2db42941107fc2ec69107784828a1f81e91xdu
1097135ec2db42941107fc2ec69107784828a1f81e91xdu    if (!PhyDetect (AdapterInfo)) {
1098135ec2db42941107fc2ec69107784828a1f81e91xdu      CdbPtr->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_MEDIA;
1099135ec2db42941107fc2ec69107784828a1f81e91xdu    }
1100135ec2db42941107fc2ec69107784828a1f81e91xdu  }
1101135ec2db42941107fc2ec69107784828a1f81e91xdu
110251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
110351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
110451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
110551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
110651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
110751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to fill media header(s) in transmit packet(s).
110851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Copies the MAC address into the media header whether it is dealing
110951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  with fragmented or non-fragmented packets.
111051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
111151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
111251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
111351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
111451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
111551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
111651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
111751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
111851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
111951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_FillHeader (
112051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
112151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
112251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
112351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
112451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_CPB_FILL_HEADER             *Cpb;
112551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_CPB_FILL_HEADER_FRAGMENTED  *Cpbf;
112651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  EtherHeader                     *MacHeader;
112751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UINTN                           Index;
112851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
112951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
113051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
113151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
113251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
113351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
113451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
113551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((CdbPtr->OpFlags & PXE_OPFLAGS_FILL_HEADER_FRAGMENTED) != 0) {
113651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    Cpbf = (PXE_CPB_FILL_HEADER_FRAGMENTED *) (UINTN) CdbPtr->CPBaddr;
113751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
113851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
113951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // assume 1st fragment is big enough for the mac header
114051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
114151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if ((Cpbf->FragCnt == 0) || (Cpbf->FragDesc[0].FragLen < PXE_MAC_HEADER_LEN_ETHER)) {
114251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      //
114351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      // no buffers given
114451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      //
114551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
114651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
114751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      return ;
114851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
114951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
115051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    MacHeader = (EtherHeader *) (UINTN) Cpbf->FragDesc[0].FragAddr;
115151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
115251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // we don't swap the protocol bytes
115351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
115451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    MacHeader->type = Cpbf->Protocol;
115551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
115651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
115751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      MacHeader->dest_addr[Index] = Cpbf->DestAddr[Index];
115851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      MacHeader->src_addr[Index]  = Cpbf->SrcAddr[Index];
115951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
116051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  } else {
116151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    Cpb       = (PXE_CPB_FILL_HEADER *) (UINTN) CdbPtr->CPBaddr;
116251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
116351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    MacHeader = (EtherHeader *) (UINTN) Cpb->MediaHeader;
116451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
116551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // we don't swap the protocol bytes
116651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
116751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    MacHeader->type = Cpb->Protocol;
116851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
116951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    for (Index = 0; Index < PXE_HWADDR_LEN_ETHER; Index++) {
117051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      MacHeader->dest_addr[Index] = Cpb->DestAddr[Index];
117151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      MacHeader->src_addr[Index]  = Cpb->SrcAddr[Index];
117251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
117351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
117451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
117551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
117651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
117751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
117851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
117951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
118051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This routine is used to place a packet into the transmit queue.  The data buffers given to
118151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  this command are to be considered locked and the application or network driver loses
118251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  ownership of these buffers and must not free or relocate them until the ownership returns.
118351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  When the packets are transmitted, a transmit complete interrupt is generated (if interrupts
118451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  are disabled, the transmit interrupt status is still set and can be checked using the UNDI_Status
118551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  command.
118651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Some implementations and adapters support transmitting multiple packets with one transmit
118751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  command.  If this feature is supported, the transmit CPBs can be linked in one transmit
118851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  command.
118951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  All UNDIs support fragmented frames, now all network devices or protocols do.  If a fragmented
119051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  frame CPB is given to UNDI and the network device does not support fragmented frames
119151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  (see !PXE.Implementation flag), the UNDI will have to copy the fragments into a local buffer
119251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  before transmitting.
119351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
119451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
119551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
119651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
119751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
119851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
119951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
120051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
120151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
120251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_Transmit (
120351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
120451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
120551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
120651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
120751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
120851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
120951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
121051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
121151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
121251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
121351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
121451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatCode = (PXE_STATCODE) E100bTransmit (AdapterInfo, CdbPtr->CPBaddr, CdbPtr->OpFlags);
121551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
121651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
121751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
121851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
121951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
122051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
122151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
122251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
122351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
122451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
122551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  When the network adapter has received a frame, this command is used to copy the frame
122651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  into the driver/application storage location.  Once a frame has been copied, it is
122751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  removed from the receive queue.
122851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
122951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
123051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
123151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
123251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
123351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
123451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
123551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
123651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
123751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_Receive (
123851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  PXE_CDB           *CdbPtr,
123951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *AdapterInfo
124051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
124151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
124251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
124351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
124451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // check if RU has started...
124551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
124651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (!AdapterInfo->Receive_Started) {
124751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
124851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
124951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
125051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
125151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
125251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
125351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatCode  = (UINT16) E100bReceive (AdapterInfo, CdbPtr->CPBaddr, CdbPtr->DBaddr);
125451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->StatCode != PXE_STATCODE_SUCCESS) {
125551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
125651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
125751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
125851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
125951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
126051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
126151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
126251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
126351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
126451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
126551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This is the main SW UNDI API entry using the newer nii protocol.
126651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  The parameter passed in is a 64 bit flat model virtual
126751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  address of the cdb.  We then jump into the common routine for both old and
126851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  new nii protocol entries.
126951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
127051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
127151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
127251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
127351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
127451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
127551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
127651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
127751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff// TODO:    cdb - add argument and description to function comment
127851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
127951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_APIEntry_new (
128051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  UINT64 cdb
128151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
128251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
128351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_CDB           *CdbPtr;
128451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  NIC_DATA_INSTANCE *AdapterInfo;
128551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
128651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (cdb == (UINT64) 0) {
128751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
128851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
128951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
129051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
129151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr = (PXE_CDB *) (UINTN) cdb;
129251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
129361f2ab909d473aaf6faa278424287685a2c502feQian Ouyang  if (CdbPtr->IFnum >= (pxe_31->IFcnt | pxe_31->IFcntExt << 8) ) {
129451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
129551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
129651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    return ;
129751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
129851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
129951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo               = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);
130051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
130151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // entering from older entry point
130251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
130351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo->VersionFlag  = 0x31;
130451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UNDI_APIEntry_Common (cdb);
130551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
130651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
130751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
130851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
130951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  This is the common routine for both old and new entry point procedures.
131051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  The parameter passed in is a 64 bit flat model virtual
131151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  address of the cdb.  We then jump into the service routine pointed to by the
131251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Api_Table[OpCode].
131351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
131451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  CdbPtr               Pointer to the command descriptor block.
131551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  AdapterInfo          Pointer to the NIC data structure information which
131651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff                               the UNDI driver is layering on..
131751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
131851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
131951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
132051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
132151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff// TODO:    cdb - add argument and description to function comment
132251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
132351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffUNDI_APIEntry_Common (
132451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  UINT64 cdb
132551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
132651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
132751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PXE_CDB           *CdbPtr;
132851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  NIC_DATA_INSTANCE *AdapterInfo;
132951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  UNDI_CALL_TABLE   *tab_ptr;
133051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
133151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr = (PXE_CDB *) (UINTN) cdb;
133251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
133351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
133451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // check the OPCODE range
133551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
133651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if ((CdbPtr->OpCode > PXE_OPCODE_LAST_VALID) ||
133751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      (CdbPtr->StatCode != PXE_STATCODE_INITIALIZE) ||
133851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      (CdbPtr->StatFlags != PXE_STATFLAGS_INITIALIZE) ||
1339a4a44892164a62c00f371faed39b02e6a23eebf7Qian Ouyang      (CdbPtr->IFnum >= (pxe_31->IFcnt |  pxe_31->IFcntExt << 8))) {
134051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    goto badcdb;
134151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
134251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
134351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
134451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->CPBsize == PXE_CPBSIZE_NOT_USED) {
134551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (CdbPtr->CPBaddr != PXE_CPBADDR_NOT_USED) {
134651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      goto badcdb;
134751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
134851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  } else if (CdbPtr->CPBaddr == PXE_CPBADDR_NOT_USED) {
134951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    goto badcdb;
135051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
135151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
135251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (CdbPtr->DBsize == PXE_DBSIZE_NOT_USED) {
135351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (CdbPtr->DBaddr != PXE_DBADDR_NOT_USED) {
135451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      goto badcdb;
135551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
135651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  } else if (CdbPtr->DBaddr == PXE_DBADDR_NOT_USED) {
135751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    goto badcdb;
135851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
135951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
136051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
136151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // check if cpbsize and dbsize are as needed
136251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // check if opflags are as expected
136351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
136451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  tab_ptr = &api_table[CdbPtr->OpCode];
136551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
136651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (tab_ptr->cpbsize != (UINT16) (DONT_CHECK) && tab_ptr->cpbsize != CdbPtr->CPBsize) {
136751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    goto badcdb;
136851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
136951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
137051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (tab_ptr->dbsize != (UINT16) (DONT_CHECK) && tab_ptr->dbsize != CdbPtr->DBsize) {
137151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    goto badcdb;
137251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
137351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
137451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (tab_ptr->opflags != (UINT16) (DONT_CHECK) && tab_ptr->opflags != CdbPtr->OpFlags) {
137551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    goto badcdb;
137651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
137751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
137851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
137951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  AdapterInfo = &(UNDI32DeviceList[CdbPtr->IFnum]->NicInfo);
138051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
138151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
138251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // check if UNDI_State is valid for this call
138351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
138451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (tab_ptr->state != (UINT16) (-1)) {
138551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
138651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // should atleast be started
138751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
138851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (AdapterInfo->State == PXE_STATFLAGS_GET_STATE_STOPPED) {
138951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
139051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      CdbPtr->StatCode  = PXE_STATCODE_NOT_STARTED;
139151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      return ;
139251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
139351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
139451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    // check if it should be initialized
139551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    //
139651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    if (tab_ptr->state == 2) {
139751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      if (AdapterInfo->State != PXE_STATFLAGS_GET_STATE_INITIALIZED) {
139851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        CdbPtr->StatCode  = PXE_STATCODE_NOT_INITIALIZED;
139951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
140051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff        return ;
140151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      }
140251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
140351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
140451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
140551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // set the return variable for success case here
140651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
140751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
140851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatCode  = PXE_STATCODE_SUCCESS;
140951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
141051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  tab_ptr->api_ptr (CdbPtr, AdapterInfo);
141151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
141251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
141351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // %% AVL - check for command linking
141451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
141551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffbadcdb:
141651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
141751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  CdbPtr->StatCode  = PXE_STATCODE_INVALID_CDB;
141851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
141951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
142051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
142151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
142251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
142351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  When called with a null NicPtr, this routine decrements the number of NICs
142451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  this UNDI is supporting and removes the NIC_DATA_POINTER from the array.
142551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Otherwise, it increments the number of NICs this UNDI is supported and
142651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  updates the pxe.Fudge to ensure a proper check sum results.
142751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
142851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  NicPtr               Pointer to the NIC data structure.
142951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
143051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @return None
143151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
143251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
143351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
143451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffPxeUpdate (
143551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN  NIC_DATA_INSTANCE *NicPtr,
143651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN PXE_SW_UNDI        *PxePtr
143751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
143851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
143961f2ab909d473aaf6faa278424287685a2c502feQian Ouyang  UINT16 NicNum;
1440a4a44892164a62c00f371faed39b02e6a23eebf7Qian Ouyang  NicNum = (PxePtr->IFcnt | PxePtr->IFcntExt << 8);
144161f2ab909d473aaf6faa278424287685a2c502feQian Ouyang
144251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  if (NicPtr == NULL) {
144361f2ab909d473aaf6faa278424287685a2c502feQian Ouyang    if (NicNum > 0) {
144451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      //
144551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      // number of NICs this undi supports
144651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff      //
144761f2ab909d473aaf6faa278424287685a2c502feQian Ouyang      NicNum --;
144851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    }
144961f2ab909d473aaf6faa278424287685a2c502feQian Ouyang    goto done;
145051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  }
145151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
145251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
145351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // number of NICs this undi supports
145451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
145561f2ab909d473aaf6faa278424287685a2c502feQian Ouyang  NicNum++;
145661f2ab909d473aaf6faa278424287685a2c502feQian Ouyang
145761f2ab909d473aaf6faa278424287685a2c502feQian Ouyangdone:
145861f2ab909d473aaf6faa278424287685a2c502feQian Ouyang  PxePtr->IFcnt = (UINT8)(NicNum & 0xFF);
1459a4a44892164a62c00f371faed39b02e6a23eebf7Qian Ouyang  PxePtr->IFcntExt = (UINT8) ((NicNum & 0xFF00) >> 8);
146051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->Fudge = (UINT8) (PxePtr->Fudge - CalculateSum8 ((VOID *) PxePtr, PxePtr->Len));
146151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  return ;
146251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
146351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
146451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
146551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff/**
146651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  Initialize the !PXE structure
146751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
146851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @param  PxePtr               Pointer to SW_UNDI data structure.
146951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
147051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @retval EFI_SUCCESS          This driver is added to Controller.
147151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  @retval other                This driver does not support this device.
147251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
147351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff**/
147451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffVOID
147551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeffPxeStructInit (
147651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  IN PXE_SW_UNDI *PxePtr
147751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  )
147851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff{
147951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
148051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // Initialize the !PXE structure
148151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
148251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->Signature = PXE_ROMID_SIGNATURE;
148380448f6c1aed17ee0fbfa79bab7e7b8eeb2eb084ydong  PxePtr->Len       = (UINT8) sizeof (PXE_SW_UNDI);
148451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
148551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // cksum
148651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
148751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->Fudge     = 0;
148851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
148951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  // number of NICs this undi supports
149051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  //
149151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->IFcnt = 0;
1492a4a44892164a62c00f371faed39b02e6a23eebf7Qian Ouyang  PxePtr->IFcntExt = 0;
149351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->Rev       = PXE_ROMID_REV;
149451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->MajorVer  = PXE_ROMID_MAJORVER;
149551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->MinorVer  = PXE_ROMID_MINORVER;
149651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->reserved1 = 0;
149751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
149851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->Implementation = PXE_ROMID_IMP_SW_VIRT_ADDR |
149951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    PXE_ROMID_IMP_FRAG_SUPPORTED |
150051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    PXE_ROMID_IMP_CMD_LINK_SUPPORTED |
150151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    PXE_ROMID_IMP_NVDATA_READ_ONLY |
150251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    PXE_ROMID_IMP_STATION_ADDR_SETTABLE |
150351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED |
150451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED |
150551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED |
150651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    PXE_ROMID_IMP_FILTERED_MULTICAST_RX_SUPPORTED |
150751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    PXE_ROMID_IMP_SOFTWARE_INT_SUPPORTED |
150851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff    PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED;
150951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
151051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->EntryPoint  = (UINT64) (UINTN) UNDI_APIEntry_new;
151151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->MinorVer    = PXE_ROMID_MINORVER_31;
151251ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
151351ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->reserved2[0]  = 0;
151451ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->reserved2[1]  = 0;
151551ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->reserved2[2]  = 0;
151651ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->BusCnt        = 1;
151751ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->BusType[0]    = PXE_BUSTYPE_PCI;
151851ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
151951ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff  PxePtr->Fudge         = (UINT8) (PxePtr->Fudge - CalculateSum8 ((VOID *) PxePtr, PxePtr->Len));
152051ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff}
152151ebae6b69f88c0e4b72202d7e97c5b280bd074avanjeff
1522