2 Provides the Simple Network functions.
4 Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 This function updates the filtering on the receiver.
20 This support routine calls ::Ax88772MacAddressSet to update
21 the MAC address. This routine then rebuilds the multicast
22 hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
23 Finally this routine enables the receiver by calling
26 @param [in] pSimpleNetwork Simple network mode pointer
28 @retval EFI_SUCCESS This operation was successful.
29 @retval EFI_NOT_STARTED The network interface was not started.
30 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
31 EFI_SIMPLE_NETWORK_PROTOCOL structure.
32 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
33 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
38 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
41 EFI_SIMPLE_NETWORK_MODE
* pMode
;
42 NIC_DEVICE
* pNicDevice
;
49 // Set the MAC address
51 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
52 pMode
= pSimpleNetwork
->Mode
;
53 Status
= Ax88772MacAddressSet ( pNicDevice
,
54 &pMode
->CurrentAddress
.Addr
[0]);
55 if ( !EFI_ERROR ( Status
)) {
57 // Clear the multicast hash table
59 Ax88772MulticastClear ( pNicDevice
);
62 // Load the multicast hash table
64 if ( 0 != ( pMode
->ReceiveFilterSetting
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
)) {
66 ( !EFI_ERROR ( Status
)) && ( Index
< pMode
->MCastFilterCount
);
69 // Enable the next multicast address
71 Ax88772MulticastSet ( pNicDevice
,
72 &pMode
->MCastFilter
[ Index
].Addr
[0]);
77 // Enable the receiver
79 if ( !EFI_ERROR ( Status
)) {
80 Status
= Ax88772RxControl ( pNicDevice
, pMode
->ReceiveFilterSetting
);
85 // Return the operation status
87 DBG_EXIT_STATUS ( Status
);
93 This function updates the SNP driver status.
95 This function gets the current interrupt and recycled transmit
96 buffer status from the network interface. The interrupt status
97 and the media status are returned as a bit mask in InterruptStatus.
98 If InterruptStatus is NULL, the interrupt status will not be read.
99 Upon successful return of the media status, the MediaPresent field
100 of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
101 of media status. If TxBuf is not NULL, a recycled transmit buffer
102 address will be retrived. If a recycled transmit buffer address
103 is returned in TxBuf, then the buffer has been successfully
104 transmitted, and the status for that buffer is cleared.
106 This function calls ::Ax88772Rx to update the media status and
107 queue any receive packets.
109 @param [in] pSimpleNetwork Protocol instance pointer
110 @param [in] pInterruptStatus A pointer to the bit mask of the current active interrupts.
111 If this is NULL, the interrupt status will not be read from
112 the device. If this is not NULL, the interrupt status will
113 be read from teh device. When the interrupt status is read,
114 it will also be cleared. Clearing the transmit interrupt
115 does not empty the recycled transmit buffer array.
116 @param [out] ppTxBuf Recycled transmit buffer address. The network interface will
117 not transmit if its internal recycled transmit buffer array is
118 full. Reading the transmit buffer does not clear the transmit
119 interrupt. If this is NULL, then the transmit buffer status
120 will not be read. If there are not transmit buffers to recycle
121 and TxBuf is not NULL, *TxBuf will be set to NULL.
123 @retval EFI_SUCCESS This operation was successful.
124 @retval EFI_NOT_STARTED The network interface was not started.
125 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
126 EFI_SIMPLE_NETWORK_PROTOCOL structure.
127 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
133 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
134 OUT UINT32
* pInterruptStatus
,
139 EFI_SIMPLE_NETWORK_MODE
* pMode
;
140 NIC_DEVICE
* pNicDevice
;
147 // Verify the parameters
149 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
151 // Return the transmit buffer
153 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
154 if (( NULL
!= ppTxBuf
) && ( NULL
!= pNicDevice
->pTxBuffer
)) {
155 *ppTxBuf
= pNicDevice
->pTxBuffer
;
156 pNicDevice
->pTxBuffer
= NULL
;
160 // Determine if interface is running
162 pMode
= pSimpleNetwork
->Mode
;
163 if ( EfiSimpleNetworkStopped
!= pMode
->State
) {
165 // Synchronize with Ax88772Timer
167 VERIFY_TPL ( TPL_AX88772
);
168 TplPrevious
= gBS
->RaiseTPL ( TPL_AX88772
);
171 // Update the link status
173 bLinkIdle
= pNicDevice
->bLinkIdle
;
174 pNicDevice
->bLinkIdle
= TRUE
;
175 Ax88772Rx ( pNicDevice
, bLinkIdle
);
176 pMode
->MediaPresent
= pNicDevice
->bLinkUp
;
179 // Release the synchronization with Ax88772Timer
181 gBS
->RestoreTPL ( TplPrevious
);
184 // Return the interrupt status
186 if ( NULL
!= pInterruptStatus
) {
187 *pInterruptStatus
= 0;
189 Status
= EFI_SUCCESS
;
192 Status
= EFI_NOT_STARTED
;
196 Status
= EFI_INVALID_PARAMETER
;
200 // Return the operation status
202 DBG_EXIT_STATUS ( Status
);
208 Resets the network adapter and allocates the transmit and receive buffers
209 required by the network interface; optionally, also requests allocation of
210 additional transmit and receive buffers. This routine must be called before
211 any other routine in the Simple Network protocol is called.
213 @param [in] pSimpleNetwork Protocol instance pointer
214 @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
215 @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
217 @retval EFI_SUCCESS This operation was successful.
218 @retval EFI_NOT_STARTED The network interface was not started.
219 @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and receive buffers
220 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
221 EFI_SIMPLE_NETWORK_PROTOCOL structure.
222 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
223 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
229 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
230 IN UINTN ExtraRxBufferSize
,
231 IN UINTN ExtraTxBufferSize
234 EFI_SIMPLE_NETWORK_MODE
* pMode
;
240 // Verify the parameters
242 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
244 // Determine if the interface is already started
246 pMode
= pSimpleNetwork
->Mode
;
247 if ( EfiSimpleNetworkStarted
== pMode
->State
) {
248 if (( 0 == ExtraRxBufferSize
) && ( 0 == ExtraTxBufferSize
)) {
252 Status
= SN_Reset ( pSimpleNetwork
, FALSE
);
253 if ( !EFI_ERROR ( Status
)) {
255 // Update the network state
257 pMode
->State
= EfiSimpleNetworkInitialized
;
261 Status
= EFI_UNSUPPORTED
;
265 Status
= EFI_NOT_STARTED
;
269 Status
= EFI_INVALID_PARAMETER
;
273 // Return the operation status
275 DBG_EXIT_STATUS ( Status
);
281 This function converts a multicast IP address to a multicast HW MAC address
282 for all packet transactions.
284 @param [in] pSimpleNetwork Protocol instance pointer
285 @param [in] bIPv6 Set to TRUE if the multicast IP address is IPv6 [RFC2460].
286 Set to FALSE if the multicast IP address is IPv4 [RFC 791].
287 @param [in] pIP The multicast IP address that is to be converted to a
288 multicast HW MAC address.
289 @param [in] pMAC The multicast HW MAC address that is to be generated from IP.
291 @retval EFI_SUCCESS This operation was successful.
292 @retval EFI_NOT_STARTED The network interface was not started.
293 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
294 EFI_SIMPLE_NETWORK_PROTOCOL structure.
295 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
296 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
302 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
304 IN EFI_IP_ADDRESS
* pIP
,
305 IN EFI_MAC_ADDRESS
* pMAC
313 // This is not currently supported
315 Status
= EFI_UNSUPPORTED
;
318 // Return the operation status
320 DBG_EXIT_STATUS ( Status
);
326 This function performs read and write operations on the NVRAM device
327 attached to a network interface.
329 @param [in] pSimpleNetwork Protocol instance pointer
330 @param [in] ReadWrite TRUE for read operations, FALSE for write operations.
331 @param [in] Offset Byte offset in the NVRAM device at which to start the
332 read or write operation. This must be a multiple of
333 NvRamAccessSize and less than NvRamSize.
334 @param [in] BufferSize The number of bytes to read or write from the NVRAM device.
335 This must also be a multiple of NvramAccessSize.
336 @param [in, out] pBuffer A pointer to the data buffer.
338 @retval EFI_SUCCESS This operation was successful.
339 @retval EFI_NOT_STARTED The network interface was not started.
340 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
341 EFI_SIMPLE_NETWORK_PROTOCOL structure.
342 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
343 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
349 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
350 IN BOOLEAN ReadWrite
,
353 IN OUT VOID
* pBuffer
361 // This is not currently supported
363 Status
= EFI_UNSUPPORTED
;
366 // Return the operation status
368 DBG_EXIT_STATUS ( Status
);
374 Attempt to receive a packet from the network adapter.
376 This function retrieves one packet from the receive queue of the network
377 interface. If there are no packets on the receive queue, then EFI_NOT_READY
378 will be returned. If there is a packet on the receive queue, and the size
379 of the packet is smaller than BufferSize, then the contents of the packet
380 will be placed in Buffer, and BufferSize will be udpated with the actual
381 size of the packet. In addition, if SrcAddr, DestAddr, and Protocol are
382 not NULL, then these values will be extracted from the media header and
383 returned. If BufferSize is smaller than the received packet, then the
384 size of the receive packet will be placed in BufferSize and
385 EFI_BUFFER_TOO_SMALL will be returned.
387 This routine calls ::Ax88772Rx to update the media status and
388 empty the network adapter of receive packets.
390 @param [in] pSimpleNetwork Protocol instance pointer
391 @param [out] pHeaderSize The size, in bytes, of the media header to be filled in by
392 the Transmit() function. If HeaderSize is non-zero, then
393 it must be equal to SimpleNetwork->Mode->MediaHeaderSize
394 and DestAddr and Protocol parameters must not be NULL.
395 @param [out] pBufferSize The size, in bytes, of the entire packet (media header and
396 data) to be transmitted through the network interface.
397 @param [out] pBuffer A pointer to the packet (media header followed by data) to
398 to be transmitted. This parameter can not be NULL. If
399 HeaderSize is zero, then the media header is Buffer must
400 already be filled in by the caller. If HeaderSize is nonzero,
401 then the media header will be filled in by the Transmit()
403 @param [out] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
404 this parameter is ignored. If HeaderSize is nonzero and
405 SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
406 is used for the source HW MAC address.
407 @param [out] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
408 this parameter is ignored.
409 @param [out] pProtocol The type of header to build. If HeaderSize is zero, then
410 this parameter is ignored.
412 @retval EFI_SUCCESS This operation was successful.
413 @retval EFI_NOT_STARTED The network interface was not started.
414 @retval EFI_NOT_READY No packets have been received on the network interface.
415 @retval EFI_BUFFER_TOO_SMALL The packet is larger than BufferSize bytes.
416 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
417 EFI_SIMPLE_NETWORK_PROTOCOL structure.
418 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
424 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
425 OUT UINTN
* pHeaderSize
,
426 OUT UINTN
* pBufferSize
,
428 OUT EFI_MAC_ADDRESS
* pSrcAddr
,
429 OUT EFI_MAC_ADDRESS
* pDestAddr
,
430 OUT UINT16
* pProtocol
433 ETHERNET_HEADER
* pHeader
;
434 EFI_SIMPLE_NETWORK_MODE
* pMode
;
435 NIC_DEVICE
* pNicDevice
;
436 RX_TX_PACKET
* pRxPacket
;
444 // Verify the parameters
446 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
448 // The interface must be running
450 pMode
= pSimpleNetwork
->Mode
;
451 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
453 // Synchronize with Ax88772Timer
455 VERIFY_TPL ( TPL_AX88772
);
456 TplPrevious
= gBS
->RaiseTPL ( TPL_AX88772
);
459 // Update the link status
461 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
462 Ax88772Rx ( pNicDevice
, FALSE
);
463 pMode
->MediaPresent
= pNicDevice
->bLinkUp
;
464 if ( pMode
->MediaPresent
) {
466 // Attempt to receive a packet
468 pRxPacket
= pNicDevice
->pRxHead
;
469 if ( NULL
!= pRxPacket
) {
470 pNicDevice
->pRxHead
= pRxPacket
->pNext
;
471 if ( NULL
== pNicDevice
->pRxHead
) {
472 pNicDevice
->pRxTail
= NULL
;
476 // Copy the received packet into the receive buffer
478 *pBufferSize
= pRxPacket
->Length
;
479 CopyMem ( pBuffer
, &pRxPacket
->Data
[0], pRxPacket
->Length
);
480 pHeader
= (ETHERNET_HEADER
*) &pRxPacket
->Data
[0];
481 if ( NULL
!= pHeaderSize
) {
482 *pHeaderSize
= sizeof ( *pHeader
);
484 if ( NULL
!= pDestAddr
) {
485 CopyMem ( pDestAddr
, &pHeader
->dest_addr
, PXE_HWADDR_LEN_ETHER
);
487 if ( NULL
!= pSrcAddr
) {
488 CopyMem ( pSrcAddr
, &pHeader
->src_addr
, PXE_HWADDR_LEN_ETHER
);
490 if ( NULL
!= pProtocol
) {
491 Type
= pHeader
->type
;
492 Type
= (UINT16
)(( Type
>> 8 ) | ( Type
<< 8 ));
495 Status
= EFI_SUCCESS
;
499 // No receive packets available
501 Status
= EFI_NOT_READY
;
508 Status
= EFI_NOT_READY
;
512 // Release the synchronization with Ax88772Timer
514 gBS
->RestoreTPL ( TplPrevious
);
517 Status
= EFI_NOT_STARTED
;
521 Status
= EFI_INVALID_PARAMETER
;
525 // Return the operation status
527 DBG_EXIT_STATUS ( Status
);
533 This function is used to enable and disable the hardware and software receive
534 filters for the underlying network device.
536 The receive filter change is broken down into three steps:
538 1. The filter mask bits that are set (ON) in the Enable parameter
539 are added to the current receive filter settings.
541 2. The filter mask bits that are set (ON) in the Disable parameter
542 are subtracted from the updated receive filter settins.
544 3. If the resulting filter settigns is not supported by the hardware
545 a more liberal setting is selected.
547 If the same bits are set in the Enable and Disable parameters, then the bits
548 in the Disable parameter takes precedence.
550 If the ResetMCastFilter parameter is TRUE, then the multicast address list
551 filter is disabled (irregardless of what other multicast bits are set in
552 the enable and Disable parameters). The SNP->Mode->MCastFilterCount field
553 is set to zero. The SNP->Mode->MCastFilter contents are undefined.
555 After enableing or disabling receive filter settings, software should
556 verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
557 SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
559 Note: Some network drivers and/or devices will automatically promote
560 receive filter settings if the requested setting can not be honored.
561 For example, if a request for four multicast addresses is made and
562 the underlying hardware only supports two multicast addresses the
563 driver might set the promiscuous or promiscuous multicast receive filters
564 instead. The receiving software is responsible for discarding any extra
565 packets that get through the hardware receive filters.
567 If ResetMCastFilter is TRUE, then the multicast receive filter list
568 on the network interface will be reset to the default multicast receive
569 filter list. If ResetMCastFilter is FALSE, and this network interface
570 allows the multicast receive filter list to be modified, then the
571 MCastFilterCnt and MCastFilter are used to update the current multicast
572 receive filter list. The modified receive filter list settings can be
573 found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
575 This routine calls ::ReceiveFilterUpdate to update the receive
576 state in the network adapter.
578 @param [in] pSimpleNetwork Protocol instance pointer
579 @param [in] Enable A bit mask of receive filters to enable on the network interface.
580 @param [in] Disable A bit mask of receive filters to disable on the network interface.
581 For backward compatibility with EFI 1.1 platforms, the
582 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
583 when the ResetMCastFilter parameter is TRUE.
584 @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
585 filters on the network interface to their default values.
586 @param [in] MCastFilterCnt Number of multicast HW MAC address in the new MCastFilter list.
587 This value must be less than or equal to the MaxMCastFilterCnt
588 field of EFI_SIMPLE_NETWORK_MODE. This field is optional if
589 ResetMCastFilter is TRUE.
590 @param [in] pMCastFilter A pointer to a list of new multicast receive filter HW MAC
591 addresses. This list will replace any existing multicast
592 HW MAC address list. This field is optional if ResetMCastFilter
595 @retval EFI_SUCCESS This operation was successful.
596 @retval EFI_NOT_STARTED The network interface was not started.
597 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
598 EFI_SIMPLE_NETWORK_PROTOCOL structure.
599 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
600 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
606 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
609 IN BOOLEAN bResetMCastFilter
,
610 IN UINTN MCastFilterCnt
,
611 IN EFI_MAC_ADDRESS
* pMCastFilter
614 EFI_SIMPLE_NETWORK_MODE
* pMode
;
615 EFI_MAC_ADDRESS
* pMulticastAddress
;
616 EFI_MAC_ADDRESS
* pTableEnd
;
622 // Verify the parameters
624 Status
= EFI_INVALID_PARAMETER
;
625 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
626 pMode
= pSimpleNetwork
->Mode
;
629 // Update the multicast list if necessary
631 if ( !bResetMCastFilter
) {
632 if ( 0 != MCastFilterCnt
) {
633 if (( MAX_MCAST_FILTER_CNT
>= MCastFilterCnt
)
634 && ( NULL
!= pMCastFilter
)) {
636 // Verify the multicast addresses
638 pMulticastAddress
= pMCastFilter
;
639 pTableEnd
= pMulticastAddress
+ MCastFilterCnt
;
640 while ( pTableEnd
> pMulticastAddress
) {
642 // The first digit of the multicast address must have the LSB set
644 if ( 0 == ( pMulticastAddress
->Addr
[0] & 1 )) {
646 // Invalid multicast address
650 pMulticastAddress
+= 1;
652 if ( pTableEnd
== pMulticastAddress
) {
654 // Update the multicast filter list.
656 CopyMem (&pMode
->MCastFilter
[0],
658 MCastFilterCnt
* sizeof ( *pMCastFilter
));
659 Status
= EFI_SUCCESS
;
664 Status
= EFI_SUCCESS
;
669 // No multicast address list is specified
672 Status
= EFI_SUCCESS
;
674 if ( !EFI_ERROR ( Status
)) {
676 // The parameters are valid!
678 pMode
->ReceiveFilterSetting
|= Enable
;
679 pMode
->ReceiveFilterSetting
&= ~Disable
;
680 pMode
->MCastFilterCount
= (UINT32
)MCastFilterCnt
;
683 // Update the receive filters in the adapter
685 Status
= ReceiveFilterUpdate ( pSimpleNetwork
);
690 // Return the operation status
692 DBG_EXIT_STATUS ( Status
);
698 Reset the network adapter.
700 Resets a network adapter and reinitializes it with the parameters that
701 were provided in the previous call to Initialize (). The transmit and
702 receive queues are cleared. Receive filters, the station address, the
703 statistics, and the multicast-IP-to-HW MAC addresses are not reset by
706 This routine calls ::Ax88772Reset to perform the adapter specific
707 reset operation. This routine also starts the link negotiation
708 by calling ::Ax88772NegotiateLinkStart.
710 @param [in] pSimpleNetwork Protocol instance pointer
711 @param [in] bExtendedVerification Indicates that the driver may perform a more
712 exhaustive verification operation of the device
715 @retval EFI_SUCCESS This operation was successful.
716 @retval EFI_NOT_STARTED The network interface was not started.
717 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
718 EFI_SIMPLE_NETWORK_PROTOCOL structure.
719 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
720 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
726 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
727 IN BOOLEAN bExtendedVerification
730 EFI_SIMPLE_NETWORK_MODE
* pMode
;
731 NIC_DEVICE
* pNicDevice
;
732 RX_TX_PACKET
* pRxPacket
;
739 // Verify the parameters
741 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
743 // Synchronize with Ax88772Timer
745 VERIFY_TPL ( TPL_AX88772
);
746 TplPrevious
= gBS
->RaiseTPL ( TPL_AX88772
);
749 // Update the device state
751 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
752 pNicDevice
->bComplete
= FALSE
;
753 pNicDevice
->bLinkUp
= FALSE
;
755 pMode
= pSimpleNetwork
->Mode
;
756 pMode
->MediaPresent
= FALSE
;
759 // Discard any received packets
761 while ( NULL
!= pNicDevice
->pRxHead
) {
763 // Remove the packet from the received packet list
765 pRxPacket
= pNicDevice
->pRxHead
;
766 pNicDevice
->pRxHead
= pRxPacket
->pNext
;
769 // Queue the packet to the free list
771 pRxPacket
->pNext
= pNicDevice
->pRxFree
;
772 pNicDevice
->pRxFree
= pRxPacket
;
774 pNicDevice
->pRxTail
= NULL
;
779 Status
= Ax88772Reset ( pNicDevice
);
780 if ( !EFI_ERROR ( Status
)) {
782 // Update the receive filters in the adapter
784 Status
= ReceiveFilterUpdate ( pSimpleNetwork
);
787 // Try to get a connection to the network
789 if ( !EFI_ERROR ( Status
)) {
791 // Start the autonegotiation
793 Status
= Ax88772NegotiateLinkStart ( pNicDevice
);
798 // Release the synchronization with Ax88772Timer
800 gBS
->RestoreTPL ( TplPrevious
);
803 Status
= EFI_INVALID_PARAMETER
;
807 // Return the operation status
809 DBG_EXIT_STATUS ( Status
);
815 Initialize the simple network protocol.
817 This routine calls ::Ax88772MacAddressGet to obtain the
820 @param [in] pNicDevice NIC_DEVICE_INSTANCE pointer
822 @retval EFI_SUCCESS Setup was successful
827 IN NIC_DEVICE
* pNicDevice
830 EFI_SIMPLE_NETWORK_MODE
* pMode
;
831 EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
;
837 // Initialize the simple network protocol
839 pSimpleNetwork
= &pNicDevice
->SimpleNetwork
;
840 pSimpleNetwork
->Revision
= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
;
841 pSimpleNetwork
->Start
= (EFI_SIMPLE_NETWORK_START
)SN_Start
;
842 pSimpleNetwork
->Stop
= (EFI_SIMPLE_NETWORK_STOP
)SN_Stop
;
843 pSimpleNetwork
->Initialize
= (EFI_SIMPLE_NETWORK_INITIALIZE
)SN_Initialize
;
844 pSimpleNetwork
->Reset
= (EFI_SIMPLE_NETWORK_RESET
)SN_Reset
;
845 pSimpleNetwork
->Shutdown
= (EFI_SIMPLE_NETWORK_SHUTDOWN
)SN_Shutdown
;
846 pSimpleNetwork
->ReceiveFilters
= (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS
)SN_ReceiveFilters
;
847 pSimpleNetwork
->StationAddress
= (EFI_SIMPLE_NETWORK_STATION_ADDRESS
)SN_StationAddress
;
848 pSimpleNetwork
->Statistics
= (EFI_SIMPLE_NETWORK_STATISTICS
)SN_Statistics
;
849 pSimpleNetwork
->MCastIpToMac
= (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC
)SN_MCastIPtoMAC
;
850 pSimpleNetwork
->NvData
= (EFI_SIMPLE_NETWORK_NVDATA
)SN_NvData
;
851 pSimpleNetwork
->GetStatus
= (EFI_SIMPLE_NETWORK_GET_STATUS
)SN_GetStatus
;
852 pSimpleNetwork
->Transmit
= (EFI_SIMPLE_NETWORK_TRANSMIT
)SN_Transmit
;
853 pSimpleNetwork
->Receive
= (EFI_SIMPLE_NETWORK_RECEIVE
)SN_Receive
;
854 pSimpleNetwork
->WaitForPacket
= NULL
;
855 pMode
= &pNicDevice
->SimpleNetworkData
;
856 pSimpleNetwork
->Mode
= pMode
;
858 pMode
->State
= EfiSimpleNetworkStopped
;
859 pMode
->HwAddressSize
= PXE_HWADDR_LEN_ETHER
;
860 pMode
->MediaHeaderSize
= sizeof ( ETHERNET_HEADER
);
861 pMode
->MaxPacketSize
= MAX_ETHERNET_PKT_SIZE
;
862 pMode
->NvRamSize
= 0;
863 pMode
->NvRamAccessSize
= 0;
864 pMode
->ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
865 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
866 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
867 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
868 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
869 pMode
->ReceiveFilterSetting
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
870 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
871 pMode
->MaxMCastFilterCount
= MAX_MCAST_FILTER_CNT
;
872 pMode
->MCastFilterCount
= 0;
873 SetMem ( &pMode
->BroadcastAddress
,
874 PXE_HWADDR_LEN_ETHER
,
876 pMode
->IfType
= EfiNetworkInterfaceUndi
;
877 pMode
->MacAddressChangeable
= TRUE
;
878 pMode
->MultipleTxSupported
= TRUE
;
879 pMode
->MediaPresentSupported
= TRUE
;
880 pMode
->MediaPresent
= FALSE
;
883 // Read the MAC address
885 pNicDevice
->PhyId
= PHY_ID_INTERNAL
;
886 pNicDevice
->b100Mbps
= TRUE
;
887 pNicDevice
->bFullDuplex
= TRUE
;
889 Status
= gBS
->AllocatePool ( EfiRuntimeServicesData
,
891 (VOID
**) &pNicDevice
->pBulkInBuff
);
892 if ( EFI_ERROR(Status
)) {
893 DEBUG (( EFI_D_ERROR
, "Memory are not enough\n"));
897 Status
= Ax88772MacAddressGet (
899 &pMode
->PermanentAddress
.Addr
[0]);
900 if ( !EFI_ERROR ( Status
)) {
902 // Display the MAC address
904 DEBUG (( DEBUG_MAC_ADDRESS
| DEBUG_INFO
,
905 "MAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
906 pMode
->PermanentAddress
.Addr
[0],
907 pMode
->PermanentAddress
.Addr
[1],
908 pMode
->PermanentAddress
.Addr
[2],
909 pMode
->PermanentAddress
.Addr
[3],
910 pMode
->PermanentAddress
.Addr
[4],
911 pMode
->PermanentAddress
.Addr
[5]));
914 // Use the hardware address as the current address
916 CopyMem ( &pMode
->CurrentAddress
,
917 &pMode
->PermanentAddress
,
918 PXE_HWADDR_LEN_ETHER
);
922 // Return the setup status
924 DBG_EXIT_STATUS ( Status
);
930 This routine starts the network interface.
932 @param [in] pSimpleNetwork Protocol instance pointer
934 @retval EFI_SUCCESS This operation was successful.
935 @retval EFI_ALREADY_STARTED The network interface was already started.
936 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
937 EFI_SIMPLE_NETWORK_PROTOCOL structure.
938 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
939 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
945 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
948 NIC_DEVICE
* pNicDevice
;
949 EFI_SIMPLE_NETWORK_MODE
* pMode
;
955 // Verify the parameters
957 Status
= EFI_INVALID_PARAMETER
;
958 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
959 pMode
= pSimpleNetwork
->Mode
;
960 if ( EfiSimpleNetworkStopped
== pMode
->State
) {
962 // Initialize the mode structure
963 // NVRAM access is not supported
965 ZeroMem ( pMode
, sizeof ( *pMode
));
967 pMode
->State
= EfiSimpleNetworkStarted
;
968 pMode
->HwAddressSize
= PXE_HWADDR_LEN_ETHER
;
969 pMode
->MediaHeaderSize
= sizeof ( ETHERNET_HEADER
);
970 pMode
->MaxPacketSize
= MAX_ETHERNET_PKT_SIZE
;
971 pMode
->ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
972 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
973 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
974 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
975 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
976 pMode
->ReceiveFilterSetting
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
977 pMode
->MaxMCastFilterCount
= MAX_MCAST_FILTER_CNT
;
978 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
979 Status
= Ax88772MacAddressGet ( pNicDevice
, &pMode
->PermanentAddress
.Addr
[0]);
980 CopyMem ( &pMode
->CurrentAddress
,
981 &pMode
->PermanentAddress
,
982 sizeof ( pMode
->CurrentAddress
));
983 pMode
->BroadcastAddress
.Addr
[0] = 0xff;
984 pMode
->BroadcastAddress
.Addr
[1] = 0xff;
985 pMode
->BroadcastAddress
.Addr
[2] = 0xff;
986 pMode
->BroadcastAddress
.Addr
[3] = 0xff;
987 pMode
->BroadcastAddress
.Addr
[4] = 0xff;
988 pMode
->BroadcastAddress
.Addr
[5] = 0xff;
990 pMode
->MacAddressChangeable
= TRUE
;
991 pMode
->MultipleTxSupported
= TRUE
;
992 pMode
->MediaPresentSupported
= TRUE
;
993 pMode
->MediaPresent
= FALSE
;
996 Status
= EFI_ALREADY_STARTED
;
1001 // Return the operation status
1003 DBG_EXIT_STATUS ( Status
);
1009 Set the MAC address.
1011 This function modifies or resets the current station address of a
1012 network interface. If Reset is TRUE, then the current station address
1013 is set ot the network interface's permanent address. If Reset if FALSE
1014 then the current station address is changed to the address specified by
1017 This routine calls ::Ax88772MacAddressSet to update the MAC address
1018 in the network adapter.
1020 @param [in] pSimpleNetwork Protocol instance pointer
1021 @param [in] bReset Flag used to reset the station address to the
1022 network interface's permanent address.
1023 @param [in] pNew New station address to be used for the network
1026 @retval EFI_SUCCESS This operation was successful.
1027 @retval EFI_NOT_STARTED The network interface was not started.
1028 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1029 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1030 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1031 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1037 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
1039 IN EFI_MAC_ADDRESS
* pNew
1042 NIC_DEVICE
* pNicDevice
;
1043 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1049 // Verify the parameters
1051 if (( NULL
!= pSimpleNetwork
)
1052 && ( NULL
!= pSimpleNetwork
->Mode
)
1053 && (( !bReset
) || ( bReset
&& ( NULL
!= pNew
)))) {
1055 // Verify that the adapter is already started
1057 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
1058 pMode
= pSimpleNetwork
->Mode
;
1059 if ( EfiSimpleNetworkStarted
== pMode
->State
) {
1061 // Determine the adapter MAC address
1065 // Use the permanent address
1067 CopyMem ( &pMode
->CurrentAddress
,
1068 &pMode
->PermanentAddress
,
1069 sizeof ( pMode
->CurrentAddress
));
1073 // Use the specified address
1075 CopyMem ( &pMode
->CurrentAddress
,
1077 sizeof ( pMode
->CurrentAddress
));
1081 // Update the address on the adapter
1083 Status
= Ax88772MacAddressSet ( pNicDevice
, &pMode
->CurrentAddress
.Addr
[0]);
1086 Status
= EFI_NOT_STARTED
;
1090 Status
= EFI_INVALID_PARAMETER
;
1094 // Return the operation status
1096 DBG_EXIT_STATUS ( Status
);
1102 This function resets or collects the statistics on a network interface.
1103 If the size of the statistics table specified by StatisticsSize is not
1104 big enough for all of the statistics that are collected by the network
1105 interface, then a partial buffer of statistics is returned in
1108 @param [in] pSimpleNetwork Protocol instance pointer
1109 @param [in] bReset Set to TRUE to reset the statistics for the network interface.
1110 @param [in, out] pStatisticsSize On input the size, in bytes, of StatisticsTable. On output
1111 the size, in bytes, of the resulting table of statistics.
1112 @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
1113 conains the statistics.
1115 @retval EFI_SUCCESS This operation was successful.
1116 @retval EFI_NOT_STARTED The network interface was not started.
1117 @retval EFI_BUFFER_TOO_SMALL The pStatisticsTable is NULL or the buffer is too small.
1118 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1119 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1120 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1121 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1127 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
1129 IN OUT UINTN
* pStatisticsSize
,
1130 OUT EFI_NETWORK_STATISTICS
* pStatisticsTable
1138 // This is not currently supported
1140 Status
= EFI_UNSUPPORTED
;
1143 // Return the operation status
1145 DBG_EXIT_STATUS ( Status
);
1151 This function stops a network interface. This call is only valid
1152 if the network interface is in the started state.
1154 @param [in] pSimpleNetwork Protocol instance pointer
1156 @retval EFI_SUCCESS This operation was successful.
1157 @retval EFI_NOT_STARTED The network interface was not started.
1158 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1159 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1160 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1161 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1167 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
1170 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1176 // Verify the parameters
1178 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1180 // Determine if the interface is started
1182 pMode
= pSimpleNetwork
->Mode
;
1183 if ( EfiSimpleNetworkStopped
!= pMode
->State
) {
1184 if ( EfiSimpleNetworkStarted
== pMode
->State
) {
1186 // Release the resources acquired in SN_Start
1190 // Mark the adapter as stopped
1192 pMode
->State
= EfiSimpleNetworkStopped
;
1193 Status
= EFI_SUCCESS
;
1196 Status
= EFI_UNSUPPORTED
;
1200 Status
= EFI_NOT_STARTED
;
1204 Status
= EFI_INVALID_PARAMETER
;
1208 // Return the operation status
1210 DBG_EXIT_STATUS ( Status
);
1216 This function releases the memory buffers assigned in the Initialize() call.
1217 Pending transmits and receives are lost, and interrupts are cleared and disabled.
1218 After this call, only Initialize() and Stop() calls may be used.
1220 @param [in] pSimpleNetwork Protocol instance pointer
1222 @retval EFI_SUCCESS This operation was successful.
1223 @retval EFI_NOT_STARTED The network interface was not started.
1224 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1225 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1226 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1227 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1233 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
1236 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1243 // Verify the parameters
1245 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1247 // Determine if the interface is already started
1249 pMode
= pSimpleNetwork
->Mode
;
1250 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
1254 RxFilter
= pMode
->ReceiveFilterSetting
;
1255 pMode
->ReceiveFilterSetting
= 0;
1256 Status
= SN_Reset ( pSimpleNetwork
, FALSE
);
1257 pMode
->ReceiveFilterSetting
= RxFilter
;
1258 if ( !EFI_ERROR ( Status
)) {
1260 // Release the resources acquired by SN_Initialize
1264 // Update the network state
1266 pMode
->State
= EfiSimpleNetworkStarted
;
1270 Status
= EFI_NOT_STARTED
;
1274 Status
= EFI_INVALID_PARAMETER
;
1278 // Return the operation status
1280 DBG_EXIT_STATUS ( Status
);
1286 Send a packet over the network.
1288 This function places the packet specified by Header and Buffer on
1289 the transmit queue. This function performs a non-blocking transmit
1290 operation. When the transmit is complete, the buffer is returned
1291 via the GetStatus() call.
1293 This routine calls ::Ax88772Rx to empty the network adapter of
1294 receive packets. The routine then passes the transmit packet
1295 to the network adapter.
1297 @param [in] pSimpleNetwork Protocol instance pointer
1298 @param [in] HeaderSize The size, in bytes, of the media header to be filled in by
1299 the Transmit() function. If HeaderSize is non-zero, then
1300 it must be equal to SimpleNetwork->Mode->MediaHeaderSize
1301 and DestAddr and Protocol parameters must not be NULL.
1302 @param [in] BufferSize The size, in bytes, of the entire packet (media header and
1303 data) to be transmitted through the network interface.
1304 @param [in] pBuffer A pointer to the packet (media header followed by data) to
1305 to be transmitted. This parameter can not be NULL. If
1306 HeaderSize is zero, then the media header is Buffer must
1307 already be filled in by the caller. If HeaderSize is nonzero,
1308 then the media header will be filled in by the Transmit()
1310 @param [in] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
1311 this parameter is ignored. If HeaderSize is nonzero and
1312 SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
1313 is used for the source HW MAC address.
1314 @param [in] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
1315 this parameter is ignored.
1316 @param [in] pProtocol The type of header to build. If HeaderSize is zero, then
1317 this parameter is ignored.
1319 @retval EFI_SUCCESS This operation was successful.
1320 @retval EFI_NOT_STARTED The network interface was not started.
1321 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
1322 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
1323 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1324 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1325 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1331 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
1332 IN UINTN HeaderSize
,
1333 IN UINTN BufferSize
,
1335 IN EFI_MAC_ADDRESS
* pSrcAddr
,
1336 IN EFI_MAC_ADDRESS
* pDestAddr
,
1337 IN UINT16
* pProtocol
1340 RX_TX_PACKET Packet
;
1341 ETHERNET_HEADER
* pHeader
;
1342 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1343 NIC_DEVICE
* pNicDevice
;
1344 EFI_USB_IO_PROTOCOL
* pUsbIo
;
1346 EFI_TPL TplPrevious
;
1347 UINTN TransferLength
;
1348 UINT32 TransferStatus
;
1354 // Verify the parameters
1356 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1358 // The interface must be running
1360 pMode
= pSimpleNetwork
->Mode
;
1361 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
1363 // Synchronize with Ax88772Timer
1365 VERIFY_TPL ( TPL_AX88772
);
1366 TplPrevious
= gBS
->RaiseTPL ( TPL_AX88772
);
1369 // Update the link status
1371 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
1374 //No need to call receive to receive packet
1376 //Ax88772Rx ( pNicDevice, FALSE );
1377 pMode
->MediaPresent
= pNicDevice
->bLinkUp
;
1380 // Release the synchronization with Ax88772Timer
1382 gBS
->RestoreTPL ( TplPrevious
);
1383 if ( pMode
->MediaPresent
) {
1385 // Copy the packet into the USB buffer
1387 CopyMem ( &Packet
.Data
[0], pBuffer
, BufferSize
);
1388 Packet
.Length
= (UINT16
) BufferSize
;
1391 // Transmit the packet
1393 pHeader
= (ETHERNET_HEADER
*) &Packet
.Data
[0];
1394 if ( 0 != HeaderSize
) {
1395 if ( NULL
!= pDestAddr
) {
1396 CopyMem ( &pHeader
->dest_addr
, pDestAddr
, PXE_HWADDR_LEN_ETHER
);
1398 if ( NULL
!= pSrcAddr
) {
1399 CopyMem ( &pHeader
->src_addr
, pSrcAddr
, PXE_HWADDR_LEN_ETHER
);
1402 CopyMem ( &pHeader
->src_addr
, &pMode
->CurrentAddress
.Addr
[0], PXE_HWADDR_LEN_ETHER
);
1404 if ( NULL
!= pProtocol
) {
1408 Type
= Packet
.Length
;
1410 Type
= (UINT16
)(( Type
>> 8 ) | ( Type
<< 8 ));
1411 pHeader
->type
= Type
;
1413 if ( Packet
.Length
< MIN_ETHERNET_PKT_SIZE
) {
1414 Packet
.Length
= MIN_ETHERNET_PKT_SIZE
;
1415 ZeroMem ( &Packet
.Data
[ BufferSize
],
1416 Packet
.Length
- BufferSize
);
1418 DEBUG (( DEBUG_TX
| DEBUG_INFO
,
1419 "TX: %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x %d bytes\r\n",
1435 Packet
.LengthBar
= ~Packet
.Length
;
1436 TransferLength
= sizeof ( Packet
.Length
)
1437 + sizeof ( Packet
.LengthBar
)
1441 // Work around USB bus driver bug where a timeout set by receive
1442 // succeeds but the timeout expires immediately after, causing the
1443 // transmit operation to timeout.
1445 pUsbIo
= pNicDevice
->pUsbIo
;
1446 Status
= pUsbIo
->UsbBulkTransfer ( pUsbIo
,
1452 if ( !EFI_ERROR ( Status
)) {
1453 Status
= TransferStatus
;
1455 if (( !EFI_ERROR ( Status
))
1456 && ( TransferLength
!= (UINTN
)( Packet
.Length
+ 4 ))) {
1457 Status
= EFI_WARN_WRITE_FAILURE
;
1459 if ( EFI_SUCCESS
== Status
) {
1460 pNicDevice
->pTxBuffer
= pBuffer
;
1463 DEBUG (( DEBUG_ERROR
| DEBUG_INFO
,
1464 "Ax88772 USB transmit error, TransferLength: %d, Status: %r\r\n",
1465 sizeof ( Packet
.Length
) + Packet
.Length
,
1468 // Reset the controller to fix the error
1470 if ( EFI_DEVICE_ERROR
== Status
) {
1471 SN_Reset ( pSimpleNetwork
, FALSE
);
1477 // No packets available.
1479 Status
= EFI_NOT_READY
;
1483 Status
= EFI_NOT_STARTED
;
1487 DEBUG (( DEBUG_ERROR
| DEBUG_INFO
,
1488 "Ax88772 invalid transmit parameter\r\n"
1489 " 0x%08x: HeaderSize\r\n"
1490 " 0x%08x: BufferSize\r\n"
1491 " 0x%08x: Buffer\r\n"
1492 " 0x%08x: SrcAddr\r\n"
1493 " 0x%08x: DestAddr\r\n"
1494 " 0x%04x: Protocol\r\n",
1501 Status
= EFI_INVALID_PARAMETER
;
1505 // Return the operation status
1507 DBG_EXIT_STATUS ( Status
);