Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Frank Fan <frank@asix.com.tw> Reviewed-by: lpleahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14149 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
985fef803e
commit
7f556e4d32
|
@ -0,0 +1,878 @@
|
||||||
|
/** @file
|
||||||
|
Implement the interface to the AX88772 Ethernet controller.
|
||||||
|
|
||||||
|
This module implements the interface to the ASIX AX88772
|
||||||
|
USB to Ethernet MAC with integrated 10/100 PHY. Note that this implementation
|
||||||
|
only supports the integrated PHY since no other test cases were available.
|
||||||
|
|
||||||
|
Copyright (c) 2011, Intel Corporation
|
||||||
|
All rights reserved. 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"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Compute the CRC
|
||||||
|
|
||||||
|
@param [in] pMacAddress Address of a six byte buffer to containing the MAC address.
|
||||||
|
|
||||||
|
@returns The CRC-32 value associated with this MAC address
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT32
|
||||||
|
Ax88772Crc (
|
||||||
|
IN UINT8 * pMacAddress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 BitNumber;
|
||||||
|
INT32 Carry;
|
||||||
|
INT32 Crc;
|
||||||
|
UINT32 Data;
|
||||||
|
UINT8 * pEnd;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Walk the MAC address
|
||||||
|
//
|
||||||
|
Crc = -1;
|
||||||
|
pEnd = &pMacAddress[ PXE_HWADDR_LEN_ETHER ];
|
||||||
|
while ( pEnd > pMacAddress ) {
|
||||||
|
Data = *pMacAddress++;
|
||||||
|
//
|
||||||
|
// CRC32: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
|
||||||
|
//
|
||||||
|
// 1 0000 0100 1100 0001 0001 1101 1011 0111
|
||||||
|
//
|
||||||
|
for ( BitNumber = 0; 8 > BitNumber; BitNumber++ ) {
|
||||||
|
Carry = (( Crc >> 31 ) & 1 ) ^ ( Data & 1 );
|
||||||
|
Crc <<= 1;
|
||||||
|
if ( 0 != Carry ) {
|
||||||
|
Crc ^= 0x04c11db7;
|
||||||
|
}
|
||||||
|
Data >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Return the CRC value
|
||||||
|
//
|
||||||
|
return (UINT32) Crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the MAC address
|
||||||
|
|
||||||
|
This routine calls ::Ax88772UsbCommand to request the MAC
|
||||||
|
address from the network adapter.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
@param [out] pMacAddress Address of a six byte buffer to receive the MAC address.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The MAC address is available.
|
||||||
|
@retval other The MAC address is not valid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
Ax88772MacAddressGet (
|
||||||
|
IN NIC_DEVICE * pNicDevice,
|
||||||
|
OUT UINT8 * pMacAddress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
USB_DEVICE_REQUEST SetupMsg;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the register address.
|
||||||
|
//
|
||||||
|
SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
|
||||||
|
| USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_MAC_ADDRESS_READ;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read the PHY register
|
||||||
|
//
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
pMacAddress );
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the MAC address
|
||||||
|
|
||||||
|
This routine calls ::Ax88772UsbCommand to set the MAC address
|
||||||
|
in the network adapter.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
@param [in] pMacAddress Address of a six byte buffer to containing the new MAC address.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The MAC address was set.
|
||||||
|
@retval other The MAC address was not set.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
Ax88772MacAddressSet (
|
||||||
|
IN NIC_DEVICE * pNicDevice,
|
||||||
|
IN UINT8 * pMacAddress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
USB_DEVICE_REQUEST SetupMsg;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the register address.
|
||||||
|
//
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read the PHY register
|
||||||
|
//
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
pMacAddress );
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Clear the multicast hash table
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
Ax88772MulticastClear (
|
||||||
|
IN NIC_DEVICE * pNicDevice
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
//
|
||||||
|
// Clear the multicast hash table
|
||||||
|
//
|
||||||
|
for ( i = 0 ; i < 8 ; i ++ )
|
||||||
|
pNicDevice->MulticastHash[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable a multicast address in the multicast hash table
|
||||||
|
|
||||||
|
This routine calls ::Ax88772Crc to compute the hash bit for
|
||||||
|
this MAC address.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
@param [in] pMacAddress Address of a six byte buffer to containing the MAC address.
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
Ax88772MulticastSet (
|
||||||
|
IN NIC_DEVICE * pNicDevice,
|
||||||
|
IN UINT8 * pMacAddress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 Crc;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compute the CRC on the destination address
|
||||||
|
//
|
||||||
|
Crc = Ax88772Crc ( pMacAddress ) >> 26;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the bit corresponding to the destination address
|
||||||
|
//
|
||||||
|
pNicDevice->MulticastHash [ Crc >> 3 ] |= ( 1<< (Crc& 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Start the link negotiation
|
||||||
|
|
||||||
|
This routine calls ::Ax88772PhyWrite to start the PHY's link
|
||||||
|
negotiation.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The link negotiation was started.
|
||||||
|
@retval other Failed to start the link negotiation.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
Ax88772NegotiateLinkStart (
|
||||||
|
IN NIC_DEVICE * pNicDevice
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT16 Control;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
int i;
|
||||||
|
//
|
||||||
|
// Set the supported capabilities.
|
||||||
|
//
|
||||||
|
Status = Ax88772PhyWrite ( pNicDevice,
|
||||||
|
PHY_ANAR,
|
||||||
|
AN_CSMA_CD
|
||||||
|
| AN_TX_FDX | AN_TX_HDX
|
||||||
|
| AN_10_FDX | AN_10_HDX );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
//
|
||||||
|
// Set the link speed and duplex
|
||||||
|
//
|
||||||
|
Control = BMCR_AUTONEGOTIATION_ENABLE
|
||||||
|
| BMCR_RESTART_AUTONEGOTIATION;
|
||||||
|
if ( pNicDevice->b100Mbps ) {
|
||||||
|
Control |= BMCR_100MBPS;
|
||||||
|
}
|
||||||
|
if ( pNicDevice->bFullDuplex ) {
|
||||||
|
Control |= BMCR_FULL_DUPLEX;
|
||||||
|
}
|
||||||
|
Status = Ax88772PhyWrite ( pNicDevice, PHY_BMCR, Control );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EFI_ERROR(Status)) {
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
|
||||||
|
if (pNicDevice->bComplete && pNicDevice->bLinkUp) {
|
||||||
|
pNicDevice->SimpleNetwork.Mode->MediaPresent
|
||||||
|
= pNicDevice->bLinkUp & pNicDevice->bComplete;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gBS->Stall(AUTONEG_DELAY);
|
||||||
|
Status = Ax88772NegotiateLinkComplete ( pNicDevice,
|
||||||
|
&pNicDevice->PollCount,
|
||||||
|
&pNicDevice->bComplete,
|
||||||
|
&pNicDevice->bLinkUp,
|
||||||
|
&pNicDevice->b100Mbps,
|
||||||
|
&pNicDevice->bFullDuplex );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}while(!pNicDevice->bLinkUp && i < AUTONEG_POLLCNT);
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Complete the negotiation of the PHY link
|
||||||
|
|
||||||
|
This routine calls ::Ax88772PhyRead to determine if the
|
||||||
|
link negotiation is complete.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
@param [in, out] pPollCount Address of number of times this routine was polled
|
||||||
|
@param [out] pbComplete Address of boolean to receive complate status.
|
||||||
|
@param [out] pbLinkUp Address of boolean to receive link status, TRUE=up.
|
||||||
|
@param [out] pbHiSpeed Address of boolean to receive link speed, TRUE=100Mbps.
|
||||||
|
@param [out] pbFullDuplex Address of boolean to receive link duplex, TRUE=full.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The MAC address is available.
|
||||||
|
@retval other The MAC address is not valid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
Ax88772NegotiateLinkComplete (
|
||||||
|
IN NIC_DEVICE * pNicDevice,
|
||||||
|
IN OUT UINTN * pPollCount,
|
||||||
|
OUT BOOLEAN * pbComplete,
|
||||||
|
OUT BOOLEAN * pbLinkUp,
|
||||||
|
OUT BOOLEAN * pbHiSpeed,
|
||||||
|
OUT BOOLEAN * pbFullDuplex
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT16 Mask;
|
||||||
|
UINT16 PhyData;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine if the link is up.
|
||||||
|
//
|
||||||
|
*pbComplete = FALSE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the link status
|
||||||
|
//
|
||||||
|
Status = Ax88772PhyRead ( pNicDevice,
|
||||||
|
PHY_BMSR,
|
||||||
|
&PhyData );
|
||||||
|
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
*pbLinkUp = (BOOLEAN)( 0 != ( PhyData & BMSR_LINKST ));
|
||||||
|
if ( 0 == *pbLinkUp ) {
|
||||||
|
DEBUG (( EFI_D_INFO, "Link Down\n" ));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*pbComplete = (BOOLEAN)( 0 != ( PhyData & 0x20 ));
|
||||||
|
if ( 0 == *pbComplete ) {
|
||||||
|
DEBUG (( EFI_D_INFO, "Autoneg is not yet Complete\n" ));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Status = Ax88772PhyRead ( pNicDevice,
|
||||||
|
PHY_ANLPAR,
|
||||||
|
&PhyData );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
//
|
||||||
|
// Autonegotiation is complete
|
||||||
|
// Determine the link speed.
|
||||||
|
//
|
||||||
|
*pbHiSpeed = (BOOLEAN)( 0 != ( PhyData & ( AN_TX_FDX | AN_TX_HDX )));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine the link duplex.
|
||||||
|
//
|
||||||
|
Mask = ( *pbHiSpeed ) ? AN_TX_FDX : AN_10_FDX;
|
||||||
|
*pbFullDuplex = (BOOLEAN)( 0 != ( PhyData & Mask ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG (( EFI_D_ERROR, "Failed to read BMCR\n" ));
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read a register from the PHY
|
||||||
|
|
||||||
|
This routine calls ::Ax88772UsbCommand to read a PHY register.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
@param [in] RegisterAddress Number of the register to read.
|
||||||
|
@param [in, out] pPhyData Address of a buffer to receive the PHY register value
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The PHY data is available.
|
||||||
|
@retval other The PHY data is not valid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
Ax88772PhyRead (
|
||||||
|
IN NIC_DEVICE * pNicDevice,
|
||||||
|
IN UINT8 RegisterAddress,
|
||||||
|
IN OUT UINT16 * pPhyData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
USB_DEVICE_REQUEST SetupMsg;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Request access to the PHY
|
||||||
|
//
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
//
|
||||||
|
// Read the PHY register address.
|
||||||
|
//
|
||||||
|
SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
|
||||||
|
| USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_PHY_REG_READ;
|
||||||
|
SetupMsg.Value = pNicDevice->PhyId;
|
||||||
|
SetupMsg.Index = RegisterAddress;
|
||||||
|
SetupMsg.Length = sizeof ( *pPhyData );
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
pPhyData );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Release the PHY to the hardware
|
||||||
|
//
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Write to a PHY register
|
||||||
|
|
||||||
|
This routine calls ::Ax88772UsbCommand to write a PHY register.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
@param [in] RegisterAddress Number of the register to read.
|
||||||
|
@param [in] PhyData Address of a buffer to receive the PHY register value
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The PHY data was written.
|
||||||
|
@retval other Failed to wwrite the PHY register.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
Ax88772PhyWrite (
|
||||||
|
IN NIC_DEVICE * pNicDevice,
|
||||||
|
IN UINT8 RegisterAddress,
|
||||||
|
IN UINT16 PhyData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
USB_DEVICE_REQUEST SetupMsg;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Request access to the PHY
|
||||||
|
//
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
//
|
||||||
|
// Write the PHY register
|
||||||
|
//
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_PHY_REG_WRITE;
|
||||||
|
SetupMsg.Value = pNicDevice->PhyId;
|
||||||
|
SetupMsg.Index = RegisterAddress;
|
||||||
|
SetupMsg.Length = sizeof ( PhyData );
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
&PhyData );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Release the PHY to the hardware
|
||||||
|
//
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Reset the AX88772
|
||||||
|
|
||||||
|
This routine uses ::Ax88772UsbCommand to reset the network
|
||||||
|
adapter. This routine also uses ::Ax88772PhyWrite to reset
|
||||||
|
the PHY.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The MAC address is available.
|
||||||
|
@retval other The MAC address is not valid.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
Ax88772Reset (
|
||||||
|
IN NIC_DEVICE * pNicDevice
|
||||||
|
)
|
||||||
|
{
|
||||||
|
USB_DEVICE_REQUEST SetupMsg;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
EFI_USB_IO_PROTOCOL *pUsbIo;
|
||||||
|
EFI_USB_DEVICE_DESCRIPTOR Device;
|
||||||
|
|
||||||
|
pUsbIo = pNicDevice->pUsbIo;
|
||||||
|
Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) goto err;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) goto err;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_PHY_SELECT;
|
||||||
|
SetupMsg.Value = SPHY_PSEL;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) goto err;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_RESET;
|
||||||
|
SetupMsg.Value = SRR_IPRL ;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) goto err;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_RESET;
|
||||||
|
SetupMsg.Value = SRR_IPPD | SRR_IPRL ;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
gBS->Stall ( 200000 );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) goto err;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_RESET;
|
||||||
|
SetupMsg.Value = SRR_IPRL ;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
gBS->Stall ( 200000 );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) goto err;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_RESET;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) goto err;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_PHY_SELECT;
|
||||||
|
SetupMsg.Value = SPHY_PSEL;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) goto err;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_RESET;
|
||||||
|
SetupMsg.Value = SRR_IPRL | SRR_BZ | SRR_BZTYPE;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) goto err;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_RX_CONTROL_WRITE;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) goto err;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_RXQTC;
|
||||||
|
SetupMsg.Value = 0x8000;
|
||||||
|
SetupMsg.Index = 0x8001;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
err:
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enable or disable the receiver
|
||||||
|
|
||||||
|
This routine calls ::Ax88772UsbCommand to update the
|
||||||
|
receiver state. This routine also calls ::Ax88772MacAddressSet
|
||||||
|
to establish the MAC address for the network adapter.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
@param [in] RxFilter Simple network RX filter mask value
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The MAC address was set.
|
||||||
|
@retval other The MAC address was not set.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
Ax88772RxControl (
|
||||||
|
IN NIC_DEVICE * pNicDevice,
|
||||||
|
IN UINT32 RxFilter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT16 MediumStatus;
|
||||||
|
UINT16 RxControl;
|
||||||
|
USB_DEVICE_REQUEST SetupMsg;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_USB_IO_PROTOCOL *pUsbIo;
|
||||||
|
EFI_USB_DEVICE_DESCRIPTOR Device;
|
||||||
|
|
||||||
|
pUsbIo = pNicDevice->pUsbIo;
|
||||||
|
Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
DEBUG (( EFI_D_ERROR, "Failed to get device descriptor\n" ));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enable the receiver if something is to be received
|
||||||
|
//
|
||||||
|
|
||||||
|
if ( 0 != RxFilter ) {
|
||||||
|
//
|
||||||
|
// Enable the receiver
|
||||||
|
//
|
||||||
|
SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
|
||||||
|
| USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_MEDIUM_STATUS_READ;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = sizeof ( MediumStatus );
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
&MediumStatus );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
if ( 0 == ( MediumStatus & MS_RE )) {
|
||||||
|
MediumStatus |= MS_RE | MS_ONE;
|
||||||
|
|
||||||
|
if ( pNicDevice->bFullDuplex )
|
||||||
|
MediumStatus |= MS_TFC | MS_RFC | MS_FD;
|
||||||
|
else
|
||||||
|
MediumStatus &= ~(MS_TFC | MS_RFC | MS_FD);
|
||||||
|
|
||||||
|
if ( pNicDevice->b100Mbps )
|
||||||
|
MediumStatus |= MS_PS;
|
||||||
|
else
|
||||||
|
MediumStatus &= ~MS_PS;
|
||||||
|
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
|
||||||
|
SetupMsg.Value = MediumStatus;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
if ( EFI_ERROR ( Status )) {
|
||||||
|
DEBUG (( EFI_D_ERROR, "Failed to enable receiver, Status: %r\r\n",
|
||||||
|
Status ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG (( EFI_D_ERROR, "Failed to read receiver status, Status: %r\r\n",
|
||||||
|
Status ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RxControl = RXC_SO | RXC_RH1M;
|
||||||
|
//
|
||||||
|
// Enable multicast if requested
|
||||||
|
//
|
||||||
|
if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
|
||||||
|
RxControl |= RXC_AM;
|
||||||
|
//
|
||||||
|
// Update the multicast hash table
|
||||||
|
//
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
|
||||||
|
SetupMsg.Value = 0;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = sizeof ( pNicDevice ->MulticastHash );
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
&pNicDevice->MulticastHash );
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Enable all multicast if requested
|
||||||
|
//
|
||||||
|
if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST )) {
|
||||||
|
RxControl |= RXC_AMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enable broadcast if requested
|
||||||
|
//
|
||||||
|
if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST )) {
|
||||||
|
RxControl |= RXC_AB;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enable promiscuous mode if requested
|
||||||
|
//
|
||||||
|
if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS )) {
|
||||||
|
RxControl |= RXC_PRO;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update the receiver control
|
||||||
|
//
|
||||||
|
if (pNicDevice->CurRxControl != RxControl) {
|
||||||
|
SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
|
||||||
|
| USB_TARGET_DEVICE;
|
||||||
|
SetupMsg.Request = CMD_RX_CONTROL_WRITE;
|
||||||
|
SetupMsg.Value = RxControl;
|
||||||
|
SetupMsg.Index = 0;
|
||||||
|
SetupMsg.Length = 0;
|
||||||
|
Status = Ax88772UsbCommand ( pNicDevice,
|
||||||
|
&SetupMsg,
|
||||||
|
NULL );
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
pNicDevice->CurRxControl = RxControl;
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG (( EFI_D_ERROR, "ERROR - Failed to set receiver control, Status: %r\r\n",
|
||||||
|
Status ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Read an SROM location
|
||||||
|
|
||||||
|
This routine calls ::Ax88772UsbCommand to read data from the
|
||||||
|
SROM.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
@param [in] Address SROM address
|
||||||
|
@param [out] pData Buffer to receive the data
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The read was successful
|
||||||
|
@retval other The read failed
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
Ax88772SromRead (
|
||||||
|
IN NIC_DEVICE * pNicDevice,
|
||||||
|
IN UINT32 Address,
|
||||||
|
OUT UINT16 * pData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Send a command to the USB device.
|
||||||
|
|
||||||
|
@param [in] pNicDevice Pointer to the NIC_DEVICE structure
|
||||||
|
@param [in] pRequest Pointer to the request structure
|
||||||
|
@param [in, out] pBuffer Data buffer address
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The USB transfer was successful
|
||||||
|
@retval other The USB transfer failed
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
Ax88772UsbCommand (
|
||||||
|
IN NIC_DEVICE * pNicDevice,
|
||||||
|
IN USB_DEVICE_REQUEST * pRequest,
|
||||||
|
IN OUT VOID * pBuffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 CmdStatus;
|
||||||
|
EFI_USB_DATA_DIRECTION Direction;
|
||||||
|
EFI_USB_IO_PROTOCOL * pUsbIo;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine the transfer direction
|
||||||
|
//
|
||||||
|
Direction = EfiUsbNoData;
|
||||||
|
if ( 0 != pRequest->Length ) {
|
||||||
|
Direction = ( 0 != ( pRequest->RequestType & USB_ENDPOINT_DIR_IN ))
|
||||||
|
? EfiUsbDataIn : EfiUsbDataOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Issue the command
|
||||||
|
//
|
||||||
|
pUsbIo = pNicDevice->pUsbIo;
|
||||||
|
Status = pUsbIo->UsbControlTransfer ( pUsbIo,
|
||||||
|
pRequest,
|
||||||
|
Direction,
|
||||||
|
USB_BUS_TIMEOUT,
|
||||||
|
pBuffer,
|
||||||
|
pRequest->Length,
|
||||||
|
&CmdStatus );
|
||||||
|
//
|
||||||
|
// Determine the operation status
|
||||||
|
//
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
Status = CmdStatus;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//
|
||||||
|
// Only use status values associated with the Simple Network protocol
|
||||||
|
//
|
||||||
|
if ( EFI_TIMEOUT == Status ) {
|
||||||
|
Status = EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,72 @@
|
||||||
|
#/** @file
|
||||||
|
# Component description file for ASIX AX88772 USB/Ethernet driver.
|
||||||
|
#
|
||||||
|
# This module provides support for the ASIX AX88772 USB/Ethernet adapter.
|
||||||
|
# Copyright (c) 2011, Intel Corporation
|
||||||
|
#
|
||||||
|
# All rights reserved. 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.
|
||||||
|
#
|
||||||
|
#**/
|
||||||
|
|
||||||
|
[Defines]
|
||||||
|
INF_VERSION = 0x00010005
|
||||||
|
BASE_NAME = Ax88772b
|
||||||
|
FILE_GUID = 95C8D770-E1A4-4422-B263-E32F14FD8186
|
||||||
|
MODULE_TYPE = DXE_RUNTIME_DRIVER
|
||||||
|
VERSION_STRING = 1.0
|
||||||
|
|
||||||
|
ENTRY_POINT = EntryPoint
|
||||||
|
|
||||||
|
#
|
||||||
|
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||||
|
#
|
||||||
|
|
||||||
|
[Sources.common]
|
||||||
|
Ax88772.h
|
||||||
|
Ax88772.c
|
||||||
|
ComponentName.c
|
||||||
|
DriverBinding.c
|
||||||
|
SimpleNetwork.c
|
||||||
|
|
||||||
|
|
||||||
|
[Packages]
|
||||||
|
MdePkg/MdePkg.dec
|
||||||
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
|
|
||||||
|
[LibraryClasses]
|
||||||
|
UefiLib
|
||||||
|
UefiBootServicesTableLib
|
||||||
|
BaseMemoryLib
|
||||||
|
DebugLib
|
||||||
|
UefiRuntimeLib
|
||||||
|
UefiDriverEntryPoint
|
||||||
|
|
||||||
|
[Protocols]
|
||||||
|
gEfiDevicePathProtocolGuid
|
||||||
|
gEfiSimpleNetworkProtocolGuid
|
||||||
|
gEfiUsbIoProtocolGuid ## TO_START
|
||||||
|
|
||||||
|
[Guids]
|
||||||
|
gEfiEventExitBootServicesGuid ## PRODUCES ## Event
|
||||||
|
gEfiEventVirtualAddressChangeGuid ## PRODUCES ## Event
|
||||||
|
gEfiNicIp4ConfigVariableGuid
|
||||||
|
|
||||||
|
[Depex]
|
||||||
|
gEfiBdsArchProtocolGuid AND
|
||||||
|
gEfiCpuArchProtocolGuid AND
|
||||||
|
gEfiMetronomeArchProtocolGuid AND
|
||||||
|
gEfiMonotonicCounterArchProtocolGuid AND
|
||||||
|
gEfiRealTimeClockArchProtocolGuid AND
|
||||||
|
gEfiResetArchProtocolGuid AND
|
||||||
|
gEfiRuntimeArchProtocolGuid AND
|
||||||
|
gEfiSecurityArchProtocolGuid AND
|
||||||
|
gEfiTimerArchProtocolGuid AND
|
||||||
|
gEfiVariableWriteArchProtocolGuid AND
|
||||||
|
gEfiVariableArchProtocolGuid AND
|
||||||
|
gEfiWatchdogTimerArchProtocolGuid
|
|
@ -0,0 +1,181 @@
|
||||||
|
/** @file
|
||||||
|
UEFI Component Name(2) protocol implementation.
|
||||||
|
|
||||||
|
Copyright (c) 2011, Intel Corporation
|
||||||
|
All rights reserved. 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"
|
||||||
|
|
||||||
|
/**
|
||||||
|
EFI Component Name Protocol declaration
|
||||||
|
**/
|
||||||
|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
|
||||||
|
GetDriverName,
|
||||||
|
GetControllerName,
|
||||||
|
"eng"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
EFI Component Name 2 Protocol declaration
|
||||||
|
**/
|
||||||
|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
|
||||||
|
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
|
||||||
|
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
|
||||||
|
"en"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Driver name table declaration
|
||||||
|
**/
|
||||||
|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
|
||||||
|
mDriverNameTable[] = {
|
||||||
|
{"eng;en", L"ASIX AX88772B Ethernet Driver 1.0"},
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves a Unicode string that is the user readable name of the driver.
|
||||||
|
|
||||||
|
This function retrieves the user readable name of a driver in the form of a
|
||||||
|
Unicode string. If the driver specified by This has a user readable name in
|
||||||
|
the language specified by Language, then a pointer to the driver name is
|
||||||
|
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
|
||||||
|
by This does not support the language specified by Language,
|
||||||
|
then EFI_UNSUPPORTED is returned.
|
||||||
|
|
||||||
|
@param [in] pThis A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||||
|
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||||
|
@param [in] pLanguage A pointer to a Null-terminated ASCII string
|
||||||
|
array indicating the language. This is the
|
||||||
|
language of the driver name that the caller is
|
||||||
|
requesting, and it must match one of the
|
||||||
|
languages specified in SupportedLanguages. The
|
||||||
|
number of languages supported by a driver is up
|
||||||
|
to the driver writer. Language is specified
|
||||||
|
in RFC 3066 or ISO 639-2 language code format.
|
||||||
|
@param [out] ppDriverName A pointer to the Unicode string to return.
|
||||||
|
This Unicode string is the name of the
|
||||||
|
driver specified by This in the language
|
||||||
|
specified by Language.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The Unicode string for the Driver specified by
|
||||||
|
This and the language specified by Language was
|
||||||
|
returned in DriverName.
|
||||||
|
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||||
|
@retval EFI_INVALID_PARAMETER DriverName is NULL.
|
||||||
|
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||||
|
the language specified by Language.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
GetDriverName (
|
||||||
|
IN EFI_COMPONENT_NAME_PROTOCOL * pThis,
|
||||||
|
IN CHAR8 * pLanguage,
|
||||||
|
OUT CHAR16 ** ppDriverName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Status = LookupUnicodeString2 (
|
||||||
|
pLanguage,
|
||||||
|
pThis->SupportedLanguages,
|
||||||
|
mDriverNameTable,
|
||||||
|
ppDriverName,
|
||||||
|
(BOOLEAN)(pThis == &gComponentName)
|
||||||
|
);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retrieves a Unicode string that is the user readable name of the controller
|
||||||
|
that is being managed by a driver.
|
||||||
|
|
||||||
|
This function retrieves the user readable name of the controller specified by
|
||||||
|
ControllerHandle and ChildHandle in the form of a Unicode string. If the
|
||||||
|
driver specified by This has a user readable name in the language specified by
|
||||||
|
Language, then a pointer to the controller name is returned in ControllerName,
|
||||||
|
and EFI_SUCCESS is returned. If the driver specified by This is not currently
|
||||||
|
managing the controller specified by ControllerHandle and ChildHandle,
|
||||||
|
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
|
||||||
|
support the language specified by Language, then EFI_UNSUPPORTED is returned.
|
||||||
|
|
||||||
|
@param [in] pThis A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
|
||||||
|
EFI_COMPONENT_NAME_PROTOCOL instance.
|
||||||
|
@param [in] ControllerHandle The handle of a controller that the driver
|
||||||
|
specified by This is managing. This handle
|
||||||
|
specifies the controller whose name is to be
|
||||||
|
returned.
|
||||||
|
@param [in] ChildHandle The handle of the child controller to retrieve
|
||||||
|
the name of. This is an optional parameter that
|
||||||
|
may be NULL. It will be NULL for device
|
||||||
|
drivers. It will also be NULL for a bus drivers
|
||||||
|
that wish to retrieve the name of the bus
|
||||||
|
controller. It will not be NULL for a bus
|
||||||
|
driver that wishes to retrieve the name of a
|
||||||
|
child controller.
|
||||||
|
@param [in] pLanguage A pointer to a Null-terminated ASCII string
|
||||||
|
array indicating the language. This is the
|
||||||
|
language of the driver name that the caller is
|
||||||
|
requesting, and it must match one of the
|
||||||
|
languages specified in SupportedLanguages. The
|
||||||
|
number of languages supported by a driver is up
|
||||||
|
to the driver writer. Language is specified in
|
||||||
|
RFC 3066 or ISO 639-2 language code format.
|
||||||
|
@param [out] ppControllerName A pointer to the Unicode string to return.
|
||||||
|
This Unicode string is the name of the
|
||||||
|
controller specified by ControllerHandle and
|
||||||
|
ChildHandle in the language specified by
|
||||||
|
Language from the point of view of the driver
|
||||||
|
specified by This.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS The Unicode string for the user readable name in
|
||||||
|
the language specified by Language for the
|
||||||
|
driver specified by This was returned in
|
||||||
|
DriverName.
|
||||||
|
@retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
|
||||||
|
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
|
||||||
|
EFI_HANDLE.
|
||||||
|
@retval EFI_INVALID_PARAMETER Language is NULL.
|
||||||
|
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
|
||||||
|
@retval EFI_UNSUPPORTED The driver specified by This is not currently
|
||||||
|
managing the controller specified by
|
||||||
|
ControllerHandle and ChildHandle.
|
||||||
|
@retval EFI_UNSUPPORTED The driver specified by This does not support
|
||||||
|
the language specified by Language.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
GetControllerName (
|
||||||
|
IN EFI_COMPONENT_NAME_PROTOCOL * pThis,
|
||||||
|
IN EFI_HANDLE ControllerHandle,
|
||||||
|
IN OPTIONAL EFI_HANDLE ChildHandle,
|
||||||
|
IN CHAR8 * pLanguage,
|
||||||
|
OUT CHAR16 ** ppControllerName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the controller name
|
||||||
|
//
|
||||||
|
*ppControllerName = L"ASIX AX88772B USB Fast Ethernet Controller";
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the operation status
|
||||||
|
//
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
|
@ -0,0 +1,672 @@
|
||||||
|
/** @file
|
||||||
|
Implement the driver binding protocol for Asix AX88772 Ethernet driver.
|
||||||
|
|
||||||
|
Copyright (c) 2011, Intel Corporation
|
||||||
|
All rights reserved. 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"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Verify the controller type
|
||||||
|
|
||||||
|
@param [in] pThis Protocol instance pointer.
|
||||||
|
@param [in] Controller Handle of device to test.
|
||||||
|
@param [in] pRemainingDevicePath Not used.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS This driver supports this device.
|
||||||
|
@retval other This driver does not support this device.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
DriverSupported (
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
|
||||||
|
IN EFI_HANDLE Controller,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_USB_DEVICE_DESCRIPTOR Device;
|
||||||
|
EFI_USB_IO_PROTOCOL * pUsbIo;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
//
|
||||||
|
// Connect to the USB stack
|
||||||
|
//
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
(VOID **) &pUsbIo,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR ( Status )) {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the interface descriptor to check the USB class and find a transport
|
||||||
|
// protocol handler.
|
||||||
|
//
|
||||||
|
Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
|
||||||
|
if (EFI_ERROR ( Status )) {
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//
|
||||||
|
// Validate the adapter
|
||||||
|
//
|
||||||
|
if ( VENDOR_ID == Device.IdVendor ) {
|
||||||
|
|
||||||
|
if (PRODUCT_ID == Device.IdProduct) {
|
||||||
|
DEBUG ((EFI_D_INFO, "Found the AX88772B\r\n"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Status = EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Done with the USB stack
|
||||||
|
//
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Start this driver on Controller by opening UsbIo and DevicePath protocols.
|
||||||
|
Initialize PXE structures, create a copy of the Controller Device Path with the
|
||||||
|
NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
|
||||||
|
on the newly created Device Path.
|
||||||
|
|
||||||
|
@param [in] pThis Protocol instance pointer.
|
||||||
|
@param [in] Controller Handle of device to work with.
|
||||||
|
@param [in] pRemainingDevicePath Not used, always produce all possible children.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS This driver is added to Controller.
|
||||||
|
@retval other This driver does not support this device.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
DriverStart (
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
|
||||||
|
IN EFI_HANDLE Controller,
|
||||||
|
IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
EFI_STATUS Status;
|
||||||
|
NIC_DEVICE *pNicDevice;
|
||||||
|
UINTN LengthInBytes;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath = NULL;
|
||||||
|
MAC_ADDR_DEVICE_PATH MacDeviceNode;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allocate the device structure
|
||||||
|
//
|
||||||
|
LengthInBytes = sizeof ( *pNicDevice );
|
||||||
|
Status = gBS->AllocatePool (
|
||||||
|
EfiRuntimeServicesData,
|
||||||
|
LengthInBytes,
|
||||||
|
(VOID **) &pNicDevice
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "gBS->AllocatePool:pNicDevice ERROR Status = %r\n", Status));
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set the structure signature
|
||||||
|
//
|
||||||
|
ZeroMem ( pNicDevice, LengthInBytes );
|
||||||
|
pNicDevice->Signature = DEV_SIGNATURE;
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
(VOID **) &pNicDevice->pUsbIo,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "gBS->OpenProtocol:EFI_USB_IO_PROTOCOL ERROR Status = %r\n", Status));
|
||||||
|
gBS->FreePool ( pNicDevice );
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize the simple network protocol
|
||||||
|
//
|
||||||
|
Status = SN_Setup ( pNicDevice );
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)){
|
||||||
|
DEBUG ((EFI_D_ERROR, "SN_Setup ERROR Status = %r\n", Status));
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
gBS->FreePool ( pNicDevice );
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set Device Path
|
||||||
|
//
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
(VOID **) &ParentDevicePath,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||||||
|
);
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "gBS->OpenProtocol:EFI_DEVICE_PATH_PROTOCOL error. Status = %r\n",
|
||||||
|
Status));
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
gBS->FreePool ( pNicDevice );
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZeroMem (&MacDeviceNode, sizeof (MAC_ADDR_DEVICE_PATH));
|
||||||
|
MacDeviceNode.Header.Type = MESSAGING_DEVICE_PATH;
|
||||||
|
MacDeviceNode.Header.SubType = MSG_MAC_ADDR_DP;
|
||||||
|
|
||||||
|
SetDevicePathNodeLength (&MacDeviceNode.Header, sizeof (MAC_ADDR_DEVICE_PATH));
|
||||||
|
|
||||||
|
CopyMem (&MacDeviceNode.MacAddress,
|
||||||
|
&pNicDevice->SimpleNetworkData.CurrentAddress,
|
||||||
|
PXE_HWADDR_LEN_ETHER);
|
||||||
|
|
||||||
|
MacDeviceNode.IfType = pNicDevice->SimpleNetworkData.IfType;
|
||||||
|
|
||||||
|
pNicDevice->MyDevPath = AppendDevicePathNode (
|
||||||
|
ParentDevicePath,
|
||||||
|
(EFI_DEVICE_PATH_PROTOCOL *) &MacDeviceNode
|
||||||
|
);
|
||||||
|
|
||||||
|
pNicDevice->Controller = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Install both the simple network and device path protocols.
|
||||||
|
//
|
||||||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
|
&pNicDevice->Controller,
|
||||||
|
&gEfiCallerIdGuid,
|
||||||
|
pNicDevice,
|
||||||
|
&gEfiSimpleNetworkProtocolGuid,
|
||||||
|
&pNicDevice->SimpleNetwork,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
pNicDevice->MyDevPath,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)){
|
||||||
|
DEBUG ((EFI_D_ERROR, "gBS->InstallMultipleProtocolInterfaces error. Status = %r\n",
|
||||||
|
Status));
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller);
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
gBS->FreePool ( pNicDevice );
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open For Child Device
|
||||||
|
//
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
(VOID **) &pNicDevice->pUsbIo,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
pNicDevice->Controller,
|
||||||
|
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)){
|
||||||
|
gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
&pNicDevice->Controller,
|
||||||
|
&gEfiCallerIdGuid,
|
||||||
|
pNicDevice,
|
||||||
|
&gEfiSimpleNetworkProtocolGuid,
|
||||||
|
&pNicDevice->SimpleNetwork,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
pNicDevice->MyDevPath,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller);
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
gBS->FreePool ( pNicDevice );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXIT:
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
|
||||||
|
closing the DevicePath and PciIo protocols on Controller.
|
||||||
|
|
||||||
|
@param [in] pThis Protocol instance pointer.
|
||||||
|
@param [in] Controller Handle of device to stop driver on.
|
||||||
|
@param [in] NumberOfChildren How many children need to be stopped.
|
||||||
|
@param [in] pChildHandleBuffer Not used.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS This driver is removed Controller.
|
||||||
|
@retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
|
||||||
|
@retval other This driver was not removed from this device.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
DriverStop (
|
||||||
|
IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
|
||||||
|
IN EFI_HANDLE Controller,
|
||||||
|
IN UINTN NumberOfChildren,
|
||||||
|
IN EFI_HANDLE * ChildHandleBuffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN AllChildrenStopped;
|
||||||
|
UINTN Index;
|
||||||
|
EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork;
|
||||||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
NIC_DEVICE *pNicDevice;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Complete all outstanding transactions to Controller.
|
||||||
|
// Don't allow any new transaction to Controller to be started.
|
||||||
|
//
|
||||||
|
if (NumberOfChildren == 0) {
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiSimpleNetworkProtocolGuid,
|
||||||
|
(VOID **) &SimpleNetwork,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller,
|
||||||
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)) {
|
||||||
|
//
|
||||||
|
// This is a 2nd type handle(multi-lun root), it needs to close devicepath
|
||||||
|
// and usbio protocol.
|
||||||
|
//
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNicDevice = DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork );
|
||||||
|
|
||||||
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
Controller,
|
||||||
|
&gEfiCallerIdGuid,
|
||||||
|
pNicDevice,
|
||||||
|
&gEfiSimpleNetworkProtocolGuid,
|
||||||
|
&pNicDevice->SimpleNetwork,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
pNicDevice->MyDevPath,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Close the bus driver
|
||||||
|
//
|
||||||
|
Status = gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)){
|
||||||
|
DEBUG ((EFI_D_ERROR, "driver stop: gBS->CloseProtocol:EfiDevicePathProtocol error. Status %r\n", Status));
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR(Status)){
|
||||||
|
DEBUG ((EFI_D_ERROR, "driver stop: gBS->CloseProtocol:EfiUsbIoProtocol error. Status %r\n", Status));
|
||||||
|
}
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
AllChildrenStopped = TRUE;
|
||||||
|
|
||||||
|
for (Index = 0; Index < NumberOfChildren; Index++) {
|
||||||
|
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
ChildHandleBuffer[Index],
|
||||||
|
&gEfiSimpleNetworkProtocolGuid,
|
||||||
|
(VOID **) &SimpleNetwork,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
Controller,
|
||||||
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
AllChildrenStopped = FALSE;
|
||||||
|
DEBUG ((EFI_D_ERROR, "Fail to stop No.%d multi-lun child handle when opening SimpleNetwork\n", (UINT32)Index));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNicDevice = DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork );
|
||||||
|
|
||||||
|
gBS->CloseProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
ChildHandleBuffer[Index]
|
||||||
|
);
|
||||||
|
|
||||||
|
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ChildHandleBuffer[Index],
|
||||||
|
&gEfiCallerIdGuid,
|
||||||
|
pNicDevice,
|
||||||
|
&gEfiSimpleNetworkProtocolGuid,
|
||||||
|
&pNicDevice->SimpleNetwork,
|
||||||
|
&gEfiDevicePathProtocolGuid,
|
||||||
|
pNicDevice->MyDevPath,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
Status = gBS->OpenProtocol (
|
||||||
|
Controller,
|
||||||
|
&gEfiUsbIoProtocolGuid,
|
||||||
|
(VOID **) &pNicDevice->pUsbIo,
|
||||||
|
pThis->DriverBindingHandle,
|
||||||
|
ChildHandleBuffer[Index],
|
||||||
|
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i;
|
||||||
|
RX_PKT * pCurr = pNicDevice->QueueHead;
|
||||||
|
RX_PKT * pFree;
|
||||||
|
|
||||||
|
for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
|
||||||
|
if ( NULL != pCurr ) {
|
||||||
|
pFree = pCurr;
|
||||||
|
pCurr = pCurr->pNext;
|
||||||
|
gBS->FreePool (pFree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( NULL != pNicDevice->pRxTest)
|
||||||
|
gBS->FreePool (pNicDevice->pRxTest);
|
||||||
|
|
||||||
|
if ( NULL != pNicDevice->pTxTest)
|
||||||
|
gBS->FreePool (pNicDevice->pTxTest);
|
||||||
|
|
||||||
|
if ( NULL != pNicDevice->MyDevPath)
|
||||||
|
gBS->FreePool (pNicDevice->MyDevPath);
|
||||||
|
|
||||||
|
if ( NULL != pNicDevice)
|
||||||
|
gBS->FreePool (pNicDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AllChildrenStopped) {
|
||||||
|
return EFI_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Driver binding protocol declaration
|
||||||
|
**/
|
||||||
|
EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
|
||||||
|
DriverSupported,
|
||||||
|
DriverStart,
|
||||||
|
DriverStop,
|
||||||
|
0xa,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Ax88772 driver unload routine.
|
||||||
|
|
||||||
|
@param [in] ImageHandle Handle for the image.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Image may be unloaded
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
DriverUnload (
|
||||||
|
IN EFI_HANDLE ImageHandle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN BufferSize;
|
||||||
|
UINTN Index;
|
||||||
|
UINTN Max;
|
||||||
|
EFI_HANDLE * pHandle;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine which devices are using this driver
|
||||||
|
//
|
||||||
|
BufferSize = 0;
|
||||||
|
pHandle = NULL;
|
||||||
|
Status = gBS->LocateHandle (
|
||||||
|
ByProtocol,
|
||||||
|
&gEfiCallerIdGuid,
|
||||||
|
NULL,
|
||||||
|
&BufferSize,
|
||||||
|
NULL );
|
||||||
|
if ( EFI_BUFFER_TOO_SMALL == Status ) {
|
||||||
|
for ( ; ; ) {
|
||||||
|
//
|
||||||
|
// One or more block IO devices are present
|
||||||
|
//
|
||||||
|
Status = gBS->AllocatePool (
|
||||||
|
EfiRuntimeServicesData,
|
||||||
|
BufferSize,
|
||||||
|
(VOID **) &pHandle
|
||||||
|
);
|
||||||
|
if ( EFI_ERROR ( Status )) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "Insufficient memory, failed handle buffer allocation\r\n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Locate the block IO devices
|
||||||
|
//
|
||||||
|
Status = gBS->LocateHandle (
|
||||||
|
ByProtocol,
|
||||||
|
&gEfiCallerIdGuid,
|
||||||
|
NULL,
|
||||||
|
&BufferSize,
|
||||||
|
pHandle );
|
||||||
|
if ( EFI_ERROR ( Status )) {
|
||||||
|
//
|
||||||
|
// Error getting handles
|
||||||
|
//
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove any use of the driver
|
||||||
|
//
|
||||||
|
Max = BufferSize / sizeof ( pHandle[ 0 ]);
|
||||||
|
for ( Index = 0; Max > Index; Index++ ) {
|
||||||
|
Status = DriverStop ( &gDriverBinding,
|
||||||
|
pHandle[ Index ],
|
||||||
|
0,
|
||||||
|
NULL );
|
||||||
|
if ( EFI_ERROR ( Status )) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( EFI_NOT_FOUND == Status ) {
|
||||||
|
//
|
||||||
|
// No devices were found
|
||||||
|
//
|
||||||
|
Status = EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free the handle array
|
||||||
|
//
|
||||||
|
if ( NULL != pHandle ) {
|
||||||
|
gBS->FreePool ( pHandle );
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove the protocols installed by the EntryPoint routine.
|
||||||
|
//
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
gBS->UninstallMultipleProtocolInterfaces (
|
||||||
|
ImageHandle,
|
||||||
|
&gEfiDriverBindingProtocolGuid,
|
||||||
|
&gDriverBinding,
|
||||||
|
&gEfiComponentNameProtocolGuid,
|
||||||
|
&gComponentName,
|
||||||
|
&gEfiComponentName2ProtocolGuid,
|
||||||
|
&gComponentName2,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
|
||||||
|
"Removed: gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
|
||||||
|
ImageHandle ));
|
||||||
|
DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
|
||||||
|
"Removed: gEfiComponentNameProtocolGuid from 0x%08x\r\n",
|
||||||
|
ImageHandle ));
|
||||||
|
DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
|
||||||
|
"Removed: gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
|
||||||
|
ImageHandle ));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Ax88772 driver entry point.
|
||||||
|
|
||||||
|
@param [in] ImageHandle Handle for the image.
|
||||||
|
@param [in] pSystemTable Address of the system table.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Image successfully loaded.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
EntryPoint (
|
||||||
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
IN EFI_SYSTEM_TABLE * pSystemTable
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_LOADED_IMAGE_PROTOCOL * pLoadedImage;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enable unload support
|
||||||
|
//
|
||||||
|
Status = gBS->HandleProtocol (
|
||||||
|
gImageHandle,
|
||||||
|
&gEfiLoadedImageProtocolGuid,
|
||||||
|
(VOID **)&pLoadedImage
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
pLoadedImage->Unload = DriverUnload;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add the driver to the list of drivers
|
||||||
|
//
|
||||||
|
Status = EfiLibInstallDriverBindingComponentName2 (
|
||||||
|
ImageHandle,
|
||||||
|
pSystemTable,
|
||||||
|
&gDriverBinding,
|
||||||
|
ImageHandle,
|
||||||
|
&gComponentName,
|
||||||
|
&gComponentName2
|
||||||
|
);
|
||||||
|
if ( !EFI_ERROR ( Status )) {
|
||||||
|
|
||||||
|
AsciiPrint ("Installed: gEfiDriverBindingProtocolGuid on 0x%08x\r\n",
|
||||||
|
ImageHandle );
|
||||||
|
AsciiPrint("Installed: gEfiComponentNameProtocolGuid on 0x%08x\r\n",
|
||||||
|
ImageHandle );
|
||||||
|
AsciiPrint("Installed: gEfiComponentName2ProtocolGuid on 0x%08x\r\n",
|
||||||
|
ImageHandle );
|
||||||
|
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue