From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web12.4689.1591663056282086718 for ; Mon, 08 Jun 2020 17:37:36 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: ray.ni@intel.com) IronPort-SDR: 9q+XWEnS45bL0XlrVatSH5wPGclke6AsWm6YzsOlIaKL+4fmuX2sEK+3+Y/95nFrfx+eZT4ayF c92iveNpyQhg== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Jun 2020 17:37:34 -0700 IronPort-SDR: V6z09ytFXqbUNzSzZ/lfqJwE77wD7l57GKQqJtgLff8SSZerZSSLNYAOu99POXnihyP0Dt/9Wp Rof5V4TlDcNA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.73,489,1583222400"; d="scan'208";a="270710641" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by orsmga003.jf.intel.com with ESMTP; 08 Jun 2020 17:37:34 -0700 Received: from fmsmsx112.amr.corp.intel.com (10.18.116.6) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 8 Jun 2020 17:37:33 -0700 Received: from shsmsx153.ccr.corp.intel.com (10.239.6.53) by FMSMSX112.amr.corp.intel.com (10.18.116.6) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 8 Jun 2020 17:37:33 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.161]) by SHSMSX153.ccr.corp.intel.com ([169.254.12.41]) with mapi id 14.03.0439.000; Tue, 9 Jun 2020 08:37:29 +0800 From: "Ni, Ray" To: Samer El-Haj-Mahmoud , "devel@edk2.groups.io" CC: Leif Lindholm , Ard Biesheuvel , "Kinney, Michael D" Subject: Re: [edk2-platform][PATCH v3 3/6] Drivers/ASIX: Add ASIX Ax88772c driver Thread-Topic: [edk2-platform][PATCH v3 3/6] Drivers/ASIX: Add ASIX Ax88772c driver Thread-Index: AQHWPZoiWMpYLsCpgkaInXO7lYkjmKjPcLcA Date: Tue, 9 Jun 2020 00:37:28 +0000 Deferred-Delivery: Tue, 9 Jun 2020 00:37:00 +0000 Message-ID: <734D49CCEBEEF84792F5B80ED585239D5C5A4965@SHSMSX104.ccr.corp.intel.com> References: <20200608133832.14100-1-Samer.El-Haj-Mahmoud@arm.com> <20200608133832.14100-4-Samer.El-Haj-Mahmoud@arm.com> In-Reply-To: <20200608133832.14100-4-Samer.El-Haj-Mahmoud@arm.com> Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.2.0.6 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: ray.ni@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Ray Ni > -----Original Message----- > From: Samer El-Haj-Mahmoud > Sent: Monday, June 8, 2020 9:38 PM > To: devel@edk2.groups.io > Cc: Ni, Ray ; Leif Lindholm ; Ard Bi= esheuvel ; Kinney, > Michael D > Subject: [edk2-platform][PATCH v3 3/6] Drivers/ASIX: Add ASIX Ax88772c dr= iver >=20 > This is the initial revision of ASIX USB networking UEFI driver > version 2.8.0 for Ax88772c / Ax88772b / Ax88772a > https://www.asix.com.tw/download.php?sub=3Ddriverdetail&PItemID=3D136 >=20 > Original source code provided by ASIX is at: > https://github.com/samerhaj/uefi_drivers/blob/master/UsbNetworking/Asix/ > zip/source/AX88772C_772B_772A_UEFI_v2.8.0_Source.zip >=20 > Cc: Ray Ni > Cc: Leif Lindholm > Cc: Ard Biesheuvel > Cc: Michael D Kinney >=20 > Signed-off-by: Samer El-Haj-Mahmoud > --- > Drivers/ASIX/Asix.dsc | 1 + > Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf | 45 + > Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772.h | 1041 +++++= ++++++++ > Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772.c | 1300 +++++= +++++++++++ > Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/ComponentName.c | 222 +++ > Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/DriverBinding.c | 652 +++++= +++ > Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/SimpleNetwork.c | 1581 +++++= +++++++++++++++ > 7 files changed, 4842 insertions(+) >=20 > diff --git a/Drivers/ASIX/Asix.dsc b/Drivers/ASIX/Asix.dsc > index 73b5cbd5a18f..5e02e1176016 100644 > --- a/Drivers/ASIX/Asix.dsc > +++ b/Drivers/ASIX/Asix.dsc > @@ -65,3 +65,4 @@ [PcdsFixedAtBuild] > ########################################################################= ######## > [Components] > Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf > +Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf > diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf > b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf > new file mode 100644 > index 000000000000..9889fc0b2067 > --- /dev/null > +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf > @@ -0,0 +1,45 @@ > +## @file > +# Component description file for ASIX AX88772 USB/Ethernet driver. > +# > +# This module provides support for the ASIX AX88772 USB/Ethernet adapter= . > +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
> +# Copyright (c) 2020, ARM Limited. All rights reserved. > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x00010018 > + BASE_NAME =3D Ax88772c > + FILE_GUID =3D B15239D6-6A01-4808-A0F7-B7F20F07355= 5 > + MODULE_TYPE =3D UEFI_DRIVER > + VERSION_STRING =3D 1.0 > + > + ENTRY_POINT =3D EntryPoint > + > +[Sources.common] > + Ax88772.h > + Ax88772.c > + ComponentName.c > + DriverBinding.c > + SimpleNetwork.c > + > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + NetworkPkg/NetworkPkg.dec > + > +[LibraryClasses] > + BaseMemoryLib > + DebugLib > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + UefiLib > + > +[Protocols] > + gEfiDevicePathProtocolGuid ## BY_START > + gEfiSimpleNetworkProtocolGuid ## BY_START > + gEfiUsbIoProtocolGuid ## TO_START > + > diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772.h > b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772.h > new file mode 100644 > index 000000000000..60afa65eee7a > --- /dev/null > +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772.h > @@ -0,0 +1,1041 @@ > +/** @file > + Definitions for ASIX AX88772 Ethernet adapter. > + > + Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved. > + Copyright (c) 2020, ARM Limited. All rights reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef AX88772_H_ > +#define AX88772_H_ > + > +#include > + > +#include > + > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +#define MAX_QUEUE_SIZE 50 > +#define MAX_BULKIN_SIZE 16384 > +#define HW_HDR_LENGTH 8 > +#define REPORTLINK 1 > + > +#define ASIX_MCAST_FILTER_CNT 8 > +#define RXTHOU 0 > + > +#define USB_IS_IN_ENDPOINT(EndPointAddr) (((EndPointAddr) & BIT7) != =3D 0) ///< Return TRUE/FALSE for IN direction > +#define USB_IS_OUT_ENDPOINT(EndPointAddr) (((EndPointAddr) & BIT7) = =3D=3D 0) ///< Return TRUE/FALSE for OUT > direction > +#define USB_IS_BULK_ENDPOINT(Attribute) (((Attribute) & (BIT0 | BI= T1)) =3D=3D USB_ENDPOINT_BULK) ///< Return > TRUE/FALSE for BULK type > +#define USB_IS_INTERRUPT_ENDPOINT(Attribute) (((Attribute) & (BIT0 | BI= T1)) =3D=3D USB_ENDPOINT_INTERRUPT) ///< > Return TRUE/FALSE for INTERRUPT type > + > + > +#define PRINT(_L_STR) (gST->ConOut->OutputString(gST->ConOut,(_L_STR))) > +//----------------------------------------------------------------------= -------- > +// Constants > +//----------------------------------------------------------------------= -------- > + > +#define DEBUG_RX_BROADCAST 0x40000000 ///< Display RX broadcast messa= ges > +#define DEBUG_RX_MULTICAST 0x20000000 ///< Display RX multicast messa= ges > +#define DEBUG_RX_UNICAST 0x10000000 ///< Display RX unicast message= s > +#define DEBUG_MAC_ADDRESS 0x08000000 ///< Display the MAC address > +#define DEBUG_LINK 0x04000000 ///< Display the link status > +#define DEBUG_TX 0x02000000 ///< Display the TX messages > +#define DEBUG_PHY 0x01000000 ///< Display the PHY register v= alues > +#define DEBUG_SROM 0x00800000 ///< Display the SROM contents > +#define DEBUG_TIMER 0x00400000 ///< Display the timer routine = entry/exit > +#define DEBUG_TPL 0x00200000 ///< Display the timer routine = entry/exit > + > +#if RXTHOU > +#define AX88772_MAX_BULKIN_SIZE 1024 * 17 //32 > +#else > +#define AX88772_MAX_BULKIN_SIZE 1024 * 3 > +#endif > + > +#define AX88772_MAX_PKT_SIZE 2048 ///< Maximum packet size > + > +#define ETHERNET_HEADER_SIZE sizeof (ETHERNET_HEADER) ///< Size in by= tes of the Ethernet header > +#define MIN_ETHERNET_PKT_SIZE 60 ///< Minimum packet size including = Ethernet header > +#define MAX_ETHERNET_PKT_SIZE 1500 ///< Ethernet spec 3.1.1: Minimum p= acket size > + > +#define USB_NETWORK_CLASS 0x09 ///< USB Network class code > +#define USB_BUS_TIMEOUT 1000 ///< USB timeout in milliseconds > + > +#define TIMER_MSEC 20 ///< Polling interval for t= he NIC > + > +#define HC_DEBUG 0 > + > +#if RXTHOU > +#define BULKIN_TIMEOUT 3 //10 //100 //1000 > +#else > +#define BULKIN_TIMEOUT 3000 > +#endif > + > +#define AUTONEG_DELAY 2000000 > +#define AUTONEG_POLL_CNT 5 > + > +/** > + Verify new TPL value > + > + This macro which is enabled when debug is enabled verifies that > + the new TPL value is >=3D the current TPL value. > +**/ > +#ifdef VERIFY_TPL > +#undef VERIFY_TPL > +#endif // VERIFY_TPL > + > +#if !defined(MDEPKG_NDEBUG) > + > +#define VERIFY_TPL(tpl) \ > +{ \ > + EFI_TPL PreviousTpl; \ > + \ > + PreviousTpl =3D gBS->RaiseTPL (TPL_HIGH_LEVEL); \ > + gBS->RestoreTPL (PreviousTpl); \ > + if (PreviousTpl > tpl) { \ > + DEBUG ((DEBUG_ERROR, "Current TPL: %d, New TPL: %d\r\n", PreviousTpl= , tpl)); \ > + ASSERT (PreviousTpl <=3D tpl); \ > + } \ > +} > + > +#else // MDEPKG_NDEBUG > + > +#define VERIFY_TPL(tpl) > + > +#endif // MDEPKG_NDEBUG > + > +//----------------------------------------------------------------------= -------- > +// Hardware Definition > +//----------------------------------------------------------------------= -------- > + > +#define FreeQueueSize 10 > + > +#define DEV_SIGNATURE SIGNATURE_32 ('A','X','8','8') ///< Signatur= e of data structures in memory > + > +#define VENDOR_ID 0x0B95 ///< Vendor ID for Asix > +#define VENDOR_AX88772B_LENOVO_ID 0x17EF > + > +#define PRODUCT_ID 0x7720 ///< Product ID for the AX88= 772 USB 10/100 Ethernet controller > +#define PRODUCT_AX88772A_ID 0x772A > +#define PRODUCT_AX88772B_ID 0x772b > +#define PRODUCT_AX88772B_ASUS_ID 0x7e2b > +#define PRODUCT_AX88772B_LENOVO_ID 0x7203 > + > + > +#define RESET_MSEC 1000 ///< Reset duration > +#define PHY_RESET_MSEC 500 ///< PHY reset duration > + > +// > +// RX Control register > +// > + > +#define RXC_PRO 0x0001 ///< Receive all packets > +#define RXC_AMALL 0x0002 ///< Receive all multicast packets > +#define RXC_SEP 0x0004 ///< Save error packets > +#define RXC_AB 0x0008 ///< Receive broadcast packets > +#define RXC_AM 0x0010 ///< Use multicast destination addres= s hash table > +#define RXC_AP 0x0020 ///< Accept physical address from Mul= ticast Filter > +#define RXC_SO 0x0080 ///< Start operation > +#define RXC_MFB 0x0300 ///< Maximum frame burst > +#define RXC_MFB_2048 0 ///< Maximum frame size: 2048 bytes > +#define RXC_MFB_4096 0x0100 ///< Maximum frame size: 4096 bytes > +#define RXC_MFB_8192 0x0200 ///< Maximum frame size: 8192 bytes > +#define RXC_MFB_16384 0x0300 ///< Maximum frame size: 16384 bytes > + > +#define RXC_RH1M 0x0100 ///< Rx header 1 > + > +// > +// Medium Status register > +// > + > +#define MS_FD 0x0002 ///< Full duplex > +#define MS_ONE 0x0004 ///< Must be one > +#define MS_RFC 0x0010 ///< RX flow control enable > +#define MS_TFC 0x0020 ///< TX flow control enable > +#define MS_PF 0x0080 ///< Pause frame enable > +#define MS_RE 0x0100 ///< Receive enable > +#define MS_PS 0x0200 ///< Port speed 1=3D100, 0=3D10 Mbps > +#define MS_SBP 0x0800 ///< Stop back pressure > +#define MS_SM 0x1000 ///< Super MAC support > + > +// > +// Software PHY Select register > +// > + > +#define SPHY_PSEL (1 << 0) ///< Select internal PHY > +#define SPHY_SSMII (1 << 2) > +#define SPHY_SSEN (1 << 4) > +#define SPHY_ASEL 0x02 ///< 1=3DAuto select, 0=3DManual sele= ct > + > +// > +// Software Reset register > +// > + > +#define SRR_RR 0x01 ///< Clear receive frame length error > +#define SRR_RT 0x02 ///< Clear transmit frame length erro= r > +#define SRR_BZTYPE 0x04 ///< External PHY reset pin tri-state= enable > +#define SRR_PRL 0x08 ///< External PHY reset pin level > +#define SRR_BZ 0x10 ///< Force Bulk to return zero length= packet > +#define SRR_IPRL 0x20 ///< Internal PHY reset control > +#define SRR_IPPD 0x40 ///< Internal PHY power down > + > +// > +// PHY ID values > +// > + > +#define PHY_ID_INTERNAL 0x0010 ///< Internal PHY > + > +// > +// USB Commands > +// > + > +#define CMD_PHY_ACCESS_SOFTWARE 0x06 ///< Software in control of PHY > +#define CMD_PHY_REG_READ 0x07 ///< Read PHY register, Value: = PHY, Index: Register, Data: Register value > +#define CMD_PHY_REG_WRITE 0x08 ///< Write PHY register, Value:= PHY, Index: Register, Data: New 16-bit value > +#define CMD_PHY_ACCESS_HARDWARE 0x0a ///< Hardware in control of PHY > +#define CMD_SROM_READ 0x0b ///< Read SROM register: Value:= Address, Data: Value > +#define CMD_SROM_WRITE 0x0c ///< Read SROM register: Value:= Address, Data: Value > +#define CMD_SROM_WRITE_EN 0x0d > +#define CMD_SROM_WRITE_DIS 0x0e > +#define CMD_RX_CONTROL_WRITE 0x10 ///< Set the RX control registe= r, Value: New value > +#define CMD_GAPS_WRITE 0x12 ///< Write the gaps register, V= alue: New value > +#define CMD_MAC_ADDRESS_READ 0x13 ///< Read the MAC address, Data= : 6 byte MAC address > +#define CMD_MAC_ADDRESS_WRITE 0x14 ///< Set the MAC address, Data:= New 6 byte MAC address > +#define CMD_MULTICAST_HASH_READ 0x15 ///< Read the multicast hash ta= ble > +#define CMD_MULTICAST_HASH_WRITE 0x16 ///< Write the multicast hash t= able, Data: New 8 byte value > +#define CMD_MEDIUM_STATUS_READ 0x1a ///< Read medium status registe= r, Data: Register value > +#define CMD_MEDIUM_STATUS_WRITE 0x1b ///< Write medium status regist= er, Value: New value > +#define CMD_WRITE_GPIOS 0x1f > +#define CMD_RESET 0x20 ///< Reset register, Value: New= value > +#define CMD_PHY_SELECT 0x22 ///< PHY select register, Value= : New value > + > +#define CMD_RXQTC 0x2a ///< RX Queue Cascade Threshold= Control Register > + > +//------------------------------ > +// USB Endpoints > +//------------------------------ > + > +#define CONTROL_ENDPOINT 0 ///< Control endpoint > +#define INTERRUPT_ENDPOINT 1 ///< Interrupt endpoint > +#define BULK_IN_ENDPOINT 2 ///< Receive endpoint > +#define BULK_OUT_ENDPOINT 3 ///< Transmit endpoint > + > +//------------------------------ > +// PHY Registers > +//------------------------------ > + > +#define PHY_BMCR 0 ///< Control register > +#define PHY_BMSR 1 ///< Status register > +#define PHY_ANAR 4 ///< Autonegotiation ad= vertisement register > +#define PHY_ANLPAR 5 ///< Autonegotiation li= nk parter ability register > +#define PHY_ANER 6 ///< Autonegotiation ex= pansion register > + > +// BMCR - Register 0 > + > +#define BMCR_RESET 0x8000 ///< 1 =3D Reset the PH= Y, bit clears after reset > +#define BMCR_LOOPBACK 0x4000 ///< 1 =3D Loopback ena= bled > +#define BMCR_100MBPS 0x2000 ///< 100 Mbits/Sec > +#define BMCR_10MBPS 0 ///< 10 Mbits/Sec > +#define BMCR_AUTONEGOTIATION_ENABLE 0x1000 ///< 1 =3D Enable auton= egotiation > +#define BMCR_POWER_DOWN 0x0800 ///< 1 =3D Power down > +#define BMCR_ISOLATE 0x0400 ///< 0 =3D Isolate PHY > +#define BMCR_RESTART_AUTONEGOTIATION 0x0200 ///< 1 =3D Restart auto= negotiation > +#define BMCR_FULL_DUPLEX 0x0100 ///< Full duplex operat= ion > +#define BMCR_HALF_DUPLEX 0 ///< Half duplex operat= ion > +#define BMCR_COLLISION_TEST 0x0080 ///< 1 =3D Collision te= st enabled > + > +// BSMR - Register 1 > + > +#define BMSR_100BASET4 0x8000 ///< 1 =3D 100BASE-T4 m= ode > +#define BMSR_100BASETX_FDX 0x4000 ///< 1 =3D 100BASE-TX f= ull duplex > +#define BMSR_100BASETX_HDX 0x2000 ///< 1 =3D 100BASE-TX h= alf duplex > +#define BMSR_10BASET_FDX 0x1000 ///< 1 =3D 10BASE-T ful= l duplex > +#define BMSR_10BASET_HDX 0x0800 ///< 1 =3D 10BASE-T hal= f duplex > +#define BMSR_MF 0x0040 ///< 1 =3D PHY accepts = frames with preamble suppressed > +#define BMSR_AUTONEG_CMPLT 0x0020 ///< 1 =3D Autonegotiat= ion complete > +#define BMSR_RF 0x0010 ///< 1 =3D Remote fault > +#define BMSR_AUTONEG 0x0008 ///< 1 =3D Able to perf= orm autonegotiation > +#define BMSR_LINKST 0x0004 ///< 1 =3D Link up > +#define BMSR_JABBER_DETECT 0x0002 ///< 1 =3D jabber condi= tion detected > +#define BMSR_EXTENDED_CAPABILITY 0x0001 ///< 1 =3D Extended reg= ister capable > + > +// ANAR and ANLPAR Registers 4, 5 > + > +#define AN_NP 0x8000 ///< 1 =3D Next page av= ailable > +#define AN_ACK 0x4000 ///< 1 =3D Link partner= acknowledged > +#define AN_RF 0x2000 ///< 1 =3D Remote fault= indicated by link partner > +#define AN_FCS 0x0400 ///< 1 =3D Flow control= ability > +#define AN_T4 0x0200 ///< 1 =3D 100BASE-T4 s= upport > +#define AN_TX_FDX 0x0100 ///< 1 =3D 100BASE-TX F= ull duplex > +#define AN_TX_HDX 0x0080 ///< 1 =3D 100BASE-TX s= upport > +#define AN_10_FDX 0x0040 ///< 1 =3D 10BASE-T Ful= l duplex > +#define AN_10_HDX 0x0020 ///< 1 =3D 10BASE-T sup= port > +#define AN_CSMA_CD 0x0001 ///< 1 =3D IEEE 802.3 C= SMA/CD support > + > + > + > +//----------------------------------------------------------------------= -------- > +// Data Types > +//----------------------------------------------------------------------= -------- > + > +/** > + Ethernet header layout > + > + IEEE 802.3-2002 Part 3 specification, section 3.1.1. > +**/ > +#pragma pack(1) > +typedef struct { > + UINT8 DestAddr[PXE_HWADDR_LEN_ETHER]; ///< Destination LAN address > + UINT8 SrcAddr[PXE_HWADDR_LEN_ETHER]; ///< Source LAN address > + UINT16 Type; ///< Protocol or length > +} ETHERNET_HEADER; > +#pragma pack() > + > +/** > + Receive and Transmit packet structure > +**/ > +#pragma pack(1) > +typedef struct _RX_TX_PACKET { > + struct _RX_TX_PACKET * Next; ///< Next receive packet > + UINT16 Length; ///< Packet length > + UINT16 LengthBar; ///< Complement of the length > + UINT8 Data[AX88772_MAX_PKT_SIZE]; ///< Received packet data > +} RX_TX_PACKET; > +#pragma pack() > + > +/** > + AX88772 control structure > + > + The driver uses this structure to manage the Asix AX88772 10/100 > + Ethernet controller. > +**/ > +typedef struct { > + UINTN Signature; ///< Structure identific= ation > + > + // > + // USB data > + // > + EFI_HANDLE Controller; ///< Controller handle > + EFI_USB_IO_PROTOCOL *UsbIo; ///< USB driver interfac= e > + > + // > + // Simple network protocol data > + // > + EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork; ///< Driver's network = stack interface > + EFI_SIMPLE_NETWORK_MODE SimpleNetworkData; ///< Data for simple n= etwork > + > + // > + // Ethernet controller data > + // > + BOOLEAN Initialized; ///< Controller initiali= zed > + UINT16 PhyId; ///< PHY ID > + > + // > + // Link state > + // > + BOOLEAN LinkSpeed100Mbps; ///< Current link speed= , FALSE =3D 10 Mbps > + BOOLEAN Complete; ///< Current state of a= uto-negotiation > + BOOLEAN FullDuplex; ///< Current duplex > + BOOLEAN LinkUp; ///< Current link state > + UINTN PollCount; ///< Number of times th= e autonegotiation status was polled > + UINT16 CurRxControl; > + VOID *TxBuffer; > + // > + // Receive buffer list > + // > + UINT8 *BulkInbuf; > + UINT8 *CurPktHdrOff; > + UINT8 *CurPktOff; > + UINT16 PktCnt; > + > + RX_TX_PACKET *TxTest; > + > + UINT8 MulticastHash[8]; > + EFI_MAC_ADDRESS MAC; > + > + > + EFI_DEVICE_PATH_PROTOCOL *MyDevPath; > + BOOLEAN Grub_f; > + BOOLEAN FirstRst; > + BOOLEAN Flag772A; > +#if RXTHOU > + UINT8 RxBurst; > +#endif > + > +} NIC_DEVICE; > + > + > +// > +// Global Variables > +// > +extern EFI_DRIVER_BINDING_PROTOCOL gDriverBinding; > +extern EFI_COMPONENT_NAME_PROTOCOL gComponentName; > +extern EFI_COMPONENT_NAME2_PROTOCOL gComponentName2; > + > +#define DEV_FROM_SIMPLE_NETWORK(a) CR (a, NIC_DEVICE, SimpleNetwork, DE= V_SIGNATURE) ///< Locate NIC_DEVICE > from Simple Network Protocol > + > +//----------------------------------------------------------------------= -------- > +// Simple Network Protocol > +//----------------------------------------------------------------------= -------- > + > +/** > + 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] SimpleNetwork Protocol instance pointer > + @param [in] ExtendedVerification Indicates that the driver may perfor= m 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 SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Reset ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN BOOLEAN ExtendedVerification > + ); > + > +/** > + Initialize the simple network protocol. > + > + This routine calls ::Ax88772MacAddressGet to obtain the > + MAC address. > + > + @param [in] NicDevice NIC_DEVICE_INSTANCE pointer > + > + @retval EFI_SUCCESS Setup was successful > + > +**/ > +EFI_STATUS > +SN_Setup ( > + IN NIC_DEVICE *NicDevice > + ); > + > +/** > + This routine starts the network interface. > + > + @param [in] SimpleNetwork Protocol instance pointer > + > + @retval EFI_SUCCESS This operation was successful. > + @retval EFI_ALREADY_STARTED The network interface was already starte= d. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Start ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork > + ); > + > +/** > + 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 FALS= E > + then the current station address is changed to the address specified b= y > + New. > + > + This routine calls ::Ax88772MacAddressSet to update the MAC address > + in the network adapter. > + > + @param [in] SimpleNetwork Protocol instance pointer > + @param [in] Reset Flag used to reset the station address to= the > + network interface's permanent address. > + @param [in] New New station address to be used for the ne= twork > + interface. > + > + @retval EFI_SUCCESS This operation was successful. > + @retval EFI_NOT_STARTED The network interface was not started. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_StationAddress ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN BOOLEAN Reset, > + IN EFI_MAC_ADDRESS *New > + ); > + > +/** > + 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] SimpleNetwork Protocol instance pointer > + @param [in] Reset Set to TRUE to reset the statistics for t= he network interface. > + @param [in, out] StatisticsSize On input the size, in bytes, of Stati= sticsTable. On output > + the size, in bytes, of the resulting tab= le of statistics. > + @param [out] StatisticsTable A pointer to the EFI_NETWORK_STATISTICS s= tructure 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 StatisticsTable is NULL or the buffe= r is too small. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Statistics ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN BOOLEAN Reset, > + IN OUT UINTN *StatisticsSize, > + OUT EFI_NETWORK_STATISTICS *StatisticsTable > + ); > + > +/** > + This function stops a network interface. This call is only valid > + if the network interface is in the started state. > + > + @param [in] SimpleNetwork Protocol instance pointer > + > + @retval EFI_SUCCESS This operation was successful. > + @retval EFI_NOT_STARTED The network interface was not started. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Stop ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork > + ); > + > +/** > + This function releases the memory buffers assigned in the Initialize()= call. > + Ending transmits and receives are lost, and interrupts are cleared and= disabled. > + After this call, only Initialize() and Stop() calls may be used. > + > + @param [in] SimpleNetwork Protocol instance pointer > + > + @retval EFI_SUCCESS This operation was successful. > + @retval EFI_NOT_STARTED The network interface was not started. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Shutdown ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork > + ); > + > +/** > + 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] SimpleNetwork 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 mus= t not be NULL. > + @param [in] BufferSize The size, in bytes, of the entire packet= (media header and > + data) to be transmitted through the netw= ork interface. > + @param [in] Buffer A pointer to the packet (media header fol= lowed by data) to > + to be transmitted. This parameter can n= ot be NULL. If > + HeaderSize is zero, then the media heade= r 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] SrcAddr The source HW MAC address. If HeaderSize= is zero, then > + this parameter is ignored. If HeaderSiz= e is nonzero and > + SrcAddr is NULL, then SimpleNetwork->Mod= e->CurrentAddress > + is used for the source HW MAC address. > + @param [in] DestAddr The destination HW MAC address. If Heade= rSize is zero, then > + this parameter is ignored. > + @param [in] Protocol The type of header to build. If HeaderSi= ze 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 acc= ept this transmit request. > + @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Transmit ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN UINTN HeaderSize, > + IN UINTN BufferSize, > + IN VOID *Buffer, > + IN EFI_MAC_ADDRESS *SrcAddr, > + IN EFI_MAC_ADDRESS *DestAddr, > + IN UINT16 *Protocol > + ); > + > +//----------------------------------------------------------------------= -------- > +// Support Routines > +//----------------------------------------------------------------------= -------- > + > +/** > + Get the MAC address > + > + This routine calls ::Ax88772UsbCommand to request the MAC > + address from the network adapter. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [out] MacAddress Address of a six byte buffer to receive t= he MAC address. > + > + @retval EFI_SUCCESS The MAC address is available. > + @retval other The MAC address is not valid. > + > +**/ > +EFI_STATUS > +Ax88772MacAddressGet ( > + IN NIC_DEVICE *NicDevice, > + OUT UINT8 *MacAddress > + ); > + > +/** > + Set the MAC address > + > + This routine calls ::Ax88772UsbCommand to set the MAC address > + in the network adapter. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] MacAddress 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 *NicDevice, > + IN UINT8 *MacAddress > + ); > + > +/** > + Clear the multicast hash table > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + > +**/ > +VOID > +Ax88772MulticastClear ( > + IN NIC_DEVICE *NicDevice > + ); > + > +/** > + Enable a multicast address in the multicast hash table > + > + This routine calls ::Ax88772Crc to compute the hash bit for > + this MAC address. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] MacAddress Address of a six byte buffer to containing= the MAC address. > + > +**/ > +VOID > +Ax88772MulticastSet ( > + IN NIC_DEVICE *NicDevice, > + IN UINT8 *MacAddress > + ); > + > +/** > + Start the link negotiation > + > + This routine calls ::Ax88772PhyWrite to start the PHY's link > + negotiation. > + > + @param [in] NicDevice 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 *NicDevice > + ); > + > +/** > + Complete the negotiation of the PHY link > + > + This routine calls ::Ax88772PhyRead to determine if the > + link negotiation is complete. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in, out] PollCount Address of number of times this routine wa= s polled > + @param [out] Complete Address of boolean to receive complate stat= us. > + @param [out] LinkUp Address of boolean to receive link status, = TRUE=3Dup. > + @param [out] HiSpeed Address of boolean to receive link speed, T= RUE=3D100Mbps. > + @param [out] FullDuplex Address of boolean to receive link duplex, = TRUE=3Dfull. > + > + @retval EFI_SUCCESS The MAC address is available. > + @retval other The MAC address is not valid. > + > +**/ > +EFI_STATUS > +Ax88772NegotiateLinkComplete ( > + IN NIC_DEVICE *NicDevice, > + IN OUT UINTN *PollCount, > + OUT BOOLEAN *Complete, > + OUT BOOLEAN *LinkUp, > + OUT BOOLEAN *HiSpeed, > + OUT BOOLEAN *FullDuplex > + ); > + > +/** > + Read a register from the PHY > + > + This routine calls ::Ax88772UsbCommand to read a PHY register. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] RegisterAddress Number of the register to read. > + @param [in, out] PhyData Address of a buffer to receive the PHY reg= ister value > + > + @retval EFI_SUCCESS The PHY data is available. > + @retval other The PHY data is not valid. > + > +**/ > +EFI_STATUS > +Ax88772PhyRead ( > + IN NIC_DEVICE * NicDevice, > + IN UINT8 RegisterAddress, > + IN OUT UINT16 * PhyData > + ); > + > +/** > + Write to a PHY register > + > + This routine calls ::Ax88772UsbCommand to write a PHY register. > + > + @param [in] NicDevice 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 re= gister value > + > + @retval EFI_SUCCESS The PHY data was written. > + @retval other Failed to wwrite the PHY register. > + > +**/ > +EFI_STATUS > +Ax88772PhyWrite ( > + IN NIC_DEVICE *NicDevice, > + IN UINT8 RegisterAddress, > + IN UINT16 PhyData > + ); > + > +/** > + Reset the AX88772 > + > + This routine uses ::Ax88772UsbCommand to reset the network > + adapter. This routine also uses ::Ax88772PhyWrite to reset > + the PHY. > + > + @param [in] NicDevice 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 *NicDevice > + ); > + > +VOID > +Ax88772ChkLink ( > + IN NIC_DEVICE * NicDevice, > + IN BOOLEAN UpdateLink > + ); > + > +/** > + Receive a frame from the network. > + > + This routine polls the USB receive interface for a packet. If a packe= t > + is available, this routine adds the receive packet to the list of > + Ending receive packets. > + > + This routine calls ::Ax88772NegotiateLinkComplete to verify > + that the link is up. This routine also calls ::SN_Reset to > + reset the network adapter when necessary. Finally this > + routine attempts to receive one or more packets from the > + network adapter. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] UpdateLink TRUE =3D Update link status > + > +**/ > +VOID > +Ax88772Rx ( > + IN NIC_DEVICE *NicDevice, > + IN BOOLEAN UpdateLink > + ); > + > +/** > + 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] NicDevice 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 *NicDevice, > + IN UINT32 RxFilter > + ); > + > +EFI_STATUS > +Ax88772ReloadSrom ( > + IN NIC_DEVICE *NicDevice > + ); > + > +/** > + Read an SROM location > + > + This routine calls ::Ax88772UsbCommand to read data from the > + SROM. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] Address SROM address > + @param [out] Data Buffer to receive the data > + > + @retval EFI_SUCCESS The read was successful > + @retval other The read failed > + > +**/ > +EFI_STATUS > +Ax88772SromRead ( > + IN NIC_DEVICE *NicDevice, > + IN UINT32 Address, > + OUT UINT16 *Data > + ); > + > + > +EFI_STATUS > +Ax88772EnableSromWrite ( > + IN NIC_DEVICE *NicDevice > + ); > + > + > +EFI_STATUS > +Ax88772DisableSromWrite ( > + IN NIC_DEVICE *NicDevice > + ); > + > +EFI_STATUS > +Ax88772SromWrite ( > + IN NIC_DEVICE *NicDevice, > + IN UINT32 Address, > + OUT UINT16 *Data > + ); > + > +/** > + Send a command to the USB device. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] Request Pointer to the request structure > + @param [in, out] Buffer Data buffer address > + > + @retval EFI_SUCCESS The USB transfer was successful > + @retval other The USB transfer failed > + > +**/ > +EFI_STATUS > +Ax88772UsbCommand ( > + IN NIC_DEVICE *NicDevice, > + IN USB_DEVICE_REQUEST *Request, > + IN OUT VOID *Buffer > + ); > + > +BOOLEAN > +Ax88772GetLinkStatus ( > + IN NIC_DEVICE *NicDevice > +) ; > + > +//----------------------------------------------------------------------= -------- > +// EFI Component Name Protocol Support > +//----------------------------------------------------------------------= -------- > + > +extern EFI_COMPONENT_NAME_PROTOCOL gComponentName; ///< Component na= me protocol declaration > +extern EFI_COMPONENT_NAME2_PROTOCOL gComponentName2; ///< Component na= me 2 protocol declaration > + > +/** > + Retrieves a Unicode string that is the user readable name of the drive= r. > + > + 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 na= me 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 spe= cified > + by This does not support the language specified by Language, > + then EFI_UNSUPPORTED is returned. > + > + @param [in] This A pointer to the EFI_COMPONENT_NAME2_PROT= OCOL or > + EFI_COMPONENT_NAME_PROTOCOL instance. > + @param [in] Language A pointer to a Null-terminated ASCII stri= ng > + array indicating the language. This is t= he > + language of the driver name that the cal= ler is > + requesting, and it must match one of the > + languages specified in SupportedLanguage= s. The > + number of languages supported by a drive= r is up > + to the driver writer. Language is specif= ied > + in RFC 3066 or ISO 639-2 language code f= ormat. > + @param [out] DriverName 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 specif= ied by > + This and the language specified by Langu= age 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 su= pport > + the language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetDriverName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN CHAR8 *Language, > + OUT CHAR16 **DriverName > + ); > + > + > +/** > + Retrieves a Unicode string that is the user readable name of the contr= oller > + that is being managed by a driver. > + > + This function retrieves the user readable name of the controller speci= fied by > + ControllerHandle and ChildHandle in the form of a Unicode string. If t= he > + driver specified by This has a user readable name in the language spec= ified by > + Language, then a pointer to the controller name is returned in Control= lerName, > + and EFI_SUCCESS is returned. If the driver specified by This is not c= urrently > + managing the controller specified by ControllerHandle and ChildHandle, > + then EFI_UNSUPPORTED is returned. If the driver specified by This doe= s not > + support the language specified by Language, then EFI_UNSUPPORTED is re= turned. > + > + @param [in] This A pointer to the EFI_COMPONENT_NAME2_PROT= OCOL or > + EFI_COMPONENT_NAME_PROTOCOL instance. > + @param [in] ControllerHandle The handle of a controller that the driv= er > + specified by This is managing. This han= dle > + specifies the controller whose name is t= o be > + returned. > + @param [in] ChildHandle The handle of the child controller to re= trieve > + the name of. This is an optional parame= ter 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 bu= s > + controller. It will not be NULL for a b= us > + driver that wishes to retrieve the name = of a > + child controller. > + @param [in] Language A pointer to a Null-terminated ASCII stri= ng > + array indicating the language. This is = the > + language of the driver name that the cal= ler is > + requesting, and it must match one of the > + languages specified in SupportedLanguage= s. The > + number of languages supported by a drive= r is up > + to the driver writer. Language is specif= ied in > + RFC 3066 or ISO 639-2 language code form= at. > + @param [out] ControllerName 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 d= river > + specified by This. > + > + @retval EFI_SUCCESS The Unicode string for the user readable= name in > + the language specified by Language for t= he > + driver specified by This was returned in > + DriverName. > + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HAND= LE. > + @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 curr= ently > + managing the controller specified by > + ControllerHandle and ChildHandle. > + @retval EFI_UNSUPPORTED The driver specified by This does not su= pport > + the language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetControllerName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN OPTIONAL EFI_HANDLE ChildHandle, > + IN CHAR8 *Language, > + OUT CHAR16 **ControllerName > + ); > + > + > +EFI_STATUS > +Ax88772BulkIn( > + IN NIC_DEVICE *NicDevice > +); > + > +//----------------------------------------------------------------------= -------- > + > +#endif // AX88772_H_ > diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772.c > b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772.c > new file mode 100644 > index 000000000000..32052ba9073a > --- /dev/null > +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772.c > @@ -0,0 +1,1300 @@ > +/** @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 implem= entation > + only supports the integrated PHY since no other test cases were availa= ble. > + > + Copyright (c) 2011, Intel Corporation. All rights reserved. > + Copyright (c) 2020, ARM Limited. All rights reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "Ax88772.h" > + > + > +/** > + Compute the CRC > + > + @param [in] MacAddress 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 *MacAddress > + ) > +{ > + UINT32 BitNumber; > + INT32 Carry; > + INT32 Crc; > + UINT32 Data; > + UINT8 *End; > + > + // > + // Walk the MAC address > + // > + Crc =3D -1; > + End =3D &MacAddress[PXE_HWADDR_LEN_ETHER]; > + while (End > MacAddress) { > + Data =3D *MacAddress++; > + > + > + // > + // 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 =3D 0; 8 > BitNumber; BitNumber++) { > + Carry =3D ((Crc >> 31) & 1) ^ (Data & 1); > + Crc <<=3D 1; > + if (Carry !=3D 0) { > + Crc ^=3D 0x04c11db7; > + } > + Data >>=3D 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] NicDevice Pointer to the NIC_DEVICE structure > + @param [out] MacAddress Address of a six byte buffer to receive t= he MAC address. > + > + @retval EFI_SUCCESS The MAC address is available. > + @retval other The MAC address is not valid. > + > +**/ > +EFI_STATUS > +Ax88772MacAddressGet ( > + IN NIC_DEVICE *NicDevice, > + OUT UINT8 *MacAddress > + ) > +{ > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status; > + > + // > + // Set the register address. > + // > + SetupMsg.RequestType =3D USB_ENDPOINT_DIR_IN > + | USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_MAC_ADDRESS_READ; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D PXE_HWADDR_LEN_ETHER; > + > + // > + // Read the PHY register > + // > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + MacAddress); > + > + // > + // Return the operation status > + // > + return Status; > +} > + > + > +/** > + Set the MAC address > + > + This routine calls ::Ax88772UsbCommand to set the MAC address > + in the network adapter. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] MacAddress 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 *NicDevice, > + IN UINT8 *MacAddress > + ) > +{ > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status; > + > + // > + // Set the register address. > + // > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_MAC_ADDRESS_WRITE; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D PXE_HWADDR_LEN_ETHER; > + > + // > + // Read the PHY register > + // > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + MacAddress); > + > + // > + // Return the operation status > + // > + return Status; > +} > + > +/** > + Clear the multicast hash table > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + > +**/ > +VOID > +Ax88772MulticastClear ( > + IN NIC_DEVICE *NicDevice > + ) > +{ > + int Index =3D 0; > + // > + // Clear the multicast hash table > + // > + for (Index =3D 0 ; Index < 8 ; Index ++) > + NicDevice->MulticastHash[Index] =3D 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] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] MacAddress Address of a six byte buffer to containing= the MAC address. > + > +**/ > +VOID > +Ax88772MulticastSet ( > + IN NIC_DEVICE *NicDevice, > + IN UINT8 *MacAddress > + ) > +{ > + UINT32 Crc; > + > + // > + // Compute the CRC on the destination address > + // > + Crc =3D Ax88772Crc (MacAddress) >> 26; > + > + // > + // Set the bit corresponding to the destination address > + // > + NicDevice->MulticastHash [Crc >> 3] |=3D (1 << (Crc & 7)); > + > +} > + > +/** > + Start the link negotiation > + > + This routine calls ::Ax88772PhyWrite to start the PHY's link > + negotiation. > + > + @param [in] NicDevice 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 *NicDevice > + ) > +{ > + UINT16 Control; > + EFI_STATUS Status; > + > + // > + // Set the supported capabilities. > + // > + Status =3D Ax88772PhyWrite (NicDevice, > + PHY_ANAR, > + AN_CSMA_CD > + | AN_TX_FDX | AN_TX_HDX > + | AN_10_FDX | AN_10_HDX | AN_FCS); > + if (!EFI_ERROR (Status)) { > + // > + // Set the link speed and duplex > + // > + Control =3D BMCR_AUTONEGOTIATION_ENABLE > + | BMCR_RESTART_AUTONEGOTIATION; > + if (NicDevice->LinkSpeed100Mbps) { > + Control |=3D BMCR_100MBPS; > + } > + if (NicDevice->FullDuplex) { > + Control |=3D BMCR_FULL_DUPLEX; > + } > + Status =3D Ax88772PhyWrite (NicDevice, PHY_BMCR, Control); > + > + if (!EFI_ERROR(Status)) > + gBS->Stall(3000000); > + } > + return Status; > +} > + > + > + > +/** > + Complete the negotiation of the PHY link > + > + This routine calls ::Ax88772PhyRead to determine if the > + link negotiation is complete. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in, out] PollCount Address of number of times this routine wa= s polled > + @param [out] Complete Address of boolean to receive complate sta= tus. > + @param [out] LinkUp Address of boolean to receive link status,= TRUE=3Dup. > + @param [out] HiSpeed Address of boolean to receive link speed, = TRUE=3D100Mbps. > + @param [out] FullDuplex Address of boolean to receive link duplex,= TRUE=3Dfull. > + > + @retval EFI_SUCCESS The MAC address is available. > + @retval other The MAC address is not valid. > + > +**/ > +EFI_STATUS > +Ax88772NegotiateLinkComplete ( > + IN NIC_DEVICE *NicDevice, > + IN OUT UINTN *PollCount, > + OUT BOOLEAN *Complete, > + OUT BOOLEAN *LinkUp, > + OUT BOOLEAN *HiSpeed, > + OUT BOOLEAN *FullDuplex > + ) > +{ > + UINT16 Mask; > + UINT16 PhyData; > + EFI_STATUS Status; > + > + // > + // Determine if the link is up. > + // > + *Complete =3D FALSE; > + > + // > + // Get the link status > + // > + Status =3D Ax88772PhyRead (NicDevice, > + PHY_BMSR, > + &PhyData); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + *LinkUp =3D ((PhyData & BMSR_LINKST) !=3D 0); > + if (0 =3D=3D *LinkUp) { > + } else { > + *Complete =3D ((PhyData & 0x20) !=3D 0); > + if (0 =3D=3D *Complete) { > + } else { > + Status =3D Ax88772PhyRead (NicDevice, > + PHY_ANLPAR, > + &PhyData); > + > + if (!EFI_ERROR (Status)) { > + // > + // Autonegotiation is complete > + // Determine the link speed. > + // > + *HiSpeed =3D ((PhyData & (AN_TX_FDX | AN_TX_HDX))!=3D 0); > + // > + // Determine the link duplex. > + // > + Mask =3D (*HiSpeed) ? AN_TX_FDX : AN_10_FDX; > + *FullDuplex =3D (BOOLEAN)((PhyData & Mask) !=3D 0); > + } > + } > + } > + > + return Status; > +} > + > + > +/** > + Read a register from the PHY > + > + This routine calls ::Ax88772UsbCommand to read a PHY register. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] RegisterAddress Number of the register to read. > + @param [in, out] PhyData Address of a buffer to receive the PHY reg= ister value > + > + @retval EFI_SUCCESS The PHY data is available. > + @retval other The PHY data is not valid. > + > +**/ > +EFI_STATUS > +Ax88772PhyRead ( > + IN NIC_DEVICE *NicDevice, > + IN UINT8 RegisterAddress, > + IN OUT UINT16 *PhyData > + ) > +{ > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status; > + > + // > + // Request access to the PHY > + // > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_PHY_ACCESS_SOFTWARE; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Read the PHY register address. > + // > + SetupMsg.RequestType =3D USB_ENDPOINT_DIR_IN > + | USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_PHY_REG_READ; > + SetupMsg.Value =3D NicDevice->PhyId; > + SetupMsg.Index =3D RegisterAddress; > + SetupMsg.Length =3D sizeof(*PhyData); > + Status =3D Ax88772UsbCommand(NicDevice, > + &SetupMsg, > + PhyData); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Release the PHY to the hardware > + // > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_PHY_ACCESS_HARDWARE; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand(NicDevice, > + &SetupMsg, > + NULL); > + > + // > + // Return the operation status. > + // > + return Status; > +} > + > + > +/** > + Write to a PHY register > + > + This routine calls ::Ax88772UsbCommand to write a PHY register. > + > + @param [in] NicDevice 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 re= gister value > + > + @retval EFI_SUCCESS The PHY data was written. > + @retval other Failed to wwrite the PHY register. > + > +**/ > +EFI_STATUS > +Ax88772PhyWrite ( > + IN NIC_DEVICE *NicDevice, > + IN UINT8 RegisterAddress, > + IN UINT16 PhyData > + ) > +{ > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status; > + > + // > + // Request access to the PHY > + // > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_PHY_ACCESS_SOFTWARE; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Write the PHY register > + // > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_PHY_REG_WRITE; > + SetupMsg.Value =3D NicDevice->PhyId; > + SetupMsg.Index =3D RegisterAddress; > + SetupMsg.Length =3D sizeof (PhyData); > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + &PhyData); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Release the PHY to the hardware > + // > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_PHY_ACCESS_HARDWARE; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + // > + // Return the operation status. > + // > + 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] NicDevice 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 *NicDevice > + ) > +{ > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_PHY_ACCESS_HARDWARE; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_ERROR(Status)) goto err; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_PHY_SELECT; > + SetupMsg.Value =3D SPHY_PSEL; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_ERROR(Status)) goto err; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_RESET; > + SetupMsg.Value =3D SRR_IPRL ; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_ERROR(Status)) goto err; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_RESET; > + SetupMsg.Value =3D SRR_IPPD | SRR_IPRL ; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + gBS->Stall (200000); > + > + if (EFI_ERROR(Status)) goto err; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_RESET; > + SetupMsg.Value =3D SRR_IPRL ; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + gBS->Stall (200000); > + > + if (EFI_ERROR(Status)) goto err; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_RESET; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_ERROR(Status)) goto err; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_PHY_SELECT; > + SetupMsg.Value =3D SPHY_PSEL; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_ERROR(Status)) goto err; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_RESET; > + SetupMsg.Value =3D SRR_IPRL | SRR_BZ | SRR_BZTYPE; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_ERROR(Status)) goto err; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_RX_CONTROL_WRITE; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_ERROR(Status)) goto err; > + > + if (!NicDevice->Flag772A) { > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_RXQTC; > +#if RXTHOU > + /*size cannot exceed 3K*/ > + //SetupMsg.Value =3D 0x0; > + //SetupMsg.Index =3D 0x8001; > + /*size cannot exceed 16K*/ > + SetupMsg.Value =3D 0x8300; > + SetupMsg.Index =3D 0x8500; > + /*size cannot exceed 32K*/ > + //SetupMsg.Value =3D 0x8784; > + //SetupMsg.Index =3D 0x8A00; > + SetupMsg.Length =3D 0; > +#else > + SetupMsg.Value =3D 0x8000; > + SetupMsg.Index =3D 0x8001; > +#endif > + Status =3D Ax88772UsbCommand (NicDevice, > + &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] NicDevice 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 *NicDevice, > + IN UINT32 RxFilter > + ) > +{ > + UINT16 MediumStatus; > + UINT16 RxControl; > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status =3D EFI_SUCCESS; > + > + // > + // Enable the receiver if something is to be received > + // > + if (RxFilter !=3D 0) { > + // > + // Enable the receiver > + // > + SetupMsg.RequestType =3D USB_ENDPOINT_DIR_IN > + | USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_MEDIUM_STATUS_READ; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D sizeof (MediumStatus); > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + &MediumStatus); > + if (!EFI_ERROR (Status)) { > + if (0 =3D=3D (MediumStatus & MS_RE)) { > + MediumStatus |=3D MS_RE | MS_ONE; > + > + if (NicDevice->FullDuplex) > + MediumStatus |=3D MS_TFC | MS_RFC | MS_FD; > + else > + MediumStatus &=3D ~(MS_TFC | MS_RFC | MS_FD); > + > + if (NicDevice->LinkSpeed100Mbps) > + MediumStatus |=3D MS_PS; > + else > + MediumStatus &=3D ~MS_PS; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_MEDIUM_STATUS_WRITE; > + SetupMsg.Value =3D MediumStatus; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_ERROR(Status)) > + goto EXIT; > + } > + } else { > + goto EXIT; > + } > + } > + RxControl =3D RXC_SO; > + if (!NicDevice->Flag772A) > + RxControl |=3D RXC_RH1M; > + > + // > + // Enable multicast if requested > + // > + if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) !=3D 0) { > + RxControl |=3D RXC_AM; > + // > + // Update the multicast hash table > + // > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_MULTICAST_HASH_WRITE; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D sizeof (NicDevice ->MulticastHash); > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + &NicDevice->MulticastHash); > + > + if (EFI_ERROR(Status)) > + goto EXIT; > + } > + > + // > + // Enable all multicast if requested > + // > + if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) !=3D= 0) { > + RxControl |=3D RXC_AMALL; > + } > + > + // > + // Enable broadcast if requested > + // > + if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) !=3D 0) { > + RxControl |=3D RXC_AB; > + } > + > + // > + // Enable promiscuous mode if requested > + // > + if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) !=3D 0) { > + RxControl |=3D RXC_PRO; > + } > + > + // > + // Update the receiver control > + // > + if (NicDevice->CurRxControl !=3D RxControl) { > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_RX_CONTROL_WRITE; > +#if RXTHOU > + if (NicDevice->Flag772A) > + RxControl |=3D 0x0300; > +#endif > + if (NicDevice->Flag772A) > + RxControl &=3D ~(RXC_MFB); > + SetupMsg.Value =3D RxControl; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + if (!EFI_ERROR (Status)) > + NicDevice->CurRxControl =3D RxControl; > + } > + > + // > + // Return the operation status > + // > +EXIT: > + return Status; > +} > + > + > + > +EFI_STATUS > +Ax88772ReloadSrom ( > + IN NIC_DEVICE *NicDevice > + ) > +{ > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status; > + > + // > + // Read a value from the SROM > + // > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + > + SetupMsg.Request =3D CMD_WRITE_GPIOS; > + SetupMsg.Value =3D 0x80; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0 ; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_SUCCESS =3D=3D Status) > + gBS->Stall(500000); > + > + return Status; > + > +} > + > + > +/** > + Read an SROM location > + > + This routine calls ::Ax88772UsbCommand to read data from the > + SROM. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] Address SROM address > + @param [out] Data Buffer to receive the data > + > + @retval EFI_SUCCESS The read was successful > + @retval other The read failed > + > +**/ > +EFI_STATUS > +Ax88772SromRead ( > + IN NIC_DEVICE *NicDevice, > + IN UINT32 Address, > + OUT UINT16 *Data > + ) > +{ > + > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status; > + > + // > + // Read a value from the SROM > + // > + SetupMsg.RequestType =3D USB_ENDPOINT_DIR_IN > + | USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_SROM_READ; > + SetupMsg.Value =3D (UINT16) Address; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D sizeof (*Data); > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + Data); > + > + // > + // Return the operation status > + // > + return Status; > +} > + > +EFI_STATUS > +Ax88772EnableSromWrite ( > + IN NIC_DEVICE * NicDevice > + ) > +{ > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status; > + > + // > + // Read a value from the SROM > + // > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + > + SetupMsg.Request =3D CMD_SROM_WRITE_EN; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0 ; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_SUCCESS =3D=3D Status) > + gBS->Stall(500000); > + > + return Status; > + > +} > + > + > +EFI_STATUS > +Ax88772DisableSromWrite ( > + IN NIC_DEVICE *NicDevice > + ) > +{ > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status; > + > + // > + // Read a value from the SROM > + // > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + > + SetupMsg.Request =3D CMD_SROM_WRITE_DIS; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + if (EFI_SUCCESS =3D=3D Status) > + gBS->Stall(500000); > + > + return Status; > + > +} > + > +/** > + Write an SROM location > + > + This routine calls ::Ax88772UsbCommand to write data from the > + SROM. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] Address SROM address > + @param [out] Data Buffer of data to write > + > + @retval EFI_SUCCESS The write was successful > + @retval other The write failed > + > +**/ > +EFI_STATUS > +Ax88772SromWrite ( > + IN NIC_DEVICE *NicDevice, > + IN UINT32 Address, > + IN UINT16 *Data > + ) > +{ > + > + USB_DEVICE_REQUEST SetupMsg; > + EFI_STATUS Status; > + > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + > + SetupMsg.Request =3D CMD_SROM_WRITE; > + SetupMsg.Value =3D (UINT16) Address; > + SetupMsg.Index =3D (UINT16) (*Data); > + SetupMsg.Length =3D 0; > + > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + > + // > + // Return the operation status > + // > + return Status; > +} > + > +/** > + Send a command to the USB device. > + > + @param [in] NicDevice Pointer to the NIC_DEVICE structure > + @param [in] Request Pointer to the request structure > + @param [in, out] Buffer Data buffer address > + > + @retval EFI_SUCCESS The USB transfer was successful > + @retval other The USB transfer failed > + > +**/ > +EFI_STATUS > +Ax88772UsbCommand ( > + IN NIC_DEVICE *NicDevice, > + IN USB_DEVICE_REQUEST *Request, > + IN OUT VOID *Buffer > + ) > +{ > + UINT32 CmdStatus; > + EFI_USB_DATA_DIRECTION Direction; > + EFI_USB_IO_PROTOCOL *UsbIo; > + EFI_STATUS Status; > + > + // > + // Determine the transfer direction > + // > + Direction =3D EfiUsbNoData; > + if (Request->Length !=3D 0) { > + Direction =3D ((Request->RequestType & USB_ENDPOINT_DIR_IN) !=3D 0) > + ? EfiUsbDataIn : EfiUsbDataOut; > + } > + > + // > + // Issue the command > + // > + UsbIo =3D NicDevice->UsbIo; > + Status =3D UsbIo->UsbControlTransfer (UsbIo, > + Request, > + Direction, > + USB_BUS_TIMEOUT, > + Buffer, > + Request->Length, > + &CmdStatus); > + > + // > + // Determine the operation status > + // > + if (!EFI_ERROR (Status)) { > + Status =3D CmdStatus; > + } else { > + // > + // Only use status values associated with the Simple Network protoco= l > + // > + if (EFI_TIMEOUT =3D=3D Status) { > + Status =3D EFI_DEVICE_ERROR; > + } > + } > + > + // > + // Return the operation status > + // > + return Status; > +} > + > +BOOLEAN > +Ax88772GetLinkStatus ( > + IN NIC_DEVICE *NicDevice > +) > +{ > + UINT32 CmdStatus; > + EFI_USB_IO_PROTOCOL *UsbIo; > + UINT64 IntData =3D 0; > + UINTN IntDataLeng =3D 8; > + EFI_STATUS Status; > + > + // > + // Issue the command > + // > + UsbIo =3D NicDevice->UsbIo; > + Status =3D UsbIo->UsbSyncInterruptTransfer(UsbIo, > + USB_ENDPOINT_DIR_IN | INTERRUPT_= ENDPOINT, > + &IntData, > + &IntDataLeng, > + USB_BUS_TIMEOUT, > + &CmdStatus); > + > + if (EFI_ERROR(Status) || EFI_ERROR(CmdStatus) || 0 =3D=3D IntDataLeng)= { > + return FALSE; > + } > + return (IntData & 0x800000)? FALSE : TRUE; > + > +} > + > +#if RXTHOU > +EFI_STATUS > +Ax88772BulkIn( > + IN NIC_DEVICE * NicDevice > +) > +{ > + UINTN Index; > + UINTN LengthInBytes =3D 0; > + UINTN TmpLen =3D AX88772_MAX_BULKIN_SIZE; > + UINTN OrigTmpLen =3D 0; > + UINT16 TmpLen2; > + UINT16 TmpLenBar; > + UINT16 TmpTotalLen =3D 0; > + UINTN TotalLen =3D LengthInBytes; > + EFI_STATUS Status =3D EFI_DEVICE_ERROR; > + EFI_USB_IO_PROTOCOL *UsbIo; > + UINT32 TransferStatus =3D 0; > + UINT16 TmpPktCnt =3D 0; > + UINT16 *TmpHdr =3D (UINT16 *)NicDevice->BulkInbuf; > + USB_DEVICE_REQUEST SetupMsg; > + > + UsbIo =3D NicDevice->UsbIo; > + for (Index =3D 0 ; Index < (AX88772_MAX_BULKIN_SIZE / 512) && UsbIo != =3D NULL; Index++) { > + VOID* TmpAddr =3D 0; > + > + TmpPktCnt =3D 0; > + TmpAddr =3D (VOID*) &NicDevice->BulkInbuf[LengthInBytes]; > + OrigTmpLen =3D TmpLen; > + Status =3D UsbIo->UsbBulkTransfer (UsbIo, > + USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT, > + TmpAddr, > + &TmpLen, > + BULKIN_TIMEOUT, > + &TransferStatus); > + > + if (OrigTmpLen =3D=3D TmpLen) { > + Status =3D EFI_NOT_READY; > + goto no_pkt; > + } > + > + if ((!EFI_ERROR (Status)) && > + (!EFI_ERROR (TransferStatus)) && > + TmpLen !=3D 0) { > + LengthInBytes +=3D TmpLen; > + if ((TmpLen % 512) !=3D 0) { > + goto done; > + } > + } else if ((!EFI_ERROR (Status)) && > + (!EFI_ERROR (TransferStatus)) && > + (TmpLen =3D=3D 0)) { > + Status =3D EFI_NOT_READY; > + goto done; > + } else if (EFI_TIMEOUT =3D=3D Status && EFI_USB_ERR_TIMEOUT =3D=3D T= ransferStatus) { > + SetupMsg.RequestType =3D USB_REQ_TYPE_STANDARD | 0x02; > + SetupMsg.Request =3D 0x01; > + SetupMsg.Value =3D 0; > + SetupMsg.Index =3D 0x82; > + SetupMsg.Length =3D 0; > + Status =3D Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + Status =3D EFI_NOT_READY; > + goto done; > + } else { > + Status =3D EFI_DEVICE_ERROR; > + goto done; > + } > + } > +done: > + if (LengthInBytes !=3D 0) { > + > + do { > + TmpLen2 =3D (*TmpHdr) & 0x7FF; > + TmpLenBar =3D *(TmpHdr + 1); > + TmpTotalLen =3D ((TmpLen + 4 + 1) & 0xfffe); > + > + if ((TmpLen2 & 0x7FF) + (TmpLenBar & 0x7FF) =3D=3D 0x7FF) { > + TmpPktCnt++; > + } else { > + if (TmpPktCnt !=3D 0) { > + break; > + } > + Status =3D EFI_NOT_READY; > + goto no_pkt; > + } > + TmpHdr +=3D (TmpTotalLen / 2); > + TotalLen -=3D TmpTotalLen; > + } while (TotalLen > 0); > + > + if (LengthInBytes >=3D 1000 && TmpPktCnt !=3D 0) { > + if ((NicDevice->RxBurst) =3D=3D 1) { > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_RESET; > + SetupMsg.Value =3D SRR_IPRL; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + } > + > + if (NicDevice->RxBurst < 2) > + NicDevice->RxBurst++; > + > + } else { > + if (NicDevice->RxBurst >=3D 2) { > + SetupMsg.RequestType =3D USB_REQ_TYPE_VENDOR > + | USB_TARGET_DEVICE; > + SetupMsg.Request =3D CMD_RESET; > + SetupMsg.Value =3D SRR_IPRL| SRR_BZ | SRR_BZTYPE; > + SetupMsg.Index =3D 0; > + SetupMsg.Length =3D 0; > + Ax88772UsbCommand (NicDevice, > + &SetupMsg, > + NULL); > + } > + NicDevice->RxBurst =3D 0; > + } > + } > + > + if (TmpPktCnt !=3D 0) { > + NicDevice->PktCnt =3D TmpPktCnt; > + NicDevice->CurPktHdrOff =3D NicDevice->BulkInbuf; > + NicDevice->CurPktOff =3D NicDevice->BulkInbuf + 4; > + Status =3D EFI_SUCCESS; > + } > + > +no_pkt: > + return Status; > +} > +#else > +EFI_STATUS > +Ax88772BulkIn( > + IN NIC_DEVICE *NicDevice > +) > +{ > + UINTN Index; > + UINTN LengthInBytes =3D 0; > + UINTN TmpLen =3D AX88772_MAX_BULKIN_SIZE; > + UINTN OrigTmpLen =3D 0; > + UINT16 TmpLen2; > + UINT16 TmpLenBar; > + UINT16 TmpTotalLen =3D 0; > + UINTN CURBufSize =3D AX88772_MAX_BULKIN_SIZE; > + EFI_STATUS Status =3D EFI_DEVICE_ERROR; > + EFI_USB_IO_PROTOCOL *UsbIo; > + UINT32 TransferStatus =3D 0; > + UINT16 TmpPktCnt =3D 0; > + UINT16 *TmpHdr =3D (UINT16 *)NicDevice->BulkInbuf; > + > + UsbIo =3D NicDevice->UsbIo; > + for (Index =3D 0 ; Index < (AX88772_MAX_BULKIN_SIZE / 512) && UsbIo != =3D NULL; Index++) { > + VOID *TmpAddr =3D 0; > + > + TmpPktCnt =3D 0; > + TmpAddr =3D (VOID*) &NicDevice->BulkInbuf[LengthInBytes]; > + OrigTmpLen =3D TmpLen; > + Status =3D UsbIo->UsbBulkTransfer (UsbIo, > + USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT, > + TmpAddr, > + &TmpLen, > + BULKIN_TIMEOUT, > + &TransferStatus); > + > + if (OrigTmpLen =3D=3D TmpLen) { > + Status =3D EFI_NOT_READY; > + goto no_pkt; > + } > + > + if ((!EFI_ERROR (Status)) && > + (!EFI_ERROR (TransferStatus)) && > + TmpLen !=3D 0) { > + > + LengthInBytes +=3D TmpLen; > + CURBufSize =3D CURBufSize - TmpLen; > + TmpLen =3D CURBufSize; > + do { > + TmpLen2 =3D *TmpHdr; > + TmpLenBar =3D *(TmpHdr + 1); > + TmpTotalLen +=3D ((TmpLen2 + 4 + 1) & 0xfffe); > + > + if (((TmpLen2 ^ TmpLenBar) =3D=3D 0xffff)) { > + if (TmpTotalLen =3D=3D LengthInBytes) { > + TmpPktCnt++; > + Status =3D EFI_SUCCESS; > + goto done; > + } else if (TmpTotalLen > LengthInBytes) { > + break; > + } > + } else if (((TmpLen2 ^ TmpLenBar) !=3D 0xffff)) { > + if (TmpPktCnt !=3D 0) { > + Status =3D EFI_SUCCESS; > + goto done; > + } > + Status =3D EFI_NOT_READY; > + goto no_pkt; > + } > + TmpHdr +=3D (TmpTotalLen / 2); > + TmpPktCnt++; > + } while (TmpTotalLen < LengthInBytes); > + } else if ((!EFI_ERROR (Status)) && > + (!EFI_ERROR (TransferStatus)) && > + (TmpLen =3D=3D 0)) { > + if (TmpPktCnt !=3D 0) { > + Status =3D EFI_SUCCESS; > + goto done; > + } > + Status =3D EFI_NOT_READY; > + goto no_pkt; > + } else if (EFI_TIMEOUT =3D=3D Status && EFI_USB_ERR_TIMEOUT =3D=3D T= ransferStatus) { > + if (TmpPktCnt !=3D 0) { > + Status =3D EFI_SUCCESS; > + goto done; > + } > + Status =3D EFI_NOT_READY; > + goto no_pkt; > + } else { > + if (TmpPktCnt !=3D 0) { > + Status =3D EFI_SUCCESS; > + goto done; > + } > + Status =3D EFI_DEVICE_ERROR; > + goto no_pkt; > + } > + } > +done: > + NicDevice->PktCnt =3D TmpPktCnt; > + NicDevice->CurPktHdrOff =3D NicDevice->BulkInbuf; > + NicDevice->CurPktOff =3D NicDevice->BulkInbuf + 4; > +no_pkt: > + return Status; > +} > +#endif > diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/ComponentName.c > b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/ComponentName.c > new file mode 100644 > index 000000000000..a8b450f77e8d > --- /dev/null > +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/ComponentName.c > @@ -0,0 +1,222 @@ > +/** @file > + UEFI Component Name(2) protocol implementation. > + > + Copyright (c) 2011, Intel Corporation. All rights reserved. > + Copyright (c) 2020, ARM Limited. All rights reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "Ax88772.h" > + > +/** > + EFI Component Name Protocol declaration > +**/ > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gComponentNam= e =3D { > + GetDriverName, > + GetControllerName, > + "eng" > +}; > + > +/** > + EFI Component Name 2 Protocol declaration > +**/ > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentNam= e2 =3D { > + (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[] =3D { > + {"eng;en", L"ASIX AX88772B Ethernet Driver 2.8.0"}, > + {NULL, NULL} > +}; > + > +/** > + Controller name table declaration > +**/ > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE > +mControllerNameTable[] =3D { > + {"eng;en", L"ASIX AX88772B USB Fast Ethernet Controller"}, > + {NULL, NULL} > +}; > + > +/** > + Retrieves a Unicode string that is the user readable name of the drive= r. > + > + 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 na= me 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 spe= cified > + by This does not support the language specified by Language, > + then EFI_UNSUPPORTED is returned. > + > + @param [in] This A pointer to the EFI_COMPONENT_NAME2_PROT= OCOL or > + EFI_COMPONENT_NAME_PROTOCOL instance. > + @param [in] Language A pointer to a Null-terminated ASCII stri= ng > + array indicating the language. This is t= he > + language of the driver name that the cal= ler is > + requesting, and it must match one of the > + languages specified in SupportedLanguage= s. The > + number of languages supported by a drive= r is up > + to the driver writer. Language is specif= ied > + in RFC 3066 or ISO 639-2 language code f= ormat. > + @param [out] DriverName 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 specif= ied by > + This and the language specified by Langu= age 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 su= pport > + the language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetDriverName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN CHAR8 *Language, > + OUT CHAR16 **DriverName > + ) > +{ > + EFI_STATUS Status; > + > + > + Status =3D LookupUnicodeString2 ( > + Language, > + This->SupportedLanguages, > + mDriverNameTable, > + DriverName, > + (BOOLEAN)(This =3D=3D &gComponentName) > + ); > + > + return Status; > +} > + > +/** > + Retrieves a Unicode string that is the user readable name of the contr= oller > + that is being managed by a driver. > + > + This function retrieves the user readable name of the controller speci= fied by > + ControllerHandle and ChildHandle in the form of a Unicode string. If t= he > + driver specified by This has a user readable name in the language spec= ified by > + Language, then a pointer to the controller name is returned in Control= lerName, > + and EFI_SUCCESS is returned. If the driver specified by This is not c= urrently > + managing the controller specified by ControllerHandle and ChildHandle, > + then EFI_UNSUPPORTED is returned. If the driver specified by This doe= s not > + support the language specified by Language, then EFI_UNSUPPORTED is re= turned. > + > + @param [in] This A pointer to the EFI_COMPONENT_NAME2_PROT= OCOL or > + EFI_COMPONENT_NAME_PROTOCOL instance. > + @param [in] ControllerHandle The handle of a controller that the driv= er > + specified by This is managing. This han= dle > + specifies the controller whose name is t= o be > + returned. > + @param [in] ChildHandle The handle of the child controller to re= trieve > + the name of. This is an optional parame= ter 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 bu= s > + controller. It will not be NULL for a b= us > + driver that wishes to retrieve the name = of a > + child controller. > + @param [in] Language A pointer to a Null-terminated ASCII stri= ng > + array indicating the language. This is = the > + language of the driver name that the cal= ler is > + requesting, and it must match one of the > + languages specified in SupportedLanguage= s. The > + number of languages supported by a drive= r is up > + to the driver writer. Language is specif= ied in > + RFC 3066 or ISO 639-2 language code form= at. > + @param [out] ControllerName 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 d= river > + specified by This. > + > + @retval EFI_SUCCESS The Unicode string for the user readable= name in > + the language specified by Language for t= he > + driver specified by This was returned in > + DriverName. > + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HAND= LE. > + @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 curr= ently > + managing the controller specified by > + ControllerHandle and ChildHandle. > + @retval EFI_UNSUPPORTED The driver specified by This does not su= pport > + the language specified by Language. > + > +**/ > + > + > + > +EFI_STATUS > +EFIAPI > +GetControllerName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN OPTIONAL EFI_HANDLE ChildHandle, > + IN CHAR8 *Language, > + OUT CHAR16 **ControllerName > + ) > +{ > + > + EFI_STATUS Status; > + EFI_USB_IO_PROTOCOL *UsbIoProtocol; > + > + // > + // This is a device driver, so ChildHandle must be NULL. > + // > + if (ChildHandle !=3D NULL) { > + return EFI_UNSUPPORTED; > + } > + > + // > + // Check Controller's handle > + // > + Status =3D gBS->OpenProtocol ( > + ControllerHandle, > + &gEfiUsbIoProtocolGuid, > + (VOID **) &UsbIoProtocol, > + gDriverBinding.DriverBindingHandle, > + ControllerHandle, > + EFI_OPEN_PROTOCOL_BY_DRIVER > + ); > + if (!EFI_ERROR (Status)) { > + gBS->CloseProtocol ( > + ControllerHandle, > + &gEfiUsbIoProtocolGuid, > + gDriverBinding.DriverBindingHandle, > + ControllerHandle > + ); > + return EFI_UNSUPPORTED; > + } > + > + if (Status !=3D EFI_ALREADY_STARTED) { > + return EFI_UNSUPPORTED; > + } > + > + Status =3D LookupUnicodeString2 ( > + Language, > + This->SupportedLanguages, > + mControllerNameTable, > + ControllerName, > + (BOOLEAN)(This =3D=3D &gComponentName) > + ); > + > + return Status; > +} > diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/DriverBinding.c > b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/DriverBinding.c > new file mode 100644 > index 000000000000..08b1f287d7b9 > --- /dev/null > +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/DriverBinding.c > @@ -0,0 +1,652 @@ > +/** @file > + Implement the driver binding protocol for Asix AX88772 Ethernet driver= . > + > + Copyright (c) 2011-2013, Intel Corporation. All rights reserved. > + Copyright (c) 2020, ARM Limited. All rights reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "Ax88772.h" > + > +/** > + Verify the controller type > + > + @param [in] This 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 *This, > + IN EFI_HANDLE Controller, > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath > + ) > +{ > + EFI_USB_DEVICE_DESCRIPTOR Device; > + EFI_USB_IO_PROTOCOL *UsbIo; > + EFI_STATUS Status; > + > + // > + // Connect to the USB stack > + // > + Status =3D gBS->OpenProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + (VOID **) &UsbIo, > + This->DriverBindingHandle, > + Controller, > + EFI_OPEN_PROTOCOL_BY_DRIVER > + ); > + if (!EFI_ERROR (Status)) { > + > + // > + // Get the interface descriptor to check the USB class and find a t= ransport > + // protocol handler. > + // > + Status =3D UsbIo->UsbGetDeviceDescriptor (UsbIo, &Device); > + if (EFI_ERROR(Status)) { > + Status =3D EFI_UNSUPPORTED; > + } else { > + // > + // Validate the adapter > + // > + if (VENDOR_ID =3D=3D Device.IdVendor) { > + if (PRODUCT_AX88772B_ID !=3D Device.IdProduct) { > + } else if (PRODUCT_AX88772B_ASUS_ID =3D=3D Device.IdProduct) { > + } else if (PRODUCT_AX88772A_ID =3D=3D Device.IdProduct) { > + } else if (PRODUCT_ID =3D=3D Device.IdProduct) { > + } else { > + Status =3D EFI_UNSUPPORTED; > + } > + } else if (VENDOR_AX88772B_LENOVO_ID =3D=3D Device.IdVendor) { > + if (PRODUCT_AX88772B_LENOVO_ID !=3D Device.IdProduct) { > + Status =3D EFI_UNSUPPORTED; > + } > + } else { > + Status =3D EFI_UNSUPPORTED; > + } > + } > + > + // > + // Done with the USB stack > + // > + gBS->CloseProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + This->DriverBindingHandle, > + Controller > + ); > + } > + > + // > + // Return the device supported status > + // > + return Status; > +} > + > + > +/** > + Start this driver on Controller by opening UsbIo and DevicePath protoc= ols. > + Initialize PXE structures, create a copy of the Controller Device Path= with the > + NIC's MAC address apEnded to it, install the NetworkInterfaceIdentifie= r protocol > + on the newly created Device Path. > + > + @param [in] This 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 *This, > + IN EFI_HANDLE Controller, > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath > + ) > +{ > + EFI_STATUS Status; > + NIC_DEVICE *NicDevice; > + UINTN LengthInBytes; > + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath =3D NULL; > + MAC_ADDR_DEVICE_PATH MacDeviceNode; > + EFI_USB_DEVICE_DESCRIPTOR Device; > + > + // > + // Allocate the device structure > + // > + LengthInBytes =3D sizeof (*NicDevice); > + Status =3D gBS->AllocatePool ( > + EfiBootServicesData, > + LengthInBytes, > + (VOID **) &NicDevice > + ); > + > + if (EFI_ERROR (Status)) { > + goto ERR; > + } > + > + // > + // Set the structure signature > + // > + ZeroMem (NicDevice, LengthInBytes); > + NicDevice->Signature =3D DEV_SIGNATURE; > + > + Status =3D gBS->OpenProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + (VOID **) &NicDevice->UsbIo, > + This->DriverBindingHandle, > + Controller, > + EFI_OPEN_PROTOCOL_BY_DRIVER > + ); > + > + if (EFI_ERROR (Status)) { > + goto ERR; > + } > + > + NicDevice->Flag772A =3D FALSE; > + NicDevice->UsbIo->UsbGetDeviceDescriptor (NicDevice->UsbIo, &Device); > + if ((PRODUCT_AX88772A_ID =3D=3D Device.IdProduct) || > + (PRODUCT_ID =3D=3D Device.IdProduct)) > + NicDevice->Flag772A =3D TRUE; > + // > + // Initialize the simple network protocol > + // > + Status =3D SN_Setup (NicDevice); > + > + if (EFI_ERROR(Status)){ > + gBS->CloseProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + This->DriverBindingHandle, > + Controller > + ); > + goto ERR; > + } > + > + // > + // Set Device Path > + // > + Status =3D gBS->OpenProtocol ( > + Controller, > + &gEfiDevicePathProtocolGuid, > + (VOID **) &ParentDevicePath, > + This->DriverBindingHandle, > + Controller, > + EFI_OPEN_PROTOCOL_BY_DRIVER > + ); > + if (EFI_ERROR(Status)) { > + gBS->CloseProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + This->DriverBindingHandle, > + Controller > + ); > + goto ERR; > + } > + > + ZeroMem (&MacDeviceNode, sizeof (MAC_ADDR_DEVICE_PATH)); > + MacDeviceNode.Header.Type =3D MESSAGING_DEVICE_PATH; > + MacDeviceNode.Header.SubType =3D MSG_MAC_ADDR_DP; > + > + SetDevicePathNodeLength (&MacDeviceNode.Header, sizeof (MAC_ADDR_DEVIC= E_PATH)); > + > + CopyMem (&MacDeviceNode.MacAddress, > + &NicDevice->SimpleNetworkData.CurrentAddress, > + PXE_HWADDR_LEN_ETHER); > + > + MacDeviceNode.IfType =3D NicDevice->SimpleNetworkData.IfType; > + > + NicDevice->MyDevPath =3D AppendDevicePathNode ( > + ParentDevicePath, > + (EFI_DEVICE_PATH_PROTOCOL *) &= MacDeviceNode > + ); > + > + NicDevice->Controller =3D NULL; > + > + // > + // Install both the simple network and device path protocols. > + // > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > + &NicDevice->Controller, > + &gEfiCallerIdGuid, > + NicDevice, > + &gEfiSimpleNetworkProtocolGuid, > + &NicDevice->SimpleNetwork, > + &gEfiDevicePathProtocolGuid, > + NicDevice->MyDevPath, > + NULL > + ); > + > + if (EFI_ERROR(Status)){ > + gBS->CloseProtocol ( > + Controller, > + &gEfiDevicePathProtocolGuid, > + This->DriverBindingHandle, > + Controller); > + gBS->CloseProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + This->DriverBindingHandle, > + Controller > + ); > + goto ERR; > + } > + > + // > + // Open For Child Device > + // > + Status =3D gBS->OpenProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + (VOID **) &NicDevice->UsbIo, > + This->DriverBindingHandle, > + NicDevice->Controller, > + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER > + ); > + > + if (EFI_ERROR(Status)){ > + gBS->UninstallMultipleProtocolInterfaces ( > + &NicDevice->Controller, > + &gEfiCallerIdGuid, > + NicDevice, > + &gEfiSimpleNetworkProtocolGuid, > + &NicDevice->SimpleNetwork, > + &gEfiDevicePathProtocolGuid, > + NicDevice->MyDevPath, > + NULL > + ); > + gBS->CloseProtocol ( > + Controller, > + &gEfiDevicePathProtocolGuid, > + This->DriverBindingHandle, > + Controller); > + gBS->CloseProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + This->DriverBindingHandle, > + Controller > + ); > + goto ERR; > + } > + > + return Status; > + > + > +ERR: > + > + if (NicDevice->BulkInbuf !=3D NULL) { > + gBS->FreePool (NicDevice->BulkInbuf); > + } > + > + if (NicDevice->TxTest !=3D NULL) { > + gBS->FreePool (NicDevice->TxTest); > + } > + > + if (NicDevice->MyDevPath !=3D NULL) { > + gBS->FreePool (NicDevice->MyDevPath); > + } > + > + if (NicDevice !=3D NULL) { > + gBS->FreePool (NicDevice); > + } > + > + return Status; > +} > + > +/** > + Stop this driver on Controller by removing NetworkInterfaceIdentifier = protocol and > + closing the DevicePath and PciIo protocols on Controller. > + > + @param [in] This 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 dev= ice. > + > +**/ > +EFI_STATUS > +EFIAPI > +DriverStop ( > + IN EFI_DRIVER_BINDING_PROTOCOL * This, > + IN EFI_HANDLE Controller, > + IN UINTN NumberOfChildren, > + IN EFI_HANDLE * ChildHandleBuffer > + ) > +{ > + BOOLEAN AllChildrenStopped; > + EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork; > + EFI_STATUS Status =3D EFI_SUCCESS; > + NIC_DEVICE *NicDevice; > + UINTN Index; > + > + // > + // Complete all outstanding transactions to Controller. > + // Don't allow any new transaction to Controller to be started. > + // > + if (NumberOfChildren =3D=3D 0) { > + Status =3D gBS->OpenProtocol ( > + Controller, > + &gEfiSimpleNetworkProtocolGuid, > + (VOID **) &SimpleNetwork, > + This->DriverBindingHandle, > + Controller, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + > + if (EFI_ERROR(Status)) { > + // > + // This is a 2nd type handle(multi-lun root), it needs to close de= vicepath > + // and usbio protocol. > + // > + gBS->CloseProtocol ( > + Controller, > + &gEfiDevicePathProtocolGuid, > + This->DriverBindingHandle, > + Controller > + ); > + gBS->CloseProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + This->DriverBindingHandle, > + Controller > + ); > + return EFI_SUCCESS; > + } > + > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + > + Status =3D gBS->UninstallMultipleProtocolInterfaces ( > + Controller, > + &gEfiCallerIdGuid, > + NicDevice, > + &gEfiSimpleNetworkProtocolGuid, > + &NicDevice->SimpleNetwork, > + &gEfiDevicePathProtocolGuid, > + NicDevice->MyDevPath, > + NULL > + ); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + // > + // Close the bus driver > + // > + Status =3D gBS->CloseProtocol ( > + Controller, > + &gEfiDevicePathProtocolGuid, > + This->DriverBindingHandle, > + Controller > + ); > + > + Status =3D gBS->CloseProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + This->DriverBindingHandle, > + Controller > + ); > + > + return EFI_SUCCESS; > + } > + > + AllChildrenStopped =3D TRUE; > + > + for (Index =3D 0; Index < NumberOfChildren; Index++) { > + Status =3D gBS->OpenProtocol ( > + ChildHandleBuffer[Index], > + &gEfiSimpleNetworkProtocolGuid, > + (VOID **) &SimpleNetwork, > + This->DriverBindingHandle, > + Controller, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + > + if (EFI_ERROR (Status)) { > + AllChildrenStopped =3D FALSE; > + continue; > + } > + > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + > + gBS->CloseProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + This->DriverBindingHandle, > + ChildHandleBuffer[Index] > + ); > + > + Status =3D gBS->UninstallMultipleProtocolInterfaces ( > + ChildHandleBuffer[Index], > + &gEfiCallerIdGuid, > + NicDevice, > + &gEfiSimpleNetworkProtocolGuid, > + &NicDevice->SimpleNetwork, > + &gEfiDevicePathProtocolGuid, > + NicDevice->MyDevPath, > + NULL > + ); > + > + if (EFI_ERROR (Status)) { > + Status =3D gBS->OpenProtocol ( > + Controller, > + &gEfiUsbIoProtocolGuid, > + (VOID **) &NicDevice->UsbIo, > + This->DriverBindingHandle, > + ChildHandleBuffer[Index], > + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER > + ); > + } else { > + if (NicDevice->BulkInbuf !=3D NULL) { > + gBS->FreePool (NicDevice->BulkInbuf); > + } > + > + if (NicDevice->TxTest !=3D NULL) { > + gBS->FreePool (NicDevice->TxTest); > + } > + > + if (NicDevice->MyDevPath !=3D NULL) { > + gBS->FreePool (NicDevice->MyDevPath); > + } > + > + if (NicDevice !=3D NULL) { > + gBS->FreePool (NicDevice); > + } > + } > + } > + > + if (!AllChildrenStopped) { > + return EFI_DEVICE_ERROR; > + } > + > + return EFI_SUCCESS; > +} > + > + > +/** > + Driver binding protocol declaration > +**/ > +EFI_DRIVER_BINDING_PROTOCOL gDriverBinding =3D { > + 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 *Handle; > + EFI_STATUS Status; > + > + // > + // Determine which devices are using this driver > + // > + BufferSize =3D 0; > + Handle =3D NULL; > + Status =3D gBS->LocateHandle ( > + ByProtocol, > + &gEfiCallerIdGuid, > + NULL, > + &BufferSize, > + NULL); > + if (EFI_BUFFER_TOO_SMALL =3D=3D Status) { > + for (; ;) { > + // > + // One or more block IO devices are present > + // > + Status =3D gBS->AllocatePool ( > + EfiBootServicesData, > + BufferSize, > + (VOID **) &Handle > + ); > + if (EFI_ERROR (Status)) { > + break; > + } > + > + // > + // Locate the block IO devices > + // > + Status =3D gBS->LocateHandle ( > + ByProtocol, > + &gEfiCallerIdGuid, > + NULL, > + &BufferSize, > + Handle); > + if (EFI_ERROR (Status)) { > + // > + // Error getting handles > + // > + > + break; > + } > + > + // > + // Remove any use of the driver > + // > + Max =3D BufferSize / sizeof (Handle[0]); > + for (Index =3D 0; Max > Index; Index++) { > + Status =3D DriverStop (&gDriverBinding, > + Handle[Index], > + 0, > + NULL); > + if (EFI_ERROR (Status)) { > + break; > + } > + } > + break; > + } > + } else { > + if (EFI_NOT_FOUND =3D=3D Status) { > + // > + // No devices were found > + // > + Status =3D EFI_SUCCESS; > + } > + } > + > + // > + // Free the handle array > + // > + if (Handle !=3D NULL) { > + gBS->FreePool (Handle); > + } > + > + // > + // Remove the protocols installed by the EntryPoint routine. > + // > + if (!EFI_ERROR (Status)) { > + gBS->UninstallMultipleProtocolInterfaces ( > + ImageHandle, > + &gEfiDriverBindingProtocolGuid, > + &gDriverBinding, > + &gEfiComponentNameProtocolGuid, > + &gComponentName, > + &gEfiComponentName2ProtocolGuid, > + &gComponentName2, > + NULL > + ); > + } > + > + // > + // Return the unload status > + // > + return Status; > +} > + > + > +/** > +Ax88772 driver entry point. > + > +@param [in] ImageHandle Handle for the image. > +@param [in] SystemTable Address of the system table. > + > +@retval EFI_SUCCESS Image successfully loaded. > + > +**/ > +EFI_STATUS > +EFIAPI > +EntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; > + EFI_STATUS Status; > + > + // > + // Enable unload support > + // > + Status =3D gBS->HandleProtocol ( > + gImageHandle, > + &gEfiLoadedImageProtocolGuid, > + (VOID **)&LoadedImage > + ); > + if (!EFI_ERROR (Status)) { > + LoadedImage->Unload =3D DriverUnload; > + } > + > + // > + // Add the driver to the list of drivers > + // > + Status =3D EfiLibInstallDriverBindingComponentName2 ( > + ImageHandle, > + SystemTable, > + &gDriverBinding, > + ImageHandle, > + &gComponentName, > + &gComponentName2 > + ); > + > + return Status; > +} > diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/SimpleNetwork.c > b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/SimpleNetwork.c > new file mode 100644 > index 000000000000..9a80bf3d33cd > --- /dev/null > +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/SimpleNetwork.c > @@ -0,0 +1,1581 @@ > +/** @file > + Provides the Simple Network functions. > + > + Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved. > + Copyright (c) 2020, ARM Limited. All rights reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#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] SimpleNetwork 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 SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +ReceiveFilterUpdate ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork > + ) > +{ > + EFI_SIMPLE_NETWORK_MODE *Mode; > + NIC_DEVICE *NicDevice; > + EFI_STATUS Status; > + UINT32 Index; > + > + // > + // Set the MAC address > + // > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + Mode =3D SimpleNetwork->Mode; > + // > + // Clear the multicast hash table > + // > + Ax88772MulticastClear (NicDevice); > + > + // > + // Load the multicast hash table > + // > + if ((Mode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST= ) !=3D 0) { > + for (Index =3D 0; Index < Mode->MCastFilterCount; Index++) { > + // > + // Enable the next multicast address > + // > + Ax88772MulticastSet (NicDevice, > + &Mode->MCastFilter[Index].Addr[0]); > + } > + } > + > + Status =3D Ax88772RxControl (NicDevice, Mode->ReceiveFilterSetting); > + > + // > + // Return the operation 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] SimpleNetwork Protocol instance pointer > + @param [in] InterruptStatus A pointer to the bit mask of the current = active interrupts. > + If this is NULL, the interrupt status wi= ll not be read from > + the device. If this is not NULL, the in= terrupt status will > + be read from teh device. When the inter= rupt status is read, > + it will also be cleared. Clearing the t= ransmit interrupt > + does not empty the recycled transmit buf= fer array. > + @param [out] TxBuf Recycled transmit buffer address. The net= work interface will > + not transmit if its internal recycled tr= ansmit buffer array is > + full. Reading the transmit buffer does = not clear the transmit > + interrupt. If this is NULL, then the tr= ansmit buffer status > + will not be read. If there are not tran= smit buffers to recycle > + and TxBuf is not NULL, *TxBuf will be se= t to NULL. > + > + @retval EFI_SUCCESS This operation was successful. > + @retval EFI_NOT_STARTED The network interface was not started. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + > +**/ > + > +EFI_STATUS > +EFIAPI > +SN_GetStatus ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + OUT UINT32 *InterruptStatus, > + OUT VOID **TxBuf > + ) > +{ > + EFI_SIMPLE_NETWORK_MODE *Mode; > + NIC_DEVICE *NicDevice =3D NULL; > + EFI_STATUS Status =3D EFI_SUCCESS; > + EFI_TPL TplPrevious; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + // > + // Verify the parameters > + // > + if ((SimpleNetwork !=3D NULL) && (SimpleNetwork->Mode !=3D NULL)) { > + // > + // Return the transmit buffer > + // > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + > + if ((TxBuf !=3D NULL) && (NicDevice->TxBuffer !=3D NULL)) { > + *TxBuf =3D NicDevice->TxBuffer; > + NicDevice->TxBuffer =3D NULL; > + } > + > + Mode =3D SimpleNetwork->Mode; > + if (EfiSimpleNetworkInitialized =3D=3D Mode->State) { > + if ((TxBuf =3D=3D NULL) && (InterruptStatus =3D=3D NULL)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + > +#if REPORTLINK > +#else > + if (!NicDevice->LinkUp || !NicDevice->Complete) { > +#endif > + Status =3D Ax88772NegotiateLinkComplete (NicDevice, > + &NicDevice->PollCount, > + &NicDevice->Complete, > + &NicDevice->LinkUp, > + &NicDevice->LinkSpeed100= Mbps, > + &NicDevice->FullDuplex); > + > + if (EFI_ERROR(Status)) > + goto EXIT; > +#if REPORTLINK > + if (NicDevice->LinkUp && NicDevice->Complete) { > + Mode->MediaPresent =3D TRUE; > + Status =3D ReceiveFilterUpdate (SimpleNetwork); > + } else { > + Mode->MediaPresent =3D FALSE; > + } > +#else > + if (NicDevice->LinkUp && NicDevice->Complete) { > + Mode->MediaPresent =3D TRUE; > + Mode->MediaPresentSupported =3D FALSE; > + Status =3D ReceiveFilterUpdate (SimpleNetwork); > + } > + } > +#endif > + } else { > + if (EfiSimpleNetworkStarted =3D=3D Mode->State) { > + Status =3D EFI_DEVICE_ERROR; > + } else { > + Status =3D EFI_NOT_STARTED ; > + } > + } > + } else { > + Status =3D EFI_INVALID_PARAMETER; > + } > + if (InterruptStatus !=3D NULL) { > + *InterruptStatus =3D 0; > + } > + > +EXIT: > + gBS->RestoreTPL(TplPrevious) ; > + > + return Status; > +} > + > +/** > + This function performs read and write operations on the NVRAM device > + attached to a network interface. > + > + @param [in] SimpleNetwork Protocol instance pointer > + @param [in] ReadWrite TRUE for read operations, FALSE for writ= e 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 fro= m the NVRAM device. > + This must also be a multiple of NvramAcc= essSize. > + @param [in, out] Buffer 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 SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_NvData ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN BOOLEAN ReadWrite, > + IN UINTN Offset, > + IN UINTN BufferSize, > + IN OUT VOID *Buffer > + ) > +{ > + EFI_STATUS Status =3D EFI_INVALID_PARAMETER; > + EFI_TPL TplPrevious; > + EFI_SIMPLE_NETWORK_MODE *Mode; > + NIC_DEVICE *NicDevice; > + UINTN Index; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + if ((SimpleNetwork =3D=3D NULL) || (SimpleNetwork->Mode =3D=3D NULL)) = { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + Mode =3D SimpleNetwork->Mode; > + > + if (EfiSimpleNetworkInitialized !=3D Mode->State) { > + Status =3D EFI_NOT_STARTED; > + goto EXIT; > + } > + > + if (Offset !=3D 0) { > + if (((Offset % Mode->NvRamAccessSize) !=3D 0) || > + (Offset >=3D Mode->NvRamSize)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + } > + // > + // Offset must be a multiple of NvRamAccessSize and less than NvRamSiz= e. > + // > + if ((BufferSize % Mode->NvRamAccessSize) !=3D 0) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + > + if (BufferSize + Offset > Mode->NvRamSize) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + > + if (Buffer =3D=3D NULL) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + > + // > + // ReadWrite: TRUE FOR READ FALSE FOR WRITE > + // > + if (ReadWrite) { > + for (Index =3D 0; Index < BufferSize / 2; Index++) { > + Status =3D Ax88772SromRead (NicDevice, > + (UINT32)(Offset/2 + Index), > + (((UINT16*)Buffer) + Index)); > + } > + } else { > + Status =3D Ax88772EnableSromWrite(NicDevice); > + if (EFI_ERROR(Status)) > + goto EXIT; > + > + for (Index =3D 0; Index < BufferSize / 2; Index++) { > + Status =3D Ax88772SromWrite (NicDevice, > + (UINT32)(Offset/2 + Index), > + (((UINT16*)Buffer) + Index)); > + } > + > + Status =3D Ax88772DisableSromWrite(NicDevice); > + > + if (BufferSize =3D=3D 272) > + Status =3D Ax88772ReloadSrom(NicDevice); > + } > + > + // > + // Return the operation status > + // > +EXIT: > + gBS->RestoreTPL (TplPrevious); > + return Status; > +} > + > +/** > + Resets the network adapter and allocates the transmit and receive buff= ers > + required by the network interface; optionally, also requests allocatio= n of > + additional transmit and receive buffers. This routine must be called = before > + any other routine in the Simple Network protocol is called. > + > + @param [in] SimpleNetwork Protocol instance pointer > + @param [in] ExtraRxBufferSize Size in bytes to add to the receive buff= er allocation > + @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buf= fer 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 tran= smit and receive buffers > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Initialize ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL * SimpleNetwork, > + IN UINTN ExtraRxBufferSize, > + IN UINTN ExtraTxBufferSize > + ) > +{ > + EFI_SIMPLE_NETWORK_MODE *Mode; > + EFI_STATUS Status; > + UINT32 TmpState; > + EFI_TPL TplPrevious; > + NIC_DEVICE *NicDevice; > + > + TplPrevious =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + // > + // Verify the parameters > + // > + if ((SimpleNetwork !=3D NULL) && (SimpleNetwork->Mode !=3D NULL)) { > + // > + // Determine if the interface is already started > + // > + Mode =3D SimpleNetwork->Mode; > + if (EfiSimpleNetworkStarted =3D=3D Mode->State) { > + if ((0 =3D=3D ExtraRxBufferSize) && (0 =3D=3D ExtraTxBufferSize)) = { > + // > + // Start the adapter > + // > + TmpState =3D Mode->State; > + Mode->State =3D EfiSimpleNetworkInitialized; > + Status =3D SN_Reset (SimpleNetwork, FALSE); > + if (EFI_ERROR (Status)) { > + // > + // Update the network state > + // > + Mode->State =3D TmpState; // EfiSimpleNetworkInitialized; > + } else { > + Mode->MediaPresentSupported =3D TRUE; > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + Mode->MediaPresent =3D Ax88772GetLinkStatus (NicDevice); > + } > + } else { > + Status =3D EFI_UNSUPPORTED; > + } > + } else { > + Status =3D EFI_NOT_STARTED; > + } > + } else { > + Status =3D EFI_INVALID_PARAMETER; > + } > + > + // > + // Return the operation status > + // > + gBS->RestoreTPL (TplPrevious); > + return Status; > +} > + > + > +/** > + This function converts a multicast IP address to a multicast HW MAC ad= dress > + for all packet transactions. > + > + @param [in] SimpleNetwork Protocol instance pointer > + @param [in] IPv6 Set to TRUE if the multicast IP address i= s IPv6 [RFC2460]. > + Set to FALSE if the multicast IP address= is IPv4 [RFC 791]. > + @param [in] IP The multicast IP address that is to be co= nverted to a > + multicast HW MAC address. > + @param [in] MAC The multicast HW MAC address that is to b= e generated from IP. > + > + @retval EFI_SUCCESS This operation was successful. > + @retval EFI_NOT_STARTED The network interface was not started. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_MCastIPtoMAC ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN BOOLEAN IPv6, > + IN EFI_IP_ADDRESS *IP, > + IN EFI_MAC_ADDRESS *MAC > + ) > +{ > + EFI_STATUS Status; > + EFI_TPL TplPrevious; > + EFI_SIMPLE_NETWORK_MODE *Mode; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + if ((SimpleNetwork !=3D NULL) && (SimpleNetwork->Mode !=3D NULL)) { > + // > + // The interface must be running > + // > + Mode =3D SimpleNetwork->Mode; > + if (EfiSimpleNetworkInitialized =3D=3D Mode->State) { > + if (IP =3D=3D NULL || MAC =3D=3D NULL) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + if (IPv6) { > + Status =3D EFI_UNSUPPORTED; > + goto EXIT; > + } else { > + // > + // check if the ip given is a mcast IP > + // > + if ((IP->v4.Addr[0] & 0xF0) !=3D 0xE0) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } else { > + MAC->Addr[0] =3D 0x01; > + MAC->Addr[1] =3D 0x00; > + MAC->Addr[2] =3D 0x5e; > + MAC->Addr[3] =3D (UINT8) (IP->v4.Addr[1] & 0x7f); > + MAC->Addr[4] =3D (UINT8) IP->v4.Addr[2]; > + MAC->Addr[5] =3D (UINT8) IP->v4.Addr[3]; > + Status =3D EFI_SUCCESS; > + } > + } > + } else { > + if (EfiSimpleNetworkStarted =3D=3D Mode->State) { > + Status =3D EFI_DEVICE_ERROR; > + } else { > + Status =3D EFI_NOT_STARTED ; > + } > + } > + } else { > + Status =3D EFI_INVALID_PARAMETER; > + } > + > +EXIT: > + gBS->RestoreTPL(TplPrevious); > + return Status; > +} > + > +/** > + Attempt to receive a packet from the network adapter. > + > + This function retrieves one packet from the receive queue of the netwo= rk > + 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 pac= ket > + will be placed in Buffer, and BufferSize will be udpated with the actu= al > + size of the packet. In addition, if SrcAddr, DestAddr, and Protocol a= re > + not NULL, then these values will be extracted from the media header an= d > + 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 ::Ax88179Rx to update the media status and > + empty the network adapter of receive packets. > + > + @param [in] SimpleNetwork Protocol instance pointer > + @param [out] HeaderSize The size, in bytes, of the media header t= o 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 mus= t not be NULL. > + @param [out] BufferSize The size, in bytes, of the entire packet = (media header and > + data) to be transmitted through the netw= ork interface. > + @param [out] Buffer A pointer to the packet (media header fol= lowed by data) to > + to be transmitted. This parameter can n= ot be NULL. If > + HeaderSize is zero, then the media heade= r 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] SrcAddr The source HW MAC address. If HeaderSize= is zero, then > + this parameter is ignored. If HeaderSiz= e is nonzero and > + SrcAddr is NULL, then SimpleNetwork->Mod= e->CurrentAddress > + is used for the source HW MAC address. > + @param [out] DestAddr The destination HW MAC address. If Heade= rSize is zero, then > + this parameter is ignored. > + @param [out] Protocol The type of header to build. If HeaderSi= ze 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 net= work interface. > + @retval EFI_BUFFER_TOO_SMALL The packet is larger than BufferSize byt= es. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Receive ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + OUT UINTN *HeaderSize, > + OUT UINTN *BufferSize, > + OUT VOID *Buffer, > + OUT EFI_MAC_ADDRESS *SrcAddr, > + OUT EFI_MAC_ADDRESS *DestAddr, > + OUT UINT16 *Protocol > + ) > +{ > + ETHERNET_HEADER *Header; > + EFI_SIMPLE_NETWORK_MODE *Mode; > + NIC_DEVICE *NicDevice =3D NULL; > + EFI_STATUS Status; > + EFI_TPL TplPrevious; > + UINT16 Type; > + UINT16 CurrentPktLen; > + > + > + TplPrevious =3D gBS->RaiseTPL (TPL_CALLBACK); > + // > + // Verify the parameters > + // > + if ((SimpleNetwork !=3D NULL) && (SimpleNetwork->Mode !=3D NULL)) { > + // > + // The interface must be running > + // > + Mode =3D SimpleNetwork->Mode; > + if (EfiSimpleNetworkInitialized =3D=3D Mode->State) { > + if ((BufferSize =3D=3D NULL) || (Buffer =3D=3D NULL)) { > + Status =3D EFI_INVALID_PARAMETER; > + gBS->RestoreTPL (TplPrevious); > + return Status; > + } > + > + // > + // Update the link status > + // > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + > + if (NicDevice->LinkUp && NicDevice->Complete) { > + if ((HeaderSize !=3D NULL) && (*HeaderSize =3D=3D 7720)) { > + NicDevice->Grub_f =3D TRUE; > + } > + > + if ((NicDevice->Grub_f) && (*HeaderSize !=3D 7720)) { > + gBS->RestoreTPL (TplPrevious); > + return EFI_NOT_READY; > + } > + > + // > + // Attempt to receive a packet > + // > + if (0 =3D=3D NicDevice->PktCnt) { > + Status =3D Ax88772BulkIn(NicDevice); > + if (EFI_ERROR(Status)) { > + goto no_pkt; > + } > + } > + > + CurrentPktLen =3D *((UINT16*) (NicDevice->CurPktHdrOff)); > + CurrentPktLen &=3D 0x7ff; > + > + if ((60 <=3D CurrentPktLen) && > + (CurrentPktLen - 14 <=3D MAX_ETHERNET_PKT_SIZE)) { > + if (*BufferSize < (UINTN)CurrentPktLen) { > + gBS->RestoreTPL (TplPrevious); > + return EFI_BUFFER_TOO_SMALL; > + } > + > + *BufferSize =3D CurrentPktLen; > + CopyMem (Buffer, NicDevice->CurPktOff, CurrentPktLen); > + Header =3D (ETHERNET_HEADER *) NicDevice->CurPktOff; > + > + if ((HeaderSize !=3D NULL) && (*HeaderSize !=3D 7720)) { > + *HeaderSize =3D sizeof (*Header); > + } > + if (DestAddr !=3D NULL) { > + CopyMem (DestAddr, &Header->DestAddr, PXE_HWADDR_LEN_ETHER= ); > + } > + if (SrcAddr !=3D NULL) { > + CopyMem (SrcAddr, &Header->SrcAddr, PXE_HWADDR_LEN_ETHER); > + } > + if (Protocol !=3D NULL) { > + Type =3D Header->Type; > + Type =3D (UINT16)((Type >> 8) | (Type << 8)); > + *Protocol =3D Type; > + } > + NicDevice->PktCnt--; > + NicDevice->CurPktHdrOff +=3D (CurrentPktLen + 4 + 1) & 0xfff= e; > + NicDevice->CurPktOff =3D NicDevice->CurPktHdrOff + 4; > + Status =3D EFI_SUCCESS; > + } else { > + NicDevice->PktCnt =3D 0; > + Status =3D EFI_DEVICE_ERROR; > + } > + } else { > + // > + // Link no up > + // > + Status =3D EFI_NOT_READY; > + } > + } else { > + if (EfiSimpleNetworkStarted =3D=3D Mode->State) { > + Status =3D EFI_DEVICE_ERROR; > + } else { > + Status =3D EFI_NOT_STARTED; > + } > + } > + } else { > + Status =3D EFI_INVALID_PARAMETER; > + } > + > + // > + // Return the operation status > + // > +no_pkt: > + gBS->RestoreTPL (TplPrevious); > + 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 hardwar= e > + a more liberal setting is selected. > + > + If the same bits are set in the Enable and Disable parameters, then th= e 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 f= ield > + 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->ReceeiveFilterSetti= ngs, > + 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 filt= ers > + instead. The receiving software is responsible for discarding any ext= ra > + 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 receiv= e > + 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 multicas= t > + 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] SimpleNetwork 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 T= RUE. > + @param [in] ResetMCastFilter Set to TRUE to reset the contents of the = multicast receive > + filters on the network interface to thei= r default values. > + @param [in] MCastFilterCnt Number of multicast HW MAC address in th= e 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] MCastFilter A pointer to a list of new multicast rece= ive filter HW MAC > + addresses. This list will replace any e= xisting multicast > + HW MAC address list. This field is opti= onal 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 SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_ReceiveFilters ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN UINT32 Enable, > + IN UINT32 Disable, > + IN BOOLEAN ResetMCastFilter, > + IN UINTN MCastFilterCnt, > + IN EFI_MAC_ADDRESS *MCastFilter > + ) > +{ > + EFI_SIMPLE_NETWORK_MODE *Mode; > + EFI_STATUS Status =3D EFI_SUCCESS; > + EFI_TPL TplPrevious; > + UINTN Index; > + UINT8 Temp; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + Mode =3D SimpleNetwork->Mode; > + > + if (SimpleNetwork =3D=3D NULL) { > + gBS->RestoreTPL(TplPrevious); > + return EFI_INVALID_PARAMETER; > + } > + > + switch (Mode->State) { > + case EfiSimpleNetworkInitialized: > + break; > + > + case EfiSimpleNetworkStopped: > + Status =3D EFI_NOT_STARTED; > + gBS->RestoreTPL(TplPrevious); > + return Status; > + > + default: > + Status =3D EFI_DEVICE_ERROR; > + gBS->RestoreTPL(TplPrevious); > + return Status; > + } > + > + // > + // check if we are asked to enable or disable something that the SNP > + // does not even support! > + // > + if (((Enable &~Mode->ReceiveFilterMask) !=3D 0) || > + ((Disable &~Mode->ReceiveFilterMask) !=3D 0)) { > + Status =3D EFI_INVALID_PARAMETER; > + gBS->RestoreTPL(TplPrevious); > + return Status; > + } > + > + if (ResetMCastFilter) { > + if ((0 =3D=3D (Mode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEI= VE_MULTICAST)) && > + Enable =3D=3D 0 && > + Disable =3D=3D 2) { > + gBS->RestoreTPL(TplPrevious); > + return EFI_SUCCESS; > + } > + Mode->MCastFilterCount =3D 0; > + SetMem (&Mode->MCastFilter[0], > + sizeof(EFI_MAC_ADDRESS) * MAX_MCAST_FILTER_CNT, > + 0); > + } else { > + if (MCastFilterCnt !=3D 0) { > + EFI_MAC_ADDRESS * MulticastAddress; > + MulticastAddress =3D MCastFilter; > + > + if ((MCastFilterCnt > Mode->MaxMCastFilterCount) || > + (MCastFilter =3D=3D NULL)) { > + Status =3D EFI_INVALID_PARAMETER; > + gBS->RestoreTPL(TplPrevious); > + return Status; > + } > + > + for (Index =3D 0 ; Index < MCastFilterCnt ; Index++) { > + Temp =3D MulticastAddress->Addr[0]; > + if ((Temp & 0x01) !=3D 0x01) { > + gBS->RestoreTPL(TplPrevious); > + return EFI_INVALID_PARAMETER; > + } > + MulticastAddress++; > + } > + > + Mode->MCastFilterCount =3D (UINT32)MCastFilterCnt; > + CopyMem (&Mode->MCastFilter[0], > + MCastFilter, > + MCastFilterCnt * sizeof (EFI_MAC_ADDRESS)); > + } > + } > + > + if (Enable =3D=3D 0 && Disable =3D=3D 0 && !ResetMCastFilter && MCastF= ilterCnt =3D=3D 0) { > + Status =3D EFI_SUCCESS; > + gBS->RestoreTPL(TplPrevious); > + return Status; > + } > + > + if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) !=3D 0 && MCastFil= terCnt =3D=3D 0) { > + Status =3D EFI_INVALID_PARAMETER; > + gBS->RestoreTPL(TplPrevious); > + return Status; > + } > + > + Mode->ReceiveFilterSetting |=3D Enable; > + Mode->ReceiveFilterSetting &=3D ~Disable; > + > + Status =3D ReceiveFilterUpdate (SimpleNetwork); > + > + if (EFI_DEVICE_ERROR =3D=3D Status || EFI_INVALID_PARAMETER =3D=3D Sta= tus) > + Status =3D EFI_SUCCESS; > + > + gBS->RestoreTPL(TplPrevious); > + > + 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] SimpleNetwork Protocol instance pointer > + @param [in] ExtendedVerification Indicates that the driver may perfor= m 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 SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Reset ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN BOOLEAN ExtendedVerification > + ) > +{ > + EFI_SIMPLE_NETWORK_MODE *Mode; > + NIC_DEVICE *NicDevice; > + EFI_STATUS Status; > + EFI_TPL TplPrevious; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + // > + // Verify the parameters > + // > + if ((SimpleNetwork !=3D NULL) && (SimpleNetwork->Mode !=3D NULL)) { > + Mode =3D SimpleNetwork->Mode; > + if (EfiSimpleNetworkInitialized =3D=3D Mode->State) { > + // > + // Update the device state > + // > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + > + // > + // Reset the device > + // > + if (!NicDevice->FirstRst) { > + Status =3D EFI_SUCCESS; > + } else { > + Status =3D Ax88772Reset (NicDevice); > + if (!EFI_ERROR (Status)) { > + Status =3D ReceiveFilterUpdate (SimpleNetwork); > + if (!EFI_ERROR (Status) && !NicDevice->LinkUp && NicDevice->Fi= rstRst) { > + Status =3D Ax88772NegotiateLinkStart (NicDevice); > + NicDevice->FirstRst =3D FALSE; > + } > + } > + } > + } else { > + Status =3D EFI_NOT_STARTED; > + } > + } else { > + Status =3D EFI_INVALID_PARAMETER; > + } > + // > + // Return the operation status > + // > + gBS->RestoreTPL(TplPrevious); > + return Status; > +} > + > +/** > + Initialize the simple network protocol. > + > + This routine calls ::Ax88772MacAddressGet to obtain the > + MAC address. > + > + @param [in] NicDevice NIC_DEVICE_INSTANCE pointer > + > + @retval EFI_SUCCESS Setup was successful > + > +**/ > +EFI_STATUS > +SN_Setup ( > + IN NIC_DEVICE *NicDevice > + ) > +{ > + EFI_SIMPLE_NETWORK_MODE *Mode; > + EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork; > + EFI_STATUS Status; > + > + // > + // Initialize the simple network protocol > + // > + SimpleNetwork =3D &NicDevice->SimpleNetwork; > + SimpleNetwork->Revision =3D EFI_SIMPLE_NETWORK_PROTOCOL_REVISION; > + SimpleNetwork->Start =3D SN_Start; > + SimpleNetwork->Stop =3D SN_Stop; > + SimpleNetwork->Initialize =3D SN_Initialize; > + SimpleNetwork->Reset =3D SN_Reset; > + SimpleNetwork->Shutdown =3D SN_Shutdown; > + SimpleNetwork->ReceiveFilters =3D SN_ReceiveFilters; > + SimpleNetwork->StationAddress =3D SN_StationAddress; > + SimpleNetwork->Statistics =3D SN_Statistics; > + SimpleNetwork->MCastIpToMac =3D SN_MCastIPtoMAC; > + SimpleNetwork->NvData =3D SN_NvData; > + SimpleNetwork->GetStatus =3D SN_GetStatus; > + SimpleNetwork->Transmit =3D SN_Transmit; > + SimpleNetwork->Receive =3D SN_Receive; > + SimpleNetwork->WaitForPacket =3D NULL; > + Mode =3D &NicDevice->SimpleNetworkData; > + SimpleNetwork->Mode =3D Mode; > + Mode->State =3D EfiSimpleNetworkStopped; > + Mode->HwAddressSize =3D PXE_HWADDR_LEN_ETHER; > + Mode->MediaHeaderSize =3D sizeof (ETHERNET_HEADER); > + Mode->MaxPacketSize =3D MAX_ETHERNET_PKT_SIZE; > + Mode->ReceiveFilterMask =3D 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_MULT= ICAST; > + Mode->ReceiveFilterSetting =3D EFI_SIMPLE_NETWORK_RECEIVE_UNICAST > + | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST; > + Mode->MaxMCastFilterCount =3D ASIX_MCAST_FILTER_CNT; > + Mode->MCastFilterCount =3D 0; > + Mode->NvRamSize =3D 512; > + Mode->NvRamAccessSize =3D 2; > + SetMem (&Mode->BroadcastAddress, > + PXE_HWADDR_LEN_ETHER, > + 0xff); > + > + SetMem (&Mode->MCastFilter[0], > + sizeof(EFI_MAC_ADDRESS) * MAX_MCAST_FILTER_CNT, > + 0); > + > + Mode->IfType =3D NET_IFTYPE_ETHERNET; > + Mode->MacAddressChangeable =3D TRUE; > + Mode->MultipleTxSupported =3D FALSE; > + Mode->MediaPresentSupported =3D TRUE; > + Mode->MediaPresent =3D FALSE; > + > + // > + // Read the MAC address > + // > + NicDevice->PhyId =3D PHY_ID_INTERNAL; > + NicDevice->LinkSpeed100Mbps =3D TRUE; > + NicDevice->FullDuplex =3D TRUE; > + NicDevice->Complete =3D FALSE; > + NicDevice->LinkUp =3D FALSE; > + NicDevice->Grub_f =3D FALSE; > + NicDevice->FirstRst =3D TRUE; > + NicDevice->PktCnt =3D 0; > + > + Status =3D Ax88772MacAddressGet ( > + NicDevice, > + &Mode->PermanentAddress.Addr[0]); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Use the hardware address as the current address > + // > + CopyMem (&Mode->CurrentAddress, > + &Mode->PermanentAddress, > + PXE_HWADDR_LEN_ETHER); > + > + CopyMem (&NicDevice->MAC, > + &Mode->PermanentAddress, > + PXE_HWADDR_LEN_ETHER); > + > + Status =3D gBS->AllocatePool (EfiBootServicesData, > + AX88772_MAX_BULKIN_SIZE, > + (VOID **) &NicDevice->BulkInbuf); > + > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status =3D gBS->AllocatePool (EfiBootServicesData, > + sizeof (RX_TX_PACKET), > + (VOID **) &NicDevice->TxTest); > + > + if (EFI_ERROR (Status)) { > + gBS->FreePool (NicDevice->BulkInbuf); > + return Status; > + } > + > + // > + // Return the setup status > + // > + return Status; > +} > + > + > +/** > + This routine starts the network interface. > + > + @param [in] SimpleNetwork Protocol instance pointer > + > + @retval EFI_SUCCESS This operation was successful. > + @retval EFI_ALREADY_STARTED The network interface was already starte= d. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Start ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork > + ) > +{ > + NIC_DEVICE *NicDevice; > + EFI_SIMPLE_NETWORK_MODE *Mode; > + EFI_STATUS Status; > + EFI_TPL TplPrevious; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + // > + // Verify the parameters > + // > + Status =3D EFI_INVALID_PARAMETER; > + if ((SimpleNetwork !=3D NULL) && (SimpleNetwork->Mode !=3D NULL)) { > + Mode =3D SimpleNetwork->Mode; > + if (EfiSimpleNetworkStopped =3D=3D Mode->State) { > + // > + // Initialize the mode structure > + // NVRAM access is not supported > + // > + ZeroMem (Mode, sizeof (*Mode)); > + > + Mode->State =3D EfiSimpleNetworkStarted; > + Mode->HwAddressSize =3D PXE_HWADDR_LEN_ETHER; > + Mode->MediaHeaderSize =3D sizeof (ETHERNET_HEADER); > + Mode->MaxPacketSize =3D MAX_ETHERNET_PKT_SIZE; > + Mode->ReceiveFilterMask =3D 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; > + Mode->ReceiveFilterSetting =3D EFI_SIMPLE_NETWORK_RECEIVE_UNICAST; > + Mode->MaxMCastFilterCount =3D ASIX_MCAST_FILTER_CNT; > + Mode->MCastFilterCount =3D 0; > + > + SetMem (&Mode->MCastFilter[0], > + sizeof(EFI_MAC_ADDRESS) * MAX_MCAST_FILTER_CNT, > + 0); > + > + Mode->NvRamSize =3D 512; > + Mode->NvRamAccessSize =3D 2; > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + Status =3D Ax88772MacAddressGet (NicDevice, &Mode->PermanentAddres= s.Addr[0]); > + CopyMem (&Mode->CurrentAddress, > + &Mode->PermanentAddress, > + sizeof (Mode->CurrentAddress)); > + SetMem(&Mode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff); > + Mode->IfType =3D NET_IFTYPE_ETHERNET; > + Mode->MacAddressChangeable =3D TRUE; > + Mode->MultipleTxSupported =3D FALSE; > + Mode->MediaPresentSupported =3D TRUE; > + Mode->MediaPresent =3D FALSE; > + > + } else { > + Status =3D EFI_ALREADY_STARTED; > + } > + } > + > + // > + // Return the operation status > + // > + gBS->RestoreTPL(TplPrevious); > + 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 FALS= E > + then the current station address is changed to the address specified b= y > + New. > + > + This routine calls ::Ax88772MacAddressSet to update the MAC address > + in the network adapter. > + > + @param [in] SimpleNetwork Protocol instance pointer > + @param [in] Reset Flag used to reset the station address to= the > + network interface's permanent address. > + @param [in] New New station address to be used for the ne= twork > + interface. > + > + @retval EFI_SUCCESS This operation was successful. > + @retval EFI_NOT_STARTED The network interface was not started. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_StationAddress ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN BOOLEAN Reset, > + IN EFI_MAC_ADDRESS *New > + ) > +{ > + NIC_DEVICE *NicDevice; > + EFI_SIMPLE_NETWORK_MODE *Mode; > + EFI_STATUS Status; > + > + EFI_TPL TplPrevious; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + // > + // Verify the parameters > + // > + if ((SimpleNetwork !=3D NULL) && > + (SimpleNetwork->Mode !=3D NULL) && > + ((!Reset) || (Reset && (New !=3D NULL)))) { > + // > + // Verify that the adapter is already started > + // > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + Mode =3D SimpleNetwork->Mode; > + if (EfiSimpleNetworkInitialized =3D=3D Mode->State) { > + // > + // Determine the adapter MAC address > + // > + if (Reset) { > + // > + // Use the permanent address > + // > + CopyMem (&Mode->CurrentAddress, > + &Mode->PermanentAddress, > + sizeof (Mode->CurrentAddress)); > + } else { > + // > + // Use the specified address > + // > + CopyMem (&Mode->CurrentAddress, > + New, > + sizeof (Mode->CurrentAddress)); > + } > + > + // > + // Update the address on the adapter > + // > + Status =3D Ax88772MacAddressSet (NicDevice, &Mode->CurrentAddress.= Addr[0]); > + } else { > + if (EfiSimpleNetworkStarted =3D=3D Mode->State) { > + Status =3D EFI_DEVICE_ERROR; ; > + } else { > + Status =3D EFI_NOT_STARTED ; > + } > + } > + } else { > + Status =3D EFI_INVALID_PARAMETER; > + } > + > + // > + // Return the operation status > + // > + gBS->RestoreTPL(TplPrevious); > + 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] SimpleNetwork Protocol instance pointer > + @param [in] Reset Set to TRUE to reset the statistics for t= he network interface. > + @param [in, out] StatisticsSize On input the size, in bytes, of Stati= sticsTable. On output > + the size, in bytes, of the resulting tab= le of statistics. > + @param [out] StatisticsTable A pointer to the EFI_NETWORK_STATISTICS s= tructure 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 StatisticsTable is NULL or the buffe= r is too small. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > +**/ > +EFI_STATUS > +EFIAPI > +SN_Statistics ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN BOOLEAN Reset, > + IN OUT UINTN *StatisticsSize, > + OUT EFI_NETWORK_STATISTICS *StatisticsTable > + ) > +{ > + EFI_STATUS Status; > + EFI_TPL TplPrevious; > + EFI_SIMPLE_NETWORK_MODE *Mode; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + Mode =3D SimpleNetwork->Mode; > + > + if (EfiSimpleNetworkInitialized =3D=3D Mode->State) { > + if ((StatisticsSize !=3D NULL) && (*StatisticsSize =3D=3D 0)) { > + Status =3D EFI_BUFFER_TOO_SMALL; > + goto EXIT; > + } > + > + if(Reset) { > + Status =3D EFI_SUCCESS; > + } else { > + Status =3D EFI_SUCCESS; > + } > + } else { > + if (EfiSimpleNetworkStarted =3D=3D Mode->State) { > + Status =3D EFI_DEVICE_ERROR; ; > + } else { > + Status =3D EFI_NOT_STARTED ; > + } > + } > + // > + // This is not currently supported > + // > + > +EXIT: > + gBS->RestoreTPL(TplPrevious); > + return Status; > +} > + > + > +/** > + This function stops a network interface. This call is only valid > + if the network interface is in the started state. > + > + @param [in] SimpleNetwork Protocol instance pointer > + > + @retval EFI_SUCCESS This operation was successful. > + @retval EFI_NOT_STARTED The network interface was not started. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Stop ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork > + ) > +{ > + EFI_SIMPLE_NETWORK_MODE *Mode; > + EFI_STATUS Status; > + EFI_TPL TplPrevious; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + // > + // Verify the parameters > + // > + if ((SimpleNetwork !=3D NULL) && (SimpleNetwork->Mode !=3D NULL)) { > + // > + // Determine if the interface is started > + // > + Mode =3D SimpleNetwork->Mode; > + > + if (EfiSimpleNetworkStarted =3D=3D Mode->State) { > + Mode->State =3D EfiSimpleNetworkStopped; > + Status =3D EFI_SUCCESS; > + } else { > + Status =3D EFI_NOT_STARTED; > + } > + } else { > + Status =3D EFI_INVALID_PARAMETER; > + } > + > + // > + // Return the operation status > + // > + gBS->RestoreTPL(TplPrevious); > + return Status; > +} > + > + > +/** > + This function releases the memory buffers assigned in the Initialize()= call. > + Ending transmits and receives are lost, and interrupts are cleared and= disabled. > + After this call, only Initialize() and Stop() calls may be used. > + > + @param [in] SimpleNetwork Protocol instance pointer > + > + @retval EFI_SUCCESS This operation was successful. > + @retval EFI_NOT_STARTED The network interface was not started. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + @retval EFI_UNSUPPORTED The increased buffer size feature is not= supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Shutdown ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork > + ) > +{ > + EFI_SIMPLE_NETWORK_MODE *Mode; > + UINT32 RxFilter; > + EFI_STATUS Status; > + EFI_TPL TplPrevious; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + // > + // Verify the parameters > + // > + if ((SimpleNetwork !=3D NULL) && (SimpleNetwork->Mode !=3D NULL)) { > + // > + // Determine if the interface is already started > + // > + Mode =3D SimpleNetwork->Mode; > + if (EfiSimpleNetworkInitialized =3D=3D Mode->State) { > + // > + // Stop the adapter > + // > + RxFilter =3D Mode->ReceiveFilterSetting; > + Mode->ReceiveFilterSetting =3D 0; > + Status =3D SN_Reset (SimpleNetwork, FALSE); > + Mode->ReceiveFilterSetting =3D RxFilter; > + if (!EFI_ERROR (Status)) { > + // > + // Update the network state > + // > + Mode->State =3D EfiSimpleNetworkStarted; > + } else if (EFI_DEVICE_ERROR =3D=3D Status) { > + Mode->State =3D EfiSimpleNetworkStopped; > + } > + > + } else { > + Status =3D EFI_NOT_STARTED; > + } > + } else { > + Status =3D EFI_INVALID_PARAMETER; > + } > + > + // > + // Return the operation status > + // > + gBS->RestoreTPL(TplPrevious); > + 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] SimpleNetwork 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 mus= t not be NULL. > + @param [in] BufferSize The size, in bytes, of the entire packet= (media header and > + data) to be transmitted through the netw= ork interface. > + @param [in] Buffer A pointer to the packet (media header fol= lowed by data) to > + to be transmitted. This parameter can n= ot be NULL. If > + HeaderSize is zero, then the media heade= r 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] SrcAddr The source HW MAC address. If HeaderSize= is zero, then > + this parameter is ignored. If HeaderSiz= e is nonzero and > + SrcAddr is NULL, then SimpleNetwork->Mod= e->CurrentAddress > + is used for the source HW MAC address. > + @param [in] DestAddr The destination HW MAC address. If Heade= rSize is zero, then > + this parameter is ignored. > + @param [in] Protocol The type of header to build. If HeaderSi= ze 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 acc= ept this transmit request. > + @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small. > + @retval EFI_INVALID_PARAMETER SimpleNetwork 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 net= work interface. > + > +**/ > +EFI_STATUS > +EFIAPI > +SN_Transmit ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork, > + IN UINTN HeaderSize, > + IN UINTN BufferSize, > + IN VOID *Buffer, > + IN EFI_MAC_ADDRESS *SrcAddr, > + IN EFI_MAC_ADDRESS *DestAddr, > + IN UINT16 *Protocol > + ) > +{ > + ETHERNET_HEADER *Header; > + EFI_SIMPLE_NETWORK_MODE *Mode; > + NIC_DEVICE *NicDevice; > + EFI_USB_IO_PROTOCOL *UsbIo; > + EFI_STATUS Status; > + UINTN TransferLength; > + UINT32 TransferStatus; > + UINT16 Type; > + EFI_TPL TplPrevious; > + > + TplPrevious =3D gBS->RaiseTPL(TPL_CALLBACK); > + // > + // Verify the parameters > + // > + if ((SimpleNetwork !=3D NULL) && (SimpleNetwork->Mode !=3D NULL)) { > + // > + // The interface must be running > + // > + Mode =3D SimpleNetwork->Mode; > + if (EfiSimpleNetworkInitialized =3D=3D Mode->State) { > + // > + // Update the link status > + // > + NicDevice =3D DEV_FROM_SIMPLE_NETWORK (SimpleNetwork); > + > + // > + // Release the synchronization with Ax88772Timer > + // > + if (NicDevice->LinkUp && NicDevice->Complete) { > + // > + // Copy the packet into the USB buffer > + // > + > + if ((HeaderSize !=3D 0) && (Mode->MediaHeaderSize !=3D HeaderSiz= e)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + if (BufferSize < Mode->MediaHeaderSize) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + if (Buffer =3D=3D NULL) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + if ((HeaderSize !=3D 0) && (DestAddr =3D=3D NULL)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + if ((HeaderSize !=3D 0) && (Protocol =3D=3D NULL)) { > + Status =3D EFI_INVALID_PARAMETER; > + goto EXIT; > + } > + > + CopyMem (&NicDevice->TxTest->Data[0], Buffer, BufferSize); > + NicDevice->TxTest->Length =3D (UINT16) BufferSize; > + > + // > + // Transmit the packet > + // > + Header =3D (ETHERNET_HEADER *) &NicDevice->TxTest->Data[0]; > + if (HeaderSize !=3D 0) { > + if (DestAddr !=3D NULL) { > + CopyMem (&Header->DestAddr, DestAddr, PXE_HWADDR_LEN_ETHER); > + } > + if (SrcAddr !=3D NULL) { > + CopyMem (&Header->SrcAddr, SrcAddr, PXE_HWADDR_LEN_ETHER); > + } else { > + CopyMem (&Header->SrcAddr, &Mode->CurrentAddress.Addr[0], PX= E_HWADDR_LEN_ETHER); > + } > + if (Protocol !=3D NULL) { > + Type =3D *Protocol; > + } else { > + Type =3D NicDevice->TxTest->Length; > + } > + Type =3D (UINT16)((Type >> 8) | (Type << 8)); > + Header->Type =3D Type; > + } > + > + > + if (NicDevice->TxTest->Length < MIN_ETHERNET_PKT_SIZE) { > + NicDevice->TxTest->Length =3D MIN_ETHERNET_PKT_SIZE; > + ZeroMem (&NicDevice->TxTest->Data[BufferSize], > + NicDevice->TxTest->Length - BufferSize); > + } > + > + NicDevice->TxTest->LengthBar =3D ~(NicDevice->TxTest->Length); > + TransferLength =3D sizeof (NicDevice->TxTest->Length) > + + sizeof (NicDevice->TxTest->LengthBar) > + + NicDevice->TxTest->Length; > + > + if (TransferLength % 512 =3D=3D 0 || TransferLength % 1024 =3D= =3D 0) > + TransferLength +=3D4; > +#if RXTHOU > + if (NicDevice->RxBurst =3D=3D 1) > + NicDevice->RxBurst--; > +#endif > + // > + // Work around USB bus driver bug where a timeout set by receiv= e > + // succeeds but the timeout expires immediately after, causing = the > + // transmit operation to timeout. > + // > + UsbIo =3D NicDevice->UsbIo; > + Status =3D UsbIo->UsbBulkTransfer (UsbIo, > + BULK_OUT_ENDPOINT, > + &NicDevice->TxTest->Length, > + &TransferLength, > + 0xfffffffe, > + &TransferStatus); > + if (EFI_SUCCESS =3D=3D Status) { > + Status =3D TransferStatus; > + } > + if (EFI_SUCCESS =3D=3D Status && EFI_SUCCESS =3D=3D TransferStat= us) { > + NicDevice->TxBuffer =3D Buffer; > + } else { > + if (EFI_DEVICE_ERROR =3D=3D Status) { > + SN_Reset (SimpleNetwork, FALSE); > + } > + Status =3D EFI_NOT_READY; > + } > + } else { > + // > + // No packets available. > + // > + Status =3D EFI_NOT_READY; > + } > + } else { > + if (EfiSimpleNetworkStarted =3D=3D Mode->State) { > + Status =3D EFI_DEVICE_ERROR; > + } else { > + Status =3D EFI_NOT_STARTED; > + } > + } > + } else { > + Status =3D EFI_INVALID_PARAMETER; > + } > + > +EXIT: > + gBS->RestoreTPL (TplPrevious); > + return Status; > +} > -- > 2.17.1