mirror of https://github.com/acidanthera/audk.git
1510 lines
51 KiB
C
1510 lines
51 KiB
C
/** @file
|
|
Provides the Simple Network functions.
|
|
|
|
Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include "Ax88772.h"
|
|
|
|
/**
|
|
This function updates the filtering on the receiver.
|
|
|
|
This support routine calls ::Ax88772MacAddressSet to update
|
|
the MAC address. This routine then rebuilds the multicast
|
|
hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
|
|
Finally this routine enables the receiver by calling
|
|
::Ax88772RxControl.
|
|
|
|
@param [in] pSimpleNetwork Simple network mode pointer
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
ReceiveFilterUpdate (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
|
|
)
|
|
{
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
NIC_DEVICE * pNicDevice;
|
|
EFI_STATUS Status;
|
|
UINT32 Index;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Set the MAC address
|
|
//
|
|
pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
|
|
pMode = pSimpleNetwork->Mode;
|
|
Status = Ax88772MacAddressSet ( pNicDevice,
|
|
&pMode->CurrentAddress.Addr[0]);
|
|
if ( !EFI_ERROR ( Status )) {
|
|
//
|
|
// Clear the multicast hash table
|
|
//
|
|
Ax88772MulticastClear ( pNicDevice );
|
|
|
|
//
|
|
// Load the multicast hash table
|
|
//
|
|
if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
|
|
for ( Index = 0;
|
|
( !EFI_ERROR ( Status )) && ( Index < pMode->MCastFilterCount );
|
|
Index++ ) {
|
|
//
|
|
// Enable the next multicast address
|
|
//
|
|
Ax88772MulticastSet ( pNicDevice,
|
|
&pMode->MCastFilter[ Index ].Addr[0]);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Enable the receiver
|
|
//
|
|
if ( !EFI_ERROR ( Status )) {
|
|
Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function updates the SNP driver status.
|
|
|
|
This function gets the current interrupt and recycled transmit
|
|
buffer status from the network interface. The interrupt status
|
|
and the media status are returned as a bit mask in InterruptStatus.
|
|
If InterruptStatus is NULL, the interrupt status will not be read.
|
|
Upon successful return of the media status, the MediaPresent field
|
|
of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
|
|
of media status. If TxBuf is not NULL, a recycled transmit buffer
|
|
address will be retrived. If a recycled transmit buffer address
|
|
is returned in TxBuf, then the buffer has been successfully
|
|
transmitted, and the status for that buffer is cleared.
|
|
|
|
This function calls ::Ax88772Rx to update the media status and
|
|
queue any receive packets.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
@param [in] pInterruptStatus A pointer to the bit mask of the current active interrupts.
|
|
If this is NULL, the interrupt status will not be read from
|
|
the device. If this is not NULL, the interrupt status will
|
|
be read from teh device. When the interrupt status is read,
|
|
it will also be cleared. Clearing the transmit interrupt
|
|
does not empty the recycled transmit buffer array.
|
|
@param [out] ppTxBuf Recycled transmit buffer address. The network interface will
|
|
not transmit if its internal recycled transmit buffer array is
|
|
full. Reading the transmit buffer does not clear the transmit
|
|
interrupt. If this is NULL, then the transmit buffer status
|
|
will not be read. If there are not transmit buffers to recycle
|
|
and TxBuf is not NULL, *TxBuf will be set to NULL.
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_GetStatus (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
|
|
OUT UINT32 * pInterruptStatus,
|
|
OUT VOID ** ppTxBuf
|
|
)
|
|
{
|
|
BOOLEAN bLinkIdle;
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
NIC_DEVICE * pNicDevice;
|
|
EFI_STATUS Status;
|
|
EFI_TPL TplPrevious;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
|
|
//
|
|
// Return the transmit buffer
|
|
//
|
|
pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
|
|
if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
|
|
*ppTxBuf = pNicDevice->pTxBuffer;
|
|
pNicDevice->pTxBuffer = NULL;
|
|
}
|
|
|
|
//
|
|
// Determine if interface is running
|
|
//
|
|
pMode = pSimpleNetwork->Mode;
|
|
if ( EfiSimpleNetworkStopped != pMode->State ) {
|
|
//
|
|
// Synchronize with Ax88772Timer
|
|
//
|
|
VERIFY_TPL ( TPL_AX88772 );
|
|
TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
|
|
|
|
//
|
|
// Update the link status
|
|
//
|
|
bLinkIdle = pNicDevice->bLinkIdle;
|
|
pNicDevice->bLinkIdle = TRUE;
|
|
Ax88772Rx ( pNicDevice, bLinkIdle );
|
|
pMode->MediaPresent = pNicDevice->bLinkUp;
|
|
|
|
//
|
|
// Release the synchronization with Ax88772Timer
|
|
//
|
|
gBS->RestoreTPL ( TplPrevious );
|
|
|
|
//
|
|
// Return the interrupt status
|
|
//
|
|
if ( NULL != pInterruptStatus ) {
|
|
*pInterruptStatus = 0;
|
|
}
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
else {
|
|
Status = EFI_NOT_STARTED;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Resets the network adapter and allocates the transmit and receive buffers
|
|
required by the network interface; optionally, also requests allocation of
|
|
additional transmit and receive buffers. This routine must be called before
|
|
any other routine in the Simple Network protocol is called.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
@param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
|
|
@param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and receive buffers
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_Initialize (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
|
|
IN UINTN ExtraRxBufferSize,
|
|
IN UINTN ExtraTxBufferSize
|
|
)
|
|
{
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
|
|
//
|
|
// Determine if the interface is already started
|
|
//
|
|
pMode = pSimpleNetwork->Mode;
|
|
if ( EfiSimpleNetworkStarted == pMode->State ) {
|
|
if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
|
|
//
|
|
// Start the adapter
|
|
//
|
|
Status = SN_Reset ( pSimpleNetwork, FALSE );
|
|
if ( !EFI_ERROR ( Status )) {
|
|
//
|
|
// Update the network state
|
|
//
|
|
pMode->State = EfiSimpleNetworkInitialized;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_NOT_STARTED;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function converts a multicast IP address to a multicast HW MAC address
|
|
for all packet transactions.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
@param [in] bIPv6 Set to TRUE if the multicast IP address is IPv6 [RFC2460].
|
|
Set to FALSE if the multicast IP address is IPv4 [RFC 791].
|
|
@param [in] pIP The multicast IP address that is to be converted to a
|
|
multicast HW MAC address.
|
|
@param [in] pMAC The multicast HW MAC address that is to be generated from IP.
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_MCastIPtoMAC (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
|
|
IN BOOLEAN bIPv6,
|
|
IN EFI_IP_ADDRESS * pIP,
|
|
IN EFI_MAC_ADDRESS * pMAC
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// This is not currently supported
|
|
//
|
|
Status = EFI_UNSUPPORTED;
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function performs read and write operations on the NVRAM device
|
|
attached to a network interface.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
@param [in] ReadWrite TRUE for read operations, FALSE for write operations.
|
|
@param [in] Offset Byte offset in the NVRAM device at which to start the
|
|
read or write operation. This must be a multiple of
|
|
NvRamAccessSize and less than NvRamSize.
|
|
@param [in] BufferSize The number of bytes to read or write from the NVRAM device.
|
|
This must also be a multiple of NvramAccessSize.
|
|
@param [in, out] pBuffer A pointer to the data buffer.
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_NvData (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
|
|
IN BOOLEAN ReadWrite,
|
|
IN UINTN Offset,
|
|
IN UINTN BufferSize,
|
|
IN OUT VOID * pBuffer
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// This is not currently supported
|
|
//
|
|
Status = EFI_UNSUPPORTED;
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Attempt to receive a packet from the network adapter.
|
|
|
|
This function retrieves one packet from the receive queue of the network
|
|
interface. If there are no packets on the receive queue, then EFI_NOT_READY
|
|
will be returned. If there is a packet on the receive queue, and the size
|
|
of the packet is smaller than BufferSize, then the contents of the packet
|
|
will be placed in Buffer, and BufferSize will be udpated with the actual
|
|
size of the packet. In addition, if SrcAddr, DestAddr, and Protocol are
|
|
not NULL, then these values will be extracted from the media header and
|
|
returned. If BufferSize is smaller than the received packet, then the
|
|
size of the receive packet will be placed in BufferSize and
|
|
EFI_BUFFER_TOO_SMALL will be returned.
|
|
|
|
This routine calls ::Ax88772Rx to update the media status and
|
|
empty the network adapter of receive packets.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
@param [out] pHeaderSize The size, in bytes, of the media header to be filled in by
|
|
the Transmit() function. If HeaderSize is non-zero, then
|
|
it must be equal to SimpleNetwork->Mode->MediaHeaderSize
|
|
and DestAddr and Protocol parameters must not be NULL.
|
|
@param [out] pBufferSize The size, in bytes, of the entire packet (media header and
|
|
data) to be transmitted through the network interface.
|
|
@param [out] pBuffer A pointer to the packet (media header followed by data) to
|
|
to be transmitted. This parameter can not be NULL. If
|
|
HeaderSize is zero, then the media header is Buffer must
|
|
already be filled in by the caller. If HeaderSize is nonzero,
|
|
then the media header will be filled in by the Transmit()
|
|
function.
|
|
@param [out] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
|
|
this parameter is ignored. If HeaderSize is nonzero and
|
|
SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
|
|
is used for the source HW MAC address.
|
|
@param [out] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
|
|
this parameter is ignored.
|
|
@param [out] pProtocol The type of header to build. If HeaderSize is zero, then
|
|
this parameter is ignored.
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_NOT_READY No packets have been received on the network interface.
|
|
@retval EFI_BUFFER_TOO_SMALL The packet is larger than BufferSize bytes.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_Receive (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
|
|
OUT UINTN * pHeaderSize,
|
|
OUT UINTN * pBufferSize,
|
|
OUT VOID * pBuffer,
|
|
OUT EFI_MAC_ADDRESS * pSrcAddr,
|
|
OUT EFI_MAC_ADDRESS * pDestAddr,
|
|
OUT UINT16 * pProtocol
|
|
)
|
|
{
|
|
ETHERNET_HEADER * pHeader;
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
NIC_DEVICE * pNicDevice;
|
|
RX_TX_PACKET * pRxPacket;
|
|
EFI_STATUS Status;
|
|
EFI_TPL TplPrevious;
|
|
UINT16 Type;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
|
|
//
|
|
// The interface must be running
|
|
//
|
|
pMode = pSimpleNetwork->Mode;
|
|
if ( EfiSimpleNetworkInitialized == pMode->State ) {
|
|
//
|
|
// Synchronize with Ax88772Timer
|
|
//
|
|
VERIFY_TPL ( TPL_AX88772 );
|
|
TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
|
|
|
|
//
|
|
// Update the link status
|
|
//
|
|
pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
|
|
Ax88772Rx ( pNicDevice, FALSE );
|
|
pMode->MediaPresent = pNicDevice->bLinkUp;
|
|
if ( pMode->MediaPresent ) {
|
|
//
|
|
// Attempt to receive a packet
|
|
//
|
|
pRxPacket = pNicDevice->pRxHead;
|
|
if ( NULL != pRxPacket ) {
|
|
pNicDevice->pRxHead = pRxPacket->pNext;
|
|
if ( NULL == pNicDevice->pRxHead ) {
|
|
pNicDevice->pRxTail = NULL;
|
|
}
|
|
|
|
//
|
|
// Copy the received packet into the receive buffer
|
|
//
|
|
*pBufferSize = pRxPacket->Length;
|
|
CopyMem ( pBuffer, &pRxPacket->Data[0], pRxPacket->Length );
|
|
pHeader = (ETHERNET_HEADER *) &pRxPacket->Data[0];
|
|
if ( NULL != pHeaderSize ) {
|
|
*pHeaderSize = sizeof ( *pHeader );
|
|
}
|
|
if ( NULL != pDestAddr ) {
|
|
CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );
|
|
}
|
|
if ( NULL != pSrcAddr ) {
|
|
CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );
|
|
}
|
|
if ( NULL != pProtocol ) {
|
|
Type = pHeader->type;
|
|
Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
|
|
*pProtocol = Type;
|
|
}
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
else {
|
|
//
|
|
// No receive packets available
|
|
//
|
|
Status = EFI_NOT_READY;
|
|
}
|
|
}
|
|
else {
|
|
//
|
|
// Link no up
|
|
//
|
|
Status = EFI_NOT_READY;
|
|
}
|
|
|
|
//
|
|
// Release the synchronization with Ax88772Timer
|
|
//
|
|
gBS->RestoreTPL ( TplPrevious );
|
|
}
|
|
else {
|
|
Status = EFI_NOT_STARTED;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function is used to enable and disable the hardware and software receive
|
|
filters for the underlying network device.
|
|
|
|
The receive filter change is broken down into three steps:
|
|
|
|
1. The filter mask bits that are set (ON) in the Enable parameter
|
|
are added to the current receive filter settings.
|
|
|
|
2. The filter mask bits that are set (ON) in the Disable parameter
|
|
are subtracted from the updated receive filter settins.
|
|
|
|
3. If the resulting filter settigns is not supported by the hardware
|
|
a more liberal setting is selected.
|
|
|
|
If the same bits are set in the Enable and Disable parameters, then the bits
|
|
in the Disable parameter takes precedence.
|
|
|
|
If the ResetMCastFilter parameter is TRUE, then the multicast address list
|
|
filter is disabled (irregardless of what other multicast bits are set in
|
|
the enable and Disable parameters). The SNP->Mode->MCastFilterCount field
|
|
is set to zero. The SNP->Mode->MCastFilter contents are undefined.
|
|
|
|
After enableing or disabling receive filter settings, software should
|
|
verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
|
|
SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
|
|
|
|
Note: Some network drivers and/or devices will automatically promote
|
|
receive filter settings if the requested setting can not be honored.
|
|
For example, if a request for four multicast addresses is made and
|
|
the underlying hardware only supports two multicast addresses the
|
|
driver might set the promiscuous or promiscuous multicast receive filters
|
|
instead. The receiving software is responsible for discarding any extra
|
|
packets that get through the hardware receive filters.
|
|
|
|
If ResetMCastFilter is TRUE, then the multicast receive filter list
|
|
on the network interface will be reset to the default multicast receive
|
|
filter list. If ResetMCastFilter is FALSE, and this network interface
|
|
allows the multicast receive filter list to be modified, then the
|
|
MCastFilterCnt and MCastFilter are used to update the current multicast
|
|
receive filter list. The modified receive filter list settings can be
|
|
found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
|
|
|
|
This routine calls ::ReceiveFilterUpdate to update the receive
|
|
state in the network adapter.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
@param [in] Enable A bit mask of receive filters to enable on the network interface.
|
|
@param [in] Disable A bit mask of receive filters to disable on the network interface.
|
|
For backward compatibility with EFI 1.1 platforms, the
|
|
EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
|
|
when the ResetMCastFilter parameter is TRUE.
|
|
@param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
|
|
filters on the network interface to their default values.
|
|
@param [in] MCastFilterCnt Number of multicast HW MAC address in the new MCastFilter list.
|
|
This value must be less than or equal to the MaxMCastFilterCnt
|
|
field of EFI_SIMPLE_NETWORK_MODE. This field is optional if
|
|
ResetMCastFilter is TRUE.
|
|
@param [in] pMCastFilter A pointer to a list of new multicast receive filter HW MAC
|
|
addresses. This list will replace any existing multicast
|
|
HW MAC address list. This field is optional if ResetMCastFilter
|
|
is TRUE.
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_ReceiveFilters (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
|
|
IN UINT32 Enable,
|
|
IN UINT32 Disable,
|
|
IN BOOLEAN bResetMCastFilter,
|
|
IN UINTN MCastFilterCnt,
|
|
IN EFI_MAC_ADDRESS * pMCastFilter
|
|
)
|
|
{
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
EFI_MAC_ADDRESS * pMulticastAddress;
|
|
EFI_MAC_ADDRESS * pTableEnd;
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
Status = EFI_INVALID_PARAMETER;
|
|
if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
|
|
pMode = pSimpleNetwork->Mode;
|
|
|
|
//
|
|
// Update the multicast list if necessary
|
|
//
|
|
if ( !bResetMCastFilter ) {
|
|
if ( 0 != MCastFilterCnt ) {
|
|
if (( MAX_MCAST_FILTER_CNT >= MCastFilterCnt )
|
|
&& ( NULL != pMCastFilter )) {
|
|
//
|
|
// Verify the multicast addresses
|
|
//
|
|
pMulticastAddress = pMCastFilter;
|
|
pTableEnd = pMulticastAddress + MCastFilterCnt;
|
|
while ( pTableEnd > pMulticastAddress ) {
|
|
//
|
|
// The first digit of the multicast address must have the LSB set
|
|
//
|
|
if ( 0 == ( pMulticastAddress->Addr[0] & 1 )) {
|
|
//
|
|
// Invalid multicast address
|
|
//
|
|
break;
|
|
}
|
|
pMulticastAddress += 1;
|
|
}
|
|
if ( pTableEnd == pMulticastAddress ) {
|
|
//
|
|
// Update the multicast filter list.
|
|
//
|
|
CopyMem (&pMode->MCastFilter[0],
|
|
pMCastFilter,
|
|
MCastFilterCnt * sizeof ( *pMCastFilter ));
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
}
|
|
else {
|
|
//
|
|
// No multicast address list is specified
|
|
//
|
|
MCastFilterCnt = 0;
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
if ( !EFI_ERROR ( Status )) {
|
|
//
|
|
// The parameters are valid!
|
|
//
|
|
pMode->ReceiveFilterSetting |= Enable;
|
|
pMode->ReceiveFilterSetting &= ~Disable;
|
|
pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
|
|
|
|
//
|
|
// Update the receive filters in the adapter
|
|
//
|
|
Status = ReceiveFilterUpdate ( pSimpleNetwork );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Reset the network adapter.
|
|
|
|
Resets a network adapter and reinitializes it with the parameters that
|
|
were provided in the previous call to Initialize (). The transmit and
|
|
receive queues are cleared. Receive filters, the station address, the
|
|
statistics, and the multicast-IP-to-HW MAC addresses are not reset by
|
|
this call.
|
|
|
|
This routine calls ::Ax88772Reset to perform the adapter specific
|
|
reset operation. This routine also starts the link negotiation
|
|
by calling ::Ax88772NegotiateLinkStart.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
@param [in] bExtendedVerification Indicates that the driver may perform a more
|
|
exhaustive verification operation of the device
|
|
during reset.
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_Reset (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
|
|
IN BOOLEAN bExtendedVerification
|
|
)
|
|
{
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
NIC_DEVICE * pNicDevice;
|
|
RX_TX_PACKET * pRxPacket;
|
|
EFI_STATUS Status;
|
|
EFI_TPL TplPrevious;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
|
|
//
|
|
// Synchronize with Ax88772Timer
|
|
//
|
|
VERIFY_TPL ( TPL_AX88772 );
|
|
TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
|
|
|
|
//
|
|
// Update the device state
|
|
//
|
|
pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
|
|
pNicDevice->bComplete = FALSE;
|
|
pNicDevice->bLinkUp = FALSE;
|
|
|
|
pMode = pSimpleNetwork->Mode;
|
|
pMode->MediaPresent = FALSE;
|
|
|
|
//
|
|
// Discard any received packets
|
|
//
|
|
while ( NULL != pNicDevice->pRxHead ) {
|
|
//
|
|
// Remove the packet from the received packet list
|
|
//
|
|
pRxPacket = pNicDevice->pRxHead;
|
|
pNicDevice->pRxHead = pRxPacket->pNext;
|
|
|
|
//
|
|
// Queue the packet to the free list
|
|
//
|
|
pRxPacket->pNext = pNicDevice->pRxFree;
|
|
pNicDevice->pRxFree = pRxPacket;
|
|
}
|
|
pNicDevice->pRxTail = NULL;
|
|
|
|
//
|
|
// Reset the device
|
|
//
|
|
Status = Ax88772Reset ( pNicDevice );
|
|
if ( !EFI_ERROR ( Status )) {
|
|
//
|
|
// Update the receive filters in the adapter
|
|
//
|
|
Status = ReceiveFilterUpdate ( pSimpleNetwork );
|
|
|
|
//
|
|
// Try to get a connection to the network
|
|
//
|
|
if ( !EFI_ERROR ( Status )) {
|
|
//
|
|
// Start the autonegotiation
|
|
//
|
|
Status = Ax88772NegotiateLinkStart ( pNicDevice );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Release the synchronization with Ax88772Timer
|
|
//
|
|
gBS->RestoreTPL ( TplPrevious );
|
|
}
|
|
else {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Initialize the simple network protocol.
|
|
|
|
This routine calls ::Ax88772MacAddressGet to obtain the
|
|
MAC address.
|
|
|
|
@param [in] pNicDevice NIC_DEVICE_INSTANCE pointer
|
|
|
|
@retval EFI_SUCCESS Setup was successful
|
|
|
|
**/
|
|
EFI_STATUS
|
|
SN_Setup (
|
|
IN NIC_DEVICE * pNicDevice
|
|
)
|
|
{
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Initialize the simple network protocol
|
|
//
|
|
pSimpleNetwork = &pNicDevice->SimpleNetwork;
|
|
pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
|
|
pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
|
|
pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
|
|
pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
|
|
pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
|
|
pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
|
|
pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
|
|
pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
|
|
pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
|
|
pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
|
|
pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
|
|
pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
|
|
pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
|
|
pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
|
|
pSimpleNetwork->WaitForPacket = NULL;
|
|
pMode = &pNicDevice->SimpleNetworkData;
|
|
pSimpleNetwork->Mode = pMode;
|
|
|
|
pMode->State = EfiSimpleNetworkStopped;
|
|
pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
|
|
pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
|
|
pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
|
|
pMode->NvRamSize = 0;
|
|
pMode->NvRamAccessSize = 0;
|
|
pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
|
|
| EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
|
|
| EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
|
|
| EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
|
|
| EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
|
|
pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
|
|
| EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
|
|
pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
|
|
pMode->MCastFilterCount = 0;
|
|
SetMem ( &pMode->BroadcastAddress,
|
|
PXE_HWADDR_LEN_ETHER,
|
|
0xff );
|
|
pMode->IfType = EfiNetworkInterfaceUndi;
|
|
pMode->MacAddressChangeable = TRUE;
|
|
pMode->MultipleTxSupported = TRUE;
|
|
pMode->MediaPresentSupported = TRUE;
|
|
pMode->MediaPresent = FALSE;
|
|
|
|
//
|
|
// Read the MAC address
|
|
//
|
|
pNicDevice->PhyId = PHY_ID_INTERNAL;
|
|
pNicDevice->b100Mbps = TRUE;
|
|
pNicDevice->bFullDuplex = TRUE;
|
|
|
|
Status = gBS->AllocatePool ( EfiRuntimeServicesData,
|
|
MAX_BULKIN_SIZE,
|
|
(VOID **) &pNicDevice->pBulkInBuff);
|
|
if ( EFI_ERROR(Status)) {
|
|
DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
|
|
return Status;
|
|
}
|
|
|
|
Status = Ax88772MacAddressGet (
|
|
pNicDevice,
|
|
&pMode->PermanentAddress.Addr[0]);
|
|
if ( !EFI_ERROR ( Status )) {
|
|
//
|
|
// Display the MAC address
|
|
//
|
|
DEBUG (( DEBUG_MAC_ADDRESS | DEBUG_INFO,
|
|
"MAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
|
|
pMode->PermanentAddress.Addr[0],
|
|
pMode->PermanentAddress.Addr[1],
|
|
pMode->PermanentAddress.Addr[2],
|
|
pMode->PermanentAddress.Addr[3],
|
|
pMode->PermanentAddress.Addr[4],
|
|
pMode->PermanentAddress.Addr[5]));
|
|
|
|
//
|
|
// Use the hardware address as the current address
|
|
//
|
|
CopyMem ( &pMode->CurrentAddress,
|
|
&pMode->PermanentAddress,
|
|
PXE_HWADDR_LEN_ETHER );
|
|
}
|
|
|
|
//
|
|
// Return the setup status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This routine starts the network interface.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_ALREADY_STARTED The network interface was already started.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_Start (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
|
|
)
|
|
{
|
|
NIC_DEVICE * pNicDevice;
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
Status = EFI_INVALID_PARAMETER;
|
|
if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
|
|
pMode = pSimpleNetwork->Mode;
|
|
if ( EfiSimpleNetworkStopped == pMode->State ) {
|
|
//
|
|
// Initialize the mode structure
|
|
// NVRAM access is not supported
|
|
//
|
|
ZeroMem ( pMode, sizeof ( *pMode ));
|
|
|
|
pMode->State = EfiSimpleNetworkStarted;
|
|
pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
|
|
pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
|
|
pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
|
|
pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
|
|
| EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
|
|
| EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
|
|
| EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
|
|
| EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
|
|
pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
|
|
pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
|
|
pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
|
|
Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
|
|
CopyMem ( &pMode->CurrentAddress,
|
|
&pMode->PermanentAddress,
|
|
sizeof ( pMode->CurrentAddress ));
|
|
pMode->BroadcastAddress.Addr[0] = 0xff;
|
|
pMode->BroadcastAddress.Addr[1] = 0xff;
|
|
pMode->BroadcastAddress.Addr[2] = 0xff;
|
|
pMode->BroadcastAddress.Addr[3] = 0xff;
|
|
pMode->BroadcastAddress.Addr[4] = 0xff;
|
|
pMode->BroadcastAddress.Addr[5] = 0xff;
|
|
pMode->IfType = 1;
|
|
pMode->MacAddressChangeable = TRUE;
|
|
pMode->MultipleTxSupported = TRUE;
|
|
pMode->MediaPresentSupported = TRUE;
|
|
pMode->MediaPresent = FALSE;
|
|
}
|
|
else {
|
|
Status = EFI_ALREADY_STARTED;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Set the MAC address.
|
|
|
|
This function modifies or resets the current station address of a
|
|
network interface. If Reset is TRUE, then the current station address
|
|
is set ot the network interface's permanent address. If Reset if FALSE
|
|
then the current station address is changed to the address specified by
|
|
pNew.
|
|
|
|
This routine calls ::Ax88772MacAddressSet to update the MAC address
|
|
in the network adapter.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
@param [in] bReset Flag used to reset the station address to the
|
|
network interface's permanent address.
|
|
@param [in] pNew New station address to be used for the network
|
|
interface.
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_StationAddress (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
|
|
IN BOOLEAN bReset,
|
|
IN EFI_MAC_ADDRESS * pNew
|
|
)
|
|
{
|
|
NIC_DEVICE * pNicDevice;
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
if (( NULL != pSimpleNetwork )
|
|
&& ( NULL != pSimpleNetwork->Mode )
|
|
&& (( !bReset ) || ( bReset && ( NULL != pNew )))) {
|
|
//
|
|
// Verify that the adapter is already started
|
|
//
|
|
pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
|
|
pMode = pSimpleNetwork->Mode;
|
|
if ( EfiSimpleNetworkStarted == pMode->State ) {
|
|
//
|
|
// Determine the adapter MAC address
|
|
//
|
|
if ( bReset ) {
|
|
//
|
|
// Use the permanent address
|
|
//
|
|
CopyMem ( &pMode->CurrentAddress,
|
|
&pMode->PermanentAddress,
|
|
sizeof ( pMode->CurrentAddress ));
|
|
}
|
|
else {
|
|
//
|
|
// Use the specified address
|
|
//
|
|
CopyMem ( &pMode->CurrentAddress,
|
|
pNew,
|
|
sizeof ( pMode->CurrentAddress ));
|
|
}
|
|
|
|
//
|
|
// Update the address on the adapter
|
|
//
|
|
Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
|
|
}
|
|
else {
|
|
Status = EFI_NOT_STARTED;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function resets or collects the statistics on a network interface.
|
|
If the size of the statistics table specified by StatisticsSize is not
|
|
big enough for all of the statistics that are collected by the network
|
|
interface, then a partial buffer of statistics is returned in
|
|
StatisticsTable.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
@param [in] bReset Set to TRUE to reset the statistics for the network interface.
|
|
@param [in, out] pStatisticsSize On input the size, in bytes, of StatisticsTable. On output
|
|
the size, in bytes, of the resulting table of statistics.
|
|
@param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
|
|
conains the statistics.
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_BUFFER_TOO_SMALL The pStatisticsTable is NULL or the buffer is too small.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_Statistics (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
|
|
IN BOOLEAN bReset,
|
|
IN OUT UINTN * pStatisticsSize,
|
|
OUT EFI_NETWORK_STATISTICS * pStatisticsTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// This is not currently supported
|
|
//
|
|
Status = EFI_UNSUPPORTED;
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function stops a network interface. This call is only valid
|
|
if the network interface is in the started state.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_Stop (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
|
|
)
|
|
{
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
|
|
//
|
|
// Determine if the interface is started
|
|
//
|
|
pMode = pSimpleNetwork->Mode;
|
|
if ( EfiSimpleNetworkStopped != pMode->State ) {
|
|
if ( EfiSimpleNetworkStarted == pMode->State ) {
|
|
//
|
|
// Release the resources acquired in SN_Start
|
|
//
|
|
|
|
//
|
|
// Mark the adapter as stopped
|
|
//
|
|
pMode->State = EfiSimpleNetworkStopped;
|
|
Status = EFI_SUCCESS;
|
|
}
|
|
else {
|
|
Status = EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_NOT_STARTED;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
This function releases the memory buffers assigned in the Initialize() call.
|
|
Pending transmits and receives are lost, and interrupts are cleared and disabled.
|
|
After this call, only Initialize() and Stop() calls may be used.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
@retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_Shutdown (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
|
|
)
|
|
{
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
UINT32 RxFilter;
|
|
EFI_STATUS Status;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
|
|
//
|
|
// Determine if the interface is already started
|
|
//
|
|
pMode = pSimpleNetwork->Mode;
|
|
if ( EfiSimpleNetworkInitialized == pMode->State ) {
|
|
//
|
|
// Stop the adapter
|
|
//
|
|
RxFilter = pMode->ReceiveFilterSetting;
|
|
pMode->ReceiveFilterSetting = 0;
|
|
Status = SN_Reset ( pSimpleNetwork, FALSE );
|
|
pMode->ReceiveFilterSetting = RxFilter;
|
|
if ( !EFI_ERROR ( Status )) {
|
|
//
|
|
// Release the resources acquired by SN_Initialize
|
|
//
|
|
|
|
//
|
|
// Update the network state
|
|
//
|
|
pMode->State = EfiSimpleNetworkStarted;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_NOT_STARTED;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
Send a packet over the network.
|
|
|
|
This function places the packet specified by Header and Buffer on
|
|
the transmit queue. This function performs a non-blocking transmit
|
|
operation. When the transmit is complete, the buffer is returned
|
|
via the GetStatus() call.
|
|
|
|
This routine calls ::Ax88772Rx to empty the network adapter of
|
|
receive packets. The routine then passes the transmit packet
|
|
to the network adapter.
|
|
|
|
@param [in] pSimpleNetwork Protocol instance pointer
|
|
@param [in] HeaderSize The size, in bytes, of the media header to be filled in by
|
|
the Transmit() function. If HeaderSize is non-zero, then
|
|
it must be equal to SimpleNetwork->Mode->MediaHeaderSize
|
|
and DestAddr and Protocol parameters must not be NULL.
|
|
@param [in] BufferSize The size, in bytes, of the entire packet (media header and
|
|
data) to be transmitted through the network interface.
|
|
@param [in] pBuffer A pointer to the packet (media header followed by data) to
|
|
to be transmitted. This parameter can not be NULL. If
|
|
HeaderSize is zero, then the media header is Buffer must
|
|
already be filled in by the caller. If HeaderSize is nonzero,
|
|
then the media header will be filled in by the Transmit()
|
|
function.
|
|
@param [in] pSrcAddr The source HW MAC address. If HeaderSize is zero, then
|
|
this parameter is ignored. If HeaderSize is nonzero and
|
|
SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
|
|
is used for the source HW MAC address.
|
|
@param [in] pDestAddr The destination HW MAC address. If HeaderSize is zero, then
|
|
this parameter is ignored.
|
|
@param [in] pProtocol The type of header to build. If HeaderSize is zero, then
|
|
this parameter is ignored.
|
|
|
|
@retval EFI_SUCCESS This operation was successful.
|
|
@retval EFI_NOT_STARTED The network interface was not started.
|
|
@retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
|
|
@retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
|
|
@retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
|
|
EFI_SIMPLE_NETWORK_PROTOCOL structure.
|
|
@retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
SN_Transmit (
|
|
IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
|
|
IN UINTN HeaderSize,
|
|
IN UINTN BufferSize,
|
|
IN VOID * pBuffer,
|
|
IN EFI_MAC_ADDRESS * pSrcAddr,
|
|
IN EFI_MAC_ADDRESS * pDestAddr,
|
|
IN UINT16 * pProtocol
|
|
)
|
|
{
|
|
RX_TX_PACKET Packet;
|
|
ETHERNET_HEADER * pHeader;
|
|
EFI_SIMPLE_NETWORK_MODE * pMode;
|
|
NIC_DEVICE * pNicDevice;
|
|
EFI_USB_IO_PROTOCOL * pUsbIo;
|
|
EFI_STATUS Status;
|
|
EFI_TPL TplPrevious;
|
|
UINTN TransferLength;
|
|
UINT32 TransferStatus;
|
|
UINT16 Type;
|
|
|
|
DBG_ENTER ( );
|
|
|
|
//
|
|
// Verify the parameters
|
|
//
|
|
if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
|
|
//
|
|
// The interface must be running
|
|
//
|
|
pMode = pSimpleNetwork->Mode;
|
|
if ( EfiSimpleNetworkInitialized == pMode->State ) {
|
|
//
|
|
// Synchronize with Ax88772Timer
|
|
//
|
|
VERIFY_TPL ( TPL_AX88772 );
|
|
TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
|
|
|
|
//
|
|
// Update the link status
|
|
//
|
|
pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
|
|
|
|
//
|
|
//No need to call receive to receive packet
|
|
//
|
|
//Ax88772Rx ( pNicDevice, FALSE );
|
|
pMode->MediaPresent = pNicDevice->bLinkUp;
|
|
|
|
//
|
|
// Release the synchronization with Ax88772Timer
|
|
//
|
|
gBS->RestoreTPL ( TplPrevious );
|
|
if ( pMode->MediaPresent ) {
|
|
//
|
|
// Copy the packet into the USB buffer
|
|
//
|
|
CopyMem ( &Packet.Data[0], pBuffer, BufferSize );
|
|
Packet.Length = (UINT16) BufferSize;
|
|
|
|
//
|
|
// Transmit the packet
|
|
//
|
|
pHeader = (ETHERNET_HEADER *) &Packet.Data[0];
|
|
if ( 0 != HeaderSize ) {
|
|
if ( NULL != pDestAddr ) {
|
|
CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
|
|
}
|
|
if ( NULL != pSrcAddr ) {
|
|
CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
|
|
}
|
|
else {
|
|
CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
|
|
}
|
|
if ( NULL != pProtocol ) {
|
|
Type = *pProtocol;
|
|
}
|
|
else {
|
|
Type = Packet.Length;
|
|
}
|
|
Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
|
|
pHeader->type = Type;
|
|
}
|
|
if ( Packet.Length < MIN_ETHERNET_PKT_SIZE ) {
|
|
Packet.Length = MIN_ETHERNET_PKT_SIZE;
|
|
ZeroMem ( &Packet.Data[ BufferSize ],
|
|
Packet.Length - BufferSize );
|
|
}
|
|
DEBUG (( DEBUG_TX | DEBUG_INFO,
|
|
"TX: %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x %d bytes\r\n",
|
|
Packet.Data[0],
|
|
Packet.Data[1],
|
|
Packet.Data[2],
|
|
Packet.Data[3],
|
|
Packet.Data[4],
|
|
Packet.Data[5],
|
|
Packet.Data[6],
|
|
Packet.Data[7],
|
|
Packet.Data[8],
|
|
Packet.Data[9],
|
|
Packet.Data[10],
|
|
Packet.Data[11],
|
|
Packet.Data[12],
|
|
Packet.Data[13],
|
|
Packet.Length ));
|
|
Packet.LengthBar = ~Packet.Length;
|
|
TransferLength = sizeof ( Packet.Length )
|
|
+ sizeof ( Packet.LengthBar )
|
|
+ Packet.Length;
|
|
|
|
//
|
|
// Work around USB bus driver bug where a timeout set by receive
|
|
// succeeds but the timeout expires immediately after, causing the
|
|
// transmit operation to timeout.
|
|
//
|
|
pUsbIo = pNicDevice->pUsbIo;
|
|
Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
|
|
BULK_OUT_ENDPOINT,
|
|
&Packet.Length,
|
|
&TransferLength,
|
|
0xfffffffe,
|
|
&TransferStatus );
|
|
if ( !EFI_ERROR ( Status )) {
|
|
Status = TransferStatus;
|
|
}
|
|
if (( !EFI_ERROR ( Status ))
|
|
&& ( TransferLength != (UINTN)( Packet.Length + 4 ))) {
|
|
Status = EFI_WARN_WRITE_FAILURE;
|
|
}
|
|
if ( EFI_SUCCESS == Status ) {
|
|
pNicDevice->pTxBuffer = pBuffer;
|
|
}
|
|
else {
|
|
DEBUG (( DEBUG_ERROR | DEBUG_INFO,
|
|
"Ax88772 USB transmit error, TransferLength: %d, Status: %r\r\n",
|
|
sizeof ( Packet.Length ) + Packet.Length,
|
|
Status ));
|
|
//
|
|
// Reset the controller to fix the error
|
|
//
|
|
if ( EFI_DEVICE_ERROR == Status ) {
|
|
SN_Reset ( pSimpleNetwork, FALSE );
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
//
|
|
// No packets available.
|
|
//
|
|
Status = EFI_NOT_READY;
|
|
}
|
|
}
|
|
else {
|
|
Status = EFI_NOT_STARTED;
|
|
}
|
|
}
|
|
else {
|
|
DEBUG (( DEBUG_ERROR | DEBUG_INFO,
|
|
"Ax88772 invalid transmit parameter\r\n"
|
|
" 0x%08x: HeaderSize\r\n"
|
|
" 0x%08x: BufferSize\r\n"
|
|
" 0x%08x: Buffer\r\n"
|
|
" 0x%08x: SrcAddr\r\n"
|
|
" 0x%08x: DestAddr\r\n"
|
|
" 0x%04x: Protocol\r\n",
|
|
HeaderSize,
|
|
BufferSize,
|
|
pBuffer,
|
|
pSrcAddr,
|
|
pDestAddr,
|
|
pProtocol ));
|
|
Status = EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// Return the operation status
|
|
//
|
|
DBG_EXIT_STATUS ( Status );
|
|
return Status;
|
|
}
|