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