]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/SnpDxe/Transmit.c
Patch to remove STATIC modifier. This is on longer recommended by EFI Framework codin...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Transmit.c
CommitLineData
a3c5f87a 1/** @file\r
2Copyright (c) 2004 - 2007, 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\r
13 transmit.c\r
14\r
15Abstract:\r
16\r
17Revision history:\r
18 2000-Feb-03 M(f)J Genesis.\r
19\r
20**/\r
21\r
22#include "Snp.h"\r
23\r
24\r
25/**\r
26 This routine calls undi to create the meadia header for the given data buffer.\r
27\r
28 @param snp pointer to SNP driver structure\r
29 @param MacHeaderPtr address where the media header will be filled in.\r
30 @param MacHeaderSize size of the memory at MacHeaderPtr\r
31 @param BufferPtr data buffer pointer\r
32 @param BufferLength Size of data in the BufferPtr\r
33 @param DestinationAddrPtr address of the destination mac address buffer\r
34 @param SourceAddrPtr address of the source mac address buffer\r
35 @param ProtocolPtr address of the protocol type\r
36\r
37 @retval EFI_SUCCESS if successfully completed the undi call\r
38 @retval Other error return from undi call.\r
39\r
40**/\r
a3c5f87a 41EFI_STATUS\r
42pxe_fillheader (\r
43 SNP_DRIVER *snp,\r
44 VOID *MacHeaderPtr,\r
45 UINTN MacHeaderSize,\r
46 VOID *BufferPtr,\r
47 UINTN BufferLength,\r
48 EFI_MAC_ADDRESS *DestinationAddrPtr,\r
49 EFI_MAC_ADDRESS *SourceAddrPtr,\r
50 UINT16 *ProtocolPtr\r
51 )\r
52{\r
53 PXE_CPB_FILL_HEADER_FRAGMENTED *cpb;\r
54\r
55 cpb = snp->cpb;\r
56 if (SourceAddrPtr) {\r
57 CopyMem (\r
58 (VOID *) cpb->SrcAddr,\r
59 (VOID *) SourceAddrPtr,\r
60 snp->mode.HwAddressSize\r
61 );\r
62 } else {\r
63 CopyMem (\r
64 (VOID *) cpb->SrcAddr,\r
65 (VOID *) &(snp->mode.CurrentAddress),\r
66 snp->mode.HwAddressSize\r
67 );\r
68 }\r
69\r
70 CopyMem (\r
71 (VOID *) cpb->DestAddr,\r
72 (VOID *) DestinationAddrPtr,\r
73 snp->mode.HwAddressSize\r
74 );\r
75\r
76 //\r
77 // we need to do the byte swapping\r
78 //\r
79 cpb->Protocol = (UINT16) PXE_SWAP_UINT16 (*ProtocolPtr);\r
80\r
81 cpb->PacketLen = (UINT32) (BufferLength);\r
82 cpb->MediaHeaderLen = (UINT16) MacHeaderSize;\r
83\r
84 cpb->FragCnt = 2;\r
85 cpb->reserved = 0;\r
86\r
87 cpb->FragDesc[0].FragAddr = (UINT64)(UINTN) MacHeaderPtr;\r
88 cpb->FragDesc[0].FragLen = (UINT32) MacHeaderSize;\r
89 cpb->FragDesc[1].FragAddr = (UINT64)(UINTN) BufferPtr;\r
90 cpb->FragDesc[1].FragLen = (UINT32) BufferLength;\r
91\r
92 cpb->FragDesc[0].reserved = cpb->FragDesc[1].reserved = 0;\r
93\r
94 snp->cdb.OpCode = PXE_OPCODE_FILL_HEADER;\r
95 snp->cdb.OpFlags = PXE_OPFLAGS_FILL_HEADER_FRAGMENTED;\r
96\r
97 snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;\r
98 snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;\r
99\r
100 snp->cdb.CPBsize = sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED);\r
101 snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;\r
102\r
103 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
104 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
105 snp->cdb.IFnum = snp->if_num;\r
106 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
107\r
108 //\r
109 // Issue UNDI command and check result.\r
110 //\r
111 DEBUG ((EFI_D_NET, "\nsnp->undi.fill_header() "));\r
112\r
113 (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);\r
114\r
115 switch (snp->cdb.StatCode) {\r
116 case PXE_STATCODE_SUCCESS:\r
117 return EFI_SUCCESS;\r
118\r
119 case PXE_STATCODE_INVALID_PARAMETER:\r
120 DEBUG (\r
121 (EFI_D_ERROR,\r
122 "\nsnp->undi.fill_header() %xh:%xh\n",\r
123 snp->cdb.StatFlags,\r
124 snp->cdb.StatCode)\r
125 );\r
126\r
127 return EFI_INVALID_PARAMETER;\r
128\r
129 default:\r
130 DEBUG (\r
131 (EFI_D_ERROR,\r
132 "\nsnp->undi.fill_header() %xh:%xh\n",\r
133 snp->cdb.StatFlags,\r
134 snp->cdb.StatCode)\r
135 );\r
136\r
137 return EFI_DEVICE_ERROR;\r
138 }\r
139}\r
140\r
141\r
142/**\r
143 This routine calls undi to transmit the given data buffer\r
144\r
145 @param snp pointer to SNP driver structure\r
146 @param BufferPtr data buffer pointer\r
147 @param BufferLength Size of data in the BufferPtr\r
148\r
149 @retval EFI_SUCCESS if successfully completed the undi call\r
150 @retval Other error return from undi call.\r
151\r
152**/\r
a3c5f87a 153EFI_STATUS\r
154pxe_transmit (\r
155 SNP_DRIVER *snp,\r
156 VOID *BufferPtr,\r
157 UINTN BufferLength\r
158 )\r
159{\r
160 PXE_CPB_TRANSMIT *cpb;\r
161 EFI_STATUS Status;\r
162\r
163 cpb = snp->cpb;\r
164 cpb->FrameAddr = (UINT64) (UINTN) BufferPtr;\r
165 cpb->DataLen = (UINT32) BufferLength;\r
166\r
167 cpb->MediaheaderLen = 0;\r
168 cpb->reserved = 0;\r
169\r
170 snp->cdb.OpFlags = PXE_OPFLAGS_TRANSMIT_WHOLE;\r
171\r
172 snp->cdb.CPBsize = sizeof (PXE_CPB_TRANSMIT);\r
173 snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;\r
174\r
175 snp->cdb.OpCode = PXE_OPCODE_TRANSMIT;\r
176 snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;\r
177 snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;\r
178\r
179 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
180 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
181 snp->cdb.IFnum = snp->if_num;\r
182 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
183\r
184 //\r
185 // Issue UNDI command and check result.\r
186 //\r
187 DEBUG ((EFI_D_NET, "\nsnp->undi.transmit() "));\r
188 DEBUG ((EFI_D_NET, "\nsnp->cdb.OpCode == %x", snp->cdb.OpCode));\r
0e549d5b 189 DEBUG ((EFI_D_NET, "\nsnp->cdb.CPBaddr == %LX", snp->cdb.CPBaddr));\r
190 DEBUG ((EFI_D_NET, "\nsnp->cdb.DBaddr == %LX", snp->cdb.DBaddr));\r
191 DEBUG ((EFI_D_NET, "\ncpb->FrameAddr == %LX\n", cpb->FrameAddr));\r
a3c5f87a 192\r
193 (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);\r
194\r
195 DEBUG ((EFI_D_NET, "\nexit snp->undi.transmit() "));\r
196 DEBUG ((EFI_D_NET, "\nsnp->cdb.StatCode == %r", snp->cdb.StatCode));\r
197\r
198 //\r
199 // we will unmap the buffers in get_status call, not here\r
200 //\r
201 switch (snp->cdb.StatCode) {\r
202 case PXE_STATCODE_SUCCESS:\r
203 return EFI_SUCCESS;\r
204\r
205 case PXE_STATCODE_QUEUE_FULL:\r
206 case PXE_STATCODE_BUSY:\r
207 Status = EFI_NOT_READY;\r
208 break;\r
209\r
210 default:\r
211 Status = EFI_DEVICE_ERROR;\r
212 }\r
213\r
214 DEBUG (\r
215 (EFI_D_ERROR,\r
216 "\nsnp->undi.transmit() %xh:%xh\n",\r
217 snp->cdb.StatFlags,\r
218 snp->cdb.StatCode)\r
219 );\r
220\r
221 return Status;\r
222}\r
223\r
224\r
225/**\r
226 This is the snp interface routine for transmitting a packet. this routine\r
227 basically retrieves the snp structure, checks the snp state and calls\r
228 pxe_fill_header and pxe_transmit calls to complete the transmission.\r
229\r
230 @param this pointer to SNP driver context\r
231 @param MacHeaderSize size of the memory at MacHeaderPtr\r
232 @param BufferLength Size of data in the BufferPtr\r
233 @param BufferPtr data buffer pointer\r
234 @param SourceAddrPtr address of the source mac address buffer\r
235 @param DestinationAddrPtr address of the destination mac address buffer\r
236 @param ProtocolPtr address of the protocol type\r
237\r
238 @retval EFI_SUCCESS if successfully completed the undi call\r
239 @retval Other error return from undi call.\r
240\r
241**/\r
242EFI_STATUS\r
243EFIAPI\r
244snp_undi32_transmit (\r
245 IN EFI_SIMPLE_NETWORK_PROTOCOL * this,\r
246 IN UINTN MacHeaderSize,\r
247 IN UINTN BufferLength,\r
248 IN VOID *BufferPtr,\r
249 IN EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,\r
250 IN EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,\r
251 IN UINT16 *ProtocolPtr OPTIONAL\r
252 )\r
253{\r
254 SNP_DRIVER *snp;\r
255 EFI_STATUS Status;\r
256 EFI_TPL OldTpl;\r
257\r
258 if (this == NULL) {\r
259 return EFI_INVALID_PARAMETER;\r
260 }\r
261\r
262 snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);\r
263\r
264 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
265\r
266 if (snp == NULL) {\r
267 return EFI_DEVICE_ERROR;\r
268 }\r
269\r
270 switch (snp->mode.State) {\r
271 case EfiSimpleNetworkInitialized:\r
272 break;\r
273\r
274 case EfiSimpleNetworkStopped:\r
275 Status = EFI_NOT_STARTED;\r
276 goto ON_EXIT;\r
277\r
278 default:\r
279 Status = EFI_DEVICE_ERROR;\r
280 goto ON_EXIT;\r
281 }\r
282\r
283 if (BufferPtr == NULL) {\r
284 Status = EFI_INVALID_PARAMETER;\r
285 goto ON_EXIT;\r
286 }\r
287\r
288 if (BufferLength < snp->mode.MediaHeaderSize) {\r
289 Status = EFI_BUFFER_TOO_SMALL;\r
290 goto ON_EXIT;\r
291 }\r
292\r
293 //\r
294 // if the MacHeaderSize is non-zero, we need to fill up the header and for that\r
295 // we need the destination address and the protocol\r
296 //\r
297 if (MacHeaderSize != 0) {\r
298 if (MacHeaderSize != snp->mode.MediaHeaderSize || DestinationAddrPtr == 0 || ProtocolPtr == 0) {\r
299 Status = EFI_INVALID_PARAMETER;\r
300 goto ON_EXIT;\r
301 }\r
302\r
303 Status = pxe_fillheader (\r
304 snp,\r
305 BufferPtr,\r
306 MacHeaderSize,\r
307 (UINT8 *) BufferPtr + MacHeaderSize,\r
308 BufferLength - MacHeaderSize,\r
309 DestinationAddrPtr,\r
310 SourceAddrPtr,\r
311 ProtocolPtr\r
312 );\r
313\r
314 if (EFI_ERROR (Status)) {\r
315 goto ON_EXIT;\r
316 }\r
317 }\r
318\r
319 Status = pxe_transmit (snp, BufferPtr, BufferLength);\r
320\r
321ON_EXIT:\r
322 gBS->RestoreTPL (OldTpl);\r
323\r
324 return Status;\r
325}\r