2 Implementation of receiving a packet from a network interface.
4 Copyright (c) 2004 - 2007, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials are licensed
6 and made available under the terms and conditions of the BSD License which
7 accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 this routine calls undi to receive a packet and fills in the data in the
22 @param Snp pointer to snp driver structure
23 @param Buffer pointer to the memory for the received data
24 @param BufferSize is a pointer to the length of the buffer on entry and
25 contains the length of the received data on return
26 @param HeaderSize pointer to the header portion of the data received.
27 @param SrcAddr optional parameter, is a pointer to contain the
28 source ethernet address on return
29 @param DestAddr optional parameter, is a pointer to contain the
30 destination ethernet address on return
31 @param Protocol optional parameter, is a pointer to contain the
32 protocol type from the ethernet header on return
42 EFI_MAC_ADDRESS
*SrcAddr
,
43 EFI_MAC_ADDRESS
*DestAddr
,
53 BuffSize
= *BufferSize
;
55 Cpb
->BufferAddr
= (UINT64
)(UINTN
) Buffer
;
56 Cpb
->BufferLen
= (UINT32
) *BufferSize
;
60 Snp
->Cdb
.OpCode
= PXE_OPCODE_RECEIVE
;
61 Snp
->Cdb
.OpFlags
= PXE_OPFLAGS_NOT_USED
;
63 Snp
->Cdb
.CPBsize
= sizeof (PXE_CPB_RECEIVE
);
64 Snp
->Cdb
.CPBaddr
= (UINT64
)(UINTN
) Cpb
;
66 Snp
->Cdb
.DBsize
= sizeof (PXE_DB_RECEIVE
);
67 Snp
->Cdb
.DBaddr
= (UINT64
)(UINTN
) Db
;
69 Snp
->Cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
70 Snp
->Cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
71 Snp
->Cdb
.IFnum
= Snp
->IfNum
;
72 Snp
->Cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
75 // Issue UNDI command and check result.
77 DEBUG ((EFI_D_NET
, "\nsnp->undi.receive () "));
79 (*Snp
->IssueUndi32Command
) ((UINT64
)(UINTN
) &Snp
->Cdb
);
81 switch (Snp
->Cdb
.StatCode
) {
82 case PXE_STATCODE_SUCCESS
:
85 case PXE_STATCODE_NO_DATA
:
88 "\nsnp->undi.receive () %xh:%xh\n",
98 "\nsnp->undi.receive() %xh:%xh\n",
103 return EFI_DEVICE_ERROR
;
106 *BufferSize
= Db
->FrameLen
;
108 if (HeaderSize
!= NULL
) {
109 *HeaderSize
= Db
->MediaHeaderLen
;
112 if (SrcAddr
!= NULL
) {
113 CopyMem (SrcAddr
, &Db
->SrcAddr
, Snp
->Mode
.HwAddressSize
);
116 if (DestAddr
!= NULL
) {
117 CopyMem (DestAddr
, &Db
->DestAddr
, Snp
->Mode
.HwAddressSize
);
120 if (Protocol
!= NULL
) {
121 *Protocol
= (UINT16
) PXE_SWAP_UINT16 (Db
->Protocol
); /* we need to do the byte swapping */
124 return (*BufferSize
<= BuffSize
) ? EFI_SUCCESS
: EFI_BUFFER_TOO_SMALL
;
128 Receives a packet from a network interface.
130 This function retrieves one packet from the receive queue of a network interface.
131 If there are no packets on the receive queue, then EFI_NOT_READY will be
132 returned. If there is a packet on the receive queue, and the size of the packet
133 is smaller than BufferSize, then the contents of the packet will be placed in
134 Buffer, and BufferSize will be updated with the actual size of the packet.
135 In addition, if SrcAddr, DestAddr, and Protocol are not NULL, then these values
136 will be extracted from the media header and returned. EFI_SUCCESS will be
137 returned if a packet was successfully received.
138 If BufferSize is smaller than the received packet, then the size of the receive
139 packet will be placed in BufferSize and EFI_BUFFER_TOO_SMALL will be returned.
140 If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
142 @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
143 @param HeaderSize The size, in bytes, of the media header received on the network
144 interface. If this parameter is NULL, then the media header size
145 will not be returned.
146 @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in
147 bytes, of the packet that was received on the network interface.
148 @param Buffer A pointer to the data buffer to receive both the media
150 @param SrcAddr The source HW MAC address. If this parameter is NULL, the HW
151 MAC source address will not be extracted from the media header.
152 @param DestAddr The destination HW MAC address. If this parameter is NULL,
153 the HW MAC destination address will not be extracted from
155 @param Protocol The media header type. If this parameter is NULL, then the
156 protocol will not be extracted from the media header. See
157 RFC 1700 section "Ether Types" for examples.
159 @retval EFI_SUCCESS The received data was stored in Buffer, and
160 BufferSize has been updated to the number of
162 @retval EFI_NOT_STARTED The network interface has not been started.
163 @retval EFI_NOT_READY No packets have been received on the network interface.
164 @retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the received packets.
165 BufferSize has been updated to the required size.
166 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
167 * The This parameter is NULL
168 * The This parameter does not point to a valid
169 EFI_SIMPLE_NETWORK_PROTOCOL structure.
170 * The BufferSize parameter is NULL
171 * The Buffer parameter is NULL
172 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
178 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
,
179 OUT UINTN
*HeaderSize OPTIONAL
,
180 IN OUT UINTN
*BufferSize
,
182 OUT EFI_MAC_ADDRESS
*SrcAddr OPTIONAL
,
183 OUT EFI_MAC_ADDRESS
*DestAddr OPTIONAL
,
184 OUT UINT16
*Protocol OPTIONAL
192 return EFI_INVALID_PARAMETER
;
195 Snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
197 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
199 switch (Snp
->Mode
.State
) {
200 case EfiSimpleNetworkInitialized
:
203 case EfiSimpleNetworkStopped
:
204 Status
= EFI_NOT_STARTED
;
208 Status
= EFI_DEVICE_ERROR
;
212 if ((BufferSize
== NULL
) || (Buffer
== NULL
)) {
213 Status
= EFI_INVALID_PARAMETER
;
217 if (!Snp
->Mode
.ReceiveFilterSetting
) {
218 Status
= EFI_DEVICE_ERROR
;
222 Status
= PxeReceive (
233 gBS
->RestoreTPL (OldTpl
);