]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/SnpDxe/Receive.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / SnpDxe / Receive.c
CommitLineData
3bb7aff3 1/** @file\r
4140a663 2 Implementation of receiving a packet from a network interface.\r
5fe48e54 3\r
e5eed7d3 4Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
3bb7aff3 6\r
3bb7aff3 7**/\r
8\r
3bb7aff3 9#include "Snp.h"\r
10\r
11/**\r
f3816027 12 Call UNDI to receive a packet and fills in the data in the input pointers.\r
13\r
14 @param Snp Pointer to snp driver structure\r
15 @param Buffer Pointer to the memory for the received data\r
16 @param BufferSize Pointer to the length of the buffer on entry and contains\r
17 the length of the received data on return\r
18 @param HeaderSize Pointer to the header portion of the data received.\r
5fe48e54 19 @param SrcAddr Pointer to contain the source ethernet address on return\r
20 @param DestAddr Pointer to contain the destination ethernet address on\r
f3816027 21 return\r
5fe48e54 22 @param Protocol Pointer to contain the protocol type from the ethernet\r
f3816027 23 header on return\r
24\r
25\r
5fe48e54 26 @retval EFI_SUCCESS The received data was stored in Buffer, and\r
27 BufferSize has been updated to the number of\r
f3816027 28 bytes received.\r
5fe48e54 29 @retval EFI_DEVICE_ERROR Fail to execute UNDI command.\r
30 @retval EFI_NOT_READY No packets have been received on the network\r
f3816027 31 interface.\r
5fe48e54 32 @retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the received\r
f3816027 33 packets. BufferSize has been updated to the\r
34 required size.\r
3bb7aff3 35\r
36**/\r
3bb7aff3 37EFI_STATUS\r
4cda7726 38PxeReceive (\r
d1050b9d
MK
39 SNP_DRIVER *Snp,\r
40 VOID *Buffer,\r
41 UINTN *BufferSize,\r
42 UINTN *HeaderSize,\r
43 EFI_MAC_ADDRESS *SrcAddr,\r
44 EFI_MAC_ADDRESS *DestAddr,\r
45 UINT16 *Protocol\r
3bb7aff3 46 )\r
47{\r
d1050b9d
MK
48 PXE_CPB_RECEIVE *Cpb;\r
49 PXE_DB_RECEIVE *Db;\r
50 UINTN BuffSize;\r
3bb7aff3 51\r
d1050b9d
MK
52 Cpb = Snp->Cpb;\r
53 Db = Snp->Db;\r
54 BuffSize = *BufferSize;\r
3bb7aff3 55\r
d1050b9d
MK
56 Cpb->BufferAddr = (UINT64)(UINTN)Buffer;\r
57 Cpb->BufferLen = (UINT32)*BufferSize;\r
3bb7aff3 58\r
d1050b9d 59 Cpb->reserved = 0;\r
3bb7aff3 60\r
d1050b9d
MK
61 Snp->Cdb.OpCode = PXE_OPCODE_RECEIVE;\r
62 Snp->Cdb.OpFlags = PXE_OPFLAGS_NOT_USED;\r
3bb7aff3 63\r
d1050b9d
MK
64 Snp->Cdb.CPBsize = (UINT16)sizeof (PXE_CPB_RECEIVE);\r
65 Snp->Cdb.CPBaddr = (UINT64)(UINTN)Cpb;\r
3bb7aff3 66\r
d1050b9d
MK
67 Snp->Cdb.DBsize = (UINT16)sizeof (PXE_DB_RECEIVE);\r
68 Snp->Cdb.DBaddr = (UINT64)(UINTN)Db;\r
3bb7aff3 69\r
d1050b9d
MK
70 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
71 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
72 Snp->Cdb.IFnum = Snp->IfNum;\r
73 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
3bb7aff3 74\r
75 //\r
76 // Issue UNDI command and check result.\r
77 //\r
c49ca4a2 78 DEBUG ((DEBUG_NET, "\nsnp->undi.receive () "));\r
3bb7aff3 79\r
d1050b9d 80 (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);\r
3bb7aff3 81\r
4cda7726 82 switch (Snp->Cdb.StatCode) {\r
d1050b9d
MK
83 case PXE_STATCODE_SUCCESS:\r
84 break;\r
85\r
86 case PXE_STATCODE_NO_DATA:\r
87 DEBUG (\r
88 (DEBUG_NET,\r
89 "\nsnp->undi.receive () %xh:%xh\n",\r
90 Snp->Cdb.StatFlags,\r
91 Snp->Cdb.StatCode)\r
92 );\r
93\r
94 return EFI_NOT_READY;\r
95\r
96 default:\r
97 DEBUG (\r
98 (DEBUG_ERROR,\r
99 "\nsnp->undi.receive() %xh:%xh\n",\r
100 Snp->Cdb.StatFlags,\r
101 Snp->Cdb.StatCode)\r
102 );\r
103\r
104 return EFI_DEVICE_ERROR;\r
3bb7aff3 105 }\r
106\r
4cda7726 107 *BufferSize = Db->FrameLen;\r
3bb7aff3 108\r
4cda7726 109 if (HeaderSize != NULL) {\r
110 *HeaderSize = Db->MediaHeaderLen;\r
3bb7aff3 111 }\r
112\r
4cda7726 113 if (SrcAddr != NULL) {\r
114 CopyMem (SrcAddr, &Db->SrcAddr, Snp->Mode.HwAddressSize);\r
3bb7aff3 115 }\r
116\r
4cda7726 117 if (DestAddr != NULL) {\r
118 CopyMem (DestAddr, &Db->DestAddr, Snp->Mode.HwAddressSize);\r
3bb7aff3 119 }\r
120\r
4cda7726 121 if (Protocol != NULL) {\r
f3816027 122 //\r
123 // We need to do the byte swapping\r
124 //\r
d1050b9d 125 *Protocol = (UINT16)PXE_SWAP_UINT16 (Db->Protocol);\r
3bb7aff3 126 }\r
127\r
553472f6 128 //\r
129 // We have received a packet from network interface, which implies that the\r
130 // network cable should be present. While, some UNDI driver may not report\r
131 // correct media status during Snp->Initialize(). So, we need ensure\r
132 // MediaPresent in SNP mode data is set to correct value.\r
133 //\r
134 if (Snp->Mode.MediaPresentSupported && !Snp->Mode.MediaPresent) {\r
135 Snp->Mode.MediaPresent = TRUE;\r
136 }\r
137\r
4cda7726 138 return (*BufferSize <= BuffSize) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;\r
3bb7aff3 139}\r
140\r
3bb7aff3 141/**\r
4cda7726 142 Receives a packet from a network interface.\r
143\r
144 This function retrieves one packet from the receive queue of a network interface.\r
5fe48e54 145 If there are no packets on the receive queue, then EFI_NOT_READY will be\r
4cda7726 146 returned. If there is a packet on the receive queue, and the size of the packet\r
147 is smaller than BufferSize, then the contents of the packet will be placed in\r
148 Buffer, and BufferSize will be updated with the actual size of the packet.\r
149 In addition, if SrcAddr, DestAddr, and Protocol are not NULL, then these values\r
5fe48e54 150 will be extracted from the media header and returned. EFI_SUCCESS will be\r
4cda7726 151 returned if a packet was successfully received.\r
152 If BufferSize is smaller than the received packet, then the size of the receive\r
153 packet will be placed in BufferSize and EFI_BUFFER_TOO_SMALL will be returned.\r
154 If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.\r
155\r
156 @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.\r
5fe48e54 157 @param HeaderSize The size, in bytes, of the media header received on the network\r
158 interface. If this parameter is NULL, then the media header size\r
4cda7726 159 will not be returned.\r
5fe48e54 160 @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in\r
4cda7726 161 bytes, of the packet that was received on the network interface.\r
162 @param Buffer A pointer to the data buffer to receive both the media\r
163 header and the data.\r
164 @param SrcAddr The source HW MAC address. If this parameter is NULL, the HW\r
5fe48e54 165 MAC source address will not be extracted from the media header.\r
166 @param DestAddr The destination HW MAC address. If this parameter is NULL,\r
167 the HW MAC destination address will not be extracted from\r
4cda7726 168 the media header.\r
5fe48e54 169 @param Protocol The media header type. If this parameter is NULL, then the\r
170 protocol will not be extracted from the media header. See\r
4cda7726 171 RFC 1700 section "Ether Types" for examples.\r
172\r
5fe48e54 173 @retval EFI_SUCCESS The received data was stored in Buffer, and\r
174 BufferSize has been updated to the number of\r
4cda7726 175 bytes received.\r
176 @retval EFI_NOT_STARTED The network interface has not been started.\r
177 @retval EFI_NOT_READY No packets have been received on the network interface.\r
5fe48e54 178 @retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the received packets.\r
4cda7726 179 BufferSize has been updated to the required size.\r
180 @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
181 * The This parameter is NULL\r
5fe48e54 182 * The This parameter does not point to a valid\r
4cda7726 183 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
184 * The BufferSize parameter is NULL\r
185 * The Buffer parameter is NULL\r
186 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
3bb7aff3 187\r
188**/\r
189EFI_STATUS\r
190EFIAPI\r
4cda7726 191SnpUndi32Receive (\r
d1050b9d
MK
192 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
193 OUT UINTN *HeaderSize OPTIONAL,\r
194 IN OUT UINTN *BufferSize,\r
195 OUT VOID *Buffer,\r
196 OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,\r
197 OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,\r
198 OUT UINT16 *Protocol OPTIONAL\r
3bb7aff3 199 )\r
200{\r
4cda7726 201 SNP_DRIVER *Snp;\r
3bb7aff3 202 EFI_TPL OldTpl;\r
203 EFI_STATUS Status;\r
204\r
4cda7726 205 if (This == NULL) {\r
3bb7aff3 206 return EFI_INVALID_PARAMETER;\r
207 }\r
208\r
4cda7726 209 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
3bb7aff3 210\r
211 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
212\r
4cda7726 213 switch (Snp->Mode.State) {\r
d1050b9d
MK
214 case EfiSimpleNetworkInitialized:\r
215 break;\r
3bb7aff3 216\r
d1050b9d
MK
217 case EfiSimpleNetworkStopped:\r
218 Status = EFI_NOT_STARTED;\r
219 goto ON_EXIT;\r
3bb7aff3 220\r
d1050b9d
MK
221 default:\r
222 Status = EFI_DEVICE_ERROR;\r
223 goto ON_EXIT;\r
3bb7aff3 224 }\r
225\r
4cda7726 226 if ((BufferSize == NULL) || (Buffer == NULL)) {\r
3bb7aff3 227 Status = EFI_INVALID_PARAMETER;\r
228 goto ON_EXIT;\r
229 }\r
230\r
4140a663 231 if (Snp->Mode.ReceiveFilterSetting == 0) {\r
3bb7aff3 232 Status = EFI_DEVICE_ERROR;\r
233 goto ON_EXIT;\r
234 }\r
235\r
4cda7726 236 Status = PxeReceive (\r
237 Snp,\r
238 Buffer,\r
239 BufferSize,\r
240 HeaderSize,\r
241 SrcAddr,\r
242 DestAddr,\r
243 Protocol\r
3bb7aff3 244 );\r
245\r
246ON_EXIT:\r
247 gBS->RestoreTPL (OldTpl);\r
248\r
249 return Status;\r
250}\r