]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/Network/Snp32_64/Dxe/receive.c
Partially make EdkModulePkg pass intel IPF compiler with /W4 /WX switched on.
[mirror_edk2.git] / EdkModulePkg / Universal / Network / Snp32_64 / Dxe / receive.c
CommitLineData
878ddf1f 1/*++\r
2Copyright (c) 2006, Intel Corporation \r
3All rights reserved. This program and the accompanying materials \r
4are licensed and made available under the terms and conditions of the BSD License \r
5which accompanies this distribution. The full text of the license may be found at \r
6http://opensource.org/licenses/bsd-license.php \r
7 \r
8THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
9WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
10\r
11Module name:\r
12 receive.c\r
13\r
14Abstract:\r
15\r
16Revision history:\r
17 2000-Feb-03 M(f)J Genesis.\r
18--*/\r
19\r
20\r
4cbd855e 21#include "Snp.h"\r
878ddf1f 22\r
1cc8ee78 23STATIC\r
878ddf1f 24EFI_STATUS\r
25pxe_receive (\r
26 SNP_DRIVER *snp,\r
27 VOID *BufferPtr,\r
28 UINTN *BuffSizePtr,\r
29 UINTN *HeaderSizePtr,\r
30 EFI_MAC_ADDRESS *SourceAddrPtr,\r
31 EFI_MAC_ADDRESS *DestinationAddrPtr,\r
32 UINT16 *ProtocolPtr\r
33 )\r
34/*++\r
35\r
36Routine Description:\r
37 this routine calls undi to receive a packet and fills in the data in the\r
38 input pointers!\r
39 \r
40Arguments:\r
41 snp - pointer to snp driver structure\r
42 BufferPtr - pointer to the memory for the received data\r
43 BuffSizePtr - is a pointer to the length of the buffer on entry and contains\r
44 the length of the received data on return\r
45 HeaderSizePtr - pointer to the header portion of the data received.\r
46 SourceAddrPtr - optional parameter, is a pointer to contain the source\r
47 ethernet address on return\r
48 DestinationAddrPtr - optional parameter, is a pointer to contain the destination\r
49 ethernet address on return\r
50 ProtocolPtr - optional parameter, is a pointer to contain the protocol type\r
51 from the ethernet header on return\r
52\r
53\r
54Returns:\r
55\r
56--*/\r
57{\r
58 PXE_CPB_RECEIVE *cpb;\r
59 PXE_DB_RECEIVE *db;\r
60 UINTN buf_size;\r
61 UINT64 TempData;\r
62\r
63 cpb = snp->cpb;\r
64 db = snp->db;\r
65 buf_size = *BuffSizePtr;\r
66 //\r
67 // IMPORTANT NOTE:\r
68 // In case of the older 3.0 UNDI, if the input buffer address is beyond 4GB,\r
69 // DO NOT call the map function on the given buffer, instead use\r
70 // a global buffer. The reason is that UNDI3.0 has some unnecessary check of\r
71 // making sure that all the addresses (whether or not they will be given\r
72 // to the NIC ) supplied to it are below 4GB. It may or may not use\r
73 // the mapped address after all (like in case of CPB and DB)!\r
74 // Instead of using the global buffer whose address is allocated within the\r
75 // 2GB limit if I start mapping the given buffer we lose the data, here is\r
76 // why!!!\r
77 // if our address is > 4GB, the map call creates another buffer below 2GB and\r
78 // copies data to/from the original buffer to the mapped buffer either at\r
79 // map time or unmap time depending on the map direction.\r
80 // UNDI will not complain since we already mapped the buffer to be\r
81 // within the 2GB limit but will not use (I know undi) the mapped address\r
82 // since it does not give the user buffers to the NIC's receive unit,\r
83 // It just copies the received packet into the user buffer using the virtual\r
84 // (CPU) address rather than the mapped (device or physical) address.\r
85 // When the UNDI call returns, if we then unmap the buffer, we will lose\r
86 // the contents because unmap copies the contents of the mapped buffer into\r
87 // the original buffer (since the direction is FROM_DEVICE) !!!\r
88 //\r
89 // this is not a problem in Undi 3.1 because this undi uses it's map callback\r
90 // routine to map a cpu address to device address and it does it only if\r
91 // it is giving the address to the device and unmaps it before using the cpu\r
92 // address!\r
93 //\r
94 TempData = (UINT64) (UINTN) BufferPtr;\r
95 if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {\r
96 cpb->BufferAddr = (UINT64) (UINTN) snp->receive_buf;\r
97 cpb->BufferLen = (UINT32) (snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);\r
98 } else {\r
99 cpb->BufferAddr = (UINT64) (UINTN) BufferPtr;\r
100 cpb->BufferLen = (UINT32) *BuffSizePtr;\r
101 }\r
102\r
103 cpb->reserved = 0;\r
104\r
105 snp->cdb.OpCode = PXE_OPCODE_RECEIVE;\r
106 snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;\r
107\r
108 snp->cdb.CPBsize = sizeof (PXE_CPB_RECEIVE);\r
109 snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;\r
110\r
111 snp->cdb.DBsize = sizeof (PXE_DB_RECEIVE);\r
112 snp->cdb.DBaddr = (UINT64) (UINTN) db;\r
113\r
114 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
115 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
116 snp->cdb.IFnum = snp->if_num;\r
117 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
118\r
119 //\r
120 // Issue UNDI command and check result.\r
121 //\r
122 DEBUG ((EFI_D_INFO, "\nsnp->undi.receive () "));\r
123\r
124 (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);\r
125\r
126 switch (snp->cdb.StatCode) {\r
127 case PXE_STATCODE_SUCCESS:\r
128 break;\r
129\r
130 case PXE_STATCODE_NO_DATA:\r
131 DEBUG (\r
132 (EFI_D_INFO,\r
133 "\nsnp->undi.receive () %xh:%xh\n",\r
134 snp->cdb.StatFlags,\r
135 snp->cdb.StatCode)\r
136 );\r
137\r
138 return EFI_NOT_READY;\r
139\r
140 default:\r
141 DEBUG (\r
142 (EFI_D_ERROR,\r
143 "\nsnp->undi.receive() %xh:%xh\n",\r
144 snp->cdb.StatFlags,\r
145 snp->cdb.StatCode)\r
146 );\r
147\r
148 return EFI_DEVICE_ERROR;\r
149 }\r
150\r
151 *BuffSizePtr = db->FrameLen;\r
152\r
153 if (HeaderSizePtr != NULL) {\r
154 *HeaderSizePtr = db->MediaHeaderLen;\r
155 }\r
156\r
157 if (SourceAddrPtr != NULL) {\r
158 CopyMem (SourceAddrPtr, &db->SrcAddr, snp->mode.HwAddressSize);\r
159 }\r
160\r
161 if (DestinationAddrPtr != NULL) {\r
162 CopyMem (DestinationAddrPtr, &db->DestAddr, snp->mode.HwAddressSize);\r
163 }\r
164\r
165 if (ProtocolPtr != NULL) {\r
166 *ProtocolPtr = (UINT16) PXE_SWAP_UINT16 (db->Protocol); /* we need to do the byte swapping */\r
167 }\r
168\r
169 TempData = (UINT64) (UINTN) BufferPtr;\r
170 if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {\r
171 CopyMem (BufferPtr, snp->receive_buf, snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);\r
172 }\r
173\r
174 return (*BuffSizePtr <= buf_size) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;\r
175}\r
176\r
177EFI_STATUS\r
178EFIAPI\r
179snp_undi32_receive (\r
180 IN EFI_SIMPLE_NETWORK_PROTOCOL * this,\r
181 OUT UINTN *HeaderSizePtr OPTIONAL,\r
182 IN OUT UINTN *BuffSizePtr,\r
183 OUT VOID *BufferPtr,\r
184 OUT EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,\r
185 OUT EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,\r
186 OUT UINT16 *ProtocolPtr OPTIONAL\r
187 )\r
188/*++\r
189\r
190Routine Description:\r
191 This is the SNP interface routine for receiving network data.\r
192 This routine basically retrieves snp structure, checks the SNP state and\r
193 calls the pxe_receive routine to actually do the receive!\r
194\r
195Arguments:\r
196 this - context pointer\r
197 HeaderSizePtr - optional parameter and is a pointer to the header portion of\r
198 the data received.\r
199 BuffSizePtr - is a pointer to the length of the buffer on entry and contains\r
200 the length of the received data on return\r
201 BufferPtr - pointer to the memory for the received data\r
202 SourceAddrPtr - optional parameter, is a pointer to contain the source\r
203 ethernet address on return\r
204 DestinationAddrPtr - optional parameter, is a pointer to contain the destination\r
205 ethernet address on return\r
206 ProtocolPtr - optional parameter, is a pointer to contain the protocol type\r
207 from the ethernet header on return\r
208\r
209Returns:\r
210\r
211--*/\r
212{\r
213 SNP_DRIVER *snp;\r
214\r
215 if (this == NULL) {\r
216 return EFI_INVALID_PARAMETER;\r
217 }\r
218\r
219 snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);\r
220\r
221 if (snp == NULL) {\r
222 return EFI_DEVICE_ERROR;\r
223 }\r
224\r
225 switch (snp->mode.State) {\r
226 case EfiSimpleNetworkInitialized:\r
227 break;\r
228\r
229 case EfiSimpleNetworkStopped:\r
230 return EFI_NOT_STARTED;\r
231\r
232 case EfiSimpleNetworkStarted:\r
233 return EFI_DEVICE_ERROR;\r
234\r
235 default:\r
236 return EFI_DEVICE_ERROR;\r
237 }\r
238\r
239 if ((BuffSizePtr == NULL) || (BufferPtr == NULL)) {\r
240 return EFI_INVALID_PARAMETER;\r
241 }\r
242\r
243 if (!snp->mode.ReceiveFilterSetting) {\r
244 return EFI_DEVICE_ERROR;\r
245 }\r
246\r
247 return pxe_receive (\r
248 snp,\r
249 BufferPtr,\r
250 BuffSizePtr,\r
251 HeaderSizePtr,\r
252 SourceAddrPtr,\r
253 DestinationAddrPtr,\r
254 ProtocolPtr\r
255 );\r
256}\r