]> git.proxmox.com Git - mirror_edk2.git/blame - OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
OptionRomPkg: Fix typos in comments
[mirror_edk2.git] / OptionRomPkg / Bus / Usb / UsbNetworking / Ax88772b / SimpleNetwork.c
CommitLineData
7f556e4d 1/** @file\r
2 Provides the Simple Network functions.\r
3\r
97b67051 4 Copyright (c) 2011 - 2016, Intel Corporation\r
7f556e4d 5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "Ax88772.h"\r
16\r
17/**\r
18 This function updates the filtering on the receiver.\r
19\r
20 This support routine calls ::Ax88772MacAddressSet to update\r
21 the MAC address. This routine then rebuilds the multicast\r
22 hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.\r
23 Finally this routine enables the receiver by calling\r
24 ::Ax88772RxControl.\r
25 \r
26 @param [in] pSimpleNetwork Simple network mode pointer \r
27\r
28 @retval EFI_SUCCESS This operation was successful.\r
29 @retval EFI_NOT_STARTED The network interface was not started.\r
30 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
31 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
32 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
33 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
34\r
35**/\r
36EFI_STATUS\r
37ReceiveFilterUpdate (\r
38 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork\r
39 )\r
40{\r
41 EFI_SIMPLE_NETWORK_MODE * pMode;\r
42 NIC_DEVICE * pNicDevice;\r
43 EFI_STATUS Status;\r
44 UINT32 Index;\r
45\r
46 //\r
47 // Set the MAC address\r
48 //\r
49 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );\r
50 pMode = pSimpleNetwork->Mode;\r
51\r
52 //\r
53 // Clear the multicast hash table\r
54 //\r
55 Ax88772MulticastClear ( pNicDevice );\r
56\r
57 //\r
58 // Load the multicast hash table\r
59 //\r
60 if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {\r
61 for ( Index = 0; Index < pMode->MCastFilterCount; Index++ ) {\r
62 //\r
63 // Enable the next multicast address\r
64 //\r
65 Ax88772MulticastSet ( pNicDevice,\r
66 &pMode->MCastFilter[ Index ].Addr[0]);\r
67 }\r
68 }\r
69\r
70 Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );\r
71\r
72 return Status;\r
73}\r
74\r
75\r
76/**\r
77 This function updates the SNP driver status.\r
78 \r
79 This function gets the current interrupt and recycled transmit\r
80 buffer status from the network interface. The interrupt status\r
81 and the media status are returned as a bit mask in InterruptStatus.\r
82 If InterruptStatus is NULL, the interrupt status will not be read.\r
83 Upon successful return of the media status, the MediaPresent field\r
84 of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change\r
85 of media status. If TxBuf is not NULL, a recycled transmit buffer\r
86 address will be retrived. If a recycled transmit buffer address\r
87 is returned in TxBuf, then the buffer has been successfully\r
88 transmitted, and the status for that buffer is cleared.\r
89\r
90 This function calls ::Ax88772Rx to update the media status and\r
91 queue any receive packets.\r
92\r
93 @param [in] pSimpleNetwork Protocol instance pointer\r
94 @param [in] pInterruptStatus A pointer to the bit mask of the current active interrupts.\r
95 If this is NULL, the interrupt status will not be read from\r
96 the device. If this is not NULL, the interrupt status will\r
97 be read from teh device. When the interrupt status is read,\r
98 it will also be cleared. Clearing the transmit interrupt\r
99 does not empty the recycled transmit buffer array.\r
100 @param [out] ppTxBuf Recycled transmit buffer address. The network interface will\r
101 not transmit if its internal recycled transmit buffer array is\r
102 full. Reading the transmit buffer does not clear the transmit\r
103 interrupt. If this is NULL, then the transmit buffer status\r
104 will not be read. If there are not transmit buffers to recycle\r
105 and TxBuf is not NULL, *TxBuf will be set to NULL.\r
106\r
107 @retval EFI_SUCCESS This operation was successful.\r
108 @retval EFI_NOT_STARTED The network interface was not started.\r
109 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
110 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
111 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
112\r
113**/\r
114EFI_STATUS\r
115EFIAPI\r
116SN_GetStatus (\r
117 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
118 OUT UINT32 * pInterruptStatus,\r
119 OUT VOID ** ppTxBuf\r
120 )\r
121{\r
122 EFI_SIMPLE_NETWORK_MODE * pMode;\r
123 NIC_DEVICE * pNicDevice;\r
124 EFI_STATUS Status;\r
125 BOOLEAN bFullDuplex;\r
126 BOOLEAN bLinkUp;\r
127 BOOLEAN bSpeed100;\r
128 EFI_TPL TplPrevious;\r
129 \r
130 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);\r
131 //\r
132 // Verify the parameters\r
133 //\r
134 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {\r
135 //\r
136 // Return the transmit buffer\r
137 //\r
138 \r
139 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );\r
140 if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {\r
141 *ppTxBuf = pNicDevice->pTxBuffer;\r
142 pNicDevice->pTxBuffer = NULL;\r
143 }\r
144 \r
145 //\r
146 // Determine if interface is running\r
147 //\r
148 pMode = pSimpleNetwork->Mode;\r
149 if ( EfiSimpleNetworkInitialized == pMode->State ) {\r
150\r
151 if ( pNicDevice->LinkIdleCnt > MAX_LINKIDLE_THRESHOLD) {\r
152\r
153 bLinkUp = pNicDevice->bLinkUp;\r
154 bSpeed100 = pNicDevice->b100Mbps;\r
155 bFullDuplex = pNicDevice->bFullDuplex;\r
156 Status = Ax88772NegotiateLinkComplete ( pNicDevice,\r
157 &pNicDevice->PollCount,\r
158 &pNicDevice->bComplete,\r
159 &pNicDevice->bLinkUp,\r
160 &pNicDevice->b100Mbps,\r
161 &pNicDevice->bFullDuplex );\r
162\r
163 //\r
164 // Determine if the autonegotiation is complete\r
165 //\r
166 if ( pNicDevice->bComplete ) {\r
167 if ( pNicDevice->bLinkUp ) {\r
168 if (( bSpeed100 && ( !pNicDevice->b100Mbps ))\r
169 || (( !bSpeed100 ) && pNicDevice->b100Mbps )\r
170 || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))\r
171 || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {\r
172 pNicDevice->PollCount = 0;\r
173 DEBUG (( EFI_D_INFO , "Reset to establish proper link setup: %d Mbps, %a duplex\r\n",\r
174 pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));\r
175 Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );\r
176 }\r
177 if (( !bLinkUp ) && pNicDevice->bLinkUp ) {\r
178 //\r
179 // Display the autonegotiation status\r
180 //\r
181 DEBUG (( EFI_D_INFO , "Link: Up, %d Mbps, %a duplex\r\n",\r
182 pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));\r
183\r
184 }\r
185 pNicDevice->LinkIdleCnt = 0;\r
186 }\r
187 }\r
188 //\r
189 // Update the link status\r
190 //\r
191 if ( bLinkUp && ( !pNicDevice->bLinkUp )) {\r
192 DEBUG (( EFI_D_INFO , "Link: Down\r\n"));\r
193 }\r
194 }\r
195\r
196 pMode->MediaPresent = pNicDevice->bLinkUp;\r
197 //\r
198 // Return the interrupt status\r
199 //\r
200 if ( NULL != pInterruptStatus ) {\r
201 *pInterruptStatus = 0;\r
202 } \r
203 Status = EFI_SUCCESS;\r
204 }\r
205 else {\r
4986bbaf
YP
206 if ( EfiSimpleNetworkStarted == pMode->State ) {\r
207 Status = EFI_DEVICE_ERROR;\r
208 }\r
209 else {\r
210 Status = EFI_NOT_STARTED;\r
211 }\r
7f556e4d 212 }\r
213 \r
214 }\r
215 else {\r
216 Status = EFI_INVALID_PARAMETER;\r
217 }\r
218 gBS->RestoreTPL(TplPrevious) ;\r
219\r
220 return Status;\r
221}\r
222\r
223\r
224/**\r
225 Resets the network adapter and allocates the transmit and receive buffers\r
226 required by the network interface; optionally, also requests allocation of\r
227 additional transmit and receive buffers. This routine must be called before\r
228 any other routine in the Simple Network protocol is called.\r
229\r
230 @param [in] pSimpleNetwork Protocol instance pointer\r
231 @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation\r
232 @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation\r
233\r
234 @retval EFI_SUCCESS This operation was successful.\r
235 @retval EFI_NOT_STARTED The network interface was not started.\r
97b67051 236 @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and receive buffers\r
7f556e4d 237 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
238 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
239 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
240 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
241\r
242**/\r
243EFI_STATUS\r
244EFIAPI\r
245SN_Initialize ( \r
246 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
247 IN UINTN ExtraRxBufferSize,\r
248 IN UINTN ExtraTxBufferSize\r
249 )\r
250{\r
251 EFI_SIMPLE_NETWORK_MODE * pMode;\r
252 EFI_STATUS Status;\r
253 UINT32 TmpState;\r
254 EFI_TPL TplPrevious;\r
255 \r
256 TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);\r
257 //\r
258 // Verify the parameters\r
259 //\r
260 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {\r
261 //\r
262 // Determine if the interface is already started\r
263 //\r
264 pMode = pSimpleNetwork->Mode;\r
265 if ( EfiSimpleNetworkStarted == pMode->State ) {\r
266 if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {\r
267 //\r
268 // Start the adapter\r
269 //\r
270 TmpState = pMode->State;\r
271 pMode->State = EfiSimpleNetworkInitialized;\r
272 Status = SN_Reset ( pSimpleNetwork, FALSE );\r
273 if ( EFI_ERROR ( Status )) {\r
274 //\r
275 // Update the network state\r
276 //\r
277 pMode->State = TmpState;\r
278 DEBUG (( EFI_D_ERROR , "SN_reset failed\n"));\r
279 }\r
280 }\r
281 else {\r
282 DEBUG (( EFI_D_ERROR , "Increase ExtraRxBufferSize = %d ExtraTxBufferSize=%d\n", \r
283 ExtraRxBufferSize, ExtraTxBufferSize));\r
284 Status = EFI_UNSUPPORTED;\r
285 }\r
286 }\r
287 else {\r
288 Status = EFI_NOT_STARTED;\r
289 }\r
290 }\r
291 else {\r
292 Status = EFI_INVALID_PARAMETER;\r
293 }\r
294 gBS->RestoreTPL (TplPrevious);\r
295\r
296 return Status;\r
297}\r
298\r
299\r
300/**\r
301 This function converts a multicast IP address to a multicast HW MAC address\r
302 for all packet transactions.\r
303\r
304 @param [in] pSimpleNetwork Protocol instance pointer\r
305 @param [in] bIPv6 Set to TRUE if the multicast IP address is IPv6 [RFC2460].\r
306 Set to FALSE if the multicast IP address is IPv4 [RFC 791].\r
307 @param [in] pIP The multicast IP address that is to be converted to a\r
308 multicast HW MAC address.\r
309 @param [in] pMAC The multicast HW MAC address that is to be generated from IP.\r
310\r
311 @retval EFI_SUCCESS This operation was successful.\r
312 @retval EFI_NOT_STARTED The network interface was not started.\r
313 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
314 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
315 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
316 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
317\r
318**/\r
319EFI_STATUS\r
320EFIAPI\r
321SN_MCastIPtoMAC (\r
322 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
323 IN BOOLEAN bIPv6,\r
324 IN EFI_IP_ADDRESS * pIP,\r
4986bbaf 325 OUT EFI_MAC_ADDRESS * pMAC\r
7f556e4d 326 )\r
327{\r
328 EFI_STATUS Status;\r
329 EFI_TPL TplPrevious;\r
330\r
331 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);\r
332 //\r
333 // Get pointer to SNP driver instance for *this.\r
334 //\r
335 if (pSimpleNetwork == NULL) {\r
336 gBS->RestoreTPL(TplPrevious);\r
337 return EFI_INVALID_PARAMETER;\r
338 }\r
339\r
340 if (pIP == NULL || pMAC == NULL) {\r
341 gBS->RestoreTPL(TplPrevious);\r
342 return EFI_INVALID_PARAMETER;\r
343 }\r
344\r
345 if (bIPv6){\r
346 Status = EFI_UNSUPPORTED;\r
347 } \r
348 else {\r
349 //\r
350 // check if the ip given is a mcast IP\r
351 //\r
352 if ((pIP->v4.Addr[0] & 0xF0) != 0xE0) {\r
353 gBS->RestoreTPL(TplPrevious);\r
354 return EFI_INVALID_PARAMETER;\r
355 }\r
356 else {\r
4986bbaf
YP
357 if (pSimpleNetwork->Mode->State == EfiSimpleNetworkInitialized)\r
358 {\r
359 pMAC->Addr[0] = 0x01;\r
360 pMAC->Addr[1] = 0x00;\r
361 pMAC->Addr[2] = 0x5e;\r
362 pMAC->Addr[3] = (UINT8) (pIP->v4.Addr[1] & 0x7f);\r
363 pMAC->Addr[4] = (UINT8) pIP->v4.Addr[2];\r
364 pMAC->Addr[5] = (UINT8) pIP->v4.Addr[3];\r
365 Status = EFI_SUCCESS;\r
366 }\r
367 else if (pSimpleNetwork->Mode->State == EfiSimpleNetworkStarted) {\r
368 Status = EFI_DEVICE_ERROR;\r
369 }\r
370 else {\r
371 Status = EFI_NOT_STARTED;\r
372 }\r
7f556e4d 373 gBS->RestoreTPL(TplPrevious);\r
374 }\r
375 }\r
376 return Status;\r
377}\r
378\r
379\r
380/**\r
381 This function performs read and write operations on the NVRAM device\r
382 attached to a network interface.\r
383\r
384 @param [in] pSimpleNetwork Protocol instance pointer\r
385 @param [in] ReadWrite TRUE for read operations, FALSE for write operations.\r
386 @param [in] Offset Byte offset in the NVRAM device at which to start the\r
387 read or write operation. This must be a multiple of\r
388 NvRamAccessSize and less than NvRamSize.\r
389 @param [in] BufferSize The number of bytes to read or write from the NVRAM device.\r
390 This must also be a multiple of NvramAccessSize.\r
391 @param [in, out] pBuffer A pointer to the data buffer.\r
392\r
393 @retval EFI_SUCCESS This operation was successful.\r
394 @retval EFI_NOT_STARTED The network interface was not started.\r
395 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
396 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
397 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
398 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
399\r
400**/\r
401EFI_STATUS\r
402EFIAPI\r
403SN_NvData (\r
404 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
405 IN BOOLEAN ReadWrite,\r
406 IN UINTN Offset,\r
407 IN UINTN BufferSize,\r
408 IN OUT VOID * pBuffer\r
409 )\r
410{\r
411 EFI_STATUS Status;\r
412 //\r
413 // This is not currently supported\r
414 //\r
415 Status = EFI_UNSUPPORTED;\r
416 return Status;\r
417}\r
418\r
419VOID \r
420FillPkt2Queue (\r
421 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
422 IN UINTN BufLength)\r
423{\r
424\r
425 UINT16 * pLength;\r
426 UINT16 * pLengthBar;\r
427 UINT8* pData;\r
428 UINT32 offset;\r
429 NIC_DEVICE * pNicDevice;\r
430 \r
431 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork);\r
432 for ( offset = 0; offset < BufLength; ){\r
433 pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);\r
434 pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);\r
435 \r
436 *pLength &= 0x7ff;\r
437 *pLengthBar &= 0x7ff;\r
438 *pLengthBar |= 0xf800;\r
439 \r
440 if ((*pLength ^ *pLengthBar ) != 0xFFFF) {\r
441 DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n", BufLength));\r
442 return;\r
443 } \r
444 \r
445 if (TRUE == pNicDevice->pNextFill->f_Used) {\r
446 return;\r
447 }\r
448 else {\r
449 pData = pNicDevice->pBulkInBuff + offset + 4;\r
450 pNicDevice->pNextFill->f_Used = TRUE;\r
451 pNicDevice->pNextFill->Length = *pLength;\r
452 CopyMem (&pNicDevice->pNextFill->Data[0], pData, *pLength);\r
453 \r
454 pNicDevice->pNextFill = pNicDevice->pNextFill->pNext;\r
455 offset += ((*pLength + HW_HDR_LENGTH - 1) &~3) + 1;\r
456 pNicDevice->PktCntInQueue++;\r
457 }\r
458 \r
459 }\r
460}\r
461\r
462EFI_STATUS\r
463EFIAPI\r
464SN_Receive (\r
465 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
466 OUT UINTN * pHeaderSize,\r
467 OUT UINTN * pBufferSize,\r
468 OUT VOID * pBuffer,\r
469 OUT EFI_MAC_ADDRESS * pSrcAddr,\r
470 OUT EFI_MAC_ADDRESS * pDestAddr,\r
471 OUT UINT16 * pProtocol\r
472 )\r
473{\r
474 EFI_SIMPLE_NETWORK_MODE * pMode;\r
475 NIC_DEVICE * pNicDevice;\r
476 EFI_STATUS Status;\r
477 EFI_TPL TplPrevious;\r
478 UINT16 Type;\r
479 EFI_USB_IO_PROTOCOL *pUsbIo;\r
480 UINTN LengthInBytes;\r
481 UINT32 TransferStatus;\r
482 RX_PKT * pFirstFill;\r
483 TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);\r
484 \r
485 //\r
486 // Verify the parameters\r
487 //\r
4986bbaf
YP
488 if (( NULL != pSimpleNetwork ) && \r
489 ( NULL != pSimpleNetwork->Mode ) && \r
490 (NULL != pBufferSize) && \r
491 (NULL != pBuffer)) {\r
7f556e4d 492 //\r
493 // The interface must be running\r
494 //\r
495 pMode = pSimpleNetwork->Mode;\r
496 if ( EfiSimpleNetworkInitialized == pMode->State ) {\r
497 //\r
498 // Update the link status\r
499 //\r
500 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );\r
501 pNicDevice->LinkIdleCnt++;\r
502 pMode->MediaPresent = pNicDevice->bLinkUp;\r
503 \r
504 if ( pMode->MediaPresent && pNicDevice->bComplete) {\r
505 \r
506 \r
507 if (pNicDevice->PktCntInQueue != 0 ) {\r
508 DEBUG (( EFI_D_INFO, "pNicDevice->PktCntInQueue = %d\n",\r
509 pNicDevice->PktCntInQueue));\r
510 }\r
511 \r
512 LengthInBytes = MAX_BULKIN_SIZE;\r
513 if (pNicDevice->PktCntInQueue == 0 ){\r
514 //\r
515 // Attempt to do bulk in\r
516 //\r
517 SetMem (&pNicDevice->pBulkInBuff[0], 4, 0);\r
518 pUsbIo = pNicDevice->pUsbIo;\r
519 Status = pUsbIo->UsbBulkTransfer ( pUsbIo,\r
520 USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,\r
521 &pNicDevice->pBulkInBuff[0],\r
522 &LengthInBytes,\r
523 BULKIN_TIMEOUT,\r
524 &TransferStatus );\r
525 \r
526 if (LengthInBytes != 0 && !EFI_ERROR(Status) && !EFI_ERROR(TransferStatus) ){\r
527 FillPkt2Queue(pSimpleNetwork, LengthInBytes);\r
528 }\r
529 }\r
530 \r
531 pFirstFill = pNicDevice->pFirstFill;\r
532 \r
533 if (TRUE == pFirstFill->f_Used) {\r
534 ETHERNET_HEADER * pHeader;\r
535 pNicDevice->LinkIdleCnt = 0;\r
536 CopyMem (pBuffer, &pFirstFill->Data[0], pFirstFill->Length);\r
537 pHeader = (ETHERNET_HEADER *) &pFirstFill->Data[0];\r
538 \r
539 DEBUG (( EFI_D_INFO, "RX: %02x-%02x-%02x-%02x-%02x-%02x " \r
540 "%02x-%02x-%02x-%02x-%02x-%02x %02x-%02x %d bytes\r\n",\r
541 pFirstFill->Data[0],\r
542 pFirstFill->Data[1],\r
543 pFirstFill->Data[2],\r
544 pFirstFill->Data[3],\r
545 pFirstFill->Data[4],\r
546 pFirstFill->Data[5],\r
547 pFirstFill->Data[6],\r
548 pFirstFill->Data[7],\r
549 pFirstFill->Data[8],\r
550 pFirstFill->Data[9],\r
551 pFirstFill->Data[10],\r
552 pFirstFill->Data[11],\r
553 pFirstFill->Data[12],\r
554 pFirstFill->Data[13],\r
555 pFirstFill->Length)); \r
556 \r
557 if ( NULL != pHeaderSize ) {\r
558 *pHeaderSize = sizeof ( *pHeader );\r
559 }\r
560 if ( NULL != pDestAddr ) {\r
561 CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );\r
562 }\r
563 if ( NULL != pSrcAddr ) {\r
564 CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );\r
565 }\r
566 if ( NULL != pProtocol ) {\r
567 Type = pHeader->type;\r
568 Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));\r
569 *pProtocol = Type;\r
570 }\r
571 Status = EFI_SUCCESS;\r
572 if (*pBufferSize < pFirstFill->Length) {\r
573 DEBUG (( EFI_D_ERROR, "RX: Buffer was too small"));\r
574 Status = EFI_BUFFER_TOO_SMALL;\r
575 }\r
576 *pBufferSize = pFirstFill->Length;\r
577 pFirstFill->f_Used = FALSE;\r
578 pNicDevice->pFirstFill = pFirstFill->pNext;\r
579 pNicDevice->PktCntInQueue--;\r
580 }\r
581 else {\r
582 pNicDevice->LinkIdleCnt++;\r
583 Status = EFI_NOT_READY;\r
584 }\r
585 }\r
586 else {\r
587 //\r
588 // Link no up\r
589 //\r
590 pNicDevice->LinkIdleCnt++;\r
591 Status = EFI_NOT_READY; \r
592 }\r
593 \r
594 }\r
595 else {\r
4986bbaf
YP
596 if (EfiSimpleNetworkStarted == pMode->State) {\r
597 Status = EFI_DEVICE_ERROR;\r
598 }\r
599 else {\r
600 Status = EFI_NOT_STARTED;\r
601 }\r
7f556e4d 602 }\r
603 }\r
604 else {\r
605 Status = EFI_INVALID_PARAMETER;\r
606 } \r
607 gBS->RestoreTPL (TplPrevious);\r
608 return Status;\r
609}\r
610\r
611/**\r
612 This function is used to enable and disable the hardware and software receive\r
613 filters for the underlying network device.\r
614\r
615 The receive filter change is broken down into three steps:\r
616\r
617 1. The filter mask bits that are set (ON) in the Enable parameter\r
618 are added to the current receive filter settings.\r
619\r
620 2. The filter mask bits that are set (ON) in the Disable parameter\r
621 are subtracted from the updated receive filter settins.\r
622\r
623 3. If the resulting filter settigns is not supported by the hardware\r
624 a more liberal setting is selected.\r
625\r
626 If the same bits are set in the Enable and Disable parameters, then the bits\r
627 in the Disable parameter takes precedence.\r
628\r
629 If the ResetMCastFilter parameter is TRUE, then the multicast address list\r
630 filter is disabled (irregardless of what other multicast bits are set in\r
631 the enable and Disable parameters). The SNP->Mode->MCastFilterCount field\r
632 is set to zero. The SNP->Mode->MCastFilter contents are undefined.\r
633\r
634 After enableing or disabling receive filter settings, software should\r
635 verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,\r
636 SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.\r
637\r
638 Note: Some network drivers and/or devices will automatically promote\r
639 receive filter settings if the requested setting can not be honored.\r
640 For example, if a request for four multicast addresses is made and\r
641 the underlying hardware only supports two multicast addresses the\r
642 driver might set the promiscuous or promiscuous multicast receive filters\r
643 instead. The receiving software is responsible for discarding any extra\r
644 packets that get through the hardware receive filters.\r
645\r
646 If ResetMCastFilter is TRUE, then the multicast receive filter list\r
647 on the network interface will be reset to the default multicast receive\r
648 filter list. If ResetMCastFilter is FALSE, and this network interface\r
649 allows the multicast receive filter list to be modified, then the\r
650 MCastFilterCnt and MCastFilter are used to update the current multicast\r
651 receive filter list. The modified receive filter list settings can be\r
652 found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.\r
653\r
654 This routine calls ::ReceiveFilterUpdate to update the receive\r
655 state in the network adapter.\r
656\r
657 @param [in] pSimpleNetwork Protocol instance pointer\r
658 @param [in] Enable A bit mask of receive filters to enable on the network interface.\r
659 @param [in] Disable A bit mask of receive filters to disable on the network interface.\r
660 For backward compatibility with EFI 1.1 platforms, the\r
661 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set\r
662 when the ResetMCastFilter parameter is TRUE.\r
663 @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive\r
664 filters on the network interface to their default values.\r
665 @param [in] MCastFilterCnt Number of multicast HW MAC address in the new MCastFilter list.\r
666 This value must be less than or equal to the MaxMCastFilterCnt\r
667 field of EFI_SIMPLE_NETWORK_MODE. This field is optional if\r
668 ResetMCastFilter is TRUE.\r
669 @param [in] pMCastFilter A pointer to a list of new multicast receive filter HW MAC\r
670 addresses. This list will replace any existing multicast\r
671 HW MAC address list. This field is optional if ResetMCastFilter\r
672 is TRUE.\r
673\r
674 @retval EFI_SUCCESS This operation was successful.\r
675 @retval EFI_NOT_STARTED The network interface was not started.\r
676 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
677 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
678 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
679 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
680\r
681**/\r
682EFI_STATUS\r
683EFIAPI\r
684SN_ReceiveFilters (\r
685 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
686 IN UINT32 Enable,\r
687 IN UINT32 Disable,\r
688/*\r
689#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01\r
690#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02\r
691#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04\r
692#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08\r
693#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10\r
694*/\r
695 IN BOOLEAN bResetMCastFilter,\r
696 IN UINTN MCastFilterCnt,\r
697 IN EFI_MAC_ADDRESS * pMCastFilter\r
698 )\r
699{\r
700 EFI_SIMPLE_NETWORK_MODE * pMode;\r
701 EFI_STATUS Status = EFI_SUCCESS; \r
702 EFI_TPL TplPrevious; \r
7f556e4d 703\r
704 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);\r
7f556e4d 705 pMode = pSimpleNetwork->Mode;\r
706\r
707 if (pSimpleNetwork == NULL) {\r
708 gBS->RestoreTPL(TplPrevious);\r
709 return EFI_INVALID_PARAMETER;\r
710 }\r
711\r
712 switch (pMode->State) {\r
713 case EfiSimpleNetworkInitialized:\r
714 break;\r
715 case EfiSimpleNetworkStopped:\r
716 Status = EFI_NOT_STARTED;\r
717 gBS->RestoreTPL(TplPrevious);\r
718 return Status;\r
719 default:\r
720 Status = EFI_DEVICE_ERROR;\r
721 gBS->RestoreTPL(TplPrevious);\r
722 return Status;\r
723 }\r
724\r
725 //\r
726 // check if we are asked to enable or disable something that the UNDI\r
727 // does not even support!\r
728 //\r
729 if (((Enable &~pMode->ReceiveFilterMask) != 0) ||\r
730 ((Disable &~pMode->ReceiveFilterMask) != 0)) {\r
731 Status = EFI_INVALID_PARAMETER;\r
732 gBS->RestoreTPL(TplPrevious);\r
733 return Status;\r
734 }\r
735 \r
736 if (bResetMCastFilter) {\r
737 Disable |= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & pMode->ReceiveFilterMask);\r
738 pMode->MCastFilterCount = 0;\r
739 if ( (0 == (pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST)) \r
740 && Enable == 0 && Disable == 2) {\r
741 gBS->RestoreTPL(TplPrevious);\r
742 return EFI_SUCCESS;\r
743 }\r
744 } \r
745 else {\r
746 if (MCastFilterCnt != 0) {\r
747 UINTN i; \r
748 EFI_MAC_ADDRESS * pMulticastAddress;\r
749 pMulticastAddress = pMCastFilter;\r
750 \r
751 if ((MCastFilterCnt > pMode->MaxMCastFilterCount) ||\r
752 (pMCastFilter == NULL)) {\r
753 Status = EFI_INVALID_PARAMETER;\r
754 gBS->RestoreTPL(TplPrevious);\r
755 return Status;\r
756 }\r
757 \r
758 for ( i = 0 ; i < MCastFilterCnt ; i++ ) {\r
759 UINT8 tmp;\r
760 tmp = pMulticastAddress->Addr[0];\r
761 if ( (tmp & 0x01) != 0x01 ) {\r
762 gBS->RestoreTPL(TplPrevious);\r
763 return EFI_INVALID_PARAMETER;\r
764 }\r
765 pMulticastAddress++;\r
766 }\r
767 \r
768 pMode->MCastFilterCount = (UINT32)MCastFilterCnt;\r
769 CopyMem (&pMode->MCastFilter[0],\r
770 pMCastFilter,\r
771 MCastFilterCnt * sizeof ( EFI_MAC_ADDRESS));\r
772 }\r
773 }\r
774 \r
775 if (Enable == 0 && Disable == 0 && !bResetMCastFilter && MCastFilterCnt == 0) {\r
776 Status = EFI_SUCCESS;\r
777 gBS->RestoreTPL(TplPrevious);\r
778 return Status;\r
779 }\r
780\r
781 if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {\r
782 Status = EFI_INVALID_PARAMETER;\r
783 gBS->RestoreTPL(TplPrevious);\r
784 return Status;\r
785 }\r
786 \r
787 pMode->ReceiveFilterSetting |= Enable;\r
788 pMode->ReceiveFilterSetting &= ~Disable;\r
789 Status = ReceiveFilterUpdate (pSimpleNetwork);\r
790 \r
791 if (EFI_DEVICE_ERROR == Status || EFI_INVALID_PARAMETER == Status)\r
792 Status = EFI_SUCCESS;\r
793\r
794 gBS->RestoreTPL(TplPrevious);\r
795 return Status;\r
796}\r
797\r
798/**\r
799 Reset the network adapter.\r
800\r
801 Resets a network adapter and reinitializes it with the parameters that\r
802 were provided in the previous call to Initialize (). The transmit and\r
803 receive queues are cleared. Receive filters, the station address, the\r
804 statistics, and the multicast-IP-to-HW MAC addresses are not reset by\r
805 this call.\r
806\r
807 This routine calls ::Ax88772Reset to perform the adapter specific\r
808 reset operation. This routine also starts the link negotiation\r
809 by calling ::Ax88772NegotiateLinkStart.\r
810\r
811 @param [in] pSimpleNetwork Protocol instance pointer\r
812 @param [in] bExtendedVerification Indicates that the driver may perform a more\r
813 exhaustive verification operation of the device\r
814 during reset.\r
815\r
816 @retval EFI_SUCCESS This operation was successful.\r
817 @retval EFI_NOT_STARTED The network interface was not started.\r
818 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
819 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
820 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
821 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
822\r
823**/\r
824EFI_STATUS\r
825EFIAPI\r
826SN_Reset (\r
827 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
828 IN BOOLEAN bExtendedVerification\r
829 )\r
830{\r
831 EFI_SIMPLE_NETWORK_MODE * pMode;\r
832 NIC_DEVICE * pNicDevice;\r
833 EFI_STATUS Status;\r
834 EFI_TPL TplPrevious;\r
835\r
836 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);\r
837 //\r
838 // Verify the parameters\r
839 //\r
840 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {\r
841 pMode = pSimpleNetwork->Mode;\r
842 if ( EfiSimpleNetworkInitialized == pMode->State ) {\r
843 //\r
844 // Update the device state\r
845 //\r
846 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );\r
847 pNicDevice->bComplete = FALSE;\r
848 pNicDevice->bLinkUp = FALSE; \r
849 pNicDevice->bHavePkt = FALSE;\r
850 pMode = pSimpleNetwork->Mode;\r
851 pMode->MediaPresent = FALSE;\r
852\r
853 //\r
854 // Reset the device\r
855 //\r
856 Status = Ax88772Reset ( pNicDevice );\r
857 if ( !EFI_ERROR ( Status )) {\r
858 //\r
859 // Update the receive filters in the adapter\r
860 //\r
861 Status = ReceiveFilterUpdate ( pSimpleNetwork );\r
862\r
863 //\r
864 // Try to get a connection to the network\r
865 //\r
866 if ( !EFI_ERROR ( Status )) {\r
867 //\r
868 // Start the autonegotiation\r
869 //\r
870 Status = Ax88772NegotiateLinkStart ( pNicDevice );\r
871 }\r
872 }\r
873 }\r
874 else {\r
4986bbaf
YP
875 if (EfiSimpleNetworkStarted == pMode->State) {\r
876 Status = EFI_DEVICE_ERROR;\r
877 }\r
878 else {\r
879 Status = EFI_NOT_STARTED;\r
880 }\r
7f556e4d 881 } \r
882 }\r
883 else {\r
884 Status = EFI_INVALID_PARAMETER;\r
885 }\r
886 gBS->RestoreTPL ( TplPrevious );\r
887 return Status;\r
888}\r
889\r
890/**\r
891 Initialize the simple network protocol.\r
892\r
893 This routine calls ::Ax88772MacAddressGet to obtain the\r
894 MAC address.\r
895\r
896 @param [in] pNicDevice NIC_DEVICE_INSTANCE pointer\r
897\r
898 @retval EFI_SUCCESS Setup was successful\r
899\r
900**/\r
901EFI_STATUS\r
902SN_Setup (\r
903 IN NIC_DEVICE * pNicDevice\r
904 )\r
905{\r
906 \r
907\r
908 EFI_SIMPLE_NETWORK_MODE * pMode;\r
909 EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;\r
910 EFI_STATUS Status;\r
911 RX_PKT * pCurr = NULL;\r
912 RX_PKT * pPrev = NULL;\r
913\r
914 pSimpleNetwork = &pNicDevice->SimpleNetwork; \r
915 pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;\r
916 pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;\r
917 pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;\r
918 pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;\r
919 pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;\r
920 pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;\r
921 pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;\r
922 pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;\r
923 pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;\r
924 pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;\r
925 pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;\r
926 pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;\r
927 pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;\r
928 pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;\r
929 pSimpleNetwork->WaitForPacket = NULL;\r
930 pMode = &pNicDevice->SimpleNetworkData;\r
931 pSimpleNetwork->Mode = pMode;\r
932 pMode->State = EfiSimpleNetworkStopped;\r
933 pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;\r
934 pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );\r
935 pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;\r
936 pMode->NvRamSize = 0;\r
937 pMode->NvRamAccessSize = 0;\r
938 pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST\r
939 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST\r
940 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST\r
941 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS\r
942 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
943 pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST\r
944 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;\r
945 pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;\r
946 pMode->MCastFilterCount = 0;\r
947 SetMem ( &pMode->BroadcastAddress,\r
948 PXE_HWADDR_LEN_ETHER,\r
949 0xff );\r
950 pMode->IfType = EfiNetworkInterfaceUndi;\r
951 pMode->MacAddressChangeable = TRUE;\r
952 pMode->MultipleTxSupported = FALSE;\r
953 pMode->MediaPresentSupported = TRUE;\r
954 pMode->MediaPresent = FALSE;\r
955 pNicDevice->LinkIdleCnt = 0;\r
956 //\r
957 // Read the MAC address\r
958 //\r
959 pNicDevice->PhyId = PHY_ID_INTERNAL;\r
960 pNicDevice->b100Mbps = TRUE;\r
961 pNicDevice->bFullDuplex = TRUE;\r
962 \r
963 Status = Ax88772MacAddressGet (\r
964 pNicDevice,\r
965 &pMode->PermanentAddress.Addr[0]);\r
966\r
967 if ( !EFI_ERROR ( Status )) {\r
968 int i; \r
969 //\r
970 // Use the hardware address as the current address\r
971 //\r
972\r
973 CopyMem ( &pMode->CurrentAddress,\r
974 &pMode->PermanentAddress,\r
975 PXE_HWADDR_LEN_ETHER );\r
976 \r
977 CopyMem ( &pNicDevice->MAC,\r
978 &pMode->PermanentAddress,\r
979 PXE_HWADDR_LEN_ETHER );\r
980 \r
981 pNicDevice->PktCntInQueue = 0;\r
982 \r
983 for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {\r
984 Status = gBS->AllocatePool ( EfiRuntimeServicesData, \r
985 sizeof (RX_PKT),\r
986 (VOID **) &pCurr);\r
987 if ( EFI_ERROR(Status)) {\r
988 DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));\r
989 return Status;\r
990 } \r
991 pCurr->f_Used = FALSE;\r
992 \r
993 if ( i ) {\r
994 pPrev->pNext = pCurr;\r
995 }\r
996 else {\r
997 pNicDevice->QueueHead = pCurr;\r
998 }\r
999 \r
1000 if (MAX_QUEUE_SIZE - 1 == i) {\r
1001 pCurr->pNext = pNicDevice->QueueHead;\r
1002 }\r
1003 \r
1004 pPrev = pCurr;\r
1005 }\r
1006 \r
1007 pNicDevice->pNextFill = pNicDevice->QueueHead;\r
1008 pNicDevice->pFirstFill = pNicDevice->QueueHead;\r
1009 \r
1010 Status = gBS->AllocatePool (EfiRuntimeServicesData,\r
1011 MAX_BULKIN_SIZE,\r
1012 (VOID **) &pNicDevice->pBulkInBuff);\r
1013 \r
1014 if (EFI_ERROR(Status)) {\r
1015 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool for pBulkInBuff error. Status = %r\n",\r
1016 Status));\r
1017 return Status;\r
1018 }\r
1019 }\r
1020 else {\r
1021 DEBUG (( EFI_D_ERROR, "Ax88772MacAddressGet error. Status = %r\n", Status));\r
1022 return Status;\r
1023 }\r
1024 \r
1025 Status = gBS->AllocatePool ( EfiRuntimeServicesData,\r
1026 sizeof ( RX_TX_PACKET ),\r
1027 (VOID **) &pNicDevice->pRxTest );\r
1028\r
1029 if (EFI_ERROR (Status)) {\r
1030 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pRxTest error. Status = %r\n",\r
1031 Status));\r
1032 return Status;\r
1033 }\r
1034 \r
1035 Status = gBS->AllocatePool ( EfiRuntimeServicesData,\r
1036 sizeof ( RX_TX_PACKET ),\r
1037 (VOID **) &pNicDevice->pTxTest );\r
1038\r
1039 if (EFI_ERROR (Status)) {\r
1040 DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pTxTest error. Status = %r\n",\r
1041 Status));\r
1042 gBS->FreePool (pNicDevice->pRxTest);\r
1043 }\r
1044\r
1045 return Status;\r
1046}\r
1047\r
1048\r
1049/**\r
1050 This routine starts the network interface.\r
1051\r
1052 @param [in] pSimpleNetwork Protocol instance pointer\r
1053\r
1054 @retval EFI_SUCCESS This operation was successful.\r
1055 @retval EFI_ALREADY_STARTED The network interface was already started.\r
1056 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
1057 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1058 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
1059 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
1060\r
1061**/\r
1062EFI_STATUS\r
1063EFIAPI\r
1064SN_Start (\r
1065 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork\r
1066 )\r
1067{\r
1068 NIC_DEVICE * pNicDevice;\r
1069 EFI_SIMPLE_NETWORK_MODE * pMode;\r
1070 EFI_STATUS Status;\r
1071 EFI_TPL TplPrevious;\r
1072 int i = 0;\r
1073 RX_PKT * pCurr = NULL;\r
1074\r
1075 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);\r
1076 //\r
1077 // Verify the parameters\r
1078 //\r
1079 Status = EFI_INVALID_PARAMETER;\r
1080 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {\r
1081 pMode = pSimpleNetwork->Mode;\r
1082 if ( EfiSimpleNetworkStopped == pMode->State ) {\r
1083 //\r
1084 // Initialize the mode structuref\r
1085 // NVRAM access is not supported\r
1086 //\r
1087 ZeroMem ( pMode, sizeof ( *pMode ));\r
1088 \r
1089 pMode->State = EfiSimpleNetworkStarted;\r
1090 pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;\r
1091 pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );\r
1092 pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;\r
1093 pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST\r
1094 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST\r
1095 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST\r
1096 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS\r
1097 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
1098 pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;\r
1099 pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;\r
1100 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );\r
1101 Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);\r
1102 CopyMem ( &pMode->CurrentAddress,\r
1103 &pMode->PermanentAddress,\r
1104 sizeof ( pMode->CurrentAddress ));\r
1105 SetMem(&pMode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);\r
1106 pMode->IfType = EfiNetworkInterfaceUndi;\r
1107 pMode->MacAddressChangeable = TRUE;\r
1108 pMode->MultipleTxSupported = FALSE;\r
1109 pMode->MediaPresentSupported = TRUE;\r
1110 pMode->MediaPresent = FALSE; \r
1111 pNicDevice->PktCntInQueue = 0;\r
1112 pNicDevice->pNextFill = pNicDevice->QueueHead;\r
1113 pNicDevice->pFirstFill = pNicDevice->QueueHead;\r
1114 pCurr = pNicDevice->QueueHead;\r
1115 \r
1116 for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) { \r
1117 pCurr->f_Used = FALSE;\r
1118 pCurr = pCurr->pNext;\r
1119 }\r
1120 \r
1121 }\r
1122 else {\r
1123 Status = EFI_ALREADY_STARTED;\r
1124 }\r
1125 }\r
1126 gBS->RestoreTPL ( TplPrevious );\r
1127 return Status;\r
1128}\r
1129\r
1130\r
1131/**\r
1132 Set the MAC address.\r
1133 \r
1134 This function modifies or resets the current station address of a\r
1135 network interface. If Reset is TRUE, then the current station address\r
1136 is set ot the network interface's permanent address. If Reset if FALSE\r
1137 then the current station address is changed to the address specified by\r
1138 pNew.\r
1139\r
1140 This routine calls ::Ax88772MacAddressSet to update the MAC address\r
1141 in the network adapter.\r
1142\r
1143 @param [in] pSimpleNetwork Protocol instance pointer\r
1144 @param [in] bReset Flag used to reset the station address to the\r
1145 network interface's permanent address.\r
1146 @param [in] pNew New station address to be used for the network\r
1147 interface.\r
1148\r
1149 @retval EFI_SUCCESS This operation was successful.\r
1150 @retval EFI_NOT_STARTED The network interface was not started.\r
1151 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
1152 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1153 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
1154 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
1155\r
1156**/\r
1157EFI_STATUS\r
1158EFIAPI\r
1159SN_StationAddress (\r
1160 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
1161 IN BOOLEAN bReset,\r
1162 IN EFI_MAC_ADDRESS * pNew\r
1163 )\r
1164{\r
1165 NIC_DEVICE * pNicDevice;\r
1166 EFI_SIMPLE_NETWORK_MODE * pMode;\r
1167 EFI_STATUS Status;\r
1168 EFI_TPL TplPrevious;\r
1169 \r
1170 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);\r
1171 //\r
1172 // Verify the parameters\r
1173 //\r
1174 if (( NULL != pSimpleNetwork )\r
1175 && ( NULL != pSimpleNetwork->Mode )\r
4986bbaf 1176 && (( bReset ) || ( ( !bReset) && ( NULL != pNew )))) {\r
7f556e4d 1177 //\r
1178 // Verify that the adapter is already started\r
1179 //\r
1180 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );\r
1181 pMode = pSimpleNetwork->Mode;\r
4986bbaf 1182 if ( EfiSimpleNetworkInitialized == pMode->State ) {\r
7f556e4d 1183 //\r
1184 // Determine the adapter MAC address\r
1185 //\r
1186 if ( bReset ) {\r
1187 //\r
1188 // Use the permanent address\r
1189 //\r
1190 CopyMem ( &pMode->CurrentAddress,\r
1191 &pMode->PermanentAddress,\r
1192 sizeof ( pMode->CurrentAddress ));\r
1193 }\r
1194 else {\r
1195 //\r
1196 // Use the specified address\r
1197 //\r
1198 CopyMem ( &pMode->CurrentAddress,\r
1199 pNew,\r
1200 sizeof ( pMode->CurrentAddress ));\r
1201 }\r
1202\r
1203 //\r
1204 // Update the address on the adapter\r
1205 //\r
1206 Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);\r
1207 }\r
1208 else {\r
4986bbaf
YP
1209 if (EfiSimpleNetworkStarted == pMode->State) {\r
1210 Status = EFI_DEVICE_ERROR;\r
1211 }\r
1212 else {\r
1213 Status = EFI_NOT_STARTED;\r
1214 }\r
7f556e4d 1215 }\r
1216 }\r
1217 else {\r
1218 Status = EFI_INVALID_PARAMETER;\r
1219 }\r
1220 gBS->RestoreTPL ( TplPrevious );\r
1221 return Status;\r
1222}\r
1223\r
1224\r
1225/**\r
1226 This function resets or collects the statistics on a network interface.\r
1227 If the size of the statistics table specified by StatisticsSize is not\r
1228 big enough for all of the statistics that are collected by the network\r
1229 interface, then a partial buffer of statistics is returned in\r
1230 StatisticsTable.\r
1231\r
1232 @param [in] pSimpleNetwork Protocol instance pointer\r
1233 @param [in] bReset Set to TRUE to reset the statistics for the network interface.\r
1234 @param [in, out] pStatisticsSize On input the size, in bytes, of StatisticsTable. On output\r
1235 the size, in bytes, of the resulting table of statistics.\r
1236 @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that\r
1237 conains the statistics.\r
1238\r
1239 @retval EFI_SUCCESS This operation was successful.\r
1240 @retval EFI_NOT_STARTED The network interface was not started.\r
1241 @retval EFI_BUFFER_TOO_SMALL The pStatisticsTable is NULL or the buffer is too small.\r
1242 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
1243 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1244 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
1245 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
1246\r
1247 typedef struct {\r
1248 UINT64 RxTotalFrames;\r
1249 UINT64 RxGoodFrames;\r
1250 UINT64 RxUndersizeFrames;\r
1251 UINT64 RxOversizeFrames;\r
1252 UINT64 RxDroppedFrames;\r
1253 UINT64 RxUnicastFrames;\r
1254 UINT64 RxBroadcastFrames;\r
1255 UINT64 RxMulticastFrames;\r
1256 UINT64 RxCrcErrorFrames;\r
1257 UINT64 RxTotalBytes;\r
1258 UINT64 TxTotalFrames;\r
1259 UINT64 TxGoodFrames;\r
1260 UINT64 TxUndersizeFrames;\r
1261 UINT64 TxOversizeFrames;\r
1262 UINT64 TxDroppedFrames;\r
1263 UINT64 TxUnicastFrames;\r
1264 UINT64 TxBroadcastFrames;\r
1265 UINT64 TxMulticastFrames;\r
1266 UINT64 TxCrcErrorFrames;\r
1267 UINT64 TxTotalBytes;\r
1268 UINT64 Collisions;\r
1269 UINT64 UnsupportedProtocol;\r
1270 } EFI_NETWORK_STATISTICS;\r
1271**/\r
1272EFI_STATUS\r
1273EFIAPI\r
1274SN_Statistics (\r
1275 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
1276 IN BOOLEAN bReset,\r
1277 IN OUT UINTN * pStatisticsSize,\r
1278 OUT EFI_NETWORK_STATISTICS * pStatisticsTable\r
1279 )\r
1280{\r
1281 EFI_STATUS Status;\r
4986bbaf
YP
1282 EFI_SIMPLE_NETWORK_MODE * pMode;\r
1283 //\r
1284 // Verify the prarameters\r
1285 //\r
1286 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {\r
1287 pMode = pSimpleNetwork->Mode;\r
1288 //\r
1289 // Determine if the interface is started \r
1290 //\r
1291 if (EfiSimpleNetworkInitialized == pMode->State){\r
1292 //\r
1293 // Determine if the StatisticsSize is big enough\r
1294 //\r
1295 if (sizeof (EFI_NETWORK_STATISTICS) <= *pStatisticsSize){\r
1296 if (bReset) {\r
1297 Status = EFI_SUCCESS;\r
1298 } \r
1299 else {\r
1300 Status = EFI_UNSUPPORTED;\r
1301 }\r
1302 }\r
1303 else {\r
1304 Status = EFI_BUFFER_TOO_SMALL;\r
1305 }\r
1306 }\r
1307 else{\r
1308 if (EfiSimpleNetworkStarted == pMode->State) {\r
1309 Status = EFI_DEVICE_ERROR;\r
1310 }\r
1311 else {\r
1312 Status = EFI_NOT_STARTED;\r
1313 }\r
1314 }\r
1315 }\r
1316 else {\r
1317 Status = EFI_INVALID_PARAMETER;\r
1318 }\r
7f556e4d 1319\r
1320 return Status;\r
1321}\r
1322\r
1323\r
1324/**\r
1325 This function stops a network interface. This call is only valid\r
1326 if the network interface is in the started state.\r
1327\r
1328 @param [in] pSimpleNetwork Protocol instance pointer\r
1329\r
1330 @retval EFI_SUCCESS This operation was successful.\r
1331 @retval EFI_NOT_STARTED The network interface was not started.\r
1332 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
1333 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1334 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
1335 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
1336\r
1337**/\r
1338EFI_STATUS\r
1339EFIAPI\r
1340SN_Stop (\r
1341 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork\r
1342 )\r
1343{\r
1344 EFI_SIMPLE_NETWORK_MODE * pMode;\r
1345 EFI_STATUS Status;\r
1346 EFI_TPL TplPrevious;\r
1347 \r
1348 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);\r
1349 //\r
1350 // Verify the parameters\r
1351 //\r
1352 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {\r
1353 //\r
1354 // Determine if the interface is started\r
1355 //\r
1356 pMode = pSimpleNetwork->Mode; \r
1357 if ( EfiSimpleNetworkStarted == pMode->State ) {\r
1358 pMode->State = EfiSimpleNetworkStopped;\r
1359 Status = EFI_SUCCESS; \r
1360 }\r
1361 else {\r
1362 Status = EFI_NOT_STARTED;\r
1363 }\r
1364 } \r
1365 else {\r
1366 Status = EFI_INVALID_PARAMETER;\r
1367 }\r
1368 \r
1369 gBS->RestoreTPL ( TplPrevious );\r
1370 return Status;\r
1371}\r
1372\r
1373\r
1374/**\r
1375 This function releases the memory buffers assigned in the Initialize() call.\r
1376 Pending transmits and receives are lost, and interrupts are cleared and disabled.\r
1377 After this call, only Initialize() and Stop() calls may be used.\r
1378\r
1379 @param [in] pSimpleNetwork Protocol instance pointer\r
1380\r
1381 @retval EFI_SUCCESS This operation was successful.\r
1382 @retval EFI_NOT_STARTED The network interface was not started.\r
1383 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
1384 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1385 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
1386 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
1387\r
1388**/\r
1389EFI_STATUS\r
1390EFIAPI\r
1391SN_Shutdown (\r
1392 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork\r
1393 )\r
1394{\r
1395 EFI_SIMPLE_NETWORK_MODE * pMode;\r
1396 UINT32 RxFilter;\r
1397 EFI_STATUS Status;\r
1398 EFI_TPL TplPrevious;\r
1399 \r
1400 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);\r
1401 //\r
1402 // Verify the parameters\r
1403 //\r
1404 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {\r
1405 //\r
1406 // Determine if the interface is already started\r
1407 //\r
1408 pMode = pSimpleNetwork->Mode;\r
1409 if ( EfiSimpleNetworkInitialized == pMode->State ) {\r
1410 //\r
1411 // Stop the adapter\r
1412 //\r
1413 RxFilter = pMode->ReceiveFilterSetting;\r
1414 pMode->ReceiveFilterSetting = 0;\r
1415 Status = SN_Reset ( pSimpleNetwork, FALSE );\r
1416 pMode->ReceiveFilterSetting = RxFilter;\r
1417 if ( !EFI_ERROR ( Status )) {\r
1418\r
1419 //\r
1420 // Update the network state\r
1421 //\r
1422 pMode->State = EfiSimpleNetworkStarted;\r
1423 }\r
1424 else if ( EFI_DEVICE_ERROR == Status ) {\r
1425 pMode->State = EfiSimpleNetworkStopped;\r
1426 }\r
1427 }\r
1428 else {\r
1429 Status = EFI_NOT_STARTED;\r
1430 }\r
1431 }\r
1432 else {\r
1433 Status = EFI_INVALID_PARAMETER;\r
1434 }\r
1435 gBS->RestoreTPL ( TplPrevious );\r
1436 return Status;\r
1437}\r
1438\r
1439\r
1440/**\r
1441 Send a packet over the network.\r
1442\r
1443 This function places the packet specified by Header and Buffer on\r
1444 the transmit queue. This function performs a non-blocking transmit\r
1445 operation. When the transmit is complete, the buffer is returned\r
1446 via the GetStatus() call.\r
1447\r
1448 This routine calls ::Ax88772Rx to empty the network adapter of\r
1449 receive packets. The routine then passes the transmit packet\r
1450 to the network adapter.\r
1451\r
1452 @param [in] pSimpleNetwork Protocol instance pointer\r
1453 @param [in] HeaderSize The size, in bytes, of the media header to be filled in by\r
1454 the Transmit() function. If HeaderSize is non-zero, then\r
1455 it must be equal to SimpleNetwork->Mode->MediaHeaderSize\r
1456 and DestAddr and Protocol parameters must not be NULL.\r
1457 @param [in] BufferSize The size, in bytes, of the entire packet (media header and\r
1458 data) to be transmitted through the network interface.\r
1459 @param [in] pBuffer A pointer to the packet (media header followed by data) to\r
1460 to be transmitted. This parameter can not be NULL. If\r
1461 HeaderSize is zero, then the media header is Buffer must\r
1462 already be filled in by the caller. If HeaderSize is nonzero,\r
1463 then the media header will be filled in by the Transmit()\r
1464 function.\r
1465 @param [in] pSrcAddr The source HW MAC address. If HeaderSize is zero, then\r
1466 this parameter is ignored. If HeaderSize is nonzero and\r
1467 SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress\r
1468 is used for the source HW MAC address.\r
1469 @param [in] pDestAddr The destination HW MAC address. If HeaderSize is zero, then\r
1470 this parameter is ignored.\r
1471 @param [in] pProtocol The type of header to build. If HeaderSize is zero, then\r
1472 this parameter is ignored.\r
1473\r
1474 @retval EFI_SUCCESS This operation was successful.\r
1475 @retval EFI_NOT_STARTED The network interface was not started.\r
1476 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.\r
1477 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
1478 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid\r
1479 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
1480 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
1481\r
1482**/\r
1483EFI_STATUS\r
1484EFIAPI\r
1485SN_Transmit (\r
1486 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,\r
1487 IN UINTN HeaderSize,\r
1488 IN UINTN BufferSize,\r
1489 IN VOID * pBuffer,\r
1490 IN EFI_MAC_ADDRESS * pSrcAddr,\r
1491 IN EFI_MAC_ADDRESS * pDestAddr,\r
1492 IN UINT16 * pProtocol\r
1493 )\r
1494{\r
1495 ETHERNET_HEADER * pHeader;\r
1496 EFI_SIMPLE_NETWORK_MODE * pMode;\r
1497 NIC_DEVICE * pNicDevice;\r
1498 EFI_USB_IO_PROTOCOL * pUsbIo;\r
1499 EFI_STATUS Status;\r
1500 UINTN TransferLength;\r
1501 UINT32 TransferStatus;\r
1502 UINT16 Type;\r
1503 EFI_TPL TplPrevious;\r
1504\r
1505 TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);\r
1506\r
1507 // Verify the parameters\r
1508 //\r
4986bbaf
YP
1509 if (( NULL != pSimpleNetwork ) && \r
1510 ( NULL != pSimpleNetwork->Mode ) && \r
1511 ( NULL != pBuffer) && \r
1512 ( (HeaderSize == 0) || ( (NULL != pDestAddr) && (NULL != pProtocol) ))) {\r
7f556e4d 1513 //\r
1514 // The interface must be running\r
1515 //\r
1516 pMode = pSimpleNetwork->Mode;\r
4986bbaf
YP
1517 //\r
1518 // Verify parameter of HeaderSize\r
1519 //\r
1520 if ((HeaderSize == 0) || (HeaderSize == pMode->MediaHeaderSize)){\r
7f556e4d 1521 //\r
4986bbaf 1522 // Determine if BufferSize is big enough\r
7f556e4d 1523 //\r
4986bbaf
YP
1524 if (BufferSize >= pMode->MediaHeaderSize){\r
1525 if ( EfiSimpleNetworkInitialized == pMode->State ) {\r
1526 //\r
1527 // Update the link status\r
1528 //\r
1529 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );\r
1530 pMode->MediaPresent = pNicDevice->bLinkUp;\r
7f556e4d 1531\r
4986bbaf
YP
1532 //\r
1533 // Release the synchronization with Ax88772Timer\r
1534 // \r
1535 if ( pMode->MediaPresent && pNicDevice->bComplete) {\r
1536 //\r
1537 // Copy the packet into the USB buffer\r
1538 //\r
7f556e4d 1539\r
4986bbaf
YP
1540 CopyMem ( &pNicDevice->pTxTest->Data[0], pBuffer, BufferSize ); \r
1541 pNicDevice->pTxTest->Length = (UINT16) BufferSize;\r
7f556e4d 1542\r
4986bbaf
YP
1543 //\r
1544 // Transmit the packet\r
1545 //\r
1546 pHeader = (ETHERNET_HEADER *) &pNicDevice->pTxTest->Data[0];\r
1547 if ( 0 != HeaderSize ) {\r
1548 if ( NULL != pDestAddr ) {\r
1549 CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );\r
1550 }\r
1551 if ( NULL != pSrcAddr ) {\r
1552 CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );\r
1553 }\r
1554 else {\r
1555 CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );\r
1556 }\r
1557 if ( NULL != pProtocol ) {\r
1558 Type = *pProtocol;\r
1559 }\r
1560 else {\r
1561 Type = pNicDevice->pTxTest->Length;\r
1562 }\r
1563 Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));\r
1564 pHeader->type = Type;\r
1565 }\r
1566 if ( pNicDevice->pTxTest->Length < MIN_ETHERNET_PKT_SIZE ) {\r
1567 pNicDevice->pTxTest->Length = MIN_ETHERNET_PKT_SIZE;\r
1568 ZeroMem ( &pNicDevice->pTxTest->Data[ BufferSize ],\r
1569 pNicDevice->pTxTest->Length - BufferSize );\r
1570 }\r
1571 \r
1572 DEBUG ((EFI_D_INFO, "TX: %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x"\r
1573 " %02x-%02x %d bytes\r\n",\r
1574 pNicDevice->pTxTest->Data[0],\r
1575 pNicDevice->pTxTest->Data[1],\r
1576 pNicDevice->pTxTest->Data[2],\r
1577 pNicDevice->pTxTest->Data[3],\r
1578 pNicDevice->pTxTest->Data[4],\r
1579 pNicDevice->pTxTest->Data[5],\r
1580 pNicDevice->pTxTest->Data[6],\r
1581 pNicDevice->pTxTest->Data[7],\r
1582 pNicDevice->pTxTest->Data[8],\r
1583 pNicDevice->pTxTest->Data[9],\r
1584 pNicDevice->pTxTest->Data[10],\r
1585 pNicDevice->pTxTest->Data[11],\r
1586 pNicDevice->pTxTest->Data[12],\r
1587 pNicDevice->pTxTest->Data[13],\r
1588 pNicDevice->pTxTest->Length ));\r
1589\r
1590 pNicDevice->pTxTest->LengthBar = ~(pNicDevice->pTxTest->Length);\r
1591 TransferLength = sizeof ( pNicDevice->pTxTest->Length )\r
1592 + sizeof ( pNicDevice->pTxTest->LengthBar )\r
1593 + pNicDevice->pTxTest->Length;\r
1594 \r
1595 if (TransferLength % 512 == 0 || TransferLength % 1024 == 0)\r
1596 TransferLength +=4;\r
1597\r
1598 //\r
1599 // Work around USB bus driver bug where a timeout set by receive\r
1600 // succeeds but the timeout expires immediately after, causing the\r
1601 // transmit operation to timeout.\r
1602 //\r
1603 pUsbIo = pNicDevice->pUsbIo;\r
1604 Status = pUsbIo->UsbBulkTransfer ( pUsbIo,\r
1605 BULK_OUT_ENDPOINT,\r
1606 &pNicDevice->pTxTest->Length,\r
1607 &TransferLength,\r
1608 0xfffffffe, \r
1609 &TransferStatus );\r
1610 if ( !EFI_ERROR ( Status )) {\r
1611 Status = TransferStatus;\r
1612 }\r
1613\r
1614 if ( !EFI_ERROR ( Status )) {\r
1615 pNicDevice->pTxBuffer = pBuffer;\r
1616 }\r
1617 else {\r
1618 if ((TransferLength != (UINTN)( pNicDevice->pTxTest->Length + 4 )) &&\r
1619 (TransferLength != (UINTN)(( pNicDevice->pTxTest->Length + 4 ) + 4))) {\r
1620 DEBUG ((EFI_D_INFO, "TransferLength didn't match Packet Length\n"));\r
1621 }\r
1622 //\r
1623 // Reset the controller to fix the error\r
1624 //\r
1625 if ( EFI_DEVICE_ERROR == Status ) {\r
1626 SN_Reset ( pSimpleNetwork, FALSE );\r
1627 }\r
1628 Status = EFI_NOT_READY;\r
1629 }\r
7f556e4d 1630 }\r
1631 else {\r
4986bbaf
YP
1632 //\r
1633 // No packets available.\r
1634 //\r
1635 Status = EFI_NOT_READY;\r
7f556e4d 1636 }\r
4986bbaf 1637 \r
7f556e4d 1638 }\r
1639 else {\r
4986bbaf
YP
1640 if (EfiSimpleNetworkStarted == pMode->State) {\r
1641 Status = EFI_DEVICE_ERROR;\r
7f556e4d 1642 }\r
4986bbaf
YP
1643 else {\r
1644 Status = EFI_NOT_STARTED ;\r
7f556e4d 1645 }\r
7f556e4d 1646 }\r
1647 }\r
1648 else {\r
4986bbaf 1649 Status = EFI_BUFFER_TOO_SMALL;\r
7f556e4d 1650 }\r
7f556e4d 1651 }\r
1652 else {\r
4986bbaf 1653 Status = EFI_INVALID_PARAMETER;\r
7f556e4d 1654 }\r
1655 }\r
1656 else {\r
1657 Status = EFI_INVALID_PARAMETER;\r
1658 }\r
1659 \r
1660 gBS->RestoreTPL (TplPrevious);\r
1661\r
1662 return Status;\r
1663}\r