2 Provides the Simple Network functions.
4 Copyright (c) 2011 - 2013, Intel Corporation
5 All rights reserved. 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
;
47 // Set the MAC address
49 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
50 pMode
= pSimpleNetwork
->Mode
;
53 // Clear the multicast hash table
55 Ax88772MulticastClear ( pNicDevice
);
58 // Load the multicast hash table
60 if ( 0 != ( pMode
->ReceiveFilterSetting
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
)) {
61 for ( Index
= 0; Index
< pMode
->MCastFilterCount
; Index
++ ) {
63 // Enable the next multicast address
65 Ax88772MulticastSet ( pNicDevice
,
66 &pMode
->MCastFilter
[ Index
].Addr
[0]);
70 Status
= Ax88772RxControl ( pNicDevice
, pMode
->ReceiveFilterSetting
);
77 This function updates the SNP driver status.
79 This function gets the current interrupt and recycled transmit
80 buffer status from the network interface. The interrupt status
81 and the media status are returned as a bit mask in InterruptStatus.
82 If InterruptStatus is NULL, the interrupt status will not be read.
83 Upon successful return of the media status, the MediaPresent field
84 of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
85 of media status. If TxBuf is not NULL, a recycled transmit buffer
86 address will be retrived. If a recycled transmit buffer address
87 is returned in TxBuf, then the buffer has been successfully
88 transmitted, and the status for that buffer is cleared.
90 This function calls ::Ax88772Rx to update the media status and
91 queue any receive packets.
93 @param [in] pSimpleNetwork Protocol instance pointer
94 @param [in] pInterruptStatus A pointer to the bit mask of the current active interrupts.
95 If this is NULL, the interrupt status will not be read from
96 the device. If this is not NULL, the interrupt status will
97 be read from teh device. When the interrupt status is read,
98 it will also be cleared. Clearing the transmit interrupt
99 does not empty the recycled transmit buffer array.
100 @param [out] ppTxBuf Recycled transmit buffer address. The network interface will
101 not transmit if its internal recycled transmit buffer array is
102 full. Reading the transmit buffer does not clear the transmit
103 interrupt. If this is NULL, then the transmit buffer status
104 will not be read. If there are not transmit buffers to recycle
105 and TxBuf is not NULL, *TxBuf will be set to NULL.
107 @retval EFI_SUCCESS This operation was successful.
108 @retval EFI_NOT_STARTED The network interface was not started.
109 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
110 EFI_SIMPLE_NETWORK_PROTOCOL structure.
111 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
117 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
118 OUT UINT32
* pInterruptStatus
,
122 EFI_SIMPLE_NETWORK_MODE
* pMode
;
123 NIC_DEVICE
* pNicDevice
;
130 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
132 // Verify the parameters
134 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
136 // Return the transmit buffer
139 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
140 if (( NULL
!= ppTxBuf
) && ( NULL
!= pNicDevice
->pTxBuffer
)) {
141 *ppTxBuf
= pNicDevice
->pTxBuffer
;
142 pNicDevice
->pTxBuffer
= NULL
;
146 // Determine if interface is running
148 pMode
= pSimpleNetwork
->Mode
;
149 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
151 if ( pNicDevice
->LinkIdleCnt
> MAX_LINKIDLE_THRESHOLD
) {
153 bLinkUp
= pNicDevice
->bLinkUp
;
154 bSpeed100
= pNicDevice
->b100Mbps
;
155 bFullDuplex
= pNicDevice
->bFullDuplex
;
156 Status
= Ax88772NegotiateLinkComplete ( pNicDevice
,
157 &pNicDevice
->PollCount
,
158 &pNicDevice
->bComplete
,
159 &pNicDevice
->bLinkUp
,
160 &pNicDevice
->b100Mbps
,
161 &pNicDevice
->bFullDuplex
);
164 // Determine if the autonegotiation is complete
166 if ( pNicDevice
->bComplete
) {
167 if ( pNicDevice
->bLinkUp
) {
168 if (( bSpeed100
&& ( !pNicDevice
->b100Mbps
))
169 || (( !bSpeed100
) && pNicDevice
->b100Mbps
)
170 || ( bFullDuplex
&& ( !pNicDevice
->bFullDuplex
))
171 || (( !bFullDuplex
) && pNicDevice
->bFullDuplex
)) {
172 pNicDevice
->PollCount
= 0;
173 DEBUG (( EFI_D_INFO
, "Reset to establish proper link setup: %d Mbps, %a duplex\r\n",
174 pNicDevice
->b100Mbps
? 100 : 10, pNicDevice
->bFullDuplex
? "Full" : "Half"));
175 Status
= SN_Reset ( &pNicDevice
->SimpleNetwork
, FALSE
);
177 if (( !bLinkUp
) && pNicDevice
->bLinkUp
) {
179 // Display the autonegotiation status
181 DEBUG (( EFI_D_INFO
, "Link: Up, %d Mbps, %a duplex\r\n",
182 pNicDevice
->b100Mbps
? 100 : 10, pNicDevice
->bFullDuplex
? "Full" : "Half"));
185 pNicDevice
->LinkIdleCnt
= 0;
189 // Update the link status
191 if ( bLinkUp
&& ( !pNicDevice
->bLinkUp
)) {
192 DEBUG (( EFI_D_INFO
, "Link: Down\r\n"));
196 pMode
->MediaPresent
= pNicDevice
->bLinkUp
;
198 // Return the interrupt status
200 if ( NULL
!= pInterruptStatus
) {
201 *pInterruptStatus
= 0;
203 Status
= EFI_SUCCESS
;
206 if ( EfiSimpleNetworkStarted
== pMode
->State
) {
207 Status
= EFI_DEVICE_ERROR
;
210 Status
= EFI_NOT_STARTED
;
216 Status
= EFI_INVALID_PARAMETER
;
218 gBS
->RestoreTPL(TplPrevious
) ;
225 Resets the network adapter and allocates the transmit and receive buffers
226 required by the network interface; optionally, also requests allocation of
227 additional transmit and receive buffers. This routine must be called before
228 any other routine in the Simple Network protocol is called.
230 @param [in] pSimpleNetwork Protocol instance pointer
231 @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
232 @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
234 @retval EFI_SUCCESS This operation was successful.
235 @retval EFI_NOT_STARTED The network interface was not started.
236 @retval EFI_OUT_OF_RESORUCES There was not enough memory for the transmit and receive buffers
237 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
238 EFI_SIMPLE_NETWORK_PROTOCOL structure.
239 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
240 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
246 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
247 IN UINTN ExtraRxBufferSize
,
248 IN UINTN ExtraTxBufferSize
251 EFI_SIMPLE_NETWORK_MODE
* pMode
;
256 TplPrevious
= gBS
->RaiseTPL (TPL_CALLBACK
);
258 // Verify the parameters
260 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
262 // Determine if the interface is already started
264 pMode
= pSimpleNetwork
->Mode
;
265 if ( EfiSimpleNetworkStarted
== pMode
->State
) {
266 if (( 0 == ExtraRxBufferSize
) && ( 0 == ExtraTxBufferSize
)) {
270 TmpState
= pMode
->State
;
271 pMode
->State
= EfiSimpleNetworkInitialized
;
272 Status
= SN_Reset ( pSimpleNetwork
, FALSE
);
273 if ( EFI_ERROR ( Status
)) {
275 // Update the network state
277 pMode
->State
= TmpState
;
278 DEBUG (( EFI_D_ERROR
, "SN_reset failed\n"));
282 DEBUG (( EFI_D_ERROR
, "Increase ExtraRxBufferSize = %d ExtraTxBufferSize=%d\n",
283 ExtraRxBufferSize
, ExtraTxBufferSize
));
284 Status
= EFI_UNSUPPORTED
;
288 Status
= EFI_NOT_STARTED
;
292 Status
= EFI_INVALID_PARAMETER
;
294 gBS
->RestoreTPL (TplPrevious
);
301 This function converts a multicast IP address to a multicast HW MAC address
302 for all packet transactions.
304 @param [in] pSimpleNetwork Protocol instance pointer
305 @param [in] bIPv6 Set to TRUE if the multicast IP address is IPv6 [RFC2460].
306 Set to FALSE if the multicast IP address is IPv4 [RFC 791].
307 @param [in] pIP The multicast IP address that is to be converted to a
308 multicast HW MAC address.
309 @param [in] pMAC The multicast HW MAC address that is to be generated from IP.
311 @retval EFI_SUCCESS This operation was successful.
312 @retval EFI_NOT_STARTED The network interface was not started.
313 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
314 EFI_SIMPLE_NETWORK_PROTOCOL structure.
315 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
316 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
322 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
324 IN EFI_IP_ADDRESS
* pIP
,
325 OUT EFI_MAC_ADDRESS
* pMAC
331 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
333 // Get pointer to SNP driver instance for *this.
335 if (pSimpleNetwork
== NULL
) {
336 gBS
->RestoreTPL(TplPrevious
);
337 return EFI_INVALID_PARAMETER
;
340 if (pIP
== NULL
|| pMAC
== NULL
) {
341 gBS
->RestoreTPL(TplPrevious
);
342 return EFI_INVALID_PARAMETER
;
346 Status
= EFI_UNSUPPORTED
;
350 // check if the ip given is a mcast IP
352 if ((pIP
->v4
.Addr
[0] & 0xF0) != 0xE0) {
353 gBS
->RestoreTPL(TplPrevious
);
354 return EFI_INVALID_PARAMETER
;
357 if (pSimpleNetwork
->Mode
->State
== EfiSimpleNetworkInitialized
)
359 pMAC
->Addr
[0] = 0x01;
360 pMAC
->Addr
[1] = 0x00;
361 pMAC
->Addr
[2] = 0x5e;
362 pMAC
->Addr
[3] = (UINT8
) (pIP
->v4
.Addr
[1] & 0x7f);
363 pMAC
->Addr
[4] = (UINT8
) pIP
->v4
.Addr
[2];
364 pMAC
->Addr
[5] = (UINT8
) pIP
->v4
.Addr
[3];
365 Status
= EFI_SUCCESS
;
367 else if (pSimpleNetwork
->Mode
->State
== EfiSimpleNetworkStarted
) {
368 Status
= EFI_DEVICE_ERROR
;
371 Status
= EFI_NOT_STARTED
;
373 gBS
->RestoreTPL(TplPrevious
);
381 This function performs read and write operations on the NVRAM device
382 attached to a network interface.
384 @param [in] pSimpleNetwork Protocol instance pointer
385 @param [in] ReadWrite TRUE for read operations, FALSE for write operations.
386 @param [in] Offset Byte offset in the NVRAM device at which to start the
387 read or write operation. This must be a multiple of
388 NvRamAccessSize and less than NvRamSize.
389 @param [in] BufferSize The number of bytes to read or write from the NVRAM device.
390 This must also be a multiple of NvramAccessSize.
391 @param [in, out] pBuffer A pointer to the data buffer.
393 @retval EFI_SUCCESS This operation was successful.
394 @retval EFI_NOT_STARTED The network interface was not started.
395 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
396 EFI_SIMPLE_NETWORK_PROTOCOL structure.
397 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
398 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
404 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
405 IN BOOLEAN ReadWrite
,
408 IN OUT VOID
* pBuffer
413 // This is not currently supported
415 Status
= EFI_UNSUPPORTED
;
421 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
429 NIC_DEVICE
* pNicDevice
;
431 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
432 for ( offset
= 0; offset
< BufLength
; ){
433 pLength
= (UINT16
*) (pNicDevice
->pBulkInBuff
+ offset
);
434 pLengthBar
= (UINT16
*) (pNicDevice
->pBulkInBuff
+ offset
+2);
437 *pLengthBar
&= 0x7ff;
438 *pLengthBar
|= 0xf800;
440 if ((*pLength
^ *pLengthBar
) != 0xFFFF) {
441 DEBUG (( EFI_D_ERROR
, "Pkt length error. BufLength = %d\n", BufLength
));
445 if (TRUE
== pNicDevice
->pNextFill
->f_Used
) {
449 pData
= pNicDevice
->pBulkInBuff
+ offset
+ 4;
450 pNicDevice
->pNextFill
->f_Used
= TRUE
;
451 pNicDevice
->pNextFill
->Length
= *pLength
;
452 CopyMem (&pNicDevice
->pNextFill
->Data
[0], pData
, *pLength
);
454 pNicDevice
->pNextFill
= pNicDevice
->pNextFill
->pNext
;
455 offset
+= ((*pLength
+ HW_HDR_LENGTH
- 1) &~3) + 1;
456 pNicDevice
->PktCntInQueue
++;
465 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
466 OUT UINTN
* pHeaderSize
,
467 OUT UINTN
* pBufferSize
,
469 OUT EFI_MAC_ADDRESS
* pSrcAddr
,
470 OUT EFI_MAC_ADDRESS
* pDestAddr
,
471 OUT UINT16
* pProtocol
474 EFI_SIMPLE_NETWORK_MODE
* pMode
;
475 NIC_DEVICE
* pNicDevice
;
479 EFI_USB_IO_PROTOCOL
*pUsbIo
;
481 UINT32 TransferStatus
;
483 TplPrevious
= gBS
->RaiseTPL (TPL_CALLBACK
);
486 // Verify the parameters
488 if (( NULL
!= pSimpleNetwork
) &&
489 ( NULL
!= pSimpleNetwork
->Mode
) &&
490 (NULL
!= pBufferSize
) &&
493 // The interface must be running
495 pMode
= pSimpleNetwork
->Mode
;
496 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
498 // Update the link status
500 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
501 pNicDevice
->LinkIdleCnt
++;
502 pMode
->MediaPresent
= pNicDevice
->bLinkUp
;
504 if ( pMode
->MediaPresent
&& pNicDevice
->bComplete
) {
507 if (pNicDevice
->PktCntInQueue
!= 0 ) {
508 DEBUG (( EFI_D_INFO
, "pNicDevice->PktCntInQueue = %d\n",
509 pNicDevice
->PktCntInQueue
));
512 LengthInBytes
= MAX_BULKIN_SIZE
;
513 if (pNicDevice
->PktCntInQueue
== 0 ){
515 // Attempt to do bulk in
517 SetMem (&pNicDevice
->pBulkInBuff
[0], 4, 0);
518 pUsbIo
= pNicDevice
->pUsbIo
;
519 Status
= pUsbIo
->UsbBulkTransfer ( pUsbIo
,
520 USB_ENDPOINT_DIR_IN
| BULK_IN_ENDPOINT
,
521 &pNicDevice
->pBulkInBuff
[0],
526 if (LengthInBytes
!= 0 && !EFI_ERROR(Status
) && !EFI_ERROR(TransferStatus
) ){
527 FillPkt2Queue(pSimpleNetwork
, LengthInBytes
);
531 pFirstFill
= pNicDevice
->pFirstFill
;
533 if (TRUE
== pFirstFill
->f_Used
) {
534 ETHERNET_HEADER
* pHeader
;
535 pNicDevice
->LinkIdleCnt
= 0;
536 CopyMem (pBuffer
, &pFirstFill
->Data
[0], pFirstFill
->Length
);
537 pHeader
= (ETHERNET_HEADER
*) &pFirstFill
->Data
[0];
539 DEBUG (( EFI_D_INFO
, "RX: %02x-%02x-%02x-%02x-%02x-%02x "
540 "%02x-%02x-%02x-%02x-%02x-%02x %02x-%02x %d bytes\r\n",
551 pFirstFill
->Data
[10],
552 pFirstFill
->Data
[11],
553 pFirstFill
->Data
[12],
554 pFirstFill
->Data
[13],
555 pFirstFill
->Length
));
557 if ( NULL
!= pHeaderSize
) {
558 *pHeaderSize
= sizeof ( *pHeader
);
560 if ( NULL
!= pDestAddr
) {
561 CopyMem ( pDestAddr
, &pHeader
->dest_addr
, PXE_HWADDR_LEN_ETHER
);
563 if ( NULL
!= pSrcAddr
) {
564 CopyMem ( pSrcAddr
, &pHeader
->src_addr
, PXE_HWADDR_LEN_ETHER
);
566 if ( NULL
!= pProtocol
) {
567 Type
= pHeader
->type
;
568 Type
= (UINT16
)(( Type
>> 8 ) | ( Type
<< 8 ));
571 Status
= EFI_SUCCESS
;
572 if (*pBufferSize
< pFirstFill
->Length
) {
573 DEBUG (( EFI_D_ERROR
, "RX: Buffer was too small"));
574 Status
= EFI_BUFFER_TOO_SMALL
;
576 *pBufferSize
= pFirstFill
->Length
;
577 pFirstFill
->f_Used
= FALSE
;
578 pNicDevice
->pFirstFill
= pFirstFill
->pNext
;
579 pNicDevice
->PktCntInQueue
--;
582 pNicDevice
->LinkIdleCnt
++;
583 Status
= EFI_NOT_READY
;
590 pNicDevice
->LinkIdleCnt
++;
591 Status
= EFI_NOT_READY
;
596 if (EfiSimpleNetworkStarted
== pMode
->State
) {
597 Status
= EFI_DEVICE_ERROR
;
600 Status
= EFI_NOT_STARTED
;
605 Status
= EFI_INVALID_PARAMETER
;
607 gBS
->RestoreTPL (TplPrevious
);
612 This function is used to enable and disable the hardware and software receive
613 filters for the underlying network device.
615 The receive filter change is broken down into three steps:
617 1. The filter mask bits that are set (ON) in the Enable parameter
618 are added to the current receive filter settings.
620 2. The filter mask bits that are set (ON) in the Disable parameter
621 are subtracted from the updated receive filter settins.
623 3. If the resulting filter settigns is not supported by the hardware
624 a more liberal setting is selected.
626 If the same bits are set in the Enable and Disable parameters, then the bits
627 in the Disable parameter takes precedence.
629 If the ResetMCastFilter parameter is TRUE, then the multicast address list
630 filter is disabled (irregardless of what other multicast bits are set in
631 the enable and Disable parameters). The SNP->Mode->MCastFilterCount field
632 is set to zero. The SNP->Mode->MCastFilter contents are undefined.
634 After enableing or disabling receive filter settings, software should
635 verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
636 SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
638 Note: Some network drivers and/or devices will automatically promote
639 receive filter settings if the requested setting can not be honored.
640 For example, if a request for four multicast addresses is made and
641 the underlying hardware only supports two multicast addresses the
642 driver might set the promiscuous or promiscuous multicast receive filters
643 instead. The receiving software is responsible for discarding any extra
644 packets that get through the hardware receive filters.
646 If ResetMCastFilter is TRUE, then the multicast receive filter list
647 on the network interface will be reset to the default multicast receive
648 filter list. If ResetMCastFilter is FALSE, and this network interface
649 allows the multicast receive filter list to be modified, then the
650 MCastFilterCnt and MCastFilter are used to update the current multicast
651 receive filter list. The modified receive filter list settings can be
652 found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
654 This routine calls ::ReceiveFilterUpdate to update the receive
655 state in the network adapter.
657 @param [in] pSimpleNetwork Protocol instance pointer
658 @param [in] Enable A bit mask of receive filters to enable on the network interface.
659 @param [in] Disable A bit mask of receive filters to disable on the network interface.
660 For backward compatibility with EFI 1.1 platforms, the
661 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
662 when the ResetMCastFilter parameter is TRUE.
663 @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
664 filters on the network interface to their default values.
665 @param [in] MCastFilterCnt Number of multicast HW MAC address in the new MCastFilter list.
666 This value must be less than or equal to the MaxMCastFilterCnt
667 field of EFI_SIMPLE_NETWORK_MODE. This field is optional if
668 ResetMCastFilter is TRUE.
669 @param [in] pMCastFilter A pointer to a list of new multicast receive filter HW MAC
670 addresses. This list will replace any existing multicast
671 HW MAC address list. This field is optional if ResetMCastFilter
674 @retval EFI_SUCCESS This operation was successful.
675 @retval EFI_NOT_STARTED The network interface was not started.
676 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
677 EFI_SIMPLE_NETWORK_PROTOCOL structure.
678 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
679 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
685 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
689 #define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 0x01
690 #define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 0x02
691 #define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 0x04
692 #define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 0x08
693 #define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10
695 IN BOOLEAN bResetMCastFilter
,
696 IN UINTN MCastFilterCnt
,
697 IN EFI_MAC_ADDRESS
* pMCastFilter
700 EFI_SIMPLE_NETWORK_MODE
* pMode
;
701 EFI_STATUS Status
= EFI_SUCCESS
;
703 NIC_DEVICE
* pNicDevice
;
705 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
706 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
707 pMode
= pSimpleNetwork
->Mode
;
709 if (pSimpleNetwork
== NULL
) {
710 gBS
->RestoreTPL(TplPrevious
);
711 return EFI_INVALID_PARAMETER
;
714 switch (pMode
->State
) {
715 case EfiSimpleNetworkInitialized
:
717 case EfiSimpleNetworkStopped
:
718 Status
= EFI_NOT_STARTED
;
719 gBS
->RestoreTPL(TplPrevious
);
722 Status
= EFI_DEVICE_ERROR
;
723 gBS
->RestoreTPL(TplPrevious
);
728 // check if we are asked to enable or disable something that the UNDI
729 // does not even support!
731 if (((Enable
&~pMode
->ReceiveFilterMask
) != 0) ||
732 ((Disable
&~pMode
->ReceiveFilterMask
) != 0)) {
733 Status
= EFI_INVALID_PARAMETER
;
734 gBS
->RestoreTPL(TplPrevious
);
738 if (bResetMCastFilter
) {
739 Disable
|= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
& pMode
->ReceiveFilterMask
);
740 pMode
->MCastFilterCount
= 0;
741 if ( (0 == (pMode
->ReceiveFilterSetting
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
))
742 && Enable
== 0 && Disable
== 2) {
743 gBS
->RestoreTPL(TplPrevious
);
748 if (MCastFilterCnt
!= 0) {
750 EFI_MAC_ADDRESS
* pMulticastAddress
;
751 pMulticastAddress
= pMCastFilter
;
753 if ((MCastFilterCnt
> pMode
->MaxMCastFilterCount
) ||
754 (pMCastFilter
== NULL
)) {
755 Status
= EFI_INVALID_PARAMETER
;
756 gBS
->RestoreTPL(TplPrevious
);
760 for ( i
= 0 ; i
< MCastFilterCnt
; i
++ ) {
762 tmp
= pMulticastAddress
->Addr
[0];
763 if ( (tmp
& 0x01) != 0x01 ) {
764 gBS
->RestoreTPL(TplPrevious
);
765 return EFI_INVALID_PARAMETER
;
770 pMode
->MCastFilterCount
= (UINT32
)MCastFilterCnt
;
771 CopyMem (&pMode
->MCastFilter
[0],
773 MCastFilterCnt
* sizeof ( EFI_MAC_ADDRESS
));
777 if (Enable
== 0 && Disable
== 0 && !bResetMCastFilter
&& MCastFilterCnt
== 0) {
778 Status
= EFI_SUCCESS
;
779 gBS
->RestoreTPL(TplPrevious
);
783 if ((Enable
& EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
) != 0 && MCastFilterCnt
== 0) {
784 Status
= EFI_INVALID_PARAMETER
;
785 gBS
->RestoreTPL(TplPrevious
);
789 pMode
->ReceiveFilterSetting
|= Enable
;
790 pMode
->ReceiveFilterSetting
&= ~Disable
;
791 Status
= ReceiveFilterUpdate (pSimpleNetwork
);
793 if (EFI_DEVICE_ERROR
== Status
|| EFI_INVALID_PARAMETER
== Status
)
794 Status
= EFI_SUCCESS
;
796 gBS
->RestoreTPL(TplPrevious
);
801 Reset the network adapter.
803 Resets a network adapter and reinitializes it with the parameters that
804 were provided in the previous call to Initialize (). The transmit and
805 receive queues are cleared. Receive filters, the station address, the
806 statistics, and the multicast-IP-to-HW MAC addresses are not reset by
809 This routine calls ::Ax88772Reset to perform the adapter specific
810 reset operation. This routine also starts the link negotiation
811 by calling ::Ax88772NegotiateLinkStart.
813 @param [in] pSimpleNetwork Protocol instance pointer
814 @param [in] bExtendedVerification Indicates that the driver may perform a more
815 exhaustive verification operation of the device
818 @retval EFI_SUCCESS This operation was successful.
819 @retval EFI_NOT_STARTED The network interface was not started.
820 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
821 EFI_SIMPLE_NETWORK_PROTOCOL structure.
822 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
823 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
829 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
830 IN BOOLEAN bExtendedVerification
833 EFI_SIMPLE_NETWORK_MODE
* pMode
;
834 NIC_DEVICE
* pNicDevice
;
838 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
840 // Verify the parameters
842 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
843 pMode
= pSimpleNetwork
->Mode
;
844 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
846 // Update the device state
848 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
849 pNicDevice
->bComplete
= FALSE
;
850 pNicDevice
->bLinkUp
= FALSE
;
851 pNicDevice
->bHavePkt
= FALSE
;
852 pMode
= pSimpleNetwork
->Mode
;
853 pMode
->MediaPresent
= FALSE
;
858 Status
= Ax88772Reset ( pNicDevice
);
859 if ( !EFI_ERROR ( Status
)) {
861 // Update the receive filters in the adapter
863 Status
= ReceiveFilterUpdate ( pSimpleNetwork
);
866 // Try to get a connection to the network
868 if ( !EFI_ERROR ( Status
)) {
870 // Start the autonegotiation
872 Status
= Ax88772NegotiateLinkStart ( pNicDevice
);
877 if (EfiSimpleNetworkStarted
== pMode
->State
) {
878 Status
= EFI_DEVICE_ERROR
;
881 Status
= EFI_NOT_STARTED
;
886 Status
= EFI_INVALID_PARAMETER
;
888 gBS
->RestoreTPL ( TplPrevious
);
893 Initialize the simple network protocol.
895 This routine calls ::Ax88772MacAddressGet to obtain the
898 @param [in] pNicDevice NIC_DEVICE_INSTANCE pointer
900 @retval EFI_SUCCESS Setup was successful
905 IN NIC_DEVICE
* pNicDevice
910 EFI_SIMPLE_NETWORK_MODE
* pMode
;
911 EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
;
913 RX_PKT
* pCurr
= NULL
;
914 RX_PKT
* pPrev
= NULL
;
916 pSimpleNetwork
= &pNicDevice
->SimpleNetwork
;
917 pSimpleNetwork
->Revision
= EFI_SIMPLE_NETWORK_PROTOCOL_REVISION
;
918 pSimpleNetwork
->Start
= (EFI_SIMPLE_NETWORK_START
)SN_Start
;
919 pSimpleNetwork
->Stop
= (EFI_SIMPLE_NETWORK_STOP
)SN_Stop
;
920 pSimpleNetwork
->Initialize
= (EFI_SIMPLE_NETWORK_INITIALIZE
)SN_Initialize
;
921 pSimpleNetwork
->Reset
= (EFI_SIMPLE_NETWORK_RESET
)SN_Reset
;
922 pSimpleNetwork
->Shutdown
= (EFI_SIMPLE_NETWORK_SHUTDOWN
)SN_Shutdown
;
923 pSimpleNetwork
->ReceiveFilters
= (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS
)SN_ReceiveFilters
;
924 pSimpleNetwork
->StationAddress
= (EFI_SIMPLE_NETWORK_STATION_ADDRESS
)SN_StationAddress
;
925 pSimpleNetwork
->Statistics
= (EFI_SIMPLE_NETWORK_STATISTICS
)SN_Statistics
;
926 pSimpleNetwork
->MCastIpToMac
= (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC
)SN_MCastIPtoMAC
;
927 pSimpleNetwork
->NvData
= (EFI_SIMPLE_NETWORK_NVDATA
)SN_NvData
;
928 pSimpleNetwork
->GetStatus
= (EFI_SIMPLE_NETWORK_GET_STATUS
)SN_GetStatus
;
929 pSimpleNetwork
->Transmit
= (EFI_SIMPLE_NETWORK_TRANSMIT
)SN_Transmit
;
930 pSimpleNetwork
->Receive
= (EFI_SIMPLE_NETWORK_RECEIVE
)SN_Receive
;
931 pSimpleNetwork
->WaitForPacket
= NULL
;
932 pMode
= &pNicDevice
->SimpleNetworkData
;
933 pSimpleNetwork
->Mode
= pMode
;
934 pMode
->State
= EfiSimpleNetworkStopped
;
935 pMode
->HwAddressSize
= PXE_HWADDR_LEN_ETHER
;
936 pMode
->MediaHeaderSize
= sizeof ( ETHERNET_HEADER
);
937 pMode
->MaxPacketSize
= MAX_ETHERNET_PKT_SIZE
;
938 pMode
->NvRamSize
= 0;
939 pMode
->NvRamAccessSize
= 0;
940 pMode
->ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
941 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
942 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
943 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
944 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
945 pMode
->ReceiveFilterSetting
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
946 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
;
947 pMode
->MaxMCastFilterCount
= MAX_MCAST_FILTER_CNT
;
948 pMode
->MCastFilterCount
= 0;
949 SetMem ( &pMode
->BroadcastAddress
,
950 PXE_HWADDR_LEN_ETHER
,
952 pMode
->IfType
= EfiNetworkInterfaceUndi
;
953 pMode
->MacAddressChangeable
= TRUE
;
954 pMode
->MultipleTxSupported
= FALSE
;
955 pMode
->MediaPresentSupported
= TRUE
;
956 pMode
->MediaPresent
= FALSE
;
957 pNicDevice
->LinkIdleCnt
= 0;
959 // Read the MAC address
961 pNicDevice
->PhyId
= PHY_ID_INTERNAL
;
962 pNicDevice
->b100Mbps
= TRUE
;
963 pNicDevice
->bFullDuplex
= TRUE
;
965 Status
= Ax88772MacAddressGet (
967 &pMode
->PermanentAddress
.Addr
[0]);
969 if ( !EFI_ERROR ( Status
)) {
972 // Use the hardware address as the current address
975 CopyMem ( &pMode
->CurrentAddress
,
976 &pMode
->PermanentAddress
,
977 PXE_HWADDR_LEN_ETHER
);
979 CopyMem ( &pNicDevice
->MAC
,
980 &pMode
->PermanentAddress
,
981 PXE_HWADDR_LEN_ETHER
);
983 pNicDevice
->PktCntInQueue
= 0;
985 for ( i
= 0 ; i
< MAX_QUEUE_SIZE
; i
++) {
986 Status
= gBS
->AllocatePool ( EfiRuntimeServicesData
,
989 if ( EFI_ERROR(Status
)) {
990 DEBUG (( EFI_D_ERROR
, "Memory are not enough\n"));
993 pCurr
->f_Used
= FALSE
;
996 pPrev
->pNext
= pCurr
;
999 pNicDevice
->QueueHead
= pCurr
;
1002 if (MAX_QUEUE_SIZE
- 1 == i
) {
1003 pCurr
->pNext
= pNicDevice
->QueueHead
;
1009 pNicDevice
->pNextFill
= pNicDevice
->QueueHead
;
1010 pNicDevice
->pFirstFill
= pNicDevice
->QueueHead
;
1012 Status
= gBS
->AllocatePool (EfiRuntimeServicesData
,
1014 (VOID
**) &pNicDevice
->pBulkInBuff
);
1016 if (EFI_ERROR(Status
)) {
1017 DEBUG (( EFI_D_ERROR
, "gBS->AllocatePool for pBulkInBuff error. Status = %r\n",
1023 DEBUG (( EFI_D_ERROR
, "Ax88772MacAddressGet error. Status = %r\n", Status
));
1027 Status
= gBS
->AllocatePool ( EfiRuntimeServicesData
,
1028 sizeof ( RX_TX_PACKET
),
1029 (VOID
**) &pNicDevice
->pRxTest
);
1031 if (EFI_ERROR (Status
)) {
1032 DEBUG (( EFI_D_ERROR
, "gBS->AllocatePool:pNicDevice->pRxTest error. Status = %r\n",
1037 Status
= gBS
->AllocatePool ( EfiRuntimeServicesData
,
1038 sizeof ( RX_TX_PACKET
),
1039 (VOID
**) &pNicDevice
->pTxTest
);
1041 if (EFI_ERROR (Status
)) {
1042 DEBUG (( EFI_D_ERROR
, "gBS->AllocatePool:pNicDevice->pTxTest error. Status = %r\n",
1044 gBS
->FreePool (pNicDevice
->pRxTest
);
1052 This routine starts the network interface.
1054 @param [in] pSimpleNetwork Protocol instance pointer
1056 @retval EFI_SUCCESS This operation was successful.
1057 @retval EFI_ALREADY_STARTED The network interface was already started.
1058 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1059 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1060 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1061 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1067 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
1070 NIC_DEVICE
* pNicDevice
;
1071 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1073 EFI_TPL TplPrevious
;
1075 RX_PKT
* pCurr
= NULL
;
1077 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
1079 // Verify the parameters
1081 Status
= EFI_INVALID_PARAMETER
;
1082 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1083 pMode
= pSimpleNetwork
->Mode
;
1084 if ( EfiSimpleNetworkStopped
== pMode
->State
) {
1086 // Initialize the mode structuref
1087 // NVRAM access is not supported
1089 ZeroMem ( pMode
, sizeof ( *pMode
));
1091 pMode
->State
= EfiSimpleNetworkStarted
;
1092 pMode
->HwAddressSize
= PXE_HWADDR_LEN_ETHER
;
1093 pMode
->MediaHeaderSize
= sizeof ( ETHERNET_HEADER
);
1094 pMode
->MaxPacketSize
= MAX_ETHERNET_PKT_SIZE
;
1095 pMode
->ReceiveFilterMask
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
1096 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
1097 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
1098 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
1099 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST
;
1100 pMode
->ReceiveFilterSetting
= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
;
1101 pMode
->MaxMCastFilterCount
= MAX_MCAST_FILTER_CNT
;
1102 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
1103 Status
= Ax88772MacAddressGet ( pNicDevice
, &pMode
->PermanentAddress
.Addr
[0]);
1104 CopyMem ( &pMode
->CurrentAddress
,
1105 &pMode
->PermanentAddress
,
1106 sizeof ( pMode
->CurrentAddress
));
1107 SetMem(&pMode
->BroadcastAddress
, PXE_HWADDR_LEN_ETHER
, 0xff);
1108 pMode
->IfType
= EfiNetworkInterfaceUndi
;
1109 pMode
->MacAddressChangeable
= TRUE
;
1110 pMode
->MultipleTxSupported
= FALSE
;
1111 pMode
->MediaPresentSupported
= TRUE
;
1112 pMode
->MediaPresent
= FALSE
;
1113 pNicDevice
->PktCntInQueue
= 0;
1114 pNicDevice
->pNextFill
= pNicDevice
->QueueHead
;
1115 pNicDevice
->pFirstFill
= pNicDevice
->QueueHead
;
1116 pCurr
= pNicDevice
->QueueHead
;
1118 for ( i
= 0 ; i
< MAX_QUEUE_SIZE
; i
++) {
1119 pCurr
->f_Used
= FALSE
;
1120 pCurr
= pCurr
->pNext
;
1125 Status
= EFI_ALREADY_STARTED
;
1128 gBS
->RestoreTPL ( TplPrevious
);
1134 Set the MAC address.
1136 This function modifies or resets the current station address of a
1137 network interface. If Reset is TRUE, then the current station address
1138 is set ot the network interface's permanent address. If Reset if FALSE
1139 then the current station address is changed to the address specified by
1142 This routine calls ::Ax88772MacAddressSet to update the MAC address
1143 in the network adapter.
1145 @param [in] pSimpleNetwork Protocol instance pointer
1146 @param [in] bReset Flag used to reset the station address to the
1147 network interface's permanent address.
1148 @param [in] pNew New station address to be used for the network
1151 @retval EFI_SUCCESS This operation was successful.
1152 @retval EFI_NOT_STARTED The network interface was not started.
1153 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1154 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1155 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1156 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1162 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
1164 IN EFI_MAC_ADDRESS
* pNew
1167 NIC_DEVICE
* pNicDevice
;
1168 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1170 EFI_TPL TplPrevious
;
1172 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
1174 // Verify the parameters
1176 if (( NULL
!= pSimpleNetwork
)
1177 && ( NULL
!= pSimpleNetwork
->Mode
)
1178 && (( bReset
) || ( ( !bReset
) && ( NULL
!= pNew
)))) {
1180 // Verify that the adapter is already started
1182 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
1183 pMode
= pSimpleNetwork
->Mode
;
1184 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
1186 // Determine the adapter MAC address
1190 // Use the permanent address
1192 CopyMem ( &pMode
->CurrentAddress
,
1193 &pMode
->PermanentAddress
,
1194 sizeof ( pMode
->CurrentAddress
));
1198 // Use the specified address
1200 CopyMem ( &pMode
->CurrentAddress
,
1202 sizeof ( pMode
->CurrentAddress
));
1206 // Update the address on the adapter
1208 Status
= Ax88772MacAddressSet ( pNicDevice
, &pMode
->CurrentAddress
.Addr
[0]);
1211 if (EfiSimpleNetworkStarted
== pMode
->State
) {
1212 Status
= EFI_DEVICE_ERROR
;
1215 Status
= EFI_NOT_STARTED
;
1220 Status
= EFI_INVALID_PARAMETER
;
1222 gBS
->RestoreTPL ( TplPrevious
);
1228 This function resets or collects the statistics on a network interface.
1229 If the size of the statistics table specified by StatisticsSize is not
1230 big enough for all of the statistics that are collected by the network
1231 interface, then a partial buffer of statistics is returned in
1234 @param [in] pSimpleNetwork Protocol instance pointer
1235 @param [in] bReset Set to TRUE to reset the statistics for the network interface.
1236 @param [in, out] pStatisticsSize On input the size, in bytes, of StatisticsTable. On output
1237 the size, in bytes, of the resulting table of statistics.
1238 @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
1239 conains the statistics.
1241 @retval EFI_SUCCESS This operation was successful.
1242 @retval EFI_NOT_STARTED The network interface was not started.
1243 @retval EFI_BUFFER_TOO_SMALL The pStatisticsTable is NULL or the buffer is too small.
1244 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1245 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1246 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1247 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1250 UINT64 RxTotalFrames;
1251 UINT64 RxGoodFrames;
1252 UINT64 RxUndersizeFrames;
1253 UINT64 RxOversizeFrames;
1254 UINT64 RxDroppedFrames;
1255 UINT64 RxUnicastFrames;
1256 UINT64 RxBroadcastFrames;
1257 UINT64 RxMulticastFrames;
1258 UINT64 RxCrcErrorFrames;
1259 UINT64 RxTotalBytes;
1260 UINT64 TxTotalFrames;
1261 UINT64 TxGoodFrames;
1262 UINT64 TxUndersizeFrames;
1263 UINT64 TxOversizeFrames;
1264 UINT64 TxDroppedFrames;
1265 UINT64 TxUnicastFrames;
1266 UINT64 TxBroadcastFrames;
1267 UINT64 TxMulticastFrames;
1268 UINT64 TxCrcErrorFrames;
1269 UINT64 TxTotalBytes;
1271 UINT64 UnsupportedProtocol;
1272 } EFI_NETWORK_STATISTICS;
1277 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
1279 IN OUT UINTN
* pStatisticsSize
,
1280 OUT EFI_NETWORK_STATISTICS
* pStatisticsTable
1284 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1286 // Verify the prarameters
1288 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1289 pMode
= pSimpleNetwork
->Mode
;
1291 // Determine if the interface is started
1293 if (EfiSimpleNetworkInitialized
== pMode
->State
){
1295 // Determine if the StatisticsSize is big enough
1297 if (sizeof (EFI_NETWORK_STATISTICS
) <= *pStatisticsSize
){
1299 Status
= EFI_SUCCESS
;
1302 Status
= EFI_UNSUPPORTED
;
1306 Status
= EFI_BUFFER_TOO_SMALL
;
1310 if (EfiSimpleNetworkStarted
== pMode
->State
) {
1311 Status
= EFI_DEVICE_ERROR
;
1314 Status
= EFI_NOT_STARTED
;
1319 Status
= EFI_INVALID_PARAMETER
;
1327 This function stops a network interface. This call is only valid
1328 if the network interface is in the started state.
1330 @param [in] pSimpleNetwork Protocol instance pointer
1332 @retval EFI_SUCCESS This operation was successful.
1333 @retval EFI_NOT_STARTED The network interface was not started.
1334 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1335 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1336 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1337 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1343 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
1346 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1348 EFI_TPL TplPrevious
;
1350 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
1352 // Verify the parameters
1354 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1356 // Determine if the interface is started
1358 pMode
= pSimpleNetwork
->Mode
;
1359 if ( EfiSimpleNetworkStarted
== pMode
->State
) {
1360 pMode
->State
= EfiSimpleNetworkStopped
;
1361 Status
= EFI_SUCCESS
;
1364 Status
= EFI_NOT_STARTED
;
1368 Status
= EFI_INVALID_PARAMETER
;
1371 gBS
->RestoreTPL ( TplPrevious
);
1377 This function releases the memory buffers assigned in the Initialize() call.
1378 Pending transmits and receives are lost, and interrupts are cleared and disabled.
1379 After this call, only Initialize() and Stop() calls may be used.
1381 @param [in] pSimpleNetwork Protocol instance pointer
1383 @retval EFI_SUCCESS This operation was successful.
1384 @retval EFI_NOT_STARTED The network interface was not started.
1385 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1386 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1387 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1388 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
1394 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
1397 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1400 EFI_TPL TplPrevious
;
1402 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
1404 // Verify the parameters
1406 if (( NULL
!= pSimpleNetwork
) && ( NULL
!= pSimpleNetwork
->Mode
)) {
1408 // Determine if the interface is already started
1410 pMode
= pSimpleNetwork
->Mode
;
1411 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
1415 RxFilter
= pMode
->ReceiveFilterSetting
;
1416 pMode
->ReceiveFilterSetting
= 0;
1417 Status
= SN_Reset ( pSimpleNetwork
, FALSE
);
1418 pMode
->ReceiveFilterSetting
= RxFilter
;
1419 if ( !EFI_ERROR ( Status
)) {
1422 // Update the network state
1424 pMode
->State
= EfiSimpleNetworkStarted
;
1426 else if ( EFI_DEVICE_ERROR
== Status
) {
1427 pMode
->State
= EfiSimpleNetworkStopped
;
1431 Status
= EFI_NOT_STARTED
;
1435 Status
= EFI_INVALID_PARAMETER
;
1437 gBS
->RestoreTPL ( TplPrevious
);
1443 Send a packet over the network.
1445 This function places the packet specified by Header and Buffer on
1446 the transmit queue. This function performs a non-blocking transmit
1447 operation. When the transmit is complete, the buffer is returned
1448 via the GetStatus() call.
1450 This routine calls ::Ax88772Rx to empty the network adapter of
1451 receive packets. The routine then passes the transmit packet
1452 to the network adapter.
1454 @param [in] pSimpleNetwork Protocol instance pointer
1455 @param [in] HeaderSize The size, in bytes, of the media header to be filled in by
1456 the Transmit() function. If HeaderSize is non-zero, then
1457 it must be equal to SimpleNetwork->Mode->MediaHeaderSize
1458 and DestAddr and Protocol parameters must not be NULL.
1459 @param [in] BufferSize The size, in bytes, of the entire packet (media header and
1460 data) to be transmitted through the network interface.
1461 @param [in] pBuffer A pointer to the packet (media header followed by data) to
1462 to be transmitted. This parameter can not be NULL. If
1463 HeaderSize is zero, then the media header is Buffer must
1464 already be filled in by the caller. If HeaderSize is nonzero,
1465 then the media header will be filled in by the Transmit()
1467 @param [in] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
1468 this parameter is ignored. If HeaderSize is nonzero and
1469 SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
1470 is used for the source HW MAC address.
1471 @param [in] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
1472 this parameter is ignored.
1473 @param [in] pProtocol The type of header to build. If HeaderSize is zero, then
1474 this parameter is ignored.
1476 @retval EFI_SUCCESS This operation was successful.
1477 @retval EFI_NOT_STARTED The network interface was not started.
1478 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
1479 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
1480 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
1481 EFI_SIMPLE_NETWORK_PROTOCOL structure.
1482 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
1488 IN EFI_SIMPLE_NETWORK_PROTOCOL
* pSimpleNetwork
,
1489 IN UINTN HeaderSize
,
1490 IN UINTN BufferSize
,
1492 IN EFI_MAC_ADDRESS
* pSrcAddr
,
1493 IN EFI_MAC_ADDRESS
* pDestAddr
,
1494 IN UINT16
* pProtocol
1497 ETHERNET_HEADER
* pHeader
;
1498 EFI_SIMPLE_NETWORK_MODE
* pMode
;
1499 NIC_DEVICE
* pNicDevice
;
1500 EFI_USB_IO_PROTOCOL
* pUsbIo
;
1502 UINTN TransferLength
;
1503 UINT32 TransferStatus
;
1505 EFI_TPL TplPrevious
;
1507 TplPrevious
= gBS
->RaiseTPL(TPL_CALLBACK
);
1509 // Verify the parameters
1511 if (( NULL
!= pSimpleNetwork
) &&
1512 ( NULL
!= pSimpleNetwork
->Mode
) &&
1513 ( NULL
!= pBuffer
) &&
1514 ( (HeaderSize
== 0) || ( (NULL
!= pDestAddr
) && (NULL
!= pProtocol
) ))) {
1516 // The interface must be running
1518 pMode
= pSimpleNetwork
->Mode
;
1520 // Verify parameter of HeaderSize
1522 if ((HeaderSize
== 0) || (HeaderSize
== pMode
->MediaHeaderSize
)){
1524 // Determine if BufferSize is big enough
1526 if (BufferSize
>= pMode
->MediaHeaderSize
){
1527 if ( EfiSimpleNetworkInitialized
== pMode
->State
) {
1529 // Update the link status
1531 pNicDevice
= DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork
);
1532 pMode
->MediaPresent
= pNicDevice
->bLinkUp
;
1535 // Release the synchronization with Ax88772Timer
1537 if ( pMode
->MediaPresent
&& pNicDevice
->bComplete
) {
1539 // Copy the packet into the USB buffer
1542 CopyMem ( &pNicDevice
->pTxTest
->Data
[0], pBuffer
, BufferSize
);
1543 pNicDevice
->pTxTest
->Length
= (UINT16
) BufferSize
;
1546 // Transmit the packet
1548 pHeader
= (ETHERNET_HEADER
*) &pNicDevice
->pTxTest
->Data
[0];
1549 if ( 0 != HeaderSize
) {
1550 if ( NULL
!= pDestAddr
) {
1551 CopyMem ( &pHeader
->dest_addr
, pDestAddr
, PXE_HWADDR_LEN_ETHER
);
1553 if ( NULL
!= pSrcAddr
) {
1554 CopyMem ( &pHeader
->src_addr
, pSrcAddr
, PXE_HWADDR_LEN_ETHER
);
1557 CopyMem ( &pHeader
->src_addr
, &pMode
->CurrentAddress
.Addr
[0], PXE_HWADDR_LEN_ETHER
);
1559 if ( NULL
!= pProtocol
) {
1563 Type
= pNicDevice
->pTxTest
->Length
;
1565 Type
= (UINT16
)(( Type
>> 8 ) | ( Type
<< 8 ));
1566 pHeader
->type
= Type
;
1568 if ( pNicDevice
->pTxTest
->Length
< MIN_ETHERNET_PKT_SIZE
) {
1569 pNicDevice
->pTxTest
->Length
= MIN_ETHERNET_PKT_SIZE
;
1570 ZeroMem ( &pNicDevice
->pTxTest
->Data
[ BufferSize
],
1571 pNicDevice
->pTxTest
->Length
- BufferSize
);
1574 DEBUG ((EFI_D_INFO
, "TX: %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x"
1575 " %02x-%02x %d bytes\r\n",
1576 pNicDevice
->pTxTest
->Data
[0],
1577 pNicDevice
->pTxTest
->Data
[1],
1578 pNicDevice
->pTxTest
->Data
[2],
1579 pNicDevice
->pTxTest
->Data
[3],
1580 pNicDevice
->pTxTest
->Data
[4],
1581 pNicDevice
->pTxTest
->Data
[5],
1582 pNicDevice
->pTxTest
->Data
[6],
1583 pNicDevice
->pTxTest
->Data
[7],
1584 pNicDevice
->pTxTest
->Data
[8],
1585 pNicDevice
->pTxTest
->Data
[9],
1586 pNicDevice
->pTxTest
->Data
[10],
1587 pNicDevice
->pTxTest
->Data
[11],
1588 pNicDevice
->pTxTest
->Data
[12],
1589 pNicDevice
->pTxTest
->Data
[13],
1590 pNicDevice
->pTxTest
->Length
));
1592 pNicDevice
->pTxTest
->LengthBar
= ~(pNicDevice
->pTxTest
->Length
);
1593 TransferLength
= sizeof ( pNicDevice
->pTxTest
->Length
)
1594 + sizeof ( pNicDevice
->pTxTest
->LengthBar
)
1595 + pNicDevice
->pTxTest
->Length
;
1597 if (TransferLength
% 512 == 0 || TransferLength
% 1024 == 0)
1601 // Work around USB bus driver bug where a timeout set by receive
1602 // succeeds but the timeout expires immediately after, causing the
1603 // transmit operation to timeout.
1605 pUsbIo
= pNicDevice
->pUsbIo
;
1606 Status
= pUsbIo
->UsbBulkTransfer ( pUsbIo
,
1608 &pNicDevice
->pTxTest
->Length
,
1612 if ( !EFI_ERROR ( Status
)) {
1613 Status
= TransferStatus
;
1616 if ( !EFI_ERROR ( Status
)) {
1617 pNicDevice
->pTxBuffer
= pBuffer
;
1620 if ((TransferLength
!= (UINTN
)( pNicDevice
->pTxTest
->Length
+ 4 )) &&
1621 (TransferLength
!= (UINTN
)(( pNicDevice
->pTxTest
->Length
+ 4 ) + 4))) {
1622 DEBUG ((EFI_D_INFO
, "TransferLength didn't match Packet Length\n"));
1625 // Reset the controller to fix the error
1627 if ( EFI_DEVICE_ERROR
== Status
) {
1628 SN_Reset ( pSimpleNetwork
, FALSE
);
1630 Status
= EFI_NOT_READY
;
1635 // No packets available.
1637 Status
= EFI_NOT_READY
;
1642 if (EfiSimpleNetworkStarted
== pMode
->State
) {
1643 Status
= EFI_DEVICE_ERROR
;
1646 Status
= EFI_NOT_STARTED
;
1651 Status
= EFI_BUFFER_TOO_SMALL
;
1655 Status
= EFI_INVALID_PARAMETER
;
1659 Status
= EFI_INVALID_PARAMETER
;
1662 gBS
->RestoreTPL (TplPrevious
);