]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/SnpDxe/Receive.c
Remove some useless EDK_RELEASE_VERSION, EFI_SPECIFICATION_VERSION ,and review VALID_...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Receive.c
1 /** @file
2 Implementation of receiving a packet from a network interface.
3
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
9
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.
12
13 **/
14
15
16 #include "Snp.h"
17
18 /**
19 this routine calls undi to receive a packet and fills in the data in the
20 input pointers!
21
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
33
34
35 **/
36 EFI_STATUS
37 PxeReceive (
38 SNP_DRIVER *Snp,
39 VOID *Buffer,
40 UINTN *BufferSize,
41 UINTN *HeaderSize,
42 EFI_MAC_ADDRESS *SrcAddr,
43 EFI_MAC_ADDRESS *DestAddr,
44 UINT16 *Protocol
45 )
46 {
47 PXE_CPB_RECEIVE *Cpb;
48 PXE_DB_RECEIVE *Db;
49 UINTN BuffSize;
50
51 Cpb = Snp->Cpb;
52 Db = Snp->Db;
53 BuffSize = *BufferSize;
54
55 Cpb->BufferAddr = (UINT64)(UINTN) Buffer;
56 Cpb->BufferLen = (UINT32) *BufferSize;
57
58 Cpb->reserved = 0;
59
60 Snp->Cdb.OpCode = PXE_OPCODE_RECEIVE;
61 Snp->Cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
62
63 Snp->Cdb.CPBsize = sizeof (PXE_CPB_RECEIVE);
64 Snp->Cdb.CPBaddr = (UINT64)(UINTN) Cpb;
65
66 Snp->Cdb.DBsize = sizeof (PXE_DB_RECEIVE);
67 Snp->Cdb.DBaddr = (UINT64)(UINTN) Db;
68
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;
73
74 //
75 // Issue UNDI command and check result.
76 //
77 DEBUG ((EFI_D_NET, "\nsnp->undi.receive () "));
78
79 (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
80
81 switch (Snp->Cdb.StatCode) {
82 case PXE_STATCODE_SUCCESS:
83 break;
84
85 case PXE_STATCODE_NO_DATA:
86 DEBUG (
87 (EFI_D_NET,
88 "\nsnp->undi.receive () %xh:%xh\n",
89 Snp->Cdb.StatFlags,
90 Snp->Cdb.StatCode)
91 );
92
93 return EFI_NOT_READY;
94
95 default:
96 DEBUG (
97 (EFI_D_ERROR,
98 "\nsnp->undi.receive() %xh:%xh\n",
99 Snp->Cdb.StatFlags,
100 Snp->Cdb.StatCode)
101 );
102
103 return EFI_DEVICE_ERROR;
104 }
105
106 *BufferSize = Db->FrameLen;
107
108 if (HeaderSize != NULL) {
109 *HeaderSize = Db->MediaHeaderLen;
110 }
111
112 if (SrcAddr != NULL) {
113 CopyMem (SrcAddr, &Db->SrcAddr, Snp->Mode.HwAddressSize);
114 }
115
116 if (DestAddr != NULL) {
117 CopyMem (DestAddr, &Db->DestAddr, Snp->Mode.HwAddressSize);
118 }
119
120 if (Protocol != NULL) {
121 *Protocol = (UINT16) PXE_SWAP_UINT16 (Db->Protocol); /* we need to do the byte swapping */
122 }
123
124 return (*BufferSize <= BuffSize) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
125 }
126
127 /**
128 Receives a packet from a network interface.
129
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.
141
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
149 header and the data.
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
154 the media header.
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.
158
159 @retval EFI_SUCCESS The received data was stored in Buffer, and
160 BufferSize has been updated to the number of
161 bytes received.
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.
173
174 **/
175 EFI_STATUS
176 EFIAPI
177 SnpUndi32Receive (
178 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
179 OUT UINTN *HeaderSize OPTIONAL,
180 IN OUT UINTN *BufferSize,
181 OUT VOID *Buffer,
182 OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
183 OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,
184 OUT UINT16 *Protocol OPTIONAL
185 )
186 {
187 SNP_DRIVER *Snp;
188 EFI_TPL OldTpl;
189 EFI_STATUS Status;
190
191 if (This == NULL) {
192 return EFI_INVALID_PARAMETER;
193 }
194
195 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
196
197 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
198
199 switch (Snp->Mode.State) {
200 case EfiSimpleNetworkInitialized:
201 break;
202
203 case EfiSimpleNetworkStopped:
204 Status = EFI_NOT_STARTED;
205 goto ON_EXIT;
206
207 default:
208 Status = EFI_DEVICE_ERROR;
209 goto ON_EXIT;
210 }
211
212 if ((BufferSize == NULL) || (Buffer == NULL)) {
213 Status = EFI_INVALID_PARAMETER;
214 goto ON_EXIT;
215 }
216
217 if (!Snp->Mode.ReceiveFilterSetting) {
218 Status = EFI_DEVICE_ERROR;
219 goto ON_EXIT;
220 }
221
222 Status = PxeReceive (
223 Snp,
224 Buffer,
225 BufferSize,
226 HeaderSize,
227 SrcAddr,
228 DestAddr,
229 Protocol
230 );
231
232 ON_EXIT:
233 gBS->RestoreTPL (OldTpl);
234
235 return Status;
236 }