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