13bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff/** @file
24140a6635b4784db9d0125e96d521d01053eca2crsun  Implementation of receiving a packet from a network interface.
35fe48e540437acce2f016715eaf0742fc72befeevanjeff
4e5eed7d3641d71d7ea539e5379ea9c6a5cd97004hhtianCopyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
5e5eed7d3641d71d7ea539e5379ea9c6a5cd97004hhtianThis program and the accompanying materials are licensed
65fe48e540437acce2f016715eaf0742fc72befeevanjeffand made available under the terms and conditions of the BSD License which
75fe48e540437acce2f016715eaf0742fc72befeevanjeffaccompanies this distribution. The full text of the license may be found at
85fe48e540437acce2f016715eaf0742fc72befeevanjeffhttp://opensource.org/licenses/bsd-license.php
93bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
103bb7aff34e8868de14a613d4bb320e50e8fce873vanjeffTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
113bb7aff34e8868de14a613d4bb320e50e8fce873vanjeffWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
123bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
133bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff**/
143bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
153bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
163bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff#include "Snp.h"
173bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
183bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff/**
19f381602727922e793de5826ee390344cb907e07aniry  Call UNDI to receive a packet and fills in the data in the input pointers.
20f381602727922e793de5826ee390344cb907e07aniry
21f381602727922e793de5826ee390344cb907e07aniry  @param  Snp          Pointer to snp driver structure
22f381602727922e793de5826ee390344cb907e07aniry  @param  Buffer       Pointer to the memory for the received data
23f381602727922e793de5826ee390344cb907e07aniry  @param  BufferSize   Pointer to the length of the buffer on entry and contains
24f381602727922e793de5826ee390344cb907e07aniry                       the length of the received data on return
25f381602727922e793de5826ee390344cb907e07aniry  @param  HeaderSize   Pointer to the header portion of the data received.
265fe48e540437acce2f016715eaf0742fc72befeevanjeff  @param  SrcAddr      Pointer to contain the source ethernet address on return
275fe48e540437acce2f016715eaf0742fc72befeevanjeff  @param  DestAddr     Pointer to contain the destination ethernet address on
28f381602727922e793de5826ee390344cb907e07aniry                       return
295fe48e540437acce2f016715eaf0742fc72befeevanjeff  @param  Protocol     Pointer to contain the protocol type from the ethernet
30f381602727922e793de5826ee390344cb907e07aniry                       header on return
31f381602727922e793de5826ee390344cb907e07aniry
32f381602727922e793de5826ee390344cb907e07aniry
335fe48e540437acce2f016715eaf0742fc72befeevanjeff  @retval EFI_SUCCESS           The received data was stored in Buffer, and
345fe48e540437acce2f016715eaf0742fc72befeevanjeff                                BufferSize has been updated to the number of
35f381602727922e793de5826ee390344cb907e07aniry                                bytes received.
365fe48e540437acce2f016715eaf0742fc72befeevanjeff  @retval EFI_DEVICE_ERROR      Fail to execute UNDI command.
375fe48e540437acce2f016715eaf0742fc72befeevanjeff  @retval EFI_NOT_READY         No packets have been received on the network
38f381602727922e793de5826ee390344cb907e07aniry                                interface.
395fe48e540437acce2f016715eaf0742fc72befeevanjeff  @retval EFI_BUFFER_TOO_SMALL  BufferSize is too small for the received
40f381602727922e793de5826ee390344cb907e07aniry                                packets. BufferSize has been updated to the
41f381602727922e793de5826ee390344cb907e07aniry                                required size.
423bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
433bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff**/
443bb7aff34e8868de14a613d4bb320e50e8fce873vanjeffEFI_STATUS
454cda7726e5fd30aaf3e05c80207ae1b264bfa123niryPxeReceive (
464cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  SNP_DRIVER      *Snp,
474cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  VOID            *Buffer,
484cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  UINTN           *BufferSize,
494cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  UINTN           *HeaderSize,
504cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  EFI_MAC_ADDRESS *SrcAddr,
514cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  EFI_MAC_ADDRESS *DestAddr,
524cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  UINT16          *Protocol
533bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  )
543bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff{
554cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  PXE_CPB_RECEIVE *Cpb;
564cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  PXE_DB_RECEIVE  *Db;
574cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  UINTN           BuffSize;
583bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
594cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Cpb       = Snp->Cpb;
604cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Db        = Snp->Db;
614cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  BuffSize  = *BufferSize;
623bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
634cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Cpb->BufferAddr = (UINT64)(UINTN) Buffer;
644cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Cpb->BufferLen  = (UINT32) *BufferSize;
653bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
664cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Cpb->reserved       = 0;
673bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
684cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Snp->Cdb.OpCode     = PXE_OPCODE_RECEIVE;
694cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Snp->Cdb.OpFlags    = PXE_OPFLAGS_NOT_USED;
703bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
71c9325700d0ef25eaf45077928af3f93b15ac5fe0ydong  Snp->Cdb.CPBsize    = (UINT16) sizeof (PXE_CPB_RECEIVE);
724cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Snp->Cdb.CPBaddr    = (UINT64)(UINTN) Cpb;
733bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
74c9325700d0ef25eaf45077928af3f93b15ac5fe0ydong  Snp->Cdb.DBsize     = (UINT16) sizeof (PXE_DB_RECEIVE);
754cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Snp->Cdb.DBaddr     = (UINT64)(UINTN) Db;
763bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
774cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;
784cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;
794cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Snp->Cdb.IFnum      = Snp->IfNum;
804cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;
813bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
823bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  //
833bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  // Issue UNDI command and check result.
843bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  //
855fe48e540437acce2f016715eaf0742fc72befeevanjeff  DEBUG ((EFI_D_NET, "\nsnp->undi.receive ()  "));
863bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
874cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
883bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
894cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  switch (Snp->Cdb.StatCode) {
903bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  case PXE_STATCODE_SUCCESS:
913bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    break;
923bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
933bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  case PXE_STATCODE_NO_DATA:
943bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    DEBUG (
955fe48e540437acce2f016715eaf0742fc72befeevanjeff      (EFI_D_NET,
963bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff      "\nsnp->undi.receive ()  %xh:%xh\n",
974cda7726e5fd30aaf3e05c80207ae1b264bfa123niry      Snp->Cdb.StatFlags,
984cda7726e5fd30aaf3e05c80207ae1b264bfa123niry      Snp->Cdb.StatCode)
993bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff      );
1003bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
1013bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    return EFI_NOT_READY;
1023bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
1033bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  default:
1043bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    DEBUG (
1059cff2f8d3687aeed765e1ee787c18ce70ae500bcniry      (EFI_D_ERROR,
1063bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff      "\nsnp->undi.receive()  %xh:%xh\n",
1074cda7726e5fd30aaf3e05c80207ae1b264bfa123niry      Snp->Cdb.StatFlags,
1084cda7726e5fd30aaf3e05c80207ae1b264bfa123niry      Snp->Cdb.StatCode)
1093bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff      );
1103bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
1113bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    return EFI_DEVICE_ERROR;
1123bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  }
1133bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
1144cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  *BufferSize = Db->FrameLen;
1153bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
1164cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  if (HeaderSize != NULL) {
1174cda7726e5fd30aaf3e05c80207ae1b264bfa123niry    *HeaderSize = Db->MediaHeaderLen;
1183bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  }
1193bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
1204cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  if (SrcAddr != NULL) {
1214cda7726e5fd30aaf3e05c80207ae1b264bfa123niry    CopyMem (SrcAddr, &Db->SrcAddr, Snp->Mode.HwAddressSize);
1223bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  }
1233bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
1244cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  if (DestAddr != NULL) {
1254cda7726e5fd30aaf3e05c80207ae1b264bfa123niry    CopyMem (DestAddr, &Db->DestAddr, Snp->Mode.HwAddressSize);
1263bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  }
1273bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
1284cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  if (Protocol != NULL) {
129f381602727922e793de5826ee390344cb907e07aniry    //
130f381602727922e793de5826ee390344cb907e07aniry    // We need to do the byte swapping
131f381602727922e793de5826ee390344cb907e07aniry    //
132f381602727922e793de5826ee390344cb907e07aniry    *Protocol = (UINT16) PXE_SWAP_UINT16 (Db->Protocol);
1333bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  }
1343bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
135553472f6447941f24bf9ae8c5ac54e04edf90dabxdu  //
136553472f6447941f24bf9ae8c5ac54e04edf90dabxdu  // We have received a packet from network interface, which implies that the
137553472f6447941f24bf9ae8c5ac54e04edf90dabxdu  // network cable should be present. While, some UNDI driver may not report
138553472f6447941f24bf9ae8c5ac54e04edf90dabxdu  // correct media status during Snp->Initialize(). So, we need ensure
139553472f6447941f24bf9ae8c5ac54e04edf90dabxdu  // MediaPresent in SNP mode data is set to correct value.
140553472f6447941f24bf9ae8c5ac54e04edf90dabxdu  //
141553472f6447941f24bf9ae8c5ac54e04edf90dabxdu  if (Snp->Mode.MediaPresentSupported && !Snp->Mode.MediaPresent) {
142553472f6447941f24bf9ae8c5ac54e04edf90dabxdu    Snp->Mode.MediaPresent = TRUE;
143553472f6447941f24bf9ae8c5ac54e04edf90dabxdu  }
144553472f6447941f24bf9ae8c5ac54e04edf90dabxdu
1454cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  return (*BufferSize <= BuffSize) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
1463bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff}
1473bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
1483bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff/**
1494cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Receives a packet from a network interface.
1504cda7726e5fd30aaf3e05c80207ae1b264bfa123niry
1514cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  This function retrieves one packet from the receive queue of a network interface.
1525fe48e540437acce2f016715eaf0742fc72befeevanjeff  If there are no packets on the receive queue, then EFI_NOT_READY will be
1534cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  returned. If there is a packet on the receive queue, and the size of the packet
1544cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  is smaller than BufferSize, then the contents of the packet will be placed in
1554cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Buffer, and BufferSize will be updated with the actual size of the packet.
1564cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  In addition, if SrcAddr, DestAddr, and Protocol are not NULL, then these values
1575fe48e540437acce2f016715eaf0742fc72befeevanjeff  will be extracted from the media header and returned. EFI_SUCCESS will be
1584cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  returned if a packet was successfully received.
1594cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  If BufferSize is smaller than the received packet, then the size of the receive
1604cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  packet will be placed in BufferSize and EFI_BUFFER_TOO_SMALL will be returned.
1614cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
1624cda7726e5fd30aaf3e05c80207ae1b264bfa123niry
1634cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  @param This       A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
1645fe48e540437acce2f016715eaf0742fc72befeevanjeff  @param HeaderSize The size, in bytes, of the media header received on the network
1655fe48e540437acce2f016715eaf0742fc72befeevanjeff                    interface. If this parameter is NULL, then the media header size
1664cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                    will not be returned.
1675fe48e540437acce2f016715eaf0742fc72befeevanjeff  @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in
1684cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                    bytes, of the packet that was received on the network interface.
1694cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  @param Buffer     A pointer to the data buffer to receive both the media
1704cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                    header and the data.
1714cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  @param SrcAddr    The source HW MAC address. If this parameter is NULL, the HW
1725fe48e540437acce2f016715eaf0742fc72befeevanjeff                    MAC source address will not be extracted from the media header.
1735fe48e540437acce2f016715eaf0742fc72befeevanjeff  @param DestAddr   The destination HW MAC address. If this parameter is NULL,
1745fe48e540437acce2f016715eaf0742fc72befeevanjeff                    the HW MAC destination address will not be extracted from
1754cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                    the media header.
1765fe48e540437acce2f016715eaf0742fc72befeevanjeff  @param Protocol   The media header type. If this parameter is NULL, then the
1775fe48e540437acce2f016715eaf0742fc72befeevanjeff                    protocol will not be extracted from the media header. See
1784cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                    RFC 1700 section "Ether Types" for examples.
1794cda7726e5fd30aaf3e05c80207ae1b264bfa123niry
1805fe48e540437acce2f016715eaf0742fc72befeevanjeff  @retval EFI_SUCCESS           The received data was stored in Buffer, and
1815fe48e540437acce2f016715eaf0742fc72befeevanjeff                                BufferSize has been updated to the number of
1824cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                                bytes received.
1834cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  @retval EFI_NOT_STARTED       The network interface has not been started.
1844cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  @retval EFI_NOT_READY         No packets have been received on the network interface.
1855fe48e540437acce2f016715eaf0742fc72befeevanjeff  @retval EFI_BUFFER_TOO_SMALL  BufferSize is too small for the received packets.
1864cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                                BufferSize has been updated to the required size.
1874cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
1884cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                                * The This parameter is NULL
1895fe48e540437acce2f016715eaf0742fc72befeevanjeff                                * The This parameter does not point to a valid
1904cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                                  EFI_SIMPLE_NETWORK_PROTOCOL structure.
1914cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                                * The BufferSize parameter is NULL
1924cda7726e5fd30aaf3e05c80207ae1b264bfa123niry                                * The Buffer parameter is NULL
1934cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
1943bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
1953bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff**/
1963bb7aff34e8868de14a613d4bb320e50e8fce873vanjeffEFI_STATUS
1973bb7aff34e8868de14a613d4bb320e50e8fce873vanjeffEFIAPI
1984cda7726e5fd30aaf3e05c80207ae1b264bfa123nirySnpUndi32Receive (
1994cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
2004cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  OUT UINTN                      *HeaderSize OPTIONAL,
2014cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  IN OUT UINTN                   *BufferSize,
2024cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  OUT VOID                       *Buffer,
2034cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  OUT EFI_MAC_ADDRESS            *SrcAddr OPTIONAL,
2044cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  OUT EFI_MAC_ADDRESS            *DestAddr OPTIONAL,
2054cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  OUT UINT16                     *Protocol OPTIONAL
2063bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  )
2073bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff{
2084cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  SNP_DRIVER  *Snp;
2093bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  EFI_TPL     OldTpl;
2103bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  EFI_STATUS  Status;
2113bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2124cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  if (This == NULL) {
2133bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    return EFI_INVALID_PARAMETER;
2143bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  }
2153bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2164cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
2173bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2183bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
2193bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2204cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  switch (Snp->Mode.State) {
2213bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  case EfiSimpleNetworkInitialized:
2223bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    break;
2233bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2243bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  case EfiSimpleNetworkStopped:
2253bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    Status = EFI_NOT_STARTED;
2263bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    goto ON_EXIT;
2273bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2283bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  default:
2293bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    Status = EFI_DEVICE_ERROR;
2303bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    goto ON_EXIT;
2313bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  }
2323bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2334cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  if ((BufferSize == NULL) || (Buffer == NULL)) {
2343bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    Status = EFI_INVALID_PARAMETER;
2353bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    goto ON_EXIT;
2363bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  }
2373bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2384140a6635b4784db9d0125e96d521d01053eca2crsun  if (Snp->Mode.ReceiveFilterSetting == 0) {
2393bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    Status = EFI_DEVICE_ERROR;
2403bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff    goto ON_EXIT;
2413bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  }
2423bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2434cda7726e5fd30aaf3e05c80207ae1b264bfa123niry  Status = PxeReceive (
2444cda7726e5fd30aaf3e05c80207ae1b264bfa123niry             Snp,
2454cda7726e5fd30aaf3e05c80207ae1b264bfa123niry             Buffer,
2464cda7726e5fd30aaf3e05c80207ae1b264bfa123niry             BufferSize,
2474cda7726e5fd30aaf3e05c80207ae1b264bfa123niry             HeaderSize,
2484cda7726e5fd30aaf3e05c80207ae1b264bfa123niry             SrcAddr,
2494cda7726e5fd30aaf3e05c80207ae1b264bfa123niry             DestAddr,
2504cda7726e5fd30aaf3e05c80207ae1b264bfa123niry             Protocol
2513bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff             );
2523bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2533bb7aff34e8868de14a613d4bb320e50e8fce873vanjeffON_EXIT:
2543bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  gBS->RestoreTPL (OldTpl);
2553bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff
2563bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff  return Status;
2573bb7aff34e8868de14a613d4bb320e50e8fce873vanjeff}
258