]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Universal/Network/Snp32_64/Dxe/transmit.c
Make variable names for protocol GUIDs consistent
[mirror_edk2.git] / EdkModulePkg / Universal / Network / Snp32_64 / Dxe / transmit.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 \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
24EFI_STATUS\r
25pxe_fillheader (\r
26 SNP_DRIVER *snp,\r
27 VOID *MacHeaderPtr,\r
28 UINTN MacHeaderSize,\r
29 VOID *BufferPtr,\r
30 UINTN BufferLength,\r
31 EFI_MAC_ADDRESS *DestinationAddrPtr,\r
32 EFI_MAC_ADDRESS *SourceAddrPtr,\r
33 UINT16 *ProtocolPtr\r
34 )\r
35/*++\r
36\r
37Routine Description:\r
38 This routine calls undi to create the meadia header for the given data buffer.\r
39 \r
40Arguments:\r
41 snp - pointer to SNP driver structure\r
42 MacHeaderPtr - address where the media header will be filled in.\r
43 MacHeaderSize - size of the memory at MacHeaderPtr\r
44 BufferPtr - data buffer pointer\r
45 BufferLength - Size of data in the BufferPtr\r
46 DestinationAddrPtr - address of the destination mac address buffer\r
47 SourceAddrPtr - address of the source mac address buffer\r
48 ProtocolPtr - address of the protocol type\r
49 \r
50Returns:\r
51 EFI_SUCCESS - if successfully completed the undi call\r
52 Other - error return from undi call.\r
53 \r
54--*/\r
55{\r
56 PXE_CPB_FILL_HEADER_FRAGMENTED *cpb;\r
57 EFI_STATUS Status;\r
58 struct s_v2p *pkt_v2p;\r
59 UINT64 TempData;\r
60\r
61 cpb = snp->cpb;\r
62 if (SourceAddrPtr) {\r
63 CopyMem (\r
64 (VOID *) cpb->SrcAddr,\r
65 (VOID *) SourceAddrPtr,\r
66 snp->mode.HwAddressSize\r
67 );\r
68 } else {\r
69 CopyMem (\r
70 (VOID *) cpb->SrcAddr,\r
71 (VOID *) &(snp->mode.CurrentAddress),\r
72 snp->mode.HwAddressSize\r
73 );\r
74 }\r
75\r
76 CopyMem (\r
77 (VOID *) cpb->DestAddr,\r
78 (VOID *) DestinationAddrPtr,\r
79 snp->mode.HwAddressSize\r
80 );\r
81\r
82 //\r
83 // we need to do the byte swapping\r
84 //\r
85 cpb->Protocol = (UINT16) PXE_SWAP_UINT16 (*ProtocolPtr);\r
86\r
87 cpb->PacketLen = (UINT32) (BufferLength);\r
88 cpb->MediaHeaderLen = (UINT16) MacHeaderSize;\r
89\r
90 cpb->FragCnt = 2;\r
91 cpb->reserved = 0;\r
92\r
93 cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) MacHeaderPtr;\r
94 cpb->FragDesc[0].FragLen = (UINT32) MacHeaderSize;\r
95 cpb->FragDesc[1].FragAddr = (UINT64) (UINTN) BufferPtr;\r
96 cpb->FragDesc[1].FragLen = (UINT32) BufferLength;\r
97\r
98 cpb->FragDesc[0].reserved = cpb->FragDesc[1].reserved = 0;\r
99\r
100 if (snp->IsOldUndi) {\r
101 TempData = (UINT64) (UINTN) MacHeaderPtr;\r
102 if (TempData >= FOUR_GIGABYTES) {\r
103 cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) snp->fill_hdr_buf;\r
104 cpb->FragDesc[0].FragLen = (UINT32) snp->init_info.MediaHeaderLen;\r
105 }\r
106\r
107 TempData = (UINT64) (UINTN) (BufferPtr);\r
108 if (TempData >= FOUR_GIGABYTES) {\r
109 //\r
110 // Let the device just read this buffer\r
111 //\r
112 Status = add_v2p (\r
113 &pkt_v2p,\r
114 EfiPciIoOperationBusMasterRead,\r
115 BufferPtr,\r
116 BufferLength\r
117 );\r
118 if (Status != EFI_SUCCESS) {\r
119 return Status;\r
120 }\r
121 //\r
122 // give the virtual address to UNDI and it will call back on Virt2Phys\r
123 // to get the mapped address, if it needs it\r
124 //\r
125 cpb->FragDesc[1].FragLen = (UINT32) pkt_v2p->bsize;\r
126 }\r
127 }\r
128\r
129 snp->cdb.OpCode = PXE_OPCODE_FILL_HEADER;\r
130 snp->cdb.OpFlags = PXE_OPFLAGS_FILL_HEADER_FRAGMENTED;\r
131\r
132 snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;\r
133 snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;\r
134\r
135 snp->cdb.CPBsize = sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED);\r
136 snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;\r
137\r
138 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
139 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
140 snp->cdb.IFnum = snp->if_num;\r
141 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
142\r
143 //\r
144 // Issue UNDI command and check result.\r
145 //\r
146 DEBUG ((EFI_D_NET, "\nsnp->undi.fill_header() "));\r
147\r
148 (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);\r
149\r
150 if (snp->IsOldUndi) {\r
151 TempData = (UINT64) (UINTN) (BufferPtr);\r
152 if (TempData >= FOUR_GIGABYTES) {\r
153 del_v2p (BufferPtr);\r
154 }\r
155 //\r
156 // if we used the global buffer for header, copy the contents\r
157 //\r
158 TempData = (UINT64) (UINTN) MacHeaderPtr;\r
159 if (TempData >= FOUR_GIGABYTES) {\r
160 CopyMem (\r
161 MacHeaderPtr,\r
162 snp->fill_hdr_buf,\r
163 snp->init_info.MediaHeaderLen\r
164 );\r
165 }\r
166 }\r
167\r
168 switch (snp->cdb.StatCode) {\r
169 case PXE_STATCODE_SUCCESS:\r
170 return EFI_SUCCESS;\r
171\r
172 case PXE_STATCODE_INVALID_PARAMETER:\r
173 DEBUG (\r
174 (EFI_D_ERROR,\r
175 "\nsnp->undi.fill_header() %xh:%xh\n",\r
176 snp->cdb.StatFlags,\r
177 snp->cdb.StatCode)\r
178 );\r
179\r
180 return EFI_INVALID_PARAMETER;\r
181\r
182 default:\r
183 DEBUG (\r
184 (EFI_D_ERROR,\r
185 "\nsnp->undi.fill_header() %xh:%xh\n",\r
186 snp->cdb.StatFlags,\r
187 snp->cdb.StatCode)\r
188 );\r
189\r
190 return EFI_DEVICE_ERROR;\r
191 }\r
192}\r
193\r
194EFI_STATUS\r
195pxe_transmit (\r
196 SNP_DRIVER *snp,\r
197 VOID *BufferPtr,\r
198 UINTN BufferLength\r
199 )\r
200/*++\r
201\r
202Routine Description:\r
203 This routine calls undi to transmit the given data buffer\r
204 \r
205Arguments:\r
206 snp - pointer to SNP driver structure\r
207 BufferPtr - data buffer pointer\r
208 BufferLength - Size of data in the BufferPtr\r
209 \r
210Returns:\r
211 EFI_SUCCESS - if successfully completed the undi call\r
212 Other - error return from undi call.\r
213 \r
214--*/\r
215{\r
216 PXE_CPB_TRANSMIT *cpb;\r
217 EFI_STATUS Status;\r
218 struct s_v2p *v2p;\r
219 UINT64 TempData;\r
220\r
221 cpb = snp->cpb;\r
222 cpb->FrameAddr = (UINT64) (UINTN) BufferPtr;\r
223 cpb->DataLen = (UINT32) BufferLength;\r
224 \r
225 TempData = (UINT64) (UINTN) BufferPtr;\r
226 if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {\r
227 //\r
228 // we need to create a mapping now and give it to the undi when it calls\r
229 // the Virt2Phys on this address.\r
230 // this is a transmit, just map it for the device to READ\r
231 //\r
232 Status = add_v2p (\r
233 &v2p,\r
234 EfiPciIoOperationBusMasterRead,\r
235 BufferPtr,\r
236 BufferLength\r
237 );\r
238 if (Status != EFI_SUCCESS) {\r
239 return Status;\r
240 }\r
241\r
242 cpb->DataLen = (UINT32) v2p->bsize;\r
243 }\r
244\r
245 cpb->MediaheaderLen = 0;\r
246 cpb->reserved = 0;\r
247\r
248 snp->cdb.OpFlags = PXE_OPFLAGS_TRANSMIT_WHOLE;\r
249\r
250 snp->cdb.CPBsize = sizeof (PXE_CPB_TRANSMIT);\r
251 snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;\r
252\r
253 snp->cdb.OpCode = PXE_OPCODE_TRANSMIT;\r
254 snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;\r
255 snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;\r
256\r
257 snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
258 snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
259 snp->cdb.IFnum = snp->if_num;\r
260 snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
261\r
262 //\r
263 // Issue UNDI command and check result.\r
264 //\r
265 DEBUG ((EFI_D_NET, "\nsnp->undi.transmit() "));\r
266 DEBUG ((EFI_D_NET, "\nsnp->cdb.OpCode == %x", snp->cdb.OpCode));\r
267 DEBUG ((EFI_D_NET, "\nsnp->cdb.CPBaddr == %X", snp->cdb.CPBaddr));\r
268 DEBUG ((EFI_D_NET, "\nsnp->cdb.DBaddr == %X", snp->cdb.DBaddr));\r
269 DEBUG ((EFI_D_NET, "\ncpb->FrameAddr == %X\n", cpb->FrameAddr));\r
270\r
271 (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);\r
272\r
273 DEBUG ((EFI_D_NET, "\nexit snp->undi.transmit() "));\r
274 DEBUG ((EFI_D_NET, "\nsnp->cdb.StatCode == %r", snp->cdb.StatCode));\r
275\r
276 //\r
277 // we will unmap the buffers in get_status call, not here\r
278 //\r
279 switch (snp->cdb.StatCode) {\r
280 case PXE_STATCODE_SUCCESS:\r
281 return EFI_SUCCESS;\r
282\r
283 case PXE_STATCODE_QUEUE_FULL:\r
284 case PXE_STATCODE_BUSY:\r
285 Status = EFI_NOT_READY;\r
286 break;\r
287\r
288 default:\r
289 Status = EFI_DEVICE_ERROR;\r
290 }\r
291\r
292 DEBUG (\r
293 (EFI_D_ERROR,\r
294 "\nsnp->undi.transmit() %xh:%xh\n",\r
295 snp->cdb.StatFlags,\r
296 snp->cdb.StatCode)\r
297 );\r
298\r
299 return Status;\r
300}\r
301\r
302EFI_STATUS\r
303EFIAPI\r
304snp_undi32_transmit (\r
305 IN EFI_SIMPLE_NETWORK_PROTOCOL * this,\r
306 IN UINTN MacHeaderSize,\r
307 IN UINTN BufferLength,\r
308 IN VOID *BufferPtr,\r
309 IN EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,\r
310 IN EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,\r
311 IN UINT16 *ProtocolPtr OPTIONAL\r
312 )\r
313/*++\r
314\r
315Routine Description:\r
316 This is the snp interface routine for transmitting a packet. this routine \r
317 basically retrieves the snp structure, checks the snp state and calls\r
318 pxe_fill_header and pxe_transmit calls to complete the transmission.\r
319 \r
320Arguments:\r
321 this - pointer to SNP driver context\r
322 MacHeaderSize - size of the memory at MacHeaderPtr\r
323 BufferLength - Size of data in the BufferPtr\r
324 BufferPtr - data buffer pointer\r
325 SourceAddrPtr - address of the source mac address buffer\r
326 DestinationAddrPtr - address of the destination mac address buffer\r
327 ProtocolPtr - address of the protocol type\r
328 \r
329Returns:\r
330 EFI_SUCCESS - if successfully completed the undi call\r
331 Other - error return from undi call.\r
332 \r
333--*/\r
334{\r
335 SNP_DRIVER *snp;\r
336 EFI_STATUS Status;\r
337\r
338 if (this == NULL) {\r
339 return EFI_INVALID_PARAMETER;\r
340 }\r
341\r
342 snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);\r
343\r
344 if (snp == NULL) {\r
345 return EFI_DEVICE_ERROR;\r
346 }\r
347\r
348 switch (snp->mode.State) {\r
349 case EfiSimpleNetworkInitialized:\r
350 break;\r
351\r
352 case EfiSimpleNetworkStopped:\r
353 return EFI_NOT_STARTED;\r
354\r
355 case EfiSimpleNetworkStarted:\r
356 return EFI_DEVICE_ERROR;\r
357\r
358 default:\r
359 return EFI_DEVICE_ERROR;\r
360 }\r
361\r
362 if (BufferPtr == NULL) {\r
363 return EFI_INVALID_PARAMETER;\r
364 }\r
365\r
366 if (BufferLength < snp->mode.MediaHeaderSize) {\r
367 return EFI_BUFFER_TOO_SMALL;\r
368 }\r
369\r
370 //\r
371 // if the MacHeaderSize is non-zero, we need to fill up the header and for that\r
372 // we need the destination address and the protocol\r
373 //\r
374 if (MacHeaderSize != 0) {\r
375 if (MacHeaderSize != snp->mode.MediaHeaderSize || DestinationAddrPtr == 0 || ProtocolPtr == 0) {\r
376 return EFI_INVALID_PARAMETER;\r
377 }\r
378\r
379 Status = pxe_fillheader (\r
380 snp,\r
381 BufferPtr,\r
382 MacHeaderSize,\r
383 (UINT8 *) BufferPtr + MacHeaderSize,\r
384 BufferLength - MacHeaderSize,\r
385 DestinationAddrPtr,\r
386 SourceAddrPtr,\r
387 ProtocolPtr\r
388 );\r
389\r
390 if (Status != EFI_SUCCESS) {\r
391 return Status;\r
392 }\r
393 }\r
394\r
395 return pxe_transmit (snp, BufferPtr, BufferLength);\r
396}\r