2 Provides the Simple Network functions.
4 Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 This function updates the filtering on the receiver.
14 This support routine calls ::Ax88772MacAddressSet to update
15 the MAC address. This routine then rebuilds the multicast
16 hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
17 Finally this routine enables the receiver by calling
20 @param [in] pSimpleNetwork Simple network mode pointer
22 @retval EFI_SUCCESS This operation was successful.
23 @retval EFI_NOT_STARTED The network interface was not started.
24 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
25 EFI_SIMPLE_NETWORK_PROTOCOL structure.
26 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
27 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
32 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
35 EFI_SIMPLE_NETWORK_MODE
* pMode
;
36 NIC_DEVICE
* pNicDevice
;
41 // Set the MAC address
43 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
44 pMode
= pSimpleNetwork
->Mode
;
47 // Clear the multicast hash table
49 Ax88772MulticastClear ( pNicDevice
);
52 // Load the multicast hash table
54 if ( 0 != ( pMode
->ReceiveFilterSetting
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
)) {
55 for ( Index
= 0; Index
< pMode
->MCastFilterCount
; Index
++ ) {
57 // Enable the next multicast address
59 Ax88772MulticastSet ( pNicDevice
,
60 &pMode
->MCastFilter
[ Index
].Addr
[0]);
64 Status
= Ax88772RxControl ( pNicDevice
, pMode
->ReceiveFilterSetting
);
71 This function updates the SNP driver status.
73 This function gets the current interrupt and recycled transmit
74 buffer status from the network interface. The interrupt status
75 and the media status are returned as a bit mask in InterruptStatus.
76 If InterruptStatus is NULL, the interrupt status will not be read.
77 Upon successful return of the media status, the MediaPresent field
78 of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
79 of media status. If TxBuf is not NULL, a recycled transmit buffer
80 address will be retrived. If a recycled transmit buffer address
81 is returned in TxBuf, then the buffer has been successfully
82 transmitted, and the status for that buffer is cleared.
84 This function calls ::Ax88772Rx to update the media status and
85 queue any receive packets.
87 @param [in] pSimpleNetwork Protocol instance pointer
88 @param [in] pInterruptStatus A pointer to the bit mask of the current active interrupts.
89 If this is NULL, the interrupt status will not be read from
90 the device. If this is not NULL, the interrupt status will
91 be read from teh device. When the interrupt status is read,
92 it will also be cleared. Clearing the transmit interrupt
93 does not empty the recycled transmit buffer array.
94 @param [out] ppTxBuf Recycled transmit buffer address. The network interface will
95 not transmit if its internal recycled transmit buffer array is
96 full. Reading the transmit buffer does not clear the transmit
97 interrupt. If this is NULL, then the transmit buffer status
98 will not be read. If there are not transmit buffers to recycle
99 and TxBuf is not NULL, *TxBuf will be set to NULL.
101 @retval EFI_SUCCESS This operation was successful.
102 @retval EFI_NOT_STARTED The network interface was not started.
103 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
104 EFI_SIMPLE_NETWORK_PROTOCOL structure.
105 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
111 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
112 OUT UINT32
* pInterruptStatus
,
116 EFI_SIMPLE_NETWORK_MODE
* pMode
;
117 NIC_DEVICE
* pNicDevice
;
124 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
126 // Verify the parameters
128 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
130 // Return the transmit buffer
133 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
134 if (( NULL
!= ppTxBuf
) && ( NULL
!= pNicDevice
->pTxBuffer
)) {
135 *ppTxBuf
= pNicDevice
->pTxBuffer
;
136 pNicDevice
->pTxBuffer
= NULL
;
140 // Determine if interface is running
142 pMode
= pSimpleNetwork
->Mode
;
143 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
145 if ( pNicDevice
->LinkIdleCnt
> MAX_LINKIDLE_THRESHOLD
) {
147 bLinkUp
= pNicDevice
->bLinkUp
;
148 bSpeed100
= pNicDevice
->b100Mbps
;
149 bFullDuplex
= pNicDevice
->bFullDuplex
;
150 Status
= Ax88772NegotiateLinkComplete ( pNicDevice
,
151 &pNicDevice
->PollCount
,
152 &pNicDevice
->bComplete
,
153 &pNicDevice
->bLinkUp
,
154 &pNicDevice
->b100Mbps
,
155 &pNicDevice
->bFullDuplex
);
158 // Determine if the autonegotiation is complete
160 if ( pNicDevice
->bComplete
) {
161 if ( pNicDevice
->bLinkUp
) {
162 if (( bSpeed100
&& ( !pNicDevice
->b100Mbps
))
163 || (( !bSpeed100
) && pNicDevice
->b100Mbps
)
164 || ( bFullDuplex
&& ( !pNicDevice
->bFullDuplex
))
165 || (( !bFullDuplex
) && pNicDevice
->bFullDuplex
)) {
166 pNicDevice
->PollCount
= 0;
167 DEBUG (( EFI_D_INFO
, "Reset to establish proper link setup: %d Mbps, %a duplex\r\n",
168 pNicDevice
->b100Mbps
? 100 : 10, pNicDevice
->bFullDuplex
? "Full" : "Half"));
169 Status
= SN_Reset ( &pNicDevice
->SimpleNetwork
, FALSE
);
171 if (( !bLinkUp
) && pNicDevice
->bLinkUp
) {
173 // Display the autonegotiation status
175 DEBUG (( EFI_D_INFO
, "Link: Up, %d Mbps, %a duplex\r\n",
176 pNicDevice
->b100Mbps
? 100 : 10, pNicDevice
->bFullDuplex
? "Full" : "Half"));
179 pNicDevice
->LinkIdleCnt
= 0;
183 // Update the link status
185 if ( bLinkUp
&& ( !pNicDevice
->bLinkUp
)) {
186 DEBUG (( EFI_D_INFO
, "Link: Down\r\n"));
190 pMode
->MediaPresent
= pNicDevice
->bLinkUp
;
192 // Return the interrupt status
194 if ( NULL
!= pInterruptStatus
) {
195 *pInterruptStatus
= 0;
197 Status
= EFI_SUCCESS
;
200 if ( EfiSimpleNetworkStarted
== pMode
->State
) {
201 Status
= EFI_DEVICE_ERROR
;
204 Status
= EFI_NOT_STARTED
;
210 Status
= EFI_INVALID_PARAMETER
;
212 gBS
->RestoreTPL(TplPrevious
) ;
219 Resets the network adapter and allocates the transmit and receive buffers
220 required by the network interface; optionally, also requests allocation of
221 additional transmit and receive buffers. This routine must be called before
222 any other routine in the Simple Network protocol is called.
224 @param [in] pSimpleNetwork Protocol instance pointer
225 @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
226 @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
228 @retval EFI_SUCCESS This operation was successful.
229 @retval EFI_NOT_STARTED The network interface was not started.
230 @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and receive buffers
231 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
232 EFI_SIMPLE_NETWORK_PROTOCOL structure.
233 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
234 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
240 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
241 IN UINTN ExtraRxBufferSize
,
242 IN UINTN ExtraTxBufferSize
245 EFI_SIMPLE_NETWORK_MODE
* pMode
;
250 TplPrevious
= gBS
->RaiseTPL (TPL_CALLBACK
);
252 // Verify the parameters
254 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
256 // Determine if the interface is already started
258 pMode
= pSimpleNetwork
->Mode
;
259 if ( EfiSimpleNetworkStarted
== pMode
->State
) {
260 if (( 0 == ExtraRxBufferSize
) && ( 0 == ExtraTxBufferSize
)) {
264 TmpState
= pMode
->State
;
265 pMode
->State
= EfiSimpleNetworkInitialized
;
266 Status
= SN_Reset ( pSimpleNetwork
, FALSE
);
267 if ( EFI_ERROR ( Status
)) {
269 // Update the network state
271 pMode
->State
= TmpState
;
272 DEBUG (( EFI_D_ERROR
, "SN_reset failed\n"));
276 DEBUG (( EFI_D_ERROR
, "Increase ExtraRxBufferSize = %d ExtraTxBufferSize=%d\n",
277 ExtraRxBufferSize
, ExtraTxBufferSize
));
278 Status
= EFI_UNSUPPORTED
;
282 Status
= EFI_NOT_STARTED
;
286 Status
= EFI_INVALID_PARAMETER
;
288 gBS
->RestoreTPL (TplPrevious
);
295 This function converts a multicast IP address to a multicast HW MAC address
296 for all packet transactions.
298 @param [in] pSimpleNetwork Protocol instance pointer
299 @param [in] bIPv6 Set to TRUE if the multicast IP address is IPv6 [RFC2460].
300 Set to FALSE if the multicast IP address is IPv4 [RFC 791].
301 @param [in] pIP The multicast IP address that is to be converted to a
302 multicast HW MAC address.
303 @param [in] pMAC The multicast HW MAC address that is to be generated from IP.
305 @retval EFI_SUCCESS This operation was successful.
306 @retval EFI_NOT_STARTED The network interface was not started.
307 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
308 EFI_SIMPLE_NETWORK_PROTOCOL structure.
309 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
310 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
316 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
318 IN EFI_IP_ADDRESS
* pIP
,
319 OUT EFI_MAC_ADDRESS
* pMAC
325 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
327 // Get pointer to SNP driver instance for *this.
329 if (pSimpleNetwork
== NULL
) {
330 gBS
->RestoreTPL(TplPrevious
);
331 return EFI_INVALID_PARAMETER
;
334 if (pIP
== NULL
|| pMAC
== NULL
) {
335 gBS
->RestoreTPL(TplPrevious
);
336 return EFI_INVALID_PARAMETER
;
340 Status
= EFI_UNSUPPORTED
;
344 // check if the ip given is a mcast IP
346 if ((pIP
->v4
.Addr
[0] & 0xF0) != 0xE0) {
347 gBS
->RestoreTPL(TplPrevious
);
348 return EFI_INVALID_PARAMETER
;
351 if (pSimpleNetwork
->Mode
->State
== EfiSimpleNetworkInitialized
)
353 pMAC
->Addr
[0] = 0x01;
354 pMAC
->Addr
[1] = 0x00;
355 pMAC
->Addr
[2] = 0x5e;
356 pMAC
->Addr
[3] = (UINT8
) (pIP
->v4
.Addr
[1] & 0x7f);
357 pMAC
->Addr
[4] = (UINT8
) pIP
->v4
.Addr
[2];
358 pMAC
->Addr
[5] = (UINT8
) pIP
->v4
.Addr
[3];
359 Status
= EFI_SUCCESS
;
361 else if (pSimpleNetwork
->Mode
->State
== EfiSimpleNetworkStarted
) {
362 Status
= EFI_DEVICE_ERROR
;
365 Status
= EFI_NOT_STARTED
;
367 gBS
->RestoreTPL(TplPrevious
);
375 This function performs read and write operations on the NVRAM device
376 attached to a network interface.
378 @param [in] pSimpleNetwork Protocol instance pointer
379 @param [in] ReadWrite TRUE for read operations, FALSE for write operations.
380 @param [in] Offset Byte offset in the NVRAM device at which to start the
381 read or write operation. This must be a multiple of
382 NvRamAccessSize and less than NvRamSize.
383 @param [in] BufferSize The number of bytes to read or write from the NVRAM device.
384 This must also be a multiple of NvramAccessSize.
385 @param [in, out] pBuffer A pointer to the data buffer.
387 @retval EFI_SUCCESS This operation was successful.
388 @retval EFI_NOT_STARTED The network interface was not started.
389 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
390 EFI_SIMPLE_NETWORK_PROTOCOL structure.
391 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
392 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
398 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
399 IN BOOLEAN ReadWrite
,
402 IN OUT VOID
* pBuffer
407 // This is not currently supported
409 Status
= EFI_UNSUPPORTED
;
415 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
423 NIC_DEVICE
* pNicDevice
;
425 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
426 for ( offset
= 0; offset
< BufLength
; ){
427 pLength
= (UINT16
*) (pNicDevice
->pBulkInBuff
+ offset
);
428 pLengthBar
= (UINT16
*) (pNicDevice
->pBulkInBuff
+ offset
+2);
431 *pLengthBar
&= 0x7ff;
432 *pLengthBar
|= 0xf800;
434 if ((*pLength
^ *pLengthBar
) != 0xFFFF) {
435 DEBUG (( EFI_D_ERROR
, "Pkt length error. BufLength = %d\n", BufLength
));
439 if (TRUE
== pNicDevice
->pNextFill
->f_Used
) {
443 pData
= pNicDevice
->pBulkInBuff
+ offset
+ 4;
444 pNicDevice
->pNextFill
->f_Used
= TRUE
;
445 pNicDevice
->pNextFill
->Length
= *pLength
;
446 CopyMem (&pNicDevice
->pNextFill
->Data
[0], pData
, *pLength
);
448 pNicDevice
->pNextFill
= pNicDevice
->pNextFill
->pNext
;
449 offset
+= ((*pLength
+ HW_HDR_LENGTH
- 1) &~3) + 1;
450 pNicDevice
->PktCntInQueue
++;
459 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
460 OUT UINTN
* pHeaderSize
,
461 OUT UINTN
* pBufferSize
,
463 OUT EFI_MAC_ADDRESS
* pSrcAddr
,
464 OUT EFI_MAC_ADDRESS
* pDestAddr
,
465 OUT UINT16
* pProtocol
468 EFI_SIMPLE_NETWORK_MODE
* pMode
;
469 NIC_DEVICE
* pNicDevice
;
473 EFI_USB_IO_PROTOCOL
*pUsbIo
;
475 UINT32 TransferStatus
;
477 TplPrevious
= gBS
->RaiseTPL (TPL_CALLBACK
);
480 // Verify the parameters
482 if (( NULL
!= pSimpleNetwork
) &&
483 ( NULL
!= pSimpleNetwork
->Mode
) &&
484 (NULL
!= pBufferSize
) &&
487 // The interface must be running
489 pMode
= pSimpleNetwork
->Mode
;
490 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
492 // Update the link status
494 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
495 pNicDevice
->LinkIdleCnt
++;
496 pMode
->MediaPresent
= pNicDevice
->bLinkUp
;
498 if ( pMode
->MediaPresent
&& pNicDevice
->bComplete
) {
501 if (pNicDevice
->PktCntInQueue
!= 0 ) {
502 DEBUG (( EFI_D_INFO
, "pNicDevice->PktCntInQueue = %d\n",
503 pNicDevice
->PktCntInQueue
));
506 LengthInBytes
= MAX_BULKIN_SIZE
;
507 if (pNicDevice
->PktCntInQueue
== 0 ){
509 // Attempt to do bulk in
511 SetMem (&pNicDevice
->pBulkInBuff
[0], 4, 0);
512 pUsbIo
= pNicDevice
->pUsbIo
;
513 Status
= pUsbIo
->UsbBulkTransfer ( pUsbIo
,
514 USB_ENDPOINT_DIR_IN
| BULK_IN_ENDPOINT
,
515 &pNicDevice
->pBulkInBuff
[0],
520 if (LengthInBytes
!= 0 && !EFI_ERROR(Status
) && !EFI_ERROR(TransferStatus
) ){
521 FillPkt2Queue(pSimpleNetwork
, LengthInBytes
);
525 pFirstFill
= pNicDevice
->pFirstFill
;
527 if (TRUE
== pFirstFill
->f_Used
) {
528 ETHERNET_HEADER
* pHeader
;
529 pNicDevice
->LinkIdleCnt
= 0;
530 CopyMem (pBuffer
, &pFirstFill
->Data
[0], pFirstFill
->Length
);
531 pHeader
= (ETHERNET_HEADER
*) &pFirstFill
->Data
[0];
533 DEBUG (( EFI_D_INFO
, "RX: %02x-%02x-%02x-%02x-%02x-%02x "
534 "%02x-%02x-%02x-%02x-%02x-%02x %02x-%02x %d bytes\r\n",
545 pFirstFill
->Data
[10],
546 pFirstFill
->Data
[11],
547 pFirstFill
->Data
[12],
548 pFirstFill
->Data
[13],
549 pFirstFill
->Length
));
551 if ( NULL
!= pHeaderSize
) {
552 *pHeaderSize
= sizeof ( *pHeader
);
554 if ( NULL
!= pDestAddr
) {
555 CopyMem ( pDestAddr
, &pHeader
->dest_addr
, PXE_HWADDR_LEN_ETHER
);
557 if ( NULL
!= pSrcAddr
) {
558 CopyMem ( pSrcAddr
, &pHeader
->src_addr
, PXE_HWADDR_LEN_ETHER
);
560 if ( NULL
!= pProtocol
) {
561 Type
= pHeader
->type
;
562 Type
= (UINT16
)(( Type
>> 8 ) | ( Type
<< 8 ));
565 Status
= EFI_SUCCESS
;
566 if (*pBufferSize
< pFirstFill
->Length
) {
567 DEBUG (( EFI_D_ERROR
, "RX: Buffer was too small"));
568 Status
= EFI_BUFFER_TOO_SMALL
;
570 *pBufferSize
= pFirstFill
->Length
;
571 pFirstFill
->f_Used
= FALSE
;
572 pNicDevice
->pFirstFill
= pFirstFill
->pNext
;
573 pNicDevice
->PktCntInQueue
--;
576 pNicDevice
->LinkIdleCnt
++;
577 Status
= EFI_NOT_READY
;
584 pNicDevice
->LinkIdleCnt
++;
585 Status
= EFI_NOT_READY
;
590 if (EfiSimpleNetworkStarted
== pMode
->State
) {
591 Status
= EFI_DEVICE_ERROR
;
594 Status
= EFI_NOT_STARTED
;
599 Status
= EFI_INVALID_PARAMETER
;
601 gBS
->RestoreTPL (TplPrevious
);
606 This function is used to enable and disable the hardware and software receive
607 filters for the underlying network device.
609 The receive filter change is broken down into three steps:
611 1. The filter mask bits that are set (ON) in the Enable parameter
612 are added to the current receive filter settings.
614 2. The filter mask bits that are set (ON) in the Disable parameter
615 are subtracted from the updated receive filter settins.
617 3. If the resulting filter settigns is not supported by the hardware
618 a more liberal setting is selected.
620 If the same bits are set in the Enable and Disable parameters, then the bits
621 in the Disable parameter takes precedence.
623 If the ResetMCastFilter parameter is TRUE, then the multicast address list
624 filter is disabled (irregardless of what other multicast bits are set in
625 the enable and Disable parameters). The SNP->Mode->MCastFilterCount field
626 is set to zero. The SNP->Mode->MCastFilter contents are undefined.
628 After enableing or disabling receive filter settings, software should
629 verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
630 SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
632 Note: Some network drivers and/or devices will automatically promote
633 receive filter settings if the requested setting can not be honored.
634 For example, if a request for four multicast addresses is made and
635 the underlying hardware only supports two multicast addresses the
636 driver might set the promiscuous or promiscuous multicast receive filters
637 instead. The receiving software is responsible for discarding any extra
638 packets that get through the hardware receive filters.
640 If ResetMCastFilter is TRUE, then the multicast receive filter list
641 on the network interface will be reset to the default multicast receive
642 filter list. If ResetMCastFilter is FALSE, and this network interface
643 allows the multicast receive filter list to be modified, then the
644 MCastFilterCnt and MCastFilter are used to update the current multicast
645 receive filter list. The modified receive filter list settings can be
646 found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
648 This routine calls ::ReceiveFilterUpdate to update the receive
649 state in the network adapter.
651 @param [in] pSimpleNetwork Protocol instance pointer
652 @param [in] Enable A bit mask of receive filters to enable on the network interface.
653 @param [in] Disable A bit mask of receive filters to disable on the network interface.
654 For backward compatibility with EFI 1.1 platforms, the
655 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
656 when the ResetMCastFilter parameter is TRUE.
657 @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
658 filters on the network interface to their default values.
659 @param [in] MCastFilterCnt Number of multicast HW MAC address in the new MCastFilter list.
660 This value must be less than or equal to the MaxMCastFilterCnt
661 field of EFI_SIMPLE_NETWORK_MODE. This field is optional if
662 ResetMCastFilter is TRUE.
663 @param [in] pMCastFilter A pointer to a list of new multicast receive filter HW MAC
664 addresses. This list will replace any existing multicast
665 HW MAC address list. This field is optional if ResetMCastFilter
668 @retval EFI_SUCCESS This operation was successful.
669 @retval EFI_NOT_STARTED The network interface was not started.
670 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
671 EFI_SIMPLE_NETWORK_PROTOCOL structure.
672 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
673 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
679 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
683 #define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01
684 #define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02
685 #define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04
686 #define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08
687 #define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10
689 IN BOOLEAN bResetMCastFilter
,
690 IN UINTN MCastFilterCnt
,
691 IN EFI_MAC_ADDRESS
* pMCastFilter
694 EFI_SIMPLE_NETWORK_MODE
* pMode
;
695 EFI_STATUS Status
= EFI_SUCCESS
;
698 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
699 pMode
= pSimpleNetwork
->Mode
;
701 if (pSimpleNetwork
== NULL
) {
702 gBS
->RestoreTPL(TplPrevious
);
703 return EFI_INVALID_PARAMETER
;
706 switch (pMode
->State
) {
707 case EfiSimpleNetworkInitialized
:
709 case EfiSimpleNetworkStopped
:
710 Status
= EFI_NOT_STARTED
;
711 gBS
->RestoreTPL(TplPrevious
);
714 Status
= EFI_DEVICE_ERROR
;
715 gBS
->RestoreTPL(TplPrevious
);
720 // check if we are asked to enable or disable something that the UNDI
721 // does not even support!
723 if (((Enable
&~pMode
->ReceiveFilterMask
) != 0) ||
724 ((Disable
&~pMode
->ReceiveFilterMask
) != 0)) {
725 Status
= EFI_INVALID_PARAMETER
;
726 gBS
->RestoreTPL(TplPrevious
);
730 if (bResetMCastFilter
) {
731 Disable
|= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
& pMode
->ReceiveFilterMask
);
732 pMode
->MCastFilterCount
= 0;
733 if ( (0 == (pMode
->ReceiveFilterSetting
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
))
734 && Enable
== 0 && Disable
== 2) {
735 gBS
->RestoreTPL(TplPrevious
);
740 if (MCastFilterCnt
!= 0) {
742 EFI_MAC_ADDRESS
* pMulticastAddress
;
743 pMulticastAddress
= pMCastFilter
;
745 if ((MCastFilterCnt
> pMode
->MaxMCastFilterCount
) ||
746 (pMCastFilter
== NULL
)) {
747 Status
= EFI_INVALID_PARAMETER
;
748 gBS
->RestoreTPL(TplPrevious
);
752 for ( i
= 0 ; i
< MCastFilterCnt
; i
++ ) {
754 tmp
= pMulticastAddress
->Addr
[0];
755 if ( (tmp
& 0x01) != 0x01 ) {
756 gBS
->RestoreTPL(TplPrevious
);
757 return EFI_INVALID_PARAMETER
;
762 pMode
->MCastFilterCount
= (UINT32
)MCastFilterCnt
;
763 CopyMem (&pMode
->MCastFilter
[0],
765 MCastFilterCnt
* sizeof ( EFI_MAC_ADDRESS
));
769 if (Enable
== 0 && Disable
== 0 && !bResetMCastFilter
&& MCastFilterCnt
== 0) {
770 Status
= EFI_SUCCESS
;
771 gBS
->RestoreTPL(TplPrevious
);
775 if ((Enable
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0 && MCastFilterCnt
== 0) {
776 Status
= EFI_INVALID_PARAMETER
;
777 gBS
->RestoreTPL(TplPrevious
);
781 pMode
->ReceiveFilterSetting
|= Enable
;
782 pMode
->ReceiveFilterSetting
&= ~Disable
;
783 Status
= ReceiveFilterUpdate (pSimpleNetwork
);
785 if (EFI_DEVICE_ERROR
== Status
|| EFI_INVALID_PARAMETER
== Status
)
786 Status
= EFI_SUCCESS
;
788 gBS
->RestoreTPL(TplPrevious
);
793 Reset the network adapter.
795 Resets a network adapter and reinitializes it with the parameters that
796 were provided in the previous call to Initialize (). The transmit and
797 receive queues are cleared. Receive filters, the station address, the
798 statistics, and the multicast-IP-to-HW MAC addresses are not reset by
801 This routine calls ::Ax88772Reset to perform the adapter specific
802 reset operation. This routine also starts the link negotiation
803 by calling ::Ax88772NegotiateLinkStart.
805 @param [in] pSimpleNetwork Protocol instance pointer
806 @param [in] bExtendedVerification Indicates that the driver may perform a more
807 exhaustive verification operation of the device
810 @retval EFI_SUCCESS This operation was successful.
811 @retval EFI_NOT_STARTED The network interface was not started.
812 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
813 EFI_SIMPLE_NETWORK_PROTOCOL structure.
814 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
815 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
821 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
822 IN BOOLEAN bExtendedVerification
825 EFI_SIMPLE_NETWORK_MODE
* pMode
;
826 NIC_DEVICE
* pNicDevice
;
830 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
832 // Verify the parameters
834 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
835 pMode
= pSimpleNetwork
->Mode
;
836 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
838 // Update the device state
840 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
841 pNicDevice
->bComplete
= FALSE
;
842 pNicDevice
->bLinkUp
= FALSE
;
843 pNicDevice
->bHavePkt
= FALSE
;
844 pMode
= pSimpleNetwork
->Mode
;
845 pMode
->MediaPresent
= FALSE
;
850 Status
= Ax88772Reset ( pNicDevice
);
851 if ( !EFI_ERROR ( Status
)) {
853 // Update the receive filters in the adapter
855 Status
= ReceiveFilterUpdate ( pSimpleNetwork
);
858 // Try to get a connection to the network
860 if ( !EFI_ERROR ( Status
)) {
862 // Start the autonegotiation
864 Status
= Ax88772NegotiateLinkStart ( pNicDevice
);
869 if (EfiSimpleNetworkStarted
== pMode
->State
) {
870 Status
= EFI_DEVICE_ERROR
;
873 Status
= EFI_NOT_STARTED
;
878 Status
= EFI_INVALID_PARAMETER
;
880 gBS
->RestoreTPL ( TplPrevious
);
885 Initialize the simple network protocol.
887 This routine calls ::Ax88772MacAddressGet to obtain the
890 @param [in] pNicDevice NIC_DEVICE_INSTANCE pointer
892 @retval EFI_SUCCESS Setup was successful
897 IN NIC_DEVICE
* pNicDevice
902 EFI_SIMPLE_NETWORK_MODE
* pMode
;
903 EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
;
905 RX_PKT
* pCurr
= NULL
;
906 RX_PKT
* pPrev
= NULL
;
908 pSimpleNetwork
= &pNicDevice
->SimpleNetwork
;
909 pSimpleNetwork
->Revision
= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
;
910 pSimpleNetwork
->Start
= (EFI_SIMPLE_NETWORK_START
)SN_Start
;
911 pSimpleNetwork
->Stop
= (EFI_SIMPLE_NETWORK_STOP
)SN_Stop
;
912 pSimpleNetwork
->Initialize
= (EFI_SIMPLE_NETWORK_INITIALIZE
)SN_Initialize
;
913 pSimpleNetwork
->Reset
= (EFI_SIMPLE_NETWORK_RESET
)SN_Reset
;
914 pSimpleNetwork
->Shutdown
= (EFI_SIMPLE_NETWORK_SHUTDOWN
)SN_Shutdown
;
915 pSimpleNetwork
->ReceiveFilters
= (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS
)SN_ReceiveFilters
;
916 pSimpleNetwork
->StationAddress
= (EFI_SIMPLE_NETWORK_STATION_ADDRESS
)SN_StationAddress
;
917 pSimpleNetwork
->Statistics
= (EFI_SIMPLE_NETWORK_STATISTICS
)SN_Statistics
;
918 pSimpleNetwork
->MCastIpToMac
= (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC
)SN_MCastIPtoMAC
;
919 pSimpleNetwork
->NvData
= (EFI_SIMPLE_NETWORK_NVDATA
)SN_NvData
;
920 pSimpleNetwork
->GetStatus
= (EFI_SIMPLE_NETWORK_GET_STATUS
)SN_GetStatus
;
921 pSimpleNetwork
->Transmit
= (EFI_SIMPLE_NETWORK_TRANSMIT
)SN_Transmit
;
922 pSimpleNetwork
->Receive
= (EFI_SIMPLE_NETWORK_RECEIVE
)SN_Receive
;
923 pSimpleNetwork
->WaitForPacket
= NULL
;
924 pMode
= &pNicDevice
->SimpleNetworkData
;
925 pSimpleNetwork
->Mode
= pMode
;
926 pMode
->State
= EfiSimpleNetworkStopped
;
927 pMode
->HwAddressSize
= PXE_HWADDR_LEN_ETHER
;
928 pMode
->MediaHeaderSize
= sizeof ( ETHERNET_HEADER
);
929 pMode
->MaxPacketSize
= MAX_ETHERNET_PKT_SIZE
;
930 pMode
->NvRamSize
= 0;
931 pMode
->NvRamAccessSize
= 0;
932 pMode
->ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
933 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
934 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
935 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
936 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
937 pMode
->ReceiveFilterSetting
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
938 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
939 pMode
->MaxMCastFilterCount
= MAX_MCAST_FILTER_CNT
;
940 pMode
->MCastFilterCount
= 0;
941 SetMem ( &pMode
->BroadcastAddress
,
942 PXE_HWADDR_LEN_ETHER
,
944 pMode
->IfType
= EfiNetworkInterfaceUndi
;
945 pMode
->MacAddressChangeable
= TRUE
;
946 pMode
->MultipleTxSupported
= FALSE
;
947 pMode
->MediaPresentSupported
= TRUE
;
948 pMode
->MediaPresent
= FALSE
;
949 pNicDevice
->LinkIdleCnt
= 0;
951 // Read the MAC address
953 pNicDevice
->PhyId
= PHY_ID_INTERNAL
;
954 pNicDevice
->b100Mbps
= TRUE
;
955 pNicDevice
->bFullDuplex
= TRUE
;
957 Status
= Ax88772MacAddressGet (
959 &pMode
->PermanentAddress
.Addr
[0]);
961 if ( !EFI_ERROR ( Status
)) {
964 // Use the hardware address as the current address
967 CopyMem ( &pMode
->CurrentAddress
,
968 &pMode
->PermanentAddress
,
969 PXE_HWADDR_LEN_ETHER
);
971 CopyMem ( &pNicDevice
->MAC
,
972 &pMode
->PermanentAddress
,
973 PXE_HWADDR_LEN_ETHER
);
975 pNicDevice
->PktCntInQueue
= 0;
977 for ( i
= 0 ; i
< MAX_QUEUE_SIZE
; i
++) {
978 Status
= gBS
->AllocatePool ( EfiRuntimeServicesData
,
981 if ( EFI_ERROR(Status
)) {
982 DEBUG (( EFI_D_ERROR
, "Memory are not enough\n"));
985 pCurr
->f_Used
= FALSE
;
988 pPrev
->pNext
= pCurr
;
991 pNicDevice
->QueueHead
= pCurr
;
994 if (MAX_QUEUE_SIZE
- 1 == i
) {
995 pCurr
->pNext
= pNicDevice
->QueueHead
;
1001 pNicDevice
->pNextFill
= pNicDevice
->QueueHead
;
1002 pNicDevice
->pFirstFill
= pNicDevice
->QueueHead
;
1004 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
,
1006 (VOID
**) &pNicDevice
->pBulkInBuff
);
1008 if (EFI_ERROR(Status
)) {
1009 DEBUG (( EFI_D_ERROR
, "gBS->AllocatePool for pBulkInBuff error. Status = %r\n",
1015 DEBUG (( EFI_D_ERROR
, "Ax88772MacAddressGet error. Status = %r\n", Status
));
1019 Status
= gBS
->AllocatePool ( EfiRuntimeServicesData
,
1020 sizeof ( RX_TX_PACKET
),
1021 (VOID
**) &pNicDevice
->pRxTest
);
1023 if (EFI_ERROR (Status
)) {
1024 DEBUG (( EFI_D_ERROR
, "gBS->AllocatePool:pNicDevice->pRxTest error. Status = %r\n",
1029 Status
= gBS
->AllocatePool ( EfiRuntimeServicesData
,
1030 sizeof ( RX_TX_PACKET
),
1031 (VOID
**) &pNicDevice
->pTxTest
);
1033 if (EFI_ERROR (Status
)) {
1034 DEBUG (( EFI_D_ERROR
, "gBS->AllocatePool:pNicDevice->pTxTest error. Status = %r\n",
1036 gBS
->FreePool (pNicDevice
->pRxTest
);
1044 This routine starts the network interface.
1046 @param [in] pSimpleNetwork Protocol instance pointer
1048 @retval EFI_SUCCESS This operation was successful.
1049 @retval EFI_ALREADY_STARTED The network interface was already started.
1050 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1051 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1052 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1053 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1059 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
1062 NIC_DEVICE
* pNicDevice
;
1063 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1065 EFI_TPL TplPrevious
;
1067 RX_PKT
* pCurr
= NULL
;
1069 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
1071 // Verify the parameters
1073 Status
= EFI_INVALID_PARAMETER
;
1074 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1075 pMode
= pSimpleNetwork
->Mode
;
1076 if ( EfiSimpleNetworkStopped
== pMode
->State
) {
1078 // Initialize the mode structuref
1079 // NVRAM access is not supported
1081 ZeroMem ( pMode
, sizeof ( *pMode
));
1083 pMode
->State
= EfiSimpleNetworkStarted
;
1084 pMode
->HwAddressSize
= PXE_HWADDR_LEN_ETHER
;
1085 pMode
->MediaHeaderSize
= sizeof ( ETHERNET_HEADER
);
1086 pMode
->MaxPacketSize
= MAX_ETHERNET_PKT_SIZE
;
1087 pMode
->ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
1088 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
1089 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
1090 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
1091 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
1092 pMode
->ReceiveFilterSetting
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
1093 pMode
->MaxMCastFilterCount
= MAX_MCAST_FILTER_CNT
;
1094 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
1095 Status
= Ax88772MacAddressGet ( pNicDevice
, &pMode
->PermanentAddress
.Addr
[0]);
1096 CopyMem ( &pMode
->CurrentAddress
,
1097 &pMode
->PermanentAddress
,
1098 sizeof ( pMode
->CurrentAddress
));
1099 SetMem(&pMode
->BroadcastAddress
, PXE_HWADDR_LEN_ETHER
, 0xff);
1100 pMode
->IfType
= EfiNetworkInterfaceUndi
;
1101 pMode
->MacAddressChangeable
= TRUE
;
1102 pMode
->MultipleTxSupported
= FALSE
;
1103 pMode
->MediaPresentSupported
= TRUE
;
1104 pMode
->MediaPresent
= FALSE
;
1105 pNicDevice
->PktCntInQueue
= 0;
1106 pNicDevice
->pNextFill
= pNicDevice
->QueueHead
;
1107 pNicDevice
->pFirstFill
= pNicDevice
->QueueHead
;
1108 pCurr
= pNicDevice
->QueueHead
;
1110 for ( i
= 0 ; i
< MAX_QUEUE_SIZE
; i
++) {
1111 pCurr
->f_Used
= FALSE
;
1112 pCurr
= pCurr
->pNext
;
1117 Status
= EFI_ALREADY_STARTED
;
1120 gBS
->RestoreTPL ( TplPrevious
);
1126 Set the MAC address.
1128 This function modifies or resets the current station address of a
1129 network interface. If Reset is TRUE, then the current station address
1130 is set ot the network interface's permanent address. If Reset if FALSE
1131 then the current station address is changed to the address specified by
1134 This routine calls ::Ax88772MacAddressSet to update the MAC address
1135 in the network adapter.
1137 @param [in] pSimpleNetwork Protocol instance pointer
1138 @param [in] bReset Flag used to reset the station address to the
1139 network interface's permanent address.
1140 @param [in] pNew New station address to be used for the network
1143 @retval EFI_SUCCESS This operation was successful.
1144 @retval EFI_NOT_STARTED The network interface was not started.
1145 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1146 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1147 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1148 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1154 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
1156 IN EFI_MAC_ADDRESS
* pNew
1159 NIC_DEVICE
* pNicDevice
;
1160 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1162 EFI_TPL TplPrevious
;
1164 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
1166 // Verify the parameters
1168 if (( NULL
!= pSimpleNetwork
)
1169 && ( NULL
!= pSimpleNetwork
->Mode
)
1170 && (( bReset
) || ( ( !bReset
) && ( NULL
!= pNew
)))) {
1172 // Verify that the adapter is already started
1174 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
1175 pMode
= pSimpleNetwork
->Mode
;
1176 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
1178 // Determine the adapter MAC address
1182 // Use the permanent address
1184 CopyMem ( &pMode
->CurrentAddress
,
1185 &pMode
->PermanentAddress
,
1186 sizeof ( pMode
->CurrentAddress
));
1190 // Use the specified address
1192 CopyMem ( &pMode
->CurrentAddress
,
1194 sizeof ( pMode
->CurrentAddress
));
1198 // Update the address on the adapter
1200 Status
= Ax88772MacAddressSet ( pNicDevice
, &pMode
->CurrentAddress
.Addr
[0]);
1203 if (EfiSimpleNetworkStarted
== pMode
->State
) {
1204 Status
= EFI_DEVICE_ERROR
;
1207 Status
= EFI_NOT_STARTED
;
1212 Status
= EFI_INVALID_PARAMETER
;
1214 gBS
->RestoreTPL ( TplPrevious
);
1220 This function resets or collects the statistics on a network interface.
1221 If the size of the statistics table specified by StatisticsSize is not
1222 big enough for all of the statistics that are collected by the network
1223 interface, then a partial buffer of statistics is returned in
1226 @param [in] pSimpleNetwork Protocol instance pointer
1227 @param [in] bReset Set to TRUE to reset the statistics for the network interface.
1228 @param [in, out] pStatisticsSize On input the size, in bytes, of StatisticsTable. On output
1229 the size, in bytes, of the resulting table of statistics.
1230 @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
1231 conains the statistics.
1233 @retval EFI_SUCCESS This operation was successful.
1234 @retval EFI_NOT_STARTED The network interface was not started.
1235 @retval EFI_BUFFER_TOO_SMALL The pStatisticsTable is NULL or the buffer is too small.
1236 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1237 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1238 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1239 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1242 UINT64 RxTotalFrames;
1243 UINT64 RxGoodFrames;
1244 UINT64 RxUndersizeFrames;
1245 UINT64 RxOversizeFrames;
1246 UINT64 RxDroppedFrames;
1247 UINT64 RxUnicastFrames;
1248 UINT64 RxBroadcastFrames;
1249 UINT64 RxMulticastFrames;
1250 UINT64 RxCrcErrorFrames;
1251 UINT64 RxTotalBytes;
1252 UINT64 TxTotalFrames;
1253 UINT64 TxGoodFrames;
1254 UINT64 TxUndersizeFrames;
1255 UINT64 TxOversizeFrames;
1256 UINT64 TxDroppedFrames;
1257 UINT64 TxUnicastFrames;
1258 UINT64 TxBroadcastFrames;
1259 UINT64 TxMulticastFrames;
1260 UINT64 TxCrcErrorFrames;
1261 UINT64 TxTotalBytes;
1263 UINT64 UnsupportedProtocol;
1264 } EFI_NETWORK_STATISTICS;
1269 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
1271 IN OUT UINTN
* pStatisticsSize
,
1272 OUT EFI_NETWORK_STATISTICS
* pStatisticsTable
1276 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1278 // Verify the prarameters
1280 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1281 pMode
= pSimpleNetwork
->Mode
;
1283 // Determine if the interface is started
1285 if (EfiSimpleNetworkInitialized
== pMode
->State
){
1287 // Determine if the StatisticsSize is big enough
1289 if (sizeof (EFI_NETWORK_STATISTICS
) <= *pStatisticsSize
){
1291 Status
= EFI_SUCCESS
;
1294 Status
= EFI_UNSUPPORTED
;
1298 Status
= EFI_BUFFER_TOO_SMALL
;
1302 if (EfiSimpleNetworkStarted
== pMode
->State
) {
1303 Status
= EFI_DEVICE_ERROR
;
1306 Status
= EFI_NOT_STARTED
;
1311 Status
= EFI_INVALID_PARAMETER
;
1319 This function stops a network interface. This call is only valid
1320 if the network interface is in the started state.
1322 @param [in] pSimpleNetwork Protocol instance pointer
1324 @retval EFI_SUCCESS This operation was successful.
1325 @retval EFI_NOT_STARTED The network interface was not started.
1326 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1327 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1328 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1329 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1335 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
1338 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1340 EFI_TPL TplPrevious
;
1342 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
1344 // Verify the parameters
1346 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1348 // Determine if the interface is started
1350 pMode
= pSimpleNetwork
->Mode
;
1351 if ( EfiSimpleNetworkStarted
== pMode
->State
) {
1352 pMode
->State
= EfiSimpleNetworkStopped
;
1353 Status
= EFI_SUCCESS
;
1356 Status
= EFI_NOT_STARTED
;
1360 Status
= EFI_INVALID_PARAMETER
;
1363 gBS
->RestoreTPL ( TplPrevious
);
1369 This function releases the memory buffers assigned in the Initialize() call.
1370 Pending transmits and receives are lost, and interrupts are cleared and disabled.
1371 After this call, only Initialize() and Stop() calls may be used.
1373 @param [in] pSimpleNetwork Protocol instance pointer
1375 @retval EFI_SUCCESS This operation was successful.
1376 @retval EFI_NOT_STARTED The network interface was not started.
1377 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1378 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1379 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1380 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1386 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
1389 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1392 EFI_TPL TplPrevious
;
1394 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
1396 // Verify the parameters
1398 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1400 // Determine if the interface is already started
1402 pMode
= pSimpleNetwork
->Mode
;
1403 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
1407 RxFilter
= pMode
->ReceiveFilterSetting
;
1408 pMode
->ReceiveFilterSetting
= 0;
1409 Status
= SN_Reset ( pSimpleNetwork
, FALSE
);
1410 pMode
->ReceiveFilterSetting
= RxFilter
;
1411 if ( !EFI_ERROR ( Status
)) {
1414 // Update the network state
1416 pMode
->State
= EfiSimpleNetworkStarted
;
1418 else if ( EFI_DEVICE_ERROR
== Status
) {
1419 pMode
->State
= EfiSimpleNetworkStopped
;
1423 Status
= EFI_NOT_STARTED
;
1427 Status
= EFI_INVALID_PARAMETER
;
1429 gBS
->RestoreTPL ( TplPrevious
);
1435 Send a packet over the network.
1437 This function places the packet specified by Header and Buffer on
1438 the transmit queue. This function performs a non-blocking transmit
1439 operation. When the transmit is complete, the buffer is returned
1440 via the GetStatus() call.
1442 This routine calls ::Ax88772Rx to empty the network adapter of
1443 receive packets. The routine then passes the transmit packet
1444 to the network adapter.
1446 @param [in] pSimpleNetwork Protocol instance pointer
1447 @param [in] HeaderSize The size, in bytes, of the media header to be filled in by
1448 the Transmit() function. If HeaderSize is non-zero, then
1449 it must be equal to SimpleNetwork->Mode->MediaHeaderSize
1450 and DestAddr and Protocol parameters must not be NULL.
1451 @param [in] BufferSize The size, in bytes, of the entire packet (media header and
1452 data) to be transmitted through the network interface.
1453 @param [in] pBuffer A pointer to the packet (media header followed by data) to
1454 to be transmitted. This parameter can not be NULL. If
1455 HeaderSize is zero, then the media header is Buffer must
1456 already be filled in by the caller. If HeaderSize is nonzero,
1457 then the media header will be filled in by the Transmit()
1459 @param [in] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
1460 this parameter is ignored. If HeaderSize is nonzero and
1461 SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
1462 is used for the source HW MAC address.
1463 @param [in] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
1464 this parameter is ignored.
1465 @param [in] pProtocol The type of header to build. If HeaderSize is zero, then
1466 this parameter is ignored.
1468 @retval EFI_SUCCESS This operation was successful.
1469 @retval EFI_NOT_STARTED The network interface was not started.
1470 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
1471 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
1472 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1473 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1474 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1480 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
1481 IN UINTN HeaderSize
,
1482 IN UINTN BufferSize
,
1484 IN EFI_MAC_ADDRESS
* pSrcAddr
,
1485 IN EFI_MAC_ADDRESS
* pDestAddr
,
1486 IN UINT16
* pProtocol
1489 ETHERNET_HEADER
* pHeader
;
1490 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1491 NIC_DEVICE
* pNicDevice
;
1492 EFI_USB_IO_PROTOCOL
* pUsbIo
;
1494 UINTN TransferLength
;
1495 UINT32 TransferStatus
;
1497 EFI_TPL TplPrevious
;
1499 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
1501 // Verify the parameters
1503 if (( NULL
!= pSimpleNetwork
) &&
1504 ( NULL
!= pSimpleNetwork
->Mode
) &&
1505 ( NULL
!= pBuffer
) &&
1506 ( (HeaderSize
== 0) || ( (NULL
!= pDestAddr
) && (NULL
!= pProtocol
) ))) {
1508 // The interface must be running
1510 pMode
= pSimpleNetwork
->Mode
;
1512 // Verify parameter of HeaderSize
1514 if ((HeaderSize
== 0) || (HeaderSize
== pMode
->MediaHeaderSize
)){
1516 // Determine if BufferSize is big enough
1518 if (BufferSize
>= pMode
->MediaHeaderSize
){
1519 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
1521 // Update the link status
1523 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
1524 pMode
->MediaPresent
= pNicDevice
->bLinkUp
;
1527 // Release the synchronization with Ax88772Timer
1529 if ( pMode
->MediaPresent
&& pNicDevice
->bComplete
) {
1531 // Copy the packet into the USB buffer
1534 CopyMem ( &pNicDevice
->pTxTest
->Data
[0], pBuffer
, BufferSize
);
1535 pNicDevice
->pTxTest
->Length
= (UINT16
) BufferSize
;
1538 // Transmit the packet
1540 pHeader
= (ETHERNET_HEADER
*) &pNicDevice
->pTxTest
->Data
[0];
1541 if ( 0 != HeaderSize
) {
1542 if ( NULL
!= pDestAddr
) {
1543 CopyMem ( &pHeader
->dest_addr
, pDestAddr
, PXE_HWADDR_LEN_ETHER
);
1545 if ( NULL
!= pSrcAddr
) {
1546 CopyMem ( &pHeader
->src_addr
, pSrcAddr
, PXE_HWADDR_LEN_ETHER
);
1549 CopyMem ( &pHeader
->src_addr
, &pMode
->CurrentAddress
.Addr
[0], PXE_HWADDR_LEN_ETHER
);
1551 if ( NULL
!= pProtocol
) {
1555 Type
= pNicDevice
->pTxTest
->Length
;
1557 Type
= (UINT16
)(( Type
>> 8 ) | ( Type
<< 8 ));
1558 pHeader
->type
= Type
;
1560 if ( pNicDevice
->pTxTest
->Length
< MIN_ETHERNET_PKT_SIZE
) {
1561 pNicDevice
->pTxTest
->Length
= MIN_ETHERNET_PKT_SIZE
;
1562 ZeroMem ( &pNicDevice
->pTxTest
->Data
[ BufferSize
],
1563 pNicDevice
->pTxTest
->Length
- BufferSize
);
1566 DEBUG ((EFI_D_INFO
, "TX: %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x"
1567 " %02x-%02x %d bytes\r\n",
1568 pNicDevice
->pTxTest
->Data
[0],
1569 pNicDevice
->pTxTest
->Data
[1],
1570 pNicDevice
->pTxTest
->Data
[2],
1571 pNicDevice
->pTxTest
->Data
[3],
1572 pNicDevice
->pTxTest
->Data
[4],
1573 pNicDevice
->pTxTest
->Data
[5],
1574 pNicDevice
->pTxTest
->Data
[6],
1575 pNicDevice
->pTxTest
->Data
[7],
1576 pNicDevice
->pTxTest
->Data
[8],
1577 pNicDevice
->pTxTest
->Data
[9],
1578 pNicDevice
->pTxTest
->Data
[10],
1579 pNicDevice
->pTxTest
->Data
[11],
1580 pNicDevice
->pTxTest
->Data
[12],
1581 pNicDevice
->pTxTest
->Data
[13],
1582 pNicDevice
->pTxTest
->Length
));
1584 pNicDevice
->pTxTest
->LengthBar
= ~(pNicDevice
->pTxTest
->Length
);
1585 TransferLength
= sizeof ( pNicDevice
->pTxTest
->Length
)
1586 + sizeof ( pNicDevice
->pTxTest
->LengthBar
)
1587 + pNicDevice
->pTxTest
->Length
;
1589 if (TransferLength
% 512 == 0 || TransferLength
% 1024 == 0)
1593 // Work around USB bus driver bug where a timeout set by receive
1594 // succeeds but the timeout expires immediately after, causing the
1595 // transmit operation to timeout.
1597 pUsbIo
= pNicDevice
->pUsbIo
;
1598 Status
= pUsbIo
->UsbBulkTransfer ( pUsbIo
,
1600 &pNicDevice
->pTxTest
->Length
,
1604 if ( !EFI_ERROR ( Status
)) {
1605 Status
= TransferStatus
;
1608 if ( !EFI_ERROR ( Status
)) {
1609 pNicDevice
->pTxBuffer
= pBuffer
;
1612 if ((TransferLength
!= (UINTN
)( pNicDevice
->pTxTest
->Length
+ 4 )) &&
1613 (TransferLength
!= (UINTN
)(( pNicDevice
->pTxTest
->Length
+ 4 ) + 4))) {
1614 DEBUG ((EFI_D_INFO
, "TransferLength didn't match Packet Length\n"));
1617 // Reset the controller to fix the error
1619 if ( EFI_DEVICE_ERROR
== Status
) {
1620 SN_Reset ( pSimpleNetwork
, FALSE
);
1622 Status
= EFI_NOT_READY
;
1627 // No packets available.
1629 Status
= EFI_NOT_READY
;
1634 if (EfiSimpleNetworkStarted
== pMode
->State
) {
1635 Status
= EFI_DEVICE_ERROR
;
1638 Status
= EFI_NOT_STARTED
;
1643 Status
= EFI_BUFFER_TOO_SMALL
;
1647 Status
= EFI_INVALID_PARAMETER
;
1651 Status
= EFI_INVALID_PARAMETER
;
1654 gBS
->RestoreTPL (TplPrevious
);