public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers
@ 2020-06-08 13:38 Samer El-Haj-Mahmoud
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 1/6] Drivers/ASIX: Create ASIX package Samer El-Haj-Mahmoud
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Samer El-Haj-Mahmoud @ 2020-06-08 13:38 UTC (permalink / raw)
  To: devel
  Cc: Ray Ni, Leif Lindholm, Ard Biesheuvel, Michael D Kinney,
	Pete Batard, Andrei Warkentin

This series updates the ASIX USB networking drivers:

 - Create new Drivers/ASIX/ package
 - Add new ASIX drivers Ax88179 and Ax88772c to the new ASIX package
 - Delete old Ax88772 and Ax88772b drivers from OptionRomPkg

Code pushed to https://github.com/samerhaj/edk2-platforms/tree/asix_usb_nic_drivers_ver3

version 1: https://edk2.groups.io/g/devel/message/58771
version 2: https://edk2.groups.io/g/devel/message/58986
version 3 changes:
 - Rename AsixPkg to ASIX [Ray]
 - Changed SNP Mode->IfType from EfiNetworkInterfaceUndi to
   NET_IFTYPE_ETHERNET [Ard]
 - Dropped runtime module types and associated depex, libraries,
   and memory allocation [Ard]
 - Dropped "SCT_PASS" and kept the enable logic [Leif]
 - Dropped dead / commented out code and macros
   (including "ARM" and "AMI") [Ard, Leif]
 - Dropped unused debug macros [Leif, Ard]
 - Dropped "Freddy" Comments and unused macros [Leif, Ard]
 - Dropped inorrect VALID_ARCHITECTURES from INF files [Ard]
 - Dropped all Hungarian notation variables [Ard, Leif]
 - Dropped 'Yoda-style' compariosns [Ard, Leif]
 - Dropped redundant casts [Ard]
 - Fixed spacing, indentation, and curly braces [Ard, Leif]
 - Used CamelCase definitions per coding style [Ard]
 - Dropped 'success handling' [Ard]
 - Sorted LibraryClasses and include files [Ard]
 - Aligned variables and function parameters declarations [Ard]
 - Cleaned up include headers [Leif]
 - Added public link to orignal ASIX provided code [Leif]

Cc: Ray Ni <ray.ni@intel.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Pete Batard <pete@akeo.ie>
Cc: Andrei Warkentin <andrey.warkentin@gmail.com>

Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>

Samer El-Haj-Mahmoud (6):
  Drivers/ASIX: Create ASIX drivers package
  Drivers/ASIX: Add ASIX Ax88179 driver
  Drivers/ASIX: Add ASIX Ax88772c driver
  Platform/RaspberryPi: Switch RPi3 USB NIC driver to Ax88772c
  Platform/HiSilicon: Switch HiKey USB NIC driver to Ax88772c
  Drivers/OptionRomPkg: Remove old ASIX NIC drivers

 Drivers/ASIX/Asix.dec                         |   30 +
 Drivers/ASIX/Asix.dsc                         |   68 +
 Drivers/OptionRomPkg/OptionRomPkg.dsc         |    3 +-
 Platform/Hisilicon/HiKey/HiKey.dsc            |    2 +-
 Platform/RaspberryPi/RPi3/RPi3.dsc            |    2 +-
 Platform/Hisilicon/HiKey/HiKey.fdf            |    2 +-
 Platform/RaspberryPi/RPi3/RPi3.fdf            |    2 +-
 .../Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf |   45 +
 .../Usb/UsbNetworking/Ax88772c/Ax88772c.inf}  |   28 +-
 .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 -
 .../Bus/Usb/UsbNetworking/Ax88179/Ax88179.h}  |  792 ++++----
 .../Bus/Usb/UsbNetworking/Ax88772c}/Ax88772.h |  489 ++---
 .../Bus/Usb/UsbNetworking/Ax88179/Ax88179.c   | 1042 +++++++++++
 .../UsbNetworking/Ax88179}/ComponentName.c    |  107 +-
 .../Usb/UsbNetworking/Ax88179/DriverBinding.c |  639 +++++++
 .../Usb/UsbNetworking/Ax88179/SimpleNetwork.c | 1548 +++++++++++++++
 .../Bus/Usb/UsbNetworking/Ax88772c/Ax88772.c  | 1300 +++++++++++++
 .../UsbNetworking/Ax88772c}/ComponentName.c   |   97 +-
 .../UsbNetworking/Ax88772c/DriverBinding.c    |  652 +++++++
 .../UsbNetworking/Ax88772c/SimpleNetwork.c    | 1581 ++++++++++++++++
 .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318 -------------
 .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 -----
 .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503 ---------------
 .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875 ---------
 .../UsbNetworking/Ax88772b/DriverBinding.c    |  696 -------
 .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657 -----------------
 26 files changed, 7754 insertions(+), 7292 deletions(-)
 create mode 100644 Drivers/ASIX/Asix.dec
 create mode 100644 Drivers/ASIX/Asix.dsc
 create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf
 rename Drivers/{OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf => ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf} (58%)
 delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
 rename Drivers/{OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h => ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.h} (52%)
 rename Drivers/{OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b => ASIX/Bus/Usb/UsbNetworking/Ax88772c}/Ax88772.h (69%)
 create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.c
 rename Drivers/{OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772 => ASIX/Bus/Usb/UsbNetworking/Ax88179}/ComponentName.c (69%)
 create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/DriverBinding.c
 create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/SimpleNetwork.c
 create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772.c
 rename Drivers/{OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b => ASIX/Bus/Usb/UsbNetworking/Ax88772c}/ComponentName.c (70%)
 create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/DriverBinding.c
 create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/SimpleNetwork.c
 delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
 delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
 delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
 delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
 delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
 delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c

-- 
2.17.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [edk2-platform][PATCH v3 1/6] Drivers/ASIX: Create ASIX package
  2020-06-08 13:38 [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Samer El-Haj-Mahmoud
@ 2020-06-08 13:38 ` Samer El-Haj-Mahmoud
  2020-06-09  0:37   ` Ni, Ray
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 2/6] Drivers/ASIX: Add ASIX Ax88179 driver Samer El-Haj-Mahmoud
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Samer El-Haj-Mahmoud @ 2020-06-08 13:38 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Leif Lindholm, Ard Biesheuvel, Michael D Kinney

Create a new ASIX package for build verification of ASIX USB drivers.

Cc: Ray Ni <ray.ni@intel.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>

Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
---
 Drivers/ASIX/Asix.dec | 30 +++++++++
 Drivers/ASIX/Asix.dsc | 67 ++++++++++++++++++++
 2 files changed, 97 insertions(+)

diff --git a/Drivers/ASIX/Asix.dec b/Drivers/ASIX/Asix.dec
new file mode 100644
index 000000000000..5639f2096751
--- /dev/null
+++ b/Drivers/ASIX/Asix.dec
@@ -0,0 +1,30 @@
+## @file
+# Package for ASIX drivers build validation file for All Architectures.
+#
+# Copyright (c) 2020, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = Asix
+  PACKAGE_GUID                   = 687fc389-78e4-4a28-90c1-3b22c949da80
+  PACKAGE_VERSION                = 0.1
+
+[Includes]
+  Include
+
+[LibraryClasses]
+
+[Guids]
+  gAsixTokenSpaceGuid = {0x7a7a1758, 0x5234, 0x4b3f, {0x8a, 0x5c, 0x1c, 0x35, 0x6d, 0x2d, 0xbd, 0x37}}
+
+
+[PcdsFeatureFlag]
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+
+
diff --git a/Drivers/ASIX/Asix.dsc b/Drivers/ASIX/Asix.dsc
new file mode 100644
index 000000000000..d65857bb1cd4
--- /dev/null
+++ b/Drivers/ASIX/Asix.dsc
@@ -0,0 +1,67 @@
+## @file
+# Package for ASIX drivers build validation file for All Architectures.
+#
+# Copyright (c) 2020, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = Asix
+  PLATFORM_GUID                  = 11c6ff4c-5931-464b-8a2f-1716d57fb134
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/$(PLATFORM_NAME)
+  SUPPORTED_ARCHITECTURES        = IA32|X64|EBC|ARM|AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+  DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+
+[LibraryClasses.AARCH64, LibraryClasses.ARM]
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+[LibraryClasses.ARM]
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+[PcdsFeatureFlag]
+
+[PcdsFixedAtBuild]
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components]
+
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [edk2-platform][PATCH v3 2/6] Drivers/ASIX: Add ASIX Ax88179 driver
  2020-06-08 13:38 [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Samer El-Haj-Mahmoud
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 1/6] Drivers/ASIX: Create ASIX package Samer El-Haj-Mahmoud
@ 2020-06-08 13:38 ` Samer El-Haj-Mahmoud
  2020-06-09  0:37   ` Ni, Ray
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 3/6] Drivers/ASIX: Add ASIX Ax88772c driver Samer El-Haj-Mahmoud
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Samer El-Haj-Mahmoud @ 2020-06-08 13:38 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Leif Lindholm, Ard Biesheuvel, Michael D Kinney

This is the initial revision of ASIX USB networking UEFI driver
version 2.9.0 for Ax88179 and Ax88178a
https://www.asix.com.tw/products.php?op=pItemdetail&PItemID=131;71;112

Original source code provided by ASIX is at:
https://github.com/samerhaj/uefi_drivers/blob/master/UsbNetworking/Asix/
zip/source/AX88179_178a_UEFI_v2.9.0_Source.zip

Cc: Ray Ni <ray.ni@intel.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>

Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
---
 Drivers/ASIX/Asix.dsc                                      |    2 +-
 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf     |   45 +
 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.h       | 1053 +++++++++++++
 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.c       | 1042 +++++++++++++
 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/ComponentName.c |  223 +++
 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/DriverBinding.c |  639 ++++++++
 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/SimpleNetwork.c | 1548 ++++++++++++++++++++
 7 files changed, 4551 insertions(+), 1 deletion(-)

diff --git a/Drivers/ASIX/Asix.dsc b/Drivers/ASIX/Asix.dsc
index d65857bb1cd4..73b5cbd5a18f 100644
--- a/Drivers/ASIX/Asix.dsc
+++ b/Drivers/ASIX/Asix.dsc
@@ -64,4 +64,4 @@ [PcdsFixedAtBuild]
 #
 ################################################################################
 [Components]
-
+Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf
diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf
new file mode 100644
index 000000000000..317ec538fa60
--- /dev/null
+++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.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, Intel Corporation
+# Copyright (c) 2020, ARM Limited. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010018
+  BASE_NAME                      = Ax88179
+  FILE_GUID                      = 27E5D3B6-7839-47C2-8618-5D2190729BC7
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = EntryPoint
+
+[Sources.common]
+  Ax88179.h
+  Ax88179.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/Ax88179/Ax88179.h b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.h
new file mode 100644
index 000000000000..498212ec149b
--- /dev/null
+++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.h
@@ -0,0 +1,1053 @@
+/** @file
+  Definitions for ASIX AX88179 Ethernet adapter.
+
+  Copyright (c) 2011, Intel Corporation
+  Copyright (c) 2020, ARM Limited. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef AX88179_H_
+#define AX88179_H_
+
+#include <Uefi.h>
+
+#include <Guid/EventGroup.h>
+
+#include <IndustryStandard/Pci.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/NetLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeLib.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/NetworkInterfaceIdentifier.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/UsbIo.h>
+
+
+#define FORCE_100Mbps 0
+#define REPORTLINK    1
+
+
+//------------------------------------------------------------------------------
+//  Macros
+//------------------------------------------------------------------------------
+
+#define USB_IS_IN_ENDPOINT(EndPointAddr)      (((EndPointAddr) & BIT7) != 0)  ///<  Return TRUE/FALSE for IN direction
+#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7) == 0)  ///<  Return TRUE/FALSE for OUT direction
+#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_BULK)      ///<  Return TRUE/FALSE for BULK type
+#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) ///<  Return TRUE/FALSE for INTERRUPT type
+
+//------------------------------------------------------------------------------
+//  Constants
+//------------------------------------------------------------------------------
+
+#define DEBUG_RX_BROADCAST  0x40000000  ///<  Display RX broadcast messages
+#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast messages
+#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast messages
+#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 values
+#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
+
+
+#define ETHERNET_HEADER_SIZE  sizeof (ETHERNET_HEADER)  ///<  Size in bytes of the Ethernet header
+#define MIN_ETHERNET_PKT_SIZE 60    ///<  Minimum packet size including Ethernet header
+#define MAX_ETHERNET_PKT_SIZE 1500
+
+#define USB_NETWORK_CLASS   0x09    ///<  USB Network class code
+#define USB_BUS_TIMEOUT     1000    ///<  USB timeout in milliseconds
+
+#define AX88179_BULKIN_SIZE_INK     2
+#define AX88179_MAX_BULKIN_SIZE    (1024 * AX88179_BULKIN_SIZE_INK)
+#define AX88179_MAX_PKT_SIZE  2048
+
+#define HC_DEBUG        0
+#define ADD_MACPATHNOD  1
+#define BULKIN_TIMEOUT  3 //5000
+#define TX_RETRY        0
+#define AUTONEG_DELAY   1000000
+
+/**
+  Verify new TPL value
+
+  This macro which is enabled when debug is enabled verifies that
+  the new TPL value is >= 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 = 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 <= tpl);                \
+  }                                             \
+}
+
+#else   //  MDEPKG_NDEBUG
+
+#define VERIFY_TPL(tpl)
+
+#endif  //  MDEPKG_NDEBUG
+
+//------------------------------------------------------------------------------
+//  Hardware Definition
+//------------------------------------------------------------------------------
+
+#define DEV_SIGNATURE     SIGNATURE_32 ('A','X','8','8')  ///<  Signature of data structures in memory
+
+#define VENDOR_ID         0x0B95  ///<  Vendor ID for Asix
+#define PRODUCT_ID        0x1790  ///<  Product ID for the AX88179 USB 10/100 Ethernet controller
+#define PRODUCT_ID_178A   0x178A
+
+#define RESET_MSEC        1000    ///<  Reset duration
+#define PHY_RESET_MSEC    100     ///<  PHY reset duration
+
+//
+//  RX Control register
+//
+
+
+//
+//  Medium Status register
+//
+
+
+
+//
+//  Software PHY Select register
+//
+
+#define SPHY_PSEL         0x01    ///<  Select internal PHY
+#define SPHY_ASEL         0x02    ///<  1=Auto select, 0=Manual select
+
+//
+//  Software Reset register
+//
+
+#define SRR_RR            0x01    ///<  Clear receive frame length error
+#define SRR_RT            0x02    ///<  Clear transmit frame length error
+#define SRR_PRTE          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   0x0003  ///<  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_RX_CONTROL_WRITE      0x10  ///<  Set the RX control register, Value: New value
+#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value: New value
+#define CMD_MAC_ADDRESS_READ      0x11  ///<  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_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status register, Data: Register value
+#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status register, Value: New value
+#define CMD_RESET                 0x20  ///<  Reset register, Value: New value
+#define CMD_PHY_SELECT            0x22  ///<  PHY select register, Value: New value
+
+//------------------------------
+//  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_ANER                        6       ///<  Autonegotiation expansion register
+//  BSMR - Register 1
+//  ANAR and ANLPAR Registers 4, 5
+#define RXHDR_DROP 0x8000
+#define RXHDR_CRCERR 0x2000
+
+
+//------------------------------------------------------------------------------
+//  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 _TX_PACKET {
+  UINT32  TxHdr1;
+  UINT32  TxHdr2;
+  UINT8   Data[AX88179_MAX_PKT_SIZE]; ///<  Received packet data
+} TX_PACKET;
+#pragma pack()
+
+#pragma pack(1)
+typedef struct _RX_PACKET {
+  struct _RX_PACKET *Next;
+  UINT16            Length;
+  UINT16            EEEE;
+  UINT8             Data[AX88179_MAX_PKT_SIZE];
+} RX_PACKET;
+#pragma pack()
+
+/**
+  AX88179 control structure
+
+  The driver uses this structure to manage the Asix AX88179 10/100
+  Ethernet controller.
+**/
+typedef struct {
+  UINTN                     Signature;         ///<  Structure identification
+
+  //
+  //  USB data
+  //
+  EFI_HANDLE                Controller;        ///<  Controller handle
+  EFI_USB_IO_PROTOCOL       *UsbIo;            ///<  USB driver interface
+
+  //
+  //  Simple network protocol data
+  //
+  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;     ///<  Driver's network stack interface
+  EFI_SIMPLE_NETWORK_MODE     SimpleNetworkData; ///<  Data for simple network
+
+  //
+  // Ethernet controller data
+  //
+  BOOLEAN                   Initialized;       ///<  Controller initialized
+  UINT16                    PhyId;             ///<  PHY ID
+
+  //
+  //  Link state
+  //
+  BOOLEAN                   LinkSpeed100Mbps;   ///<  Current link speed, FALSE = 10 Mbps
+  BOOLEAN                   LinkSpeed1000Mbps;  ///<  Current link speed, FALSE = 100/10 bps
+  BOOLEAN                   Complete;           ///<  Current state of auto-negotiation
+  BOOLEAN                   FullDuplex;         ///<  Current duplex
+  BOOLEAN                   LinkUp;             ///<  Current link state
+  BOOLEAN                   LinkIdle;           ///<  TRUE = No received traffic
+  EFI_EVENT                 Timer;              ///<  Timer to monitor link state and receive packets
+  UINTN                     PollCount;          ///<  Number of times the autonegotiation status was polled
+  UINTN                     SkipRXCnt;
+
+  UINT8                     *BulkInbuf;
+  UINT16                    PktCnt;
+  UINT8                     *CurPktHdrOff;
+  UINT8                     *CurPktOff;
+
+  TX_PACKET                 *TxTest;
+
+  INT8                      MulticastHash[8];
+  EFI_MAC_ADDRESS           MAC;
+
+  UINT16                    CurMediumStatus;
+  UINT16                    CurRxControl;
+  VOID *                    TxBuffer;
+
+  EFI_DEVICE_PATH_PROTOCOL  *MyDevPath;
+  BOOLEAN                   Grub_f;
+  BOOLEAN                   FirstRst;
+  BOOLEAN                   SetZeroLen;
+  UINT8                     RxBurst;
+  UINTN                     UsbMaxPktSize;
+} NIC_DEVICE;
+
+#define DEV_FROM_SIMPLE_NETWORK(a)  CR (a, NIC_DEVICE, SimpleNetwork, DEV_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 ::Ax88179Reset to perform the adapter specific
+  reset operation.  This routine also starts the link negotiation
+  by calling ::Ax88179NegotiateLinkStart.
+
+  @param [in] SimpleNetwork    Protocol instance pointer
+  @param [in] ExtendedVerification  Indicates that the driver may perform a more
+                                exhaustive verification operation of the device
+                                during reset.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER 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 network 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 ::Ax88179MacAddressGet 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 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 network 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 FALSE
+  then the current station address is changed to the address specified by
+  New.
+
+  This routine calls ::Ax88179MacAddressSet 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 network
+                                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 network 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 the network interface.
+  @param [in, out] StatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
+                                the size, in bytes, of the resulting table of statistics.
+  @param [out] StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+                                conains the statistics.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_BUFFER_TOO_SMALL  The StatisticsTable is NULL or the buffer 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 network 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 network 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 network 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 ::Ax88179Rx 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 must not be NULL.
+  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [in] Buffer           A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [in] SrcAddr          The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [in] DestAddr         The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [in] Protocol         The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
+  @retval EFI_INVALID_PARAMETER 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 network 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 ::Ax88179UsbCommand 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 the MAC address.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88179MacAddressGet (
+  IN NIC_DEVICE *NicDevice,
+  OUT UINT8     *MacAddress
+  );
+
+
+/**
+  Clear the multicast hash table
+
+  @param [in] NicDevice       Pointer to the NIC_DEVICE structure
+
+**/
+VOID
+Ax88179MulticastClear (
+  IN NIC_DEVICE *NicDevice
+  );
+
+/**
+  Enable a multicast address in the multicast hash table
+
+  This routine calls ::Ax88179Crc 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
+Ax88179MulticastSet (
+  IN NIC_DEVICE *NicDevice,
+  IN UINT8      *MacAddress
+  );
+
+/**
+  Start the link negotiation
+
+  This routine calls ::Ax88179PhyWrite 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
+Ax88179NegotiateLinkStart (
+  IN NIC_DEVICE *NicDevice
+  );
+
+/**
+  Complete the negotiation of the PHY link
+
+  This routine calls ::Ax88179PhyRead 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 was polled
+  @param [out] Complete      Address of boolean to receive complate status.
+  @param [out] LinkUp        Address of boolean to receive link status, TRUE=up.
+  @param [out] HiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
+  @param [out] FullDuplex    Address of boolean to receive link duplex, TRUE=full.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88179NegotiateLinkComplete (
+  IN     NIC_DEVICE *NicDevice,
+  IN OUT UINTN      *PollCount,
+  OUT    BOOLEAN    *Complete,
+  OUT    BOOLEAN    *LinkUp,
+  OUT    BOOLEAN    *HiSpeed,
+  OUT    BOOLEAN    *GigaSpeed,
+  OUT    BOOLEAN    *FullDuplex
+  );
+
+/**
+  Read a register from the PHY
+
+  This routine calls ::Ax88179UsbCommand 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 register value
+
+  @retval EFI_SUCCESS          The PHY data is available.
+  @retval other                The PHY data is not valid.
+
+**/
+
+
+/**
+  Reset the AX88179
+
+  This routine uses ::Ax88179UsbCommand to reset the network
+  adapter.  This routine also uses ::Ax88179PhyWrite 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
+Ax88179Reset (
+  IN NIC_DEVICE *NicDevice
+  );
+
+/**
+  Enable or disable the receiver
+
+  This routine calls ::Ax88179UsbCommand to update the
+  receiver state.  This routine also calls ::Ax88179MacAddressSet
+  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
+Ax88179RxControl (
+  IN NIC_DEVICE *NicDevice,
+  IN UINT32     RxFilter
+  );
+
+  EFI_STATUS
+Ax88179ReloadSrom  (
+  IN NIC_DEVICE *NicDevice
+  );
+
+/**
+  Read an SROM location
+
+  This routine calls ::Ax88179UsbCommand 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
+Ax88179SromRead (
+  IN  NIC_DEVICE *NicDevice,
+  IN  UINT32     Address,
+  OUT UINT16     *Data
+  );
+
+
+EFI_STATUS
+Ax88179EnableSromWrite  (
+  IN NIC_DEVICE *NicDevice
+  );
+
+
+EFI_STATUS
+Ax88179DisableSromWrite  (
+  IN NIC_DEVICE *NicDevice
+  );
+
+EFI_STATUS
+Ax88179SromWrite (
+  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
+Ax88179UsbCommand (
+  IN NIC_DEVICE         *NicDevice,
+  IN USB_DEVICE_REQUEST *Request,
+  IN OUT VOID           *Buffer
+  );
+
+//------------------------------------------------------------------------------
+// EFI Component Name Protocol Support
+//------------------------------------------------------------------------------
+extern EFI_DRIVER_BINDING_PROTOCOL   gDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL   gComponentName;  ///<  Component name protocol declaration
+extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<  Component name 2 protocol declaration
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] Language         A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+  @param [out] 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 specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
+  IN  CHAR8                       *Language,
+  OUT CHAR16                      **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] ControllerHandle  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+  @param [in] ChildHandle       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+  @param [in] Language         A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+  @param [out] 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 driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
+  IN  EFI_HANDLE                  ControllerHandle,
+  IN OPTIONAL EFI_HANDLE          ChildHandle,
+  IN  CHAR8                       *Language,
+  OUT CHAR16                      **ControllerName
+  );
+
+EFI_STATUS
+Ax88179SetMedium (
+  IN NIC_DEVICE * NicDevice
+  );
+
+//-----------------------------------------------------------------------------
+
+
+#define ACCESS_MAC  0x01
+#define ACCESS_PHY  0x02
+
+#define PLSR                0x02
+  #define PLSR_USB_FS  0x01
+  #define PLSR_USB_HS  0x02
+  #define PLSR_USB_SS  0x04
+
+#define NODE_ID               0x10
+
+#define RXCTL                 0x0b
+  #define RXCTL_PRO         0x0001  ///<  Receive all packets
+  #define RXCTL_AMALL       0x0002  ///<  Receive all multicast packets
+  #define RXCTL_SEP         0x0004  ///<  Save error packets
+  #define RXCTL_AB          0x0008  ///<  Receive broadcast packets
+  #define RXCTL_AM          0x0010  ///<  Use multicast destination address hash table
+  #define RXCTL_AP          0x0020  ///<  Accept physical address from Multicast Filter
+  #define RXCTL_ARP         0x0040  ///<  Accept runt packet
+  #define RXCTL_SO          0x0080  ///<  Start operation
+  #define RXCTL_DROPCRCERR  0x0100  ///<  RX header 1 formate selection
+  #define RXCTL_IPE         0x0200  ///<  RX header 2 formate selection
+  #define RXCTL_TXPADCRC    0x0400  ///<  RX header 3 formate selection
+  #define RXCTL_LPBK        0x1000  ///<  MAC loop back for diagnostic
+
+#define MULCATFLTARRY       0x16  ///<  Write the multicast hash table, Data: New 8 byte value
+
+#define MEDIUMSTSMOD          0x22
+  #define MEDIUMSTSMOD_GM   0x0001  ///<  Gigabit Mode
+  #define MEDIUMSTSMOD_FD   0x0002  ///<  Full duplex
+  #define MEDIUMSTSMOD_ONE  0x0004  ///<  Must be one
+  #define MEDIUMSTSMOD_ENCK 0x0008  ///<  Add in 04h
+  #define MEDIUMSTSMOD_RFC  0x0010  ///<  RX flow control enable
+  #define MEDIUMSTSMOD_TFC  0x0020  ///<  TX flow control enable
+  #define MEDIUMSTSMOD_JFE  0x0040  ///<  Pause frame enable
+  #define MEDIUMSTSMOD_PF   0x0080  ///<  Pause frame enable
+  #define MEDIUMSTSMOD_RE   0x0100  ///<  Receive enable
+  #define MEDIUMSTSMOD_PS   0x0200  ///<  Port speed 1=100, 0=10 Mbps
+  #define MEDIUMSTSMOD_SBP  0x0800  ///<  Stop back pressure
+  #define MEDIUMSTSMOD_SM   0x1000  ///<  Super MAC support
+
+#define MONITORSTAUS          0x24
+  #define  MONITORSTAUS_PMETYPE   0x40
+  #define  MONITORSTAUS_PMEPOL    0x20
+
+#define PHYPWRRSTCTL          0x26
+  #define PHYPWRRSTCTL_IPRL     0x20
+  #define PHYPWRRSTCTL_OSCDSSEL 0x80
+  #define PHYPWRRSTCTL_BZTYPE   0x4
+  #define PHYPWRRSTCTL_BZ      0x10
+
+#define SISSR                 0x28
+  #define SISSR_PSEL        0x01
+  #define SISSR_ASEL        0x02
+
+#define RXBINQCTRL            0x2e
+  #define RXBINQCTRL_TIMEN  0x01
+  #define RXBINQCTRL_IFGEN  0x02
+  #define RXBINQCTRL_SIZEN  0x04
+
+#define RXBINQTIMERL          0x2f
+#define RXBINQTIMERH          0x30
+#define RXBINQSIZE            0x31
+#define RXBINQIFG             0x32
+
+#define CLKSELECT             0x33
+  #define CLKSELECT_ACS       0x02
+  #define CLKSELECT_BCS       0x01
+
+#define PAUSE_WATERLVL_HIGH   0x54
+#define PAUSE_WATERLVL_LOW    0x55
+
+#define RXFREEBUF             0x57
+  #define MAX_RXBUF_PAGE    0x067F
+
+#define PHY_BMCR                        0       ///<  Control register
+  #define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears after reset
+  #define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
+  #define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable autonegotiation
+  #define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
+  #define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
+  #define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart autonegotiation
+  #define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
+  #define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test enabled
+  #define BMCR_1000MBPS                   0x40  ///<  Forced mode in 1000Mbps
+  #define BMCR_100MBPS                    0x2000    ///<  Forced mode in 10Mbps
+
+#define PHY_BMSR                        1       ///<  Status register
+  #define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
+  #define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full duplex
+  #define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half duplex
+  #define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
+  #define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half duplex
+  #define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with preamble suppressed
+  #define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation complete
+  #define BMSR_RF                         0x0010  ///<  1 = Remote fault
+  #define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform autonegotiation
+  #define BMSR_LINKST                     0x0004  ///<  1 = Link up
+  #define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition detected
+  #define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended register capable
+
+#define PHY_ANAR                        4       ///<  Autonegotiation advertisement register
+  #define AN_NP                           0x8000  ///<  1 = Next page available
+  #define AN_RF                           0x2000  ///<  1 = Remote fault indicated by link partner
+  #define AN_FCS                          0x0400  ///<  1 = Flow control ability
+  #define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
+  #define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
+  #define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
+  #define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
+  #define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
+  #define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/CD support
+
+#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter ability register
+
+#define PHY_PHYSR                       0x11
+  #define PHYSR_SPEED_MASK                0xC000
+  #define PHYSR_1000                      0x8000
+  #define PHYSR_100                       0x4000
+  #define PHYSR_FULLDUP                   0x2000
+  #define PHYSR_LINK                      0x400
+
+EFI_STATUS
+Ax88179PhyRead (
+  IN     NIC_DEVICE *NicDevice,
+  IN     UINT8      RegisterAddress,
+  IN OUT UINT16     *PhyData
+  );
+
+EFI_STATUS
+Ax88179PhyWrite (
+  IN NIC_DEVICE *NicDevice,
+  IN UINT8      RegisterAddress,
+  IN UINT16     PhyData
+  );
+
+EFI_STATUS
+Ax88179MacRead (
+  IN            UINT8 Offset,
+  IN            UINT8 Length,
+  IN            NIC_DEVICE * NicDevice,
+  IN  OUT  VOID *Data
+  );
+
+EFI_STATUS
+Ax88179SetIInInterval (
+  IN  NIC_DEVICE *NicDevice,
+  IN  UINT8      Offset
+  );
+
+EFI_STATUS
+Ax88179MacWrite (
+  IN      UINT8      Offset,
+  IN      UINT8      Length,
+  IN      NIC_DEVICE *NicDevice,
+  IN  OUT VOID       *Data
+  );
+
+EFI_STATUS
+Ax88179MacAddressGet (
+  IN  NIC_DEVICE *NicDevice,
+  OUT UINT8      *MacAddress
+  );
+
+EFI_STATUS
+Ax88179MacAddressSet (
+  IN  NIC_DEVICE *NicDevice,
+  OUT UINT8      *MacAddress
+  );
+
+BOOLEAN
+Ax88179GetLinkStatus (
+  IN NIC_DEVICE *NicDevice
+);
+
+EFI_STATUS
+Ax88179BulkIn(
+  IN NIC_DEVICE *NicDevice
+);
+
+
+#endif  //  AX88179_H_
diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.c b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.c
new file mode 100644
index 000000000000..a2af3c5618d1
--- /dev/null
+++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.c
@@ -0,0 +1,1042 @@
+ /** @file
+  Implement the interface to the AX88179 Ethernet controller.
+
+  This module implements the interface to the ASIX AX88179
+  USB to Ethernet MAC with integrated 10/100 PHY.  Note that this implementation
+  only supports the integrated PHY since no other test cases were available.
+
+  Copyright (c) 2011, Intel Corporation
+  Copyright (c) 2020, ARM Limited. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88179.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
+Ax88179Crc (
+  IN UINT8 *MacAddress
+  )
+{
+  UINT32 BitNumber;
+  INT32  Carry;
+  INT32  Crc;
+  UINT32 Data;
+  UINT8  *End;
+
+  //
+  //  Walk the MAC address
+  //
+  Crc = -1;
+  End = &MacAddress[PXE_HWADDR_LEN_ETHER];
+  while (End > MacAddress) {
+    Data = *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 = 0; 8 > BitNumber; BitNumber++) {
+      Carry = ((Crc >> 31) & 1) ^ (Data & 1);
+      Crc <<= 1;
+      if (Carry != 0) {
+        Crc ^= 0x04c11db7;
+      }
+      Data >>= 1;
+    }
+  }
+
+  //
+  //  Return the CRC value
+  //
+  return (UINT32) Crc;
+}
+
+/**
+  Get the MAC address
+
+  This routine calls ::Ax88179UsbCommand 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 the MAC address.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88179MacAddressGet (
+  IN  NIC_DEVICE *NicDevice,
+  OUT UINT8      *MacAddress
+  )
+{
+  EFI_STATUS Status;
+
+  Status  = Ax88179MacRead (NODE_ID,
+                            PXE_HWADDR_LEN_ETHER,
+                            NicDevice,
+                            MacAddress);
+
+  return Status;
+}
+
+/**
+  Set the MAC address
+
+  This routine calls ::Ax88179UsbCommand 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
+Ax88179MacAddressSet (
+  IN  NIC_DEVICE *NicDevice,
+  OUT UINT8      *MacAddress
+  )
+{
+  EFI_STATUS Status;
+
+  Status  = Ax88179MacWrite (NODE_ID,
+                             PXE_HWADDR_LEN_ETHER,
+                             NicDevice,
+                             MacAddress);
+
+  return Status;
+}
+
+/**
+  Clear the multicast hash table
+
+  @param [in] NicDevice       Pointer to the NIC_DEVICE structure
+
+**/
+VOID
+Ax88179MulticastClear (
+  IN NIC_DEVICE *NicDevice
+  )
+{
+  int Index = 0;
+  //
+  // Clear the multicast hash table
+  //
+  for (Index = 0 ; Index < 8 ; Index ++)
+    NicDevice->MulticastHash[Index] = 0;
+}
+
+/**
+  Enable a multicast address in the multicast hash table
+
+  This routine calls ::Ax88179Crc 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
+Ax88179MulticastSet (
+  IN NIC_DEVICE *NicDevice,
+  IN UINT8      *MacAddress
+  )
+{
+  UINT32 Crc;
+
+  //
+  // Compute the CRC on the destination address
+  //
+  Crc = Ax88179Crc (MacAddress) >> 26;
+
+  //
+  //  Set the bit corresponding to the destination address
+  //
+  NicDevice->MulticastHash [Crc >> 3] |= (1 << (Crc & 7));
+
+}
+
+/**
+  Start the link negotiation
+
+  This routine calls ::Ax88179PhyWrite 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
+Ax88179NegotiateLinkStart (
+  IN NIC_DEVICE *NicDevice
+  )
+{
+  UINT16     Control = 0;
+  EFI_STATUS Status;
+
+#if FORCE_100Mbps
+  Ax88179PhyRead (NicDevice,
+                   0x09,
+                   &Control);
+  Control &= 0xFCFF;
+  Ax88179PhyWrite (NicDevice, 0x09, Control);
+#endif
+
+  //
+  // Set the link speed and duplex
+  //
+  Control = BMCR_AUTONEGOTIATION_ENABLE
+          | BMCR_RESTART_AUTONEGOTIATION;
+  if (NicDevice->LinkSpeed1000Mbps) {
+    Control |= BMCR_1000MBPS;
+  } else if (NicDevice->LinkSpeed100Mbps) {
+    Control |= BMCR_100MBPS;
+  }
+
+  if (NicDevice->FullDuplex) {
+    Control |= BMCR_FULL_DUPLEX;
+  }
+  Status = Ax88179PhyWrite (NicDevice, PHY_BMCR, Control);
+  if (!EFI_ERROR(Status))
+    gBS->Stall(3000000);
+  //
+  // Return the operation status
+  //
+  return Status;
+}
+
+
+
+/**
+  Complete the negotiation of the PHY link
+
+  This routine calls ::Ax88179PhyRead 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 was polled
+  @param [out] Complete      Address of boolean to receive complate status.
+  @param [out] LinkUp        Address of boolean to receive link status, TRUE=up.
+  @param [out] HiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
+  @param [out] FullDuplex    Address of boolean to receive link duplex, TRUE=full.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88179NegotiateLinkComplete (
+  IN     NIC_DEVICE *NicDevice,
+  IN OUT UINTN      *PollCount,
+  OUT    BOOLEAN    *Complete,
+  OUT    BOOLEAN    *LinkUp,
+  OUT    BOOLEAN    *HiSpeed,
+  OUT    BOOLEAN    *GigaSpeed,
+  OUT    BOOLEAN    *FullDuplex
+  )
+{
+  UINT16      PhyData;
+  EFI_STATUS  Status;
+
+  //
+  //  Determine if the link is up.
+  //
+  *Complete = FALSE;
+
+  //
+  //  Get the link status
+  //
+  Status = Ax88179PhyRead (NicDevice,
+                            PHY_PHYSR,
+                            &PhyData);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  *LinkUp = ((PhyData & PHYSR_LINK) != 0);
+  if (*LinkUp) {
+    //
+    //  Determine if the autonegotiation is complete.
+    //
+    Status = Ax88179PhyRead (NicDevice,
+                          PHY_BMSR,
+                          &PhyData);
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+
+    *Complete = ((PhyData & BMSR_AUTONEG_CMPLT) != 0);
+
+    if (*Complete != 0) {
+      //
+      //  Get the partners capabilities.
+      //
+      Status = Ax88179PhyRead (NicDevice,
+                                PHY_PHYSR,
+                                &PhyData);
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+
+      //
+      //  Autonegotiation is complete
+      //  Determine the link speed.
+      //
+      *GigaSpeed = ((PhyData & PHYSR_SPEED_MASK) == PHYSR_1000);
+      *HiSpeed = ((PhyData & PHYSR_SPEED_MASK) == PHYSR_100);
+
+      //
+      //  Determine the link duplex.
+      //
+      *FullDuplex = ((PhyData & PHYSR_FULLDUP) == PHYSR_FULLDUP);
+    }
+  }
+
+
+  //
+  // Return the operation status
+  //
+  return Status;
+}
+
+
+/**
+  Read a register from the PHY
+
+  This routine calls ::Ax88179UsbCommand 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 register value
+
+  @retval EFI_SUCCESS          The PHY data is available.
+  @retval other                The PHY data is not valid.
+
+**/
+EFI_STATUS
+Ax88179PhyRead (
+  IN     NIC_DEVICE *NicDevice,
+  IN     UINT8      RegisterAddress,
+  IN OUT UINT16     *PhyData
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS         Status;
+
+  //
+  //  Read the PHY register address.
+  //
+  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                       | USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = ACCESS_PHY;
+  SetupMsg.Value = NicDevice->PhyId;
+  SetupMsg.Index = RegisterAddress;
+  SetupMsg.Length = sizeof (*PhyData);
+  Status = Ax88179UsbCommand (NicDevice,
+                               &SetupMsg,
+                               PhyData);
+
+  //
+  //  Return the operation status.
+  //
+  return Status;
+}
+
+
+/**
+  Write to a PHY register
+
+  This routine calls ::Ax88179UsbCommand 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 register value
+
+  @retval EFI_SUCCESS          The PHY data was written.
+  @retval other                Failed to wwrite the PHY register.
+
+**/
+EFI_STATUS
+Ax88179PhyWrite (
+  IN NIC_DEVICE *NicDevice,
+  IN UINT8      RegisterAddress,
+  IN UINT16     PhyData
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS         Status;
+
+  //
+  //  Write the PHY register
+  //
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = ACCESS_PHY;
+  SetupMsg.Value = NicDevice->PhyId;
+  SetupMsg.Index = RegisterAddress;
+  SetupMsg.Length = sizeof (PhyData);
+  Status = Ax88179UsbCommand (NicDevice,
+                               &SetupMsg,
+                               &PhyData);
+  //
+  //  Return the operation status.
+  //
+  return Status;
+}
+
+
+/**
+  Reset the AX88179
+
+  This routine uses ::Ax88179UsbCommand to reset the network
+  adapter.  This routine also uses ::Ax88179PhyWrite 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
+Ax88179Reset (
+  IN NIC_DEVICE *NicDevice
+  )
+{
+  EFI_STATUS Status;
+  UINT16     Val;
+  UINT8      Val8;
+
+  Status = Ax88179SetIInInterval(NicDevice, 0xff);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  Val8 = 0;
+  Status  = Ax88179MacRead (PLSR,
+                            sizeof(Val8),
+                            NicDevice,
+                            &Val8);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  if (Val8 & PLSR_USB_SS)
+    NicDevice->UsbMaxPktSize = 1024;
+  else
+    NicDevice->UsbMaxPktSize = 512;
+
+  Val = 0;
+  Status = Ax88179MacWrite (PHYPWRRSTCTL,
+                             sizeof (Val),
+                             NicDevice,
+                             &Val);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  gBS->Stall (10000);
+
+  Val =  PHYPWRRSTCTL_IPRL;
+  Status = Ax88179MacWrite (PHYPWRRSTCTL,
+                             sizeof (Val),
+                             NicDevice,
+                             &Val);
+
+  if (EFI_ERROR(Status)){
+    goto err;
+  }
+
+  gBS->Stall (200000);
+
+  Val = CLKSELECT_BCS | CLKSELECT_ACS;
+  Status = Ax88179MacWrite (CLKSELECT,
+                             1,
+                             NicDevice,
+                             &Val);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  gBS->Stall (100000);
+
+  Val = 0x52;
+  Status = Ax88179MacWrite (PAUSE_WATERLVL_HIGH,
+                             1,
+                             NicDevice,
+                             &Val);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  Val = 0x34;
+  Status = Ax88179MacWrite (PAUSE_WATERLVL_LOW,
+                             1,
+                             NicDevice,
+                             &Val);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  Val = RXBINQCTRL_TIMEN | RXBINQCTRL_IFGEN | RXBINQCTRL_SIZEN;
+
+  Status =  Ax88179MacWrite (RXBINQCTRL,
+                              0x01,
+                              NicDevice,
+                              &Val);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  Val = 0;
+  Status =  Ax88179MacWrite (RXBINQTIMERL,
+                              0x01,
+                              NicDevice,
+                              &Val);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  Val = 0;
+  Status =  Ax88179MacWrite (RXBINQTIMERH,
+                              0x01,
+                              NicDevice,
+                              &Val);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  Val = 12; //AX88179_BULKIN_SIZE_INK - 1;
+  Status =  Ax88179MacWrite (RXBINQSIZE,
+                              0x01,
+                              NicDevice,
+                              &Val);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  Val = 0x0F;
+  Status =  Ax88179MacWrite (RXBINQIFG,
+                              0x01,
+                              NicDevice,
+                              &Val);
+
+err:
+  return Status;
+}
+
+EFI_STATUS
+Ax88179RxControl (
+  IN NIC_DEVICE *NicDevice,
+  IN UINT32     RxFilter
+  )
+{
+  UINT16     MediumStatus;
+  UINT16     RxControl = 0;
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  //
+  // Enable the receiver if something is to be received
+  //
+  if (RxFilter != 0) {
+    //
+    //  Enable the receiver
+    //
+    Status  = Ax88179MacRead (MEDIUMSTSMOD,
+                              sizeof (MediumStatus),
+                              NicDevice,
+                              &MediumStatus);
+
+    if (!EFI_ERROR (Status) && NicDevice->CurMediumStatus != MediumStatus) {
+        MediumStatus = MEDIUMSTSMOD_RE | MEDIUMSTSMOD_ONE;
+        if (NicDevice->FullDuplex) {
+          MediumStatus |= MEDIUMSTSMOD_TFC | MEDIUMSTSMOD_RFC | MEDIUMSTSMOD_FD;
+        } else {
+          MediumStatus &= ~(MEDIUMSTSMOD_TFC | MEDIUMSTSMOD_RFC | MEDIUMSTSMOD_FD);
+        }
+        if (NicDevice->LinkSpeed1000Mbps) {
+          MediumStatus |= MEDIUMSTSMOD_GM;
+          MediumStatus |= MEDIUMSTSMOD_ENCK;
+          MediumStatus &= ~MEDIUMSTSMOD_PS;
+        } else {
+          MediumStatus &= ~MEDIUMSTSMOD_GM;
+          MediumStatus &= ~MEDIUMSTSMOD_ENCK;
+          if (NicDevice->LinkSpeed100Mbps) {
+            MediumStatus |= MEDIUMSTSMOD_PS;
+          }  else {
+            MediumStatus &= ~MEDIUMSTSMOD_PS;
+          }
+        }
+        Status  = Ax88179MacWrite (MEDIUMSTSMOD,
+                                   sizeof (MediumStatus),
+                                   NicDevice,
+                                   &MediumStatus);
+        if (!EFI_ERROR (Status)) {
+          NicDevice->CurMediumStatus = MediumStatus;
+        }
+    }
+  }
+
+  RxControl = RXCTL_SO | RXCTL_IPE;
+
+  //
+  //  Enable multicast if requested
+  //
+  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
+    RxControl |= RXCTL_AM;
+    //
+    //  Update the multicast hash table
+    //
+    Status  = Ax88179MacWrite (MULCATFLTARRY,
+                               8,
+                               NicDevice,
+                               &NicDevice->MulticastHash);
+  }
+
+  //
+  //  Enable all multicast if requested
+  //
+  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
+    RxControl |= RXCTL_AMALL;
+  }
+  //
+  //  Enable broadcast if requested
+  //
+  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
+    RxControl |= RXCTL_AB;
+  }
+
+  //
+  //  Enable promiscuous mode if requested
+  //
+  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
+    RxControl |= RXCTL_PRO;
+  }
+
+  //
+  //  Update the receiver control
+  //
+  if (NicDevice->CurRxControl != RxControl) {
+    Status  = Ax88179MacWrite (RXCTL,
+                               0x02,
+                               NicDevice,
+                               &RxControl);
+    if (!EFI_ERROR (Status))
+      NicDevice->CurRxControl = RxControl;
+  }
+
+  //
+  // Return the operation status
+  //
+  return Status;
+}
+
+EFI_STATUS
+Ax88179ReloadSrom  (
+  IN NIC_DEVICE *NicDevice
+ )
+{
+  EFI_STATUS Status;
+
+  Status = EFI_UNSUPPORTED;
+  return Status;
+
+}
+
+/**
+  Read an SROM location
+
+  This routine calls ::Ax88179UsbCommand 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
+Ax88179SromRead (
+  IN  NIC_DEVICE *NicDevice,
+  IN  UINT32     Address,
+  OUT UINT16     *Data
+  )
+{
+  EFI_STATUS Status;
+
+  Status = EFI_UNSUPPORTED;
+  return Status;
+}
+
+EFI_STATUS
+Ax88179EnableSromWrite  (
+  IN NIC_DEVICE *NicDevice
+  )
+{
+  EFI_STATUS Status;
+
+  Status = EFI_UNSUPPORTED;
+  return Status;
+}
+
+
+EFI_STATUS
+Ax88179DisableSromWrite  (
+  IN NIC_DEVICE *NicDevice
+  )
+{
+  EFI_STATUS Status;
+
+  Status = EFI_UNSUPPORTED;
+  return Status;
+}
+
+/**
+  Write an SROM location
+
+  This routine calls ::Ax88179UsbCommand 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
+Ax88179SromWrite (
+  IN NIC_DEVICE *NicDevice,
+  IN UINT32     Address,
+  IN UINT16     *Data
+  )
+{
+  EFI_STATUS Status;
+
+  Status = EFI_UNSUPPORTED;
+  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
+Ax88179UsbCommand (
+  IN     NIC_DEVICE         *NicDevice,
+  IN     USB_DEVICE_REQUEST *Request,
+  IN OUT VOID               *Buffer
+  )
+{
+  EFI_USB_DATA_DIRECTION Direction;
+  EFI_USB_IO_PROTOCOL    *UsbIo;
+  EFI_STATUS             Status = EFI_TIMEOUT;
+  UINT32                 CmdStatus = EFI_USB_NOERROR;
+  int                    i;
+  //
+  // Determine the transfer direction
+  //
+  Direction = EfiUsbNoData;
+  if (Request->Length != 0) {
+    Direction = ((Request->RequestType & USB_ENDPOINT_DIR_IN) != 0)
+                        ? EfiUsbDataIn : EfiUsbDataOut;
+  }
+
+  //
+  // Issue the command
+  //
+  UsbIo = NicDevice->UsbIo;
+
+  for (i = 0 ; i < 3 && EFI_TIMEOUT == Status; i++) {
+    Status = UsbIo->UsbControlTransfer (UsbIo,
+                                        Request,
+                                        Direction,
+                                        USB_BUS_TIMEOUT,
+                                        Buffer,
+                                        Request->Length,
+                                        &CmdStatus);
+  }
+  //
+  // Determine the operation status
+  //
+  if (EFI_ERROR(Status) || EFI_ERROR(CmdStatus))
+    Status = EFI_DEVICE_ERROR;
+  //
+  // Return the operation status
+  //
+  return Status;
+}
+
+EFI_STATUS
+Ax88179MacRead (
+  IN       UINT8      Offset,
+  IN       UINT8      Length,
+  IN       NIC_DEVICE *NicDevice,
+  IN  OUT  VOID       *Data
+  )
+{
+
+  EFI_STATUS         Status;
+  USB_DEVICE_REQUEST SetupMsg;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE
+                       | USB_ENDPOINT_DIR_IN;
+
+  SetupMsg.Request = ACCESS_MAC;
+  SetupMsg.Value  = Offset;
+  SetupMsg.Index  = Length;
+  SetupMsg.Length = SetupMsg.Index;
+
+  Status = Ax88179UsbCommand (NicDevice,
+                               &SetupMsg,
+                               Data);
+
+  return Status;
+
+}
+
+EFI_STATUS
+Ax88179MacWrite (
+  IN       UINT8      Offset,
+  IN       UINT8      Length,
+  IN       NIC_DEVICE *NicDevice,
+  IN  OUT  VOID       *Data
+ )
+{
+
+  EFI_STATUS         Status;
+  USB_DEVICE_REQUEST SetupMsg;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+
+  SetupMsg.Request = ACCESS_MAC;
+  SetupMsg.Value  = Offset;
+  SetupMsg.Index  = Length;
+  SetupMsg.Length = SetupMsg.Index;
+
+  Status = Ax88179UsbCommand (NicDevice,
+                               &SetupMsg,
+                               Data);
+
+  return Status;
+
+}
+
+EFI_STATUS
+Ax88179SetIInInterval (
+  IN  NIC_DEVICE *NicDevice,
+  IN  UINT8      Interval
+ )
+{
+
+  EFI_STATUS         Status;
+  USB_DEVICE_REQUEST SetupMsg;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+
+  SetupMsg.Request = 0x91;
+  SetupMsg.Value  = Interval;
+  SetupMsg.Index  = 0;
+  SetupMsg.Length = 0;
+
+  Status = Ax88179UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  return Status;
+
+}
+
+EFI_STATUS
+Ax88179SetMedium (
+  IN NIC_DEVICE *NicDevice
+ )
+{
+  UINT16     MediumStatus;
+  EFI_STATUS Status;
+
+  MediumStatus = MEDIUMSTSMOD_RE | MEDIUMSTSMOD_ONE;
+  if (NicDevice->FullDuplex) {
+    MediumStatus |= MEDIUMSTSMOD_TFC | MEDIUMSTSMOD_RFC | MEDIUMSTSMOD_FD;
+  } else {
+    MediumStatus &= ~(MEDIUMSTSMOD_TFC | MEDIUMSTSMOD_RFC | MEDIUMSTSMOD_FD);
+  }
+  if (NicDevice->LinkSpeed1000Mbps) {
+    MediumStatus |= MEDIUMSTSMOD_GM;
+    MediumStatus &= ~MEDIUMSTSMOD_PS;
+  } else {
+    MediumStatus &= ~MEDIUMSTSMOD_GM;
+    if (NicDevice->LinkSpeed100Mbps) {
+      MediumStatus |= MEDIUMSTSMOD_PS;
+    } else {
+      MediumStatus &= ~MEDIUMSTSMOD_PS;
+    }
+  }
+  Status  = Ax88179MacWrite (MEDIUMSTSMOD,
+                             sizeof (MediumStatus),
+                             NicDevice,
+                             &MediumStatus);
+  if (!EFI_ERROR (Status)) {
+    NicDevice->CurMediumStatus = MediumStatus;
+  }
+
+  return Status;
+}
+
+
+BOOLEAN
+Ax88179GetLinkStatus (
+  IN NIC_DEVICE *NicDevice
+)
+{
+  UINT32              CmdStatus;
+  EFI_USB_IO_PROTOCOL *UsbIo;
+  UINT64              IntData = 0;
+  UINTN               IntDataLeng = 8;
+  EFI_STATUS          Status;
+
+  //
+  // Issue the command
+  //
+  UsbIo = NicDevice->UsbIo;
+  Status = UsbIo->UsbSyncInterruptTransfer(UsbIo,
+                                        USB_ENDPOINT_DIR_IN | INTERRUPT_ENDPOINT,
+                                        &IntData,
+                                        &IntDataLeng,
+                                        USB_BUS_TIMEOUT,
+                                        &CmdStatus);
+
+  if (EFI_ERROR(Status) || EFI_ERROR(CmdStatus) || 0 == IntDataLeng)
+    return FALSE;
+
+  return (IntData & 0x10000)? TRUE : FALSE;
+
+}
+
+EFI_STATUS
+Ax88179BulkIn(
+  IN NIC_DEVICE *NicDevice
+)
+{
+  int i;
+  UINT16  Val;
+  UINTN               LengthInBytes = 0;
+  UINTN               TmpLen = AX88179_MAX_BULKIN_SIZE;
+  UINTN               CURBufSize = AX88179_MAX_BULKIN_SIZE;
+  UINTN               PREBufSize = 0;
+  EFI_STATUS          Status = EFI_NOT_READY;
+  EFI_USB_IO_PROTOCOL *UsbIo;
+  UINT32 TransferStatus;
+
+  NicDevice->SkipRXCnt = 0;
+
+  UsbIo = NicDevice->UsbIo;
+  for (i = 0 ; i < (AX88179_MAX_BULKIN_SIZE / 512) && UsbIo != NULL; i++) {
+    VOID* TmpAddr = 0;
+
+    if (NicDevice->SetZeroLen) {
+      Val =  PHYPWRRSTCTL_IPRL | PHYPWRRSTCTL_BZ;
+      Status = Ax88179MacWrite (PHYPWRRSTCTL,
+                                 sizeof (Val),
+                                 NicDevice,
+                                 &Val);
+      if (EFI_ERROR(Status)) {
+        LengthInBytes = 0;
+        Status = EFI_NOT_READY;
+        goto no_pkt;
+      }
+      NicDevice->SetZeroLen = FALSE;
+    }
+    TmpAddr = (VOID*) &NicDevice->BulkInbuf[LengthInBytes];
+
+    Status =  EFI_NOT_READY;
+    Status = UsbIo->UsbBulkTransfer (UsbIo,
+                          USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
+                          TmpAddr,
+                          &TmpLen,
+                          BULKIN_TIMEOUT,
+                          &TransferStatus);
+
+    if ((!EFI_ERROR (Status)) && (!EFI_ERROR (TransferStatus)) && TmpLen != 0) {
+      LengthInBytes += TmpLen;
+      if ((TmpLen % NicDevice->UsbMaxPktSize) != 0) {
+        goto done;
+      }
+      CURBufSize = CURBufSize - TmpLen;
+      TmpLen = CURBufSize;
+      NicDevice->SetZeroLen = TRUE;
+    } else if ((!EFI_ERROR (Status)) &&
+               (!EFI_ERROR (TransferStatus)) &&
+               (TmpLen == 0) &&
+               LengthInBytes) {
+      if (PREBufSize == CURBufSize) {
+        goto done;
+      }
+      TmpLen = CURBufSize;
+      PREBufSize = CURBufSize;
+      NicDevice->SetZeroLen = TRUE;
+    } else if ((!EFI_ERROR (Status)) &&
+               (!EFI_ERROR (TransferStatus)) &&
+               (TmpLen == 0)) {
+      NicDevice->SetZeroLen = TRUE;
+      LengthInBytes = 0;
+      Status = EFI_NOT_READY;
+      goto done;
+    } else if (EFI_TIMEOUT == Status && EFI_USB_ERR_TIMEOUT == TransferStatus) {
+      NicDevice->SetZeroLen = TRUE;
+      LengthInBytes = 0;
+      Status = EFI_NOT_READY;
+      goto done;
+    } else {
+      NicDevice->SetZeroLen = TRUE;
+      LengthInBytes = 0;
+      Status = EFI_NOT_READY;
+      goto done;
+    }
+  }
+
+done:
+  if (LengthInBytes != 0) {
+    UINT16 tmplen = 0;
+    UINT16 TmpPktCnt = 0;
+
+    TmpPktCnt = *((UINT16 *) (NicDevice->BulkInbuf + LengthInBytes - 4));
+    tmplen =  *((UINT16*) (NicDevice->BulkInbuf + LengthInBytes - 2));
+
+    if (((UINTN)(((TmpPktCnt * 4 + 4 + 7) & 0xfff8) + tmplen)) == LengthInBytes) {
+      NicDevice->PktCnt = TmpPktCnt;
+      NicDevice->CurPktHdrOff = NicDevice->BulkInbuf + tmplen;
+      NicDevice->CurPktOff = NicDevice->BulkInbuf;
+      *((UINT16 *) (NicDevice->BulkInbuf + LengthInBytes - 4)) = 0;
+      *((UINT16*) (NicDevice->BulkInbuf + LengthInBytes - 2)) = 0;
+      Status = EFI_SUCCESS;
+    } else {
+      Status = EFI_NOT_READY;
+    }
+  } else {
+    Status = EFI_NOT_READY;
+  }
+no_pkt:
+   return Status;
+}
diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/ComponentName.c b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/ComponentName.c
new file mode 100644
index 000000000000..daf917ce5b7d
--- /dev/null
+++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/ComponentName.c
@@ -0,0 +1,223 @@
+/** @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 "Ax88179.h"
+
+/**
+  EFI Component Name Protocol declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {
+  GetDriverName,
+  GetControllerName,
+  "eng"
+};
+
+/**
+  EFI Component Name 2 Protocol declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
+  "en"
+};
+
+
+/**
+  Driver name table declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
+mDriverNameTable[] = {
+  {"eng;en", L"ASIX AX88179 Ethernet Driver 2.9.0"},
+  {NULL,  NULL}
+};
+
+/**
+  Controller name table declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
+mControllerNameTable[] = {
+  {"eng;en", L"AX88179 USB3.0 Gigabit Ethernet Controller"},
+  {NULL,  NULL}
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] Language         A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+  @param [out] 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 specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
+  IN  CHAR8                       *Language,
+  OUT CHAR16                      **DriverName
+  )
+{
+  EFI_STATUS Status;
+
+
+  Status = LookupUnicodeString2 (
+             Language,
+             This->SupportedLanguages,
+             mDriverNameTable,
+             DriverName,
+             (BOOLEAN)(This == &gComponentName)
+             );
+
+  return Status;
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] ControllerHandle  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+  @param [in] ChildHandle       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+  @param [in] Language         A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+  @param [out] 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 driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+
+
+
+EFI_STATUS
+EFIAPI
+GetControllerName (
+  IN          EFI_COMPONENT_NAME_PROTOCOL *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 != NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check Controller's handle
+  //
+  Status = 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 != EFI_ALREADY_STARTED) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status =  LookupUnicodeString2 (
+           Language,
+            This->SupportedLanguages,
+           mControllerNameTable,
+           ControllerName,
+           (BOOLEAN)(This == &gComponentName)
+           );
+
+  return  Status;
+}
+
diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/DriverBinding.c b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/DriverBinding.c
new file mode 100644
index 000000000000..7a287cfbfb5d
--- /dev/null
+++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/DriverBinding.c
@@ -0,0 +1,639 @@
+/** @file
+  Implement the driver binding protocol for Asix AX88179 Ethernet driver.
+
+  Copyright (c) 2011, Intel Corporation
+  Copyright (c) 2020, ARM Limited. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88179.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 = 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 transport
+    //  protocol handler.
+    //
+    Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &Device);
+    if (EFI_ERROR(Status)) {
+      Status = EFI_UNSUPPORTED;
+    } else {
+      //
+      //  Validate the adapter
+      //
+      if ((VENDOR_ID == Device.IdVendor) &&
+          (PRODUCT_ID == Device.IdProduct)) {
+        Status = EFI_SUCCESS;
+      } else if ((VENDOR_ID == Device.IdVendor) &&
+                 (PRODUCT_ID_178A == Device.IdProduct)) {
+        Status = EFI_SUCCESS;
+      } else {
+        Status = 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 protocols.
+  Initialize PXE structures, create a copy of the Controller Device Path with the
+  NIC's MAC address apEnded to it, install the NetworkInterfaceIdentifier 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 = NULL;
+  MAC_ADDR_DEVICE_PATH      MacDeviceNode;
+
+  //
+  //  Allocate the device structure
+  //
+  LengthInBytes = sizeof (*NicDevice);
+  Status = gBS->AllocatePool (
+                  EfiBootServicesData,
+                  LengthInBytes,
+                  (VOID **) &NicDevice
+                  );
+
+  if (EFI_ERROR (Status)) {
+    goto ERR;
+  }
+
+  //
+  //  Set the structure signature
+  //
+  ZeroMem (NicDevice, LengthInBytes);
+  NicDevice->Signature = DEV_SIGNATURE;
+
+  Status = gBS->OpenProtocol (
+                    Controller,
+                    &gEfiUsbIoProtocolGuid,
+                    (VOID **) &NicDevice->UsbIo,
+                    This->DriverBindingHandle,
+                    Controller,
+                    EFI_OPEN_PROTOCOL_BY_DRIVER
+                    );
+
+  if (EFI_ERROR (Status)) {
+    goto ERR;
+  }
+
+  //
+  //  Initialize the simple network protocol
+  //
+  Status = SN_Setup (NicDevice);
+
+  if (EFI_ERROR(Status)){
+    gBS->CloseProtocol (
+              Controller,
+              &gEfiUsbIoProtocolGuid,
+              This->DriverBindingHandle,
+              Controller
+              );
+    goto ERR;
+  }
+
+  //
+  // Set Device Path
+  //
+  Status = 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 = MESSAGING_DEVICE_PATH;
+  MacDeviceNode.Header.SubType = MSG_MAC_ADDR_DP;
+
+  SetDevicePathNodeLength (&MacDeviceNode.Header, sizeof (MAC_ADDR_DEVICE_PATH));
+
+  CopyMem (&MacDeviceNode.MacAddress,
+           &NicDevice->SimpleNetworkData.CurrentAddress,
+           PXE_HWADDR_LEN_ETHER);
+
+  MacDeviceNode.IfType = NicDevice->SimpleNetworkData.IfType;
+
+  NicDevice->MyDevPath = AppendDevicePathNode (
+                                          ParentDevicePath,
+                                          (EFI_DEVICE_PATH_PROTOCOL *) &MacDeviceNode
+                                          );
+
+  NicDevice->Controller = NULL;
+
+  //
+  //  Install both the simple network and device path protocols.
+  //
+  Status = 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 = 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 != NULL) {
+    gBS->FreePool (NicDevice->BulkInbuf);
+  }
+
+  if (NicDevice->TxTest != NULL) {
+    gBS->FreePool (NicDevice->TxTest);
+  }
+
+  if (NicDevice->MyDevPath != NULL) {
+    gBS->FreePool (NicDevice->MyDevPath);
+  }
+
+  if (NicDevice != 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 device.
+
+**/
+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 = 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 == 0) {
+    Status = 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 devicepath
+      // and usbio protocol.
+      //
+      gBS->CloseProtocol (
+                Controller,
+                &gEfiDevicePathProtocolGuid,
+                This->DriverBindingHandle,
+                Controller
+                );
+      gBS->CloseProtocol (
+                Controller,
+                &gEfiUsbIoProtocolGuid,
+                This->DriverBindingHandle,
+                Controller
+                );
+      return EFI_SUCCESS;
+    }
+
+    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+    Status = gBS->UninstallMultipleProtocolInterfaces (
+                          Controller,
+                          &gEfiCallerIdGuid,
+                          NicDevice,
+                          &gEfiSimpleNetworkProtocolGuid,
+                          &NicDevice->SimpleNetwork,
+                          &gEfiDevicePathProtocolGuid,
+                          NicDevice->MyDevPath,
+                          NULL
+                          );
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    //
+    // Close the bus driver
+    //
+    Status = gBS->CloseProtocol (
+                        Controller,
+                        &gEfiDevicePathProtocolGuid,
+                        This->DriverBindingHandle,
+                        Controller
+                        );
+
+    Status = gBS->CloseProtocol (
+                        Controller,
+                        &gEfiUsbIoProtocolGuid,
+                        This->DriverBindingHandle,
+                        Controller
+                        );
+    return EFI_SUCCESS;
+  }
+
+  AllChildrenStopped = TRUE;
+
+  for (Index = 0; Index < NumberOfChildren; Index++) {
+    Status = gBS->OpenProtocol (
+                      ChildHandleBuffer[Index],
+                      &gEfiSimpleNetworkProtocolGuid,
+                      (VOID **) &SimpleNetwork,
+                      This->DriverBindingHandle,
+                      Controller,
+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                      );
+
+    if (EFI_ERROR (Status)) {
+      AllChildrenStopped = FALSE;
+      continue;
+    }
+
+    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+    gBS->CloseProtocol (
+              Controller,
+              &gEfiUsbIoProtocolGuid,
+              This->DriverBindingHandle,
+              ChildHandleBuffer[Index]
+              );
+
+    Status = gBS->UninstallMultipleProtocolInterfaces (
+                          ChildHandleBuffer[Index],
+                          &gEfiCallerIdGuid,
+                          NicDevice,
+                          &gEfiSimpleNetworkProtocolGuid,
+                          &NicDevice->SimpleNetwork,
+                          &gEfiDevicePathProtocolGuid,
+                          NicDevice->MyDevPath,
+                          NULL
+                          );
+
+    if (EFI_ERROR (Status)) {
+      Status = gBS->OpenProtocol (
+                        Controller,
+                        &gEfiUsbIoProtocolGuid,
+                        (VOID **) &NicDevice->UsbIo,
+                        This->DriverBindingHandle,
+                        ChildHandleBuffer[Index],
+                        EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+                        );
+    } else {
+      if (NicDevice->BulkInbuf != NULL) {
+        gBS->FreePool (NicDevice->BulkInbuf);
+      }
+
+      if (NicDevice->TxTest != NULL) {
+        gBS->FreePool (NicDevice->TxTest);
+      }
+
+      if (NicDevice->MyDevPath != NULL) {
+        gBS->FreePool (NicDevice->MyDevPath);
+      }
+
+      if (NicDevice != NULL) {
+        gBS->FreePool (NicDevice);
+      }
+    }
+  }
+
+  if (!AllChildrenStopped) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Driver binding protocol declaration
+**/
+EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
+  DriverSupported,
+  DriverStart,
+  DriverStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+
+/**
+  Ax88179 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 = 0;
+  Handle = NULL;
+  Status = gBS->LocateHandle (
+                  ByProtocol,
+                  &gEfiCallerIdGuid,
+                  NULL,
+                  &BufferSize,
+                  NULL);
+  if (EFI_BUFFER_TOO_SMALL == Status) {
+    for (; ;) {
+      //
+      //  One or more block IO devices are present
+      //
+      Status = gBS->AllocatePool (
+                      EfiBootServicesData,
+                      BufferSize,
+                      (VOID **) &Handle
+                      );
+      if (EFI_ERROR (Status)) {
+        break;
+      }
+
+      //
+      //  Locate the block IO devices
+      //
+      Status = gBS->LocateHandle (
+                      ByProtocol,
+                      &gEfiCallerIdGuid,
+                      NULL,
+                      &BufferSize,
+                      Handle);
+      if (EFI_ERROR (Status)) {
+        //
+        //  Error getting handles
+        //
+
+        break;
+      }
+
+      //
+      //  Remove any use of the driver
+      //
+      Max = BufferSize / sizeof (Handle[0]);
+      for (Index = 0; Max > Index; Index++) {
+        Status = DriverStop (&gDriverBinding,
+                              Handle[Index],
+                              0,
+                              NULL);
+        if (EFI_ERROR (Status)) {
+          break;
+        }
+      }
+      break;
+    }
+  } else {
+    if (EFI_NOT_FOUND == Status) {
+      //
+      //  No devices were found
+      //
+      Status = EFI_SUCCESS;
+    }
+  }
+
+  //
+  //  Free the handle array
+  //
+  if (Handle != 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;
+}
+
+
+/**
+Ax88179 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 = gBS->HandleProtocol (
+                  gImageHandle,
+                  &gEfiLoadedImageProtocolGuid,
+                  (VOID **)&LoadedImage
+                  );
+  if (!EFI_ERROR (Status)) {
+    LoadedImage->Unload = DriverUnload;
+  }
+
+  //
+  //  Add the driver to the list of drivers
+  //
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             SystemTable,
+             &gDriverBinding,
+             ImageHandle,
+             &gComponentName,
+             &gComponentName2
+             );
+
+  return Status;
+}
diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/SimpleNetwork.c b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/SimpleNetwork.c
new file mode 100644
index 000000000000..948b73031463
--- /dev/null
+++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/SimpleNetwork.c
@@ -0,0 +1,1548 @@
+/** @file
+  Provides the Simple Network functions.
+
+  Copyright (c) 2011, Intel Corporation
+  Copyright (c) 2020, ARM Limited. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ax88179.h"
+
+/**
+  This function updates the filtering on the receiver.
+
+  This support routine calls ::Ax88179MacAddressSet to update
+  the MAC address.  This routine then rebuilds the multicast
+  hash by calling ::Ax88179MulticastClear and ::Ax88179MulticastSet.
+  Finally this routine enables the receiver by calling
+  ::Ax88179RxControl.
+
+  @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 network 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 = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+  Mode = SimpleNetwork->Mode;
+  //
+  // Clear the multicast hash table
+  //
+  Ax88179MulticastClear (NicDevice);
+
+  //
+  // Load the multicast hash table
+  //
+  if ((Mode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
+    for (Index = 0; Index < Mode->MCastFilterCount; Index++) {
+      //
+      // Enable the next multicast address
+      //
+      Ax88179MulticastSet (NicDevice,
+                            &Mode->MCastFilter[Index].Addr[0]);
+    }
+  }
+
+  //
+  // Enable the receiver
+  //
+  Status = Ax88179RxControl (NicDevice, Mode->ReceiveFilterSetting);
+
+  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 ::Ax88179Rx 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 will not be read from
+                                the device.  If this is not NULL, the interrupt status will
+                                be read from teh device.  When the interrupt status is read,
+                                it will also be cleared.  Clearing the transmit interrupt
+                                does not empty the recycled transmit buffer array.
+  @param [out] TxBuf          Recycled transmit buffer address.  The network interface will
+                                not transmit if its internal recycled transmit buffer array is
+                                full.  Reading the transmit buffer does not clear the transmit
+                                interrupt.  If this is NULL, then the transmit buffer status
+                                will not be read.  If there are not transmit buffers to recycle
+                                and TxBuf is not NULL, *TxBuf will be set to NULL.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER 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 network 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;
+  EFI_STATUS              Status = EFI_SUCCESS;
+  EFI_TPL                 TplPrevious;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // Return the transmit buffer
+    //
+    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+    if ((TxBuf != NULL) && (NicDevice->TxBuffer != NULL)) {
+      *TxBuf = NicDevice->TxBuffer;
+      NicDevice->TxBuffer = NULL;
+    }
+
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      if ((TxBuf == NULL) && (InterruptStatus == NULL)) {
+        Status = EFI_INVALID_PARAMETER;
+        goto EXIT;
+      }
+
+#if REPORTLINK
+#else
+      if (!NicDevice->LinkUp || !NicDevice->Complete) {
+#endif
+        Status = Ax88179NegotiateLinkComplete (NicDevice,
+                                                &NicDevice->PollCount,
+                                                &NicDevice->Complete,
+                                                &NicDevice->LinkUp,
+                                                &NicDevice->LinkSpeed100Mbps,
+                                                &NicDevice->LinkSpeed1000Mbps,
+                                                &NicDevice->FullDuplex);
+
+        if (EFI_ERROR(Status))
+          goto EXIT;
+#if REPORTLINK
+        if (NicDevice->LinkUp && NicDevice->Complete) {
+          Mode->MediaPresent = TRUE;
+          Status = Ax88179SetMedium (NicDevice);
+        } else {
+          Mode->MediaPresent = FALSE;
+        }
+#else
+        if (NicDevice->LinkUp && NicDevice->Complete) {
+          Mode->MediaPresent = TRUE;
+          Mode->MediaPresentSupported = FALSE;
+          Status = Ax88179SetMedium (NicDevice);
+
+        }
+      }
+#endif
+    } else {
+      if (EfiSimpleNetworkStarted == Mode->State) {
+        Status = EFI_DEVICE_ERROR;
+      } else {
+        Status = EFI_NOT_STARTED ;
+      }
+    }
+  } else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  if (InterruptStatus != NULL) {
+    *InterruptStatus = 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 write operations.
+  @param [in] Offset            Byte offset in the NVRAM device at which to start the
+                                read or write operation.  This must be a multiple of
+                                NvRamAccessSize and less than NvRamSize.
+  @param [in] BufferSize        The number of bytes to read or write from the NVRAM device.
+                                This must also be a multiple of NvramAccessSize.
+  @param [in, out] 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 network 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 = EFI_INVALID_PARAMETER;
+  EFI_TPL                 TplPrevious;
+  EFI_SIMPLE_NETWORK_MODE *Mode;
+  NIC_DEVICE              *NicDevice;
+  UINTN                   Index;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  if ((SimpleNetwork == NULL) || (SimpleNetwork->Mode == NULL)) {
+    Status = EFI_INVALID_PARAMETER;
+    goto  EXIT;
+  }
+
+  NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+  Mode = SimpleNetwork->Mode;
+
+  if (EfiSimpleNetworkInitialized != Mode->State) {
+    Status = EFI_NOT_STARTED;
+    goto  EXIT;
+  }
+
+  if (Offset != 0) {
+    if (((Offset % Mode->NvRamAccessSize) != 0) || (Offset >= Mode->NvRamSize)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto  EXIT;
+    }
+  }
+  //
+  // Offset must be a multiple of NvRamAccessSize and less than NvRamSize.
+  //
+  if ((BufferSize % Mode->NvRamAccessSize) != 0) {
+    Status = EFI_INVALID_PARAMETER;
+    goto  EXIT;
+  }
+
+  if (BufferSize + Offset > Mode->NvRamSize) {
+    Status = EFI_INVALID_PARAMETER;
+    goto  EXIT;
+  }
+
+  if (Buffer == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto  EXIT;
+  }
+
+  //
+  // ReadWrite: TRUE FOR READ FALSE FOR WRITE
+  //
+  if (ReadWrite) {
+    for (Index = 0; Index < BufferSize / 2; Index++) {
+      Status = Ax88179SromRead (NicDevice,
+                                 (UINT32)(Offset/2 + Index),
+                                 (((UINT16*)Buffer) + Index));
+    }
+  } else {
+    Status = Ax88179EnableSromWrite(NicDevice);
+    if (EFI_ERROR(Status))
+      goto EXIT;
+
+    for (Index = 0; Index < BufferSize / 2; Index++) {
+      Status = Ax88179SromWrite (NicDevice,
+                                  (UINT32)(Offset/2 + Index),
+                                  (((UINT16*)Buffer) + Index));
+    }
+
+    Status = Ax88179DisableSromWrite(NicDevice);
+
+    if (BufferSize == 272)
+      Status = Ax88179ReloadSrom(NicDevice);
+  }
+
+  //
+  // Return the operation status
+  //
+EXIT:
+  gBS->RestoreTPL (TplPrevious);
+  return Status;
+}
+
+/**
+  Resets the network adapter and allocates the transmit and receive buffers
+  required by the network interface; optionally, also requests allocation of
+  additional transmit and receive buffers.  This routine must be called before
+  any other routine in the Simple Network protocol is called.
+
+  @param [in] SimpleNetwork    Protocol instance pointer
+  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
+  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and receive buffers
+  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL (TPL_CALLBACK);
+
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // Determine if the interface is already started
+    //
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkStarted == Mode->State) {
+      if ((0 == ExtraRxBufferSize) && (0 == ExtraTxBufferSize)) {
+        //
+        // Start the adapter
+        //
+        TmpState = Mode->State;
+        Mode->State = EfiSimpleNetworkInitialized;
+        Status = SN_Reset (SimpleNetwork, FALSE);
+        if (EFI_ERROR (Status)) {
+          //
+          // Update the network state
+          //
+          Mode->State = TmpState;
+        } else {
+          Mode->MediaPresentSupported = TRUE;
+          NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+          Mode->MediaPresent = Ax88179GetLinkStatus (NicDevice);
+        }
+      } else {
+        Status = EFI_UNSUPPORTED;
+      }
+    } else {
+      Status = EFI_NOT_STARTED;
+    }
+  } else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return the operation status
+  //
+  gBS->RestoreTPL (TplPrevious);
+  return Status;
+}
+
+
+/**
+  This function converts a multicast IP address to a multicast HW MAC address
+  for all packet transactions.
+
+  @param [in] SimpleNetwork    Protocol instance pointer
+  @param [in] IPv6             Set to TRUE if the multicast IP address is IPv6 [RFC2460].
+                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
+  @param [in] IP               The multicast IP address that is to be converted to a
+                                multicast HW MAC address.
+  @param [in] MAC              The multicast HW MAC address that is to be generated from IP.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // The interface must be running
+    //
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      if (IP == NULL || MAC == NULL) {
+        Status = EFI_INVALID_PARAMETER;
+        goto EXIT;
+      }
+      if (IPv6) {
+        Status = EFI_UNSUPPORTED;
+        goto EXIT;
+      } else {
+        //
+        // check if the ip given is a mcast IP
+        //
+        if ((IP->v4.Addr[0] & 0xF0) != 0xE0) {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        } else {
+          MAC->Addr[0] = 0x01;
+          MAC->Addr[1] = 0x00;
+          MAC->Addr[2] = 0x5e;
+          MAC->Addr[3] = (UINT8) (IP->v4.Addr[1] & 0x7f);
+          MAC->Addr[4] = (UINT8) IP->v4.Addr[2];
+          MAC->Addr[5] = (UINT8) IP->v4.Addr[3];
+          Status = EFI_SUCCESS;
+        }
+      }
+    } else {
+      if (EfiSimpleNetworkStarted == Mode->State) {
+        Status = EFI_DEVICE_ERROR;
+      } else {
+        Status = EFI_NOT_STARTED ;
+      }
+    }
+  } else {
+    Status = 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 network
+  interface.  If there are no packets on the receive queue, then EFI_NOT_READY
+  will be returned.  If there is a packet on the receive queue, and the size
+  of the packet is smaller than BufferSize, then the contents of the packet
+  will be placed in Buffer, and BufferSize will be udpated with the actual
+  size of the packet.  In addition, if SrcAddr, DestAddr, and Protocol are
+  not NULL, then these values will be extracted from the media header and
+  returned.  If BufferSize is smaller than the received packet, then the
+  size of the receive packet will be placed in BufferSize and
+  EFI_BUFFER_TOO_SMALL will be returned.
+
+  This routine calls ::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 to be filled in by
+                                the Transmit() function.  If HeaderSize is non-zero, then
+                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
+                                and DestAddr and Protocol parameters must not be NULL.
+  @param [out] BufferSize      The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [out] Buffer          A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [out] SrcAddr         The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [out] DestAddr        The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [out] Protocol        The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         No packets have been received on the network interface.
+  @retval EFI_BUFFER_TOO_SMALL  The packet is larger than BufferSize bytes.
+  @retval EFI_INVALID_PARAMETER 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 network 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;
+  EFI_STATUS              Status;
+  UINT16                  Type = 0;
+  UINT16                  CurrentPktLen;
+  BOOLEAN                 Valid = TRUE;
+  EFI_TPL                 TplPrevious;
+
+  TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // The interface must be running
+    //
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      if ((BufferSize == NULL) || (Buffer == NULL)) {
+        Status = EFI_INVALID_PARAMETER;
+        gBS->RestoreTPL (TplPrevious);
+        return Status;
+      }
+
+      //
+      // Update the link status
+      //
+      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+      if (NicDevice->LinkUp && NicDevice->Complete) {
+        if ((HeaderSize != NULL) && (*HeaderSize == 7720)) {
+          NicDevice->Grub_f = TRUE;
+        }
+
+        if ((NicDevice->Grub_f) && (*HeaderSize != 7720)) {
+          gBS->RestoreTPL (TplPrevious);
+          return EFI_NOT_READY;
+        }
+
+        //
+        //  Attempt to do bulk in
+        //
+        if (NicDevice->PktCnt == 0) {
+          Status = Ax88179BulkIn(NicDevice);
+          if (EFI_ERROR(Status))
+            goto  no_pkt;
+        }
+        CurrentPktLen = *((UINT16*) (NicDevice->CurPktHdrOff + 2));
+        if (CurrentPktLen & (RXHDR_DROP | RXHDR_CRCERR))
+          Valid = FALSE;
+        CurrentPktLen &=  0x1fff;
+        CurrentPktLen -= 2; /*EEEE*/
+
+        if (Valid && (60 <= CurrentPktLen) &&
+        ((CurrentPktLen - 14) <= MAX_ETHERNET_PKT_SIZE) &&
+            (*((UINT16*)NicDevice->CurPktOff)) == 0xEEEE) {
+          if (*BufferSize < (UINTN)CurrentPktLen) {
+            gBS->RestoreTPL (TplPrevious);
+            return EFI_BUFFER_TOO_SMALL;
+          }
+          *BufferSize = CurrentPktLen;
+          CopyMem (Buffer, NicDevice->CurPktOff + 2, CurrentPktLen);
+
+          Header = (ETHERNET_HEADER *) NicDevice->CurPktOff + 2;
+
+          if ((HeaderSize != NULL)  && ((*HeaderSize != 7720))) {
+            *HeaderSize = sizeof (*Header);
+          }
+
+          if (DestAddr != NULL) {
+            CopyMem (DestAddr, &Header->DestAddr, PXE_HWADDR_LEN_ETHER);
+          }
+          if (SrcAddr != NULL) {
+            CopyMem (SrcAddr, &Header->SrcAddr, PXE_HWADDR_LEN_ETHER);
+          }
+          if (Protocol != NULL) {
+            Type = Header->Type;
+            Type = (UINT16)((Type >> 8) | (Type << 8));
+            *Protocol = Type;
+          }
+          NicDevice->PktCnt--;
+          NicDevice->CurPktHdrOff += 4;
+          NicDevice->CurPktOff += (CurrentPktLen + 2 + 7) & 0xfff8;
+          Status = EFI_SUCCESS;
+        } else {
+          NicDevice->PktCnt = 0;
+          Status = EFI_NOT_READY;
+        }
+      } else {
+        Status = EFI_NOT_READY;
+      }
+    } else {
+      if (EfiSimpleNetworkStarted == Mode->State) {
+        Status = EFI_DEVICE_ERROR;
+      } else {
+        Status = EFI_NOT_STARTED;
+      }
+    }
+  } else {
+    Status = 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 hardware
+        a more liberal setting is selected.
+
+  If the same bits are set in the Enable and Disable parameters, then the bits
+  in the Disable parameter takes precedence.
+
+  If the ResetMCastFilter parameter is TRUE, then the multicast address list
+  filter is disabled (irregardless of what other multicast bits are set in
+  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount field
+  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
+
+  After enableing or disabling receive filter settings, software should
+  verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
+  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
+
+  Note: Some network drivers and/or devices will automatically promote
+  receive filter settings if the requested setting can not be honored.
+  For example, if a request for four multicast addresses is made and
+  the underlying hardware only supports two multicast addresses the
+  driver might set the promiscuous or promiscuous multicast receive filters
+  instead.  The receiving software is responsible for discarding any extra
+  packets that get through the hardware receive filters.
+
+  If ResetMCastFilter is TRUE, then the multicast receive filter list
+  on the network interface will be reset to the default multicast receive
+  filter list.  If ResetMCastFilter is FALSE, and this network interface
+  allows the multicast receive filter list to be modified, then the
+  MCastFilterCnt and MCastFilter are used to update the current multicast
+  receive filter list.  The modified receive filter list settings can be
+  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
+
+  This routine calls ::ReceiveFilterUpdate to update the receive
+  state in the network adapter.
+
+  @param [in] 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 TRUE.
+  @param [in] ResetMCastFilter Set to TRUE to reset the contents of the multicast receive
+                                filters on the network interface to their default values.
+  @param [in] MCastFilterCnt    Number of multicast HW MAC address in the new MCastFilter list.
+                                This value must be less than or equal to the MaxMCastFilterCnt
+                                field of EFI_SIMPLE_NETWORK_MODE.  This field is optional if
+                                ResetMCastFilter is TRUE.
+  @param [in] MCastFilter      A pointer to a list of new multicast receive filter HW MAC
+                                addresses.  This list will replace any existing multicast
+                                HW MAC address list.  This field is optional if ResetMCastFilter
+                                is TRUE.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER 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 network 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 = EFI_SUCCESS;
+  EFI_TPL                 TplPrevious;
+  UINTN                   Index;
+  UINT8                   Temp;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  Mode = SimpleNetwork->Mode;
+
+  if (SimpleNetwork == NULL) {
+    gBS->RestoreTPL(TplPrevious);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (Mode->State) {
+  case EfiSimpleNetworkInitialized:
+    break;
+
+  case EfiSimpleNetworkStopped:
+    Status = EFI_NOT_STARTED;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+
+  default:
+    Status = 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) != 0) ||
+      ((Disable &~Mode->ReceiveFilterMask) != 0)) {
+    Status = EFI_INVALID_PARAMETER;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+  }
+
+  if (ResetMCastFilter) {
+    Disable |= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & Mode->ReceiveFilterMask);
+    MCastFilterCnt = 0;
+    Mode->MCastFilterCount = 0;
+    if ((0 == (Mode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST)) &&
+   Enable == 0 && Disable == 2) {
+      gBS->RestoreTPL(TplPrevious);
+      return EFI_SUCCESS;
+    }
+  } else {
+    if (MCastFilterCnt != 0) {
+      EFI_MAC_ADDRESS * MulticastAddress;
+      MulticastAddress =  MCastFilter;
+
+      if ((MCastFilterCnt > Mode->MaxMCastFilterCount) ||
+          (MCastFilter == NULL)) {
+        Status = EFI_INVALID_PARAMETER;
+        gBS->RestoreTPL(TplPrevious);
+        return Status;
+      }
+
+      for (Index = 0 ; Index < MCastFilterCnt ; Index++) {
+          Temp = MulticastAddress->Addr[0];
+          if ((Temp & 0x01) != 0x01) {
+            gBS->RestoreTPL(TplPrevious);
+            return EFI_INVALID_PARAMETER;
+          }
+          MulticastAddress++;
+      }
+
+      Mode->MCastFilterCount = (UINT32)MCastFilterCnt;
+      CopyMem (&Mode->MCastFilter[0],
+               MCastFilter,
+               MCastFilterCnt * sizeof (EFI_MAC_ADDRESS/**MCastFilter*/));
+    }
+  }
+
+  if (Enable == 0 && Disable == 0 && !ResetMCastFilter && MCastFilterCnt == 0) {
+    Status = EFI_SUCCESS;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+  }
+
+  if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
+    Status = EFI_INVALID_PARAMETER;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+  }
+
+  Mode->ReceiveFilterSetting |= Enable;
+  Mode->ReceiveFilterSetting &= ~Disable;
+
+  Status = ReceiveFilterUpdate (SimpleNetwork);
+
+  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 ::Ax88179Reset to perform the adapter specific
+  reset operation.  This routine also starts the link negotiation
+  by calling ::Ax88179NegotiateLinkStart.
+
+  @param [in] SimpleNetwork    Protocol instance pointer
+  @param [in] ExtendedVerification  Indicates that the driver may perform a more
+                                exhaustive verification operation of the device
+                                during reset.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  //  Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      //
+      //  Update the device state
+      //
+      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+      //
+      //  Reset the device
+      //
+      if (!NicDevice->FirstRst) {
+        Status = EFI_SUCCESS;
+      } else {
+        Status = Ax88179Reset (NicDevice);
+        if (!EFI_ERROR (Status)) {
+          Status = ReceiveFilterUpdate (SimpleNetwork);
+          if (!EFI_ERROR (Status) && !NicDevice->LinkUp && NicDevice->FirstRst) {
+            Status = Ax88179NegotiateLinkStart (NicDevice);
+            NicDevice->FirstRst = FALSE;
+          }
+        }
+      }
+    } else {
+      Status = EFI_NOT_STARTED;
+    }
+  } else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  //
+  // Return the operation status
+  //
+  gBS->RestoreTPL(TplPrevious);
+  return Status;
+}
+
+/**
+  Initialize the simple network protocol.
+
+  This routine calls ::Ax88179MacAddressGet 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 = &NicDevice->SimpleNetwork;
+  SimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
+  SimpleNetwork->Start = SN_Start;
+  SimpleNetwork->Stop = SN_Stop;
+  SimpleNetwork->Initialize = SN_Initialize;
+  SimpleNetwork->Reset = SN_Reset;
+  SimpleNetwork->Shutdown = SN_Shutdown;
+  SimpleNetwork->ReceiveFilters = SN_ReceiveFilters;
+  SimpleNetwork->StationAddress = SN_StationAddress;
+  SimpleNetwork->Statistics = SN_Statistics;
+  SimpleNetwork->MCastIpToMac = SN_MCastIPtoMAC;
+  SimpleNetwork->NvData = SN_NvData;
+  SimpleNetwork->GetStatus = SN_GetStatus;
+  SimpleNetwork->Transmit = SN_Transmit;
+  SimpleNetwork->Receive = SN_Receive;
+  SimpleNetwork->WaitForPacket = NULL;
+  Mode = &NicDevice->SimpleNetworkData;
+  SimpleNetwork->Mode = Mode;
+  Mode->State = EfiSimpleNetworkStopped;
+  Mode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
+  Mode->MediaHeaderSize = sizeof (ETHERNET_HEADER);
+  Mode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
+  Mode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
+                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
+  Mode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
+  Mode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
+  Mode->MCastFilterCount = 0;
+  Mode->NvRamSize = 512;
+  Mode->NvRamAccessSize = 2;
+  SetMem (&Mode->BroadcastAddress,
+           PXE_HWADDR_LEN_ETHER,
+           0xff);
+  Mode->IfType = NET_IFTYPE_ETHERNET;
+  Mode->MacAddressChangeable = TRUE;
+  Mode->MultipleTxSupported = FALSE;
+  Mode->MediaPresentSupported = TRUE;
+  Mode->MediaPresent = FALSE;
+  //
+  //  Read the MAC address
+  //
+  NicDevice->PhyId = PHY_ID_INTERNAL;
+  NicDevice->LinkSpeed100Mbps = FALSE;
+  NicDevice->LinkSpeed1000Mbps = TRUE;
+  NicDevice->FullDuplex = TRUE;
+  NicDevice->Complete = FALSE;
+  NicDevice->LinkUp = FALSE;
+  NicDevice->Grub_f = FALSE;
+  NicDevice->FirstRst = TRUE;
+  NicDevice->PktCnt = 0;
+  NicDevice->SkipRXCnt = 0;
+  NicDevice->UsbMaxPktSize = 512;
+  NicDevice->SetZeroLen = TRUE;
+
+  Status = Ax88179MacAddressGet (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 = gBS->AllocatePool (EfiBootServicesData,
+                               AX88179_MAX_BULKIN_SIZE,
+                               (VOID **) &NicDevice->BulkInbuf);
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gBS->AllocatePool (EfiBootServicesData,
+                               sizeof (TX_PACKET),
+                               (VOID **) &NicDevice->TxTest);
+  if (EFI_ERROR (Status)) {
+    gBS->FreePool (NicDevice->BulkInbuf);
+  }
+
+  //
+  //  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 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  Status = EFI_INVALID_PARAMETER;
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkStopped == Mode->State) {
+      //
+      // Initialize the mode structure
+      // NVRAM access is not supported
+      //
+      ZeroMem (Mode, sizeof (*Mode));
+
+      Mode->State = EfiSimpleNetworkStarted;
+      Mode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
+      Mode->MediaHeaderSize = sizeof (ETHERNET_HEADER);
+      Mode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
+      Mode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
+                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
+      Mode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
+      Mode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
+      Mode->MCastFilterCount = 0;
+      Mode->NvRamSize = 512;
+      Mode->NvRamAccessSize = 2;
+      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+      Status = Ax88179MacAddressGet (NicDevice, &Mode->PermanentAddress.Addr[0]);
+      CopyMem (&Mode->CurrentAddress,
+                &Mode->PermanentAddress,
+                sizeof (Mode->CurrentAddress));
+      SetMem(&Mode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
+      Mode->IfType = NET_IFTYPE_ETHERNET;
+      Mode->MacAddressChangeable = TRUE;
+      Mode->MultipleTxSupported = FALSE;
+      Mode->MediaPresentSupported = TRUE;
+      Mode->MediaPresent = FALSE;
+
+    } else {
+      Status = 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 FALSE
+  then the current station address is changed to the address specified by
+  New.
+
+  This routine calls ::Ax88179MacAddressSet 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 network
+                                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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) &&
+      (SimpleNetwork->Mode != NULL) &&
+      ((!Reset) || (Reset && (New != NULL)))) {
+    //
+    // Verify that the adapter is already started
+    //
+    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == 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 = Ax88179MacAddressSet (NicDevice, &Mode->CurrentAddress.Addr[0]);
+    } else {
+      if (EfiSimpleNetworkStarted == Mode->State) {
+        Status = EFI_DEVICE_ERROR; ;
+      } else {
+        Status = EFI_NOT_STARTED ;
+      }
+    }
+  } else {
+    Status = 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 the network interface.
+  @param [in, out] StatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
+                                the size, in bytes, of the resulting table of statistics.
+  @param [out] StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+                                conains the statistics.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_BUFFER_TOO_SMALL  The StatisticsTable is NULL or the buffer 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  Mode = SimpleNetwork->Mode;
+
+  if (EfiSimpleNetworkInitialized == Mode->State) {
+    if ((StatisticsSize != NULL) && (*StatisticsSize == 0)) {
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto EXIT;
+    }
+
+    if(Reset) {
+      Status = EFI_SUCCESS;
+    } else {
+      Status = EFI_SUCCESS;
+    }
+  } else {
+    if (EfiSimpleNetworkStarted == Mode->State) {
+      Status = EFI_DEVICE_ERROR; ;
+    } else {
+      Status = EFI_NOT_STARTED ;
+    }
+  }
+
+  Status = EFI_UNSUPPORTED;
+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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // Determine if the interface is started
+    //
+    Mode = SimpleNetwork->Mode;
+
+    if (EfiSimpleNetworkStarted == Mode->State) {
+        Mode->State = EfiSimpleNetworkStopped;
+        Status = EFI_SUCCESS;
+    } else {
+        Status = EFI_NOT_STARTED;
+    }
+  } else {
+    Status = 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 network 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;
+  EFI_STATUS              Status;
+  NIC_DEVICE              *NicDevice;
+  EFI_TPL                 TplPrevious;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // Determine if the interface is already started
+    //
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      //
+      // Stop the adapter
+      //
+      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+      Status = Ax88179MacAddressGet (NicDevice, &Mode->PermanentAddress.Addr[0]);
+      if (!EFI_ERROR (Status)) {
+        //
+        // Update the network state
+        //
+        Mode->State = EfiSimpleNetworkStarted;
+      } else if (EFI_DEVICE_ERROR == Status) {
+        Mode->State = EfiSimpleNetworkStopped;
+      }
+
+    } else {
+      Status = EFI_NOT_STARTED;
+    }
+  } else {
+    Status = 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 ::Ax88179Rx 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 must not be NULL.
+  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [in] Buffer           A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [in] SrcAddr          The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [in] DestAddr         The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [in] Protocol         The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
+  @retval EFI_INVALID_PARAMETER 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 network 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 = 0;
+  EFI_TPL                 TplPrevious;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // The interface must be running
+    //
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      //
+      // Update the link status
+      //
+      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+      if (NicDevice->LinkUp && NicDevice->Complete) {
+        if ((HeaderSize != 0) && (Mode->MediaHeaderSize != HeaderSize))  {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        }
+        if (BufferSize <  Mode->MediaHeaderSize) {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        }
+        if (Buffer == NULL) {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        }
+        if ((HeaderSize != 0) && (DestAddr == NULL)) {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        }
+        if ((HeaderSize != 0) && (Protocol == NULL)) {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        }
+        //
+        //  Copy the packet into the USB buffer
+        //
+        // Buffer starting with 14 bytes 0
+        CopyMem (&NicDevice->TxTest->Data[0], Buffer, BufferSize);
+        NicDevice->TxTest->TxHdr1 = (UINT32) BufferSize;
+        NicDevice->TxTest->TxHdr2 = 0;
+        //
+        //  Transmit the packet
+        //
+        Header = (ETHERNET_HEADER *) &NicDevice->TxTest->Data[0];
+        if (HeaderSize != 0) {
+          if (DestAddr != NULL) {
+            CopyMem (&Header->DestAddr, DestAddr, PXE_HWADDR_LEN_ETHER);
+          }
+          if (SrcAddr != NULL) {
+            CopyMem (&Header->SrcAddr, SrcAddr, PXE_HWADDR_LEN_ETHER);
+          } else {
+            CopyMem (&Header->SrcAddr, &Mode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER);
+          }
+          if (Protocol != NULL) {
+            Type = *Protocol;
+          } else {
+              Type = (UINT16) BufferSize;
+          }
+          Type = (UINT16)((Type >> 8) | (Type << 8));
+          Header->Type = Type;
+        }
+
+        if (NicDevice->TxTest->TxHdr1 < MIN_ETHERNET_PKT_SIZE) {
+          NicDevice->TxTest->TxHdr1 = MIN_ETHERNET_PKT_SIZE;
+          ZeroMem (&NicDevice->TxTest->Data[BufferSize],
+                    MIN_ETHERNET_PKT_SIZE - BufferSize);
+        }
+
+        TransferLength = sizeof (NicDevice->TxTest->TxHdr1)
+                       + sizeof (NicDevice->TxTest->TxHdr2)
+                       + NicDevice->TxTest->TxHdr1;
+        //
+        //  Work around USB bus driver bug where a timeout set by receive
+        //  succeeds but the timeout expires immediately after, causing the
+        //  transmit operation to timeout.
+        //
+        UsbIo = NicDevice->UsbIo;
+        Status = UsbIo->UsbBulkTransfer (UsbIo,
+                                           BULK_OUT_ENDPOINT,
+                                           &NicDevice->TxTest->TxHdr1,
+                                           &TransferLength,
+                                           0xfffffffe,
+                                           &TransferStatus);
+
+        if (!EFI_ERROR(Status) && !EFI_ERROR(Status)) {
+          NicDevice->TxBuffer = Buffer;
+          Status = EFI_SUCCESS;
+        } else if (EFI_TIMEOUT == Status && EFI_USB_ERR_TIMEOUT == TransferStatus) {
+          Status = EFI_NOT_READY;
+        } else {
+          Status = EFI_DEVICE_ERROR;
+        }
+      } else {
+        //
+        // No packets available.
+        //
+        Status = EFI_NOT_READY;
+      }
+    } else {
+      if (EfiSimpleNetworkStarted == Mode->State) {
+        Status = EFI_DEVICE_ERROR;
+      } else {
+        Status = EFI_NOT_STARTED;
+      }
+    }
+  } else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+EXIT:
+  gBS->RestoreTPL (TplPrevious);
+  return Status;
+}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [edk2-platform][PATCH v3 3/6] Drivers/ASIX: Add ASIX Ax88772c driver
  2020-06-08 13:38 [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Samer El-Haj-Mahmoud
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 1/6] Drivers/ASIX: Create ASIX package Samer El-Haj-Mahmoud
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 2/6] Drivers/ASIX: Add ASIX Ax88179 driver Samer El-Haj-Mahmoud
@ 2020-06-08 13:38 ` Samer El-Haj-Mahmoud
  2020-06-09  0:37   ` Ni, Ray
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 4/6] Platform/RaspberryPi: Switch RPi3 USB NIC driver to Ax88772c Samer El-Haj-Mahmoud
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Samer El-Haj-Mahmoud @ 2020-06-08 13:38 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Leif Lindholm, Ard Biesheuvel, Michael D Kinney

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=driverdetail&PItemID=136

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

Cc: Ray Ni <ray.ni@intel.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>

Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
---
 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(+)

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.<BR>
+# Copyright (c) 2020, ARM Limited. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010018
+  BASE_NAME                      = Ax88772c
+  FILE_GUID                      = B15239D6-6A01-4808-A0F7-B7F20F073555
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = 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 <Uefi.h>
+
+#include <Guid/EventGroup.h>
+
+#include <IndustryStandard/Pci.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/NetLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/NetworkInterfaceIdentifier.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/UsbIo.h>
+
+#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) != 0)  ///<  Return TRUE/FALSE for IN direction
+#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7) == 0)  ///<  Return TRUE/FALSE for OUT direction
+#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_BULK)      ///<  Return TRUE/FALSE for BULK type
+#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 | BIT1)) == 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 messages
+#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast messages
+#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast messages
+#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 values
+#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 bytes 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 packet 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 the 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 >= 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 = 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 <= 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')  ///<  Signature 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 AX88772 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 address hash table
+#define RXC_AP            0x0020  ///<  Accept physical address from Multicast 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=100, 0=10 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=Auto select, 0=Manual select
+
+//
+//  Software Reset register
+//
+
+#define SRR_RR            0x01    ///<  Clear receive frame length error
+#define SRR_RT            0x02    ///<  Clear transmit frame length error
+#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 register, Value: New value
+#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value: 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 table
+#define CMD_MULTICAST_HASH_WRITE  0x16  ///<  Write the multicast hash table, Data: New 8 byte value
+#define CMD_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status register, Data: Register value
+#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status register, 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 advertisement register
+#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter ability register
+#define PHY_ANER                        6       ///<  Autonegotiation expansion register
+
+//  BMCR - Register 0
+
+#define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears after reset
+#define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
+#define BMCR_100MBPS                    0x2000  ///<  100 Mbits/Sec
+#define BMCR_10MBPS                     0       ///<  10 Mbits/Sec
+#define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable autonegotiation
+#define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
+#define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
+#define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart autonegotiation
+#define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
+#define BMCR_HALF_DUPLEX                0       ///<  Half duplex operation
+#define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test enabled
+
+//  BSMR - Register 1
+
+#define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
+#define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full duplex
+#define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half duplex
+#define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
+#define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half duplex
+#define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with preamble suppressed
+#define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation complete
+#define BMSR_RF                         0x0010  ///<  1 = Remote fault
+#define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform autonegotiation
+#define BMSR_LINKST                     0x0004  ///<  1 = Link up
+#define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition detected
+#define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended register capable
+
+//  ANAR and ANLPAR Registers 4, 5
+
+#define AN_NP                           0x8000  ///<  1 = Next page available
+#define AN_ACK                          0x4000  ///<  1 = Link partner acknowledged
+#define AN_RF                           0x2000  ///<  1 = Remote fault indicated by link partner
+#define AN_FCS                          0x0400  ///<  1 = Flow control ability
+#define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
+#define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
+#define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
+#define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
+#define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
+#define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/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 identification
+
+  //
+  //  USB data
+  //
+  EFI_HANDLE                Controller;        ///<  Controller handle
+  EFI_USB_IO_PROTOCOL       *UsbIo;            ///<  USB driver interface
+
+  //
+  //  Simple network protocol data
+  //
+  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;     ///<  Driver's network stack interface
+  EFI_SIMPLE_NETWORK_MODE     SimpleNetworkData; ///<  Data for simple network
+
+  //
+  // Ethernet controller data
+  //
+  BOOLEAN                   Initialized;       ///<  Controller initialized
+  UINT16                    PhyId;             ///<  PHY ID
+
+  //
+  //  Link state
+  //
+  BOOLEAN                   LinkSpeed100Mbps;   ///<  Current link speed, FALSE = 10 Mbps
+  BOOLEAN                   Complete;           ///<  Current state of auto-negotiation
+  BOOLEAN                   FullDuplex;         ///<  Current duplex
+  BOOLEAN                   LinkUp;             ///<  Current link state
+  UINTN                     PollCount;          ///<  Number of times the 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, DEV_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 perform a more
+                                exhaustive verification operation of the device
+                                during reset.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER 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 network 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 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 network 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 FALSE
+  then the current station address is changed to the address specified by
+  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 network
+                                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 network 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 the network interface.
+  @param [in, out] StatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
+                                the size, in bytes, of the resulting table of statistics.
+  @param [out] StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+                                conains the statistics.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_BUFFER_TOO_SMALL  The StatisticsTable is NULL or the buffer 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 network 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 network 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 network 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 must not be NULL.
+  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [in] Buffer           A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [in] SrcAddr          The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [in] DestAddr         The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [in] Protocol         The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
+  @retval EFI_INVALID_PARAMETER 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 network 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 the MAC address.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772MacAddressGet (
+  IN NIC_DEVICE *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 was polled
+  @param [out] Complete      Address of boolean to receive complate status.
+  @param [out] LinkUp        Address of boolean to receive link status, TRUE=up.
+  @param [out] HiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
+  @param [out] FullDuplex    Address of boolean to receive link duplex, TRUE=full.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772NegotiateLinkComplete (
+  IN     NIC_DEVICE *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 register 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 register 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 packet
+  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 = 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 name protocol declaration
+extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<  Component name 2 protocol declaration
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] Language         A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+  @param [out] 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 specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
+  IN  CHAR8                       *Language,
+  OUT CHAR16                      **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] ControllerHandle  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+  @param [in] ChildHandle       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+  @param [in] Language         A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+  @param [out] 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 driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL *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 implementation
+  only supports the integrated PHY since no other test cases were available.
+
+  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 = -1;
+  End = &MacAddress[PXE_HWADDR_LEN_ETHER];
+  while (End > MacAddress) {
+    Data = *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 = 0; 8 > BitNumber; BitNumber++) {
+      Carry = ((Crc >> 31) & 1) ^ (Data & 1);
+      Crc <<= 1;
+      if (Carry != 0) {
+        Crc ^= 0x04c11db7;
+      }
+      Data >>= 1;
+    }
+  }
+
+  //
+  //  Return the CRC value
+  //
+  return (UINT32) Crc;
+}
+
+/**
+  Get the MAC address
+
+  This routine calls ::Ax88772UsbCommand to request the MAC
+  address from the network adapter.
+
+  @param [in] NicDevice       Pointer to the NIC_DEVICE structure
+  @param [out] MacAddress      Address of a six byte buffer to receive the MAC address.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772MacAddressGet (
+  IN  NIC_DEVICE *NicDevice,
+  OUT UINT8      *MacAddress
+  )
+{
+  USB_DEVICE_REQUEST SetupMsg;
+  EFI_STATUS Status;
+
+  //
+  //  Set the register address.
+  //
+  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                       | USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_MAC_ADDRESS_READ;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
+
+  //
+  //  Read the PHY register
+  //
+  Status = Ax88772UsbCommand (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 = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
+
+  //
+  //  Read the PHY register
+  //
+  Status = Ax88772UsbCommand (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 = 0;
+  //
+  // Clear the multicast hash table
+  //
+  for (Index = 0 ; Index < 8 ; Index ++)
+    NicDevice->MulticastHash[Index] = 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 = Ax88772Crc (MacAddress) >> 26;
+
+  //
+  //  Set the bit corresponding to the destination address
+  //
+  NicDevice->MulticastHash [Crc >> 3] |= (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 = 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 = BMCR_AUTONEGOTIATION_ENABLE
+            | BMCR_RESTART_AUTONEGOTIATION;
+    if (NicDevice->LinkSpeed100Mbps) {
+      Control |= BMCR_100MBPS;
+    }
+    if (NicDevice->FullDuplex) {
+      Control |= BMCR_FULL_DUPLEX;
+    }
+    Status = 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 was polled
+  @param [out] Complete       Address of boolean to receive complate status.
+  @param [out] LinkUp         Address of boolean to receive link status, TRUE=up.
+  @param [out] HiSpeed        Address of boolean to receive link speed, TRUE=100Mbps.
+  @param [out] FullDuplex     Address of boolean to receive link duplex, TRUE=full.
+
+  @retval EFI_SUCCESS          The MAC address is available.
+  @retval other                The MAC address is not valid.
+
+**/
+EFI_STATUS
+Ax88772NegotiateLinkComplete (
+  IN     NIC_DEVICE *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 = FALSE;
+
+  //
+  //  Get the link status
+  //
+  Status = Ax88772PhyRead (NicDevice,
+                            PHY_BMSR,
+                            &PhyData);
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  *LinkUp = ((PhyData & BMSR_LINKST) != 0);
+  if (0 == *LinkUp) {
+  } else {
+    *Complete = ((PhyData & 0x20) != 0);
+    if (0 == *Complete) {
+    } else {
+      Status = Ax88772PhyRead (NicDevice,
+                                PHY_ANLPAR,
+                                &PhyData);
+
+      if (!EFI_ERROR (Status)) {
+        //
+        //  Autonegotiation is complete
+        //  Determine the link speed.
+        //
+        *HiSpeed = ((PhyData & (AN_TX_FDX | AN_TX_HDX))!= 0);
+         //
+        //  Determine the link duplex.
+        //
+        Mask = (*HiSpeed) ? AN_TX_FDX : AN_10_FDX;
+        *FullDuplex = (BOOLEAN)((PhyData & Mask) != 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 register 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 = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  //  Read the PHY register address.
+  //
+  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                       | USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_REG_READ;
+  SetupMsg.Value = NicDevice->PhyId;
+  SetupMsg.Index = RegisterAddress;
+  SetupMsg.Length = sizeof(*PhyData);
+  Status = Ax88772UsbCommand(NicDevice,
+                             &SetupMsg,
+                             PhyData);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  //  Release the PHY to the hardware
+  //
+    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand(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 register 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 = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  //  Write the PHY register
+  //
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_REG_WRITE;
+  SetupMsg.Value = NicDevice->PhyId;
+  SetupMsg.Index = RegisterAddress;
+  SetupMsg.Length = sizeof (PhyData);
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               &PhyData);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  //  Release the PHY to the hardware
+  //
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (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 = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                          | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_SELECT;
+  SetupMsg.Value = SPHY_PSEL;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RESET;
+  SetupMsg.Value = SRR_IPRL ;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RESET;
+  SetupMsg.Value = SRR_IPPD | SRR_IPRL ;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  gBS->Stall (200000);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RESET;
+  SetupMsg.Value =  SRR_IPRL  ;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  gBS->Stall (200000);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RESET;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_PHY_SELECT;
+  SetupMsg.Value = SPHY_PSEL;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RESET;
+  SetupMsg.Value =  SRR_IPRL | SRR_BZ | SRR_BZTYPE;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_RX_CONTROL_WRITE;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  if (EFI_ERROR(Status)) goto err;
+
+  if (!NicDevice->Flag772A) {
+    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_RXQTC;
+#if RXTHOU
+    /*size cannot exceed 3K*/
+    //SetupMsg.Value = 0x0;
+    //SetupMsg.Index = 0x8001;
+    /*size cannot exceed 16K*/
+    SetupMsg.Value = 0x8300;
+    SetupMsg.Index = 0x8500;
+    /*size cannot exceed 32K*/
+    //SetupMsg.Value = 0x8784;
+    //SetupMsg.Index = 0x8A00;
+    SetupMsg.Length = 0;
+#else
+    SetupMsg.Value = 0x8000;
+    SetupMsg.Index = 0x8001;
+#endif
+    Status = 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 = EFI_SUCCESS;
+
+  //
+  // Enable the receiver if something is to be received
+  //
+  if (RxFilter != 0) {
+    //
+    //  Enable the receiver
+    //
+    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
+                         | USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_MEDIUM_STATUS_READ;
+    SetupMsg.Value = 0;
+    SetupMsg.Index = 0;
+    SetupMsg.Length = sizeof (MediumStatus);
+    Status = Ax88772UsbCommand (NicDevice,
+                                 &SetupMsg,
+                                 &MediumStatus);
+    if (!EFI_ERROR (Status)) {
+      if (0 == (MediumStatus & MS_RE)) {
+        MediumStatus |= MS_RE | MS_ONE;
+
+        if (NicDevice->FullDuplex)
+          MediumStatus |= MS_TFC | MS_RFC | MS_FD;
+        else
+          MediumStatus &= ~(MS_TFC | MS_RFC | MS_FD);
+
+        if (NicDevice->LinkSpeed100Mbps)
+          MediumStatus |= MS_PS;
+        else
+          MediumStatus &= ~MS_PS;
+
+        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                             | USB_TARGET_DEVICE;
+        SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
+        SetupMsg.Value = MediumStatus;
+        SetupMsg.Index = 0;
+        SetupMsg.Length = 0;
+        Status = Ax88772UsbCommand (NicDevice,
+                                     &SetupMsg,
+                                     NULL);
+
+        if (EFI_ERROR(Status))
+              goto EXIT;
+      }
+    } else {
+        goto EXIT;
+    }
+  }
+  RxControl = RXC_SO;
+  if (!NicDevice->Flag772A)
+    RxControl |= RXC_RH1M;
+
+  //
+  //  Enable multicast if requested
+  //
+  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
+      RxControl |= RXC_AM;
+      //
+      //  Update the multicast hash table
+      //
+      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+      SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
+      SetupMsg.Value = 0;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = sizeof (NicDevice ->MulticastHash);
+      Status = Ax88772UsbCommand (NicDevice,
+                                   &SetupMsg,
+                                   &NicDevice->MulticastHash);
+
+      if (EFI_ERROR(Status))
+              goto EXIT;
+  }
+
+  //
+  //  Enable all multicast if requested
+  //
+  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
+      RxControl |= RXC_AMALL;
+  }
+
+  //
+  //  Enable broadcast if requested
+  //
+  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
+      RxControl |= RXC_AB;
+  }
+
+  //
+  //  Enable promiscuous mode if requested
+  //
+  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
+      RxControl |= RXC_PRO;
+  }
+
+  //
+  //  Update the receiver control
+  //
+  if (NicDevice->CurRxControl != RxControl) {
+    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                         | USB_TARGET_DEVICE;
+    SetupMsg.Request = CMD_RX_CONTROL_WRITE;
+#if RXTHOU
+    if (NicDevice->Flag772A)
+      RxControl |= 0x0300;
+#endif
+    if (NicDevice->Flag772A)
+      RxControl &= ~(RXC_MFB);
+    SetupMsg.Value = RxControl;
+    SetupMsg.Index = 0;
+    SetupMsg.Length = 0;
+    Status = Ax88772UsbCommand (NicDevice,
+                                 &SetupMsg,
+                                 NULL);
+    if (!EFI_ERROR (Status))
+      NicDevice->CurRxControl = 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 = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+
+  SetupMsg.Request = CMD_WRITE_GPIOS;
+  SetupMsg.Value = 0x80;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0 ;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  if (EFI_SUCCESS == 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 = USB_ENDPOINT_DIR_IN
+                       | USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+  SetupMsg.Request = CMD_SROM_READ;
+  SetupMsg.Value = (UINT16) Address;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = sizeof (*Data);
+  Status = 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 = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+
+  SetupMsg.Request = CMD_SROM_WRITE_EN;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0 ;
+  Status = Ax88772UsbCommand (NicDevice,
+                               &SetupMsg,
+                               NULL);
+
+  if (EFI_SUCCESS == 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 = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+
+  SetupMsg.Request = CMD_SROM_WRITE_DIS;
+  SetupMsg.Value = 0;
+  SetupMsg.Index = 0;
+  SetupMsg.Length = 0;
+  Status = Ax88772UsbCommand (NicDevice,
+                      &SetupMsg,
+                      NULL);
+
+  if (EFI_SUCCESS == 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 = USB_REQ_TYPE_VENDOR
+                       | USB_TARGET_DEVICE;
+
+  SetupMsg.Request = CMD_SROM_WRITE;
+  SetupMsg.Value = (UINT16) Address;
+  SetupMsg.Index = (UINT16) (*Data);
+  SetupMsg.Length = 0;
+
+  Status = 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 = EfiUsbNoData;
+  if (Request->Length != 0) {
+    Direction = ((Request->RequestType & USB_ENDPOINT_DIR_IN) != 0)
+              ? EfiUsbDataIn : EfiUsbDataOut;
+  }
+
+  //
+  // Issue the command
+  //
+  UsbIo = NicDevice->UsbIo;
+  Status = UsbIo->UsbControlTransfer (UsbIo,
+                                        Request,
+                                        Direction,
+                                        USB_BUS_TIMEOUT,
+                                        Buffer,
+                                        Request->Length,
+                                        &CmdStatus);
+
+  //
+  // Determine the operation status
+  //
+  if (!EFI_ERROR (Status)) {
+    Status = CmdStatus;
+  } else {
+    //
+    // Only use status values associated with the Simple Network protocol
+    //
+    if (EFI_TIMEOUT == Status) {
+      Status = EFI_DEVICE_ERROR;
+    }
+  }
+
+  //
+  // Return the operation status
+  //
+  return Status;
+}
+
+BOOLEAN
+Ax88772GetLinkStatus (
+  IN NIC_DEVICE *NicDevice
+)
+{
+  UINT32              CmdStatus;
+  EFI_USB_IO_PROTOCOL *UsbIo;
+  UINT64              IntData = 0;
+  UINTN               IntDataLeng = 8;
+  EFI_STATUS          Status;
+
+  //
+  // Issue the command
+  //
+  UsbIo = NicDevice->UsbIo;
+  Status = UsbIo->UsbSyncInterruptTransfer(UsbIo,
+                                        USB_ENDPOINT_DIR_IN | INTERRUPT_ENDPOINT,
+                                        &IntData,
+                                        &IntDataLeng,
+                                        USB_BUS_TIMEOUT,
+                                        &CmdStatus);
+
+  if (EFI_ERROR(Status) || EFI_ERROR(CmdStatus) || 0 == IntDataLeng) {
+      return FALSE;
+  }
+  return (IntData & 0x800000)? FALSE : TRUE;
+
+}
+
+#if RXTHOU
+EFI_STATUS
+Ax88772BulkIn(
+  IN NIC_DEVICE * NicDevice
+)
+{
+  UINTN               Index;
+  UINTN               LengthInBytes = 0;
+  UINTN               TmpLen = AX88772_MAX_BULKIN_SIZE;
+  UINTN               OrigTmpLen = 0;
+  UINT16              TmpLen2;
+  UINT16              TmpLenBar;
+  UINT16              TmpTotalLen = 0;
+  UINTN               TotalLen = LengthInBytes;
+  EFI_STATUS          Status = EFI_DEVICE_ERROR;
+  EFI_USB_IO_PROTOCOL *UsbIo;
+  UINT32              TransferStatus = 0;
+  UINT16              TmpPktCnt = 0;
+  UINT16              *TmpHdr = (UINT16 *)NicDevice->BulkInbuf;
+  USB_DEVICE_REQUEST  SetupMsg;
+
+  UsbIo = NicDevice->UsbIo;
+  for (Index = 0 ; Index < (AX88772_MAX_BULKIN_SIZE / 512) && UsbIo != NULL; Index++) {
+    VOID* TmpAddr = 0;
+
+    TmpPktCnt = 0;
+    TmpAddr = (VOID*) &NicDevice->BulkInbuf[LengthInBytes];
+    OrigTmpLen = TmpLen;
+    Status = UsbIo->UsbBulkTransfer (UsbIo,
+                          USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
+                          TmpAddr,
+                          &TmpLen,
+                          BULKIN_TIMEOUT,
+                          &TransferStatus);
+
+    if (OrigTmpLen == TmpLen) {
+      Status = EFI_NOT_READY;
+      goto no_pkt;
+    }
+
+    if ((!EFI_ERROR (Status)) &&
+        (!EFI_ERROR (TransferStatus)) &&
+        TmpLen != 0) {
+      LengthInBytes += TmpLen;
+      if ((TmpLen % 512) != 0) {
+        goto done;
+      }
+    } else if ((!EFI_ERROR (Status)) &&
+               (!EFI_ERROR (TransferStatus)) &&
+               (TmpLen == 0)) {
+      Status = EFI_NOT_READY;
+      goto done;
+    } else if (EFI_TIMEOUT == Status && EFI_USB_ERR_TIMEOUT == TransferStatus) {
+      SetupMsg.RequestType = USB_REQ_TYPE_STANDARD | 0x02;
+      SetupMsg.Request = 0x01;
+      SetupMsg.Value =  0;
+      SetupMsg.Index = 0x82;
+      SetupMsg.Length = 0;
+      Status = Ax88772UsbCommand (NicDevice,
+                                   &SetupMsg,
+                                   NULL);
+      Status = EFI_NOT_READY;
+      goto done;
+    } else {
+      Status = EFI_DEVICE_ERROR;
+      goto done;
+    }
+  }
+done:
+  if (LengthInBytes != 0) {
+
+    do {
+      TmpLen2 = (*TmpHdr) & 0x7FF;
+      TmpLenBar = *(TmpHdr + 1);
+      TmpTotalLen = ((TmpLen + 4 + 1) & 0xfffe);
+
+      if ((TmpLen2 & 0x7FF) + (TmpLenBar & 0x7FF) == 0x7FF) {
+        TmpPktCnt++;
+      } else {
+        if (TmpPktCnt != 0) {
+          break;
+        }
+        Status = EFI_NOT_READY;
+        goto no_pkt;
+      }
+      TmpHdr += (TmpTotalLen / 2);
+      TotalLen -= TmpTotalLen;
+    } while (TotalLen > 0);
+
+  if (LengthInBytes >= 1000 && TmpPktCnt != 0) {
+    if ((NicDevice->RxBurst) == 1) {
+      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+      SetupMsg.Request = CMD_RESET;
+      SetupMsg.Value =  SRR_IPRL;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = 0;
+      Ax88772UsbCommand (NicDevice,
+                          &SetupMsg,
+                          NULL);
+    }
+
+    if (NicDevice->RxBurst < 2)
+    NicDevice->RxBurst++;
+
+  } else {
+    if (NicDevice->RxBurst >= 2) {
+      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
+                           | USB_TARGET_DEVICE;
+      SetupMsg.Request = CMD_RESET;
+      SetupMsg.Value =  SRR_IPRL| SRR_BZ | SRR_BZTYPE;
+      SetupMsg.Index = 0;
+      SetupMsg.Length = 0;
+      Ax88772UsbCommand (NicDevice,
+                          &SetupMsg,
+                          NULL);
+      }
+      NicDevice->RxBurst = 0;
+    }
+  }
+
+  if (TmpPktCnt != 0) {
+    NicDevice->PktCnt = TmpPktCnt;
+    NicDevice->CurPktHdrOff = NicDevice->BulkInbuf;
+    NicDevice->CurPktOff = NicDevice->BulkInbuf + 4;
+    Status = EFI_SUCCESS;
+  }
+
+no_pkt:
+  return Status;
+}
+#else
+EFI_STATUS
+Ax88772BulkIn(
+  IN NIC_DEVICE *NicDevice
+)
+{
+  UINTN               Index;
+  UINTN               LengthInBytes = 0;
+  UINTN               TmpLen = AX88772_MAX_BULKIN_SIZE;
+  UINTN               OrigTmpLen = 0;
+  UINT16              TmpLen2;
+  UINT16              TmpLenBar;
+  UINT16              TmpTotalLen = 0;
+  UINTN               CURBufSize = AX88772_MAX_BULKIN_SIZE;
+  EFI_STATUS          Status = EFI_DEVICE_ERROR;
+  EFI_USB_IO_PROTOCOL *UsbIo;
+  UINT32              TransferStatus = 0;
+  UINT16              TmpPktCnt = 0;
+  UINT16              *TmpHdr = (UINT16 *)NicDevice->BulkInbuf;
+
+  UsbIo = NicDevice->UsbIo;
+  for (Index = 0 ; Index < (AX88772_MAX_BULKIN_SIZE / 512) && UsbIo != NULL; Index++) {
+    VOID *TmpAddr = 0;
+
+    TmpPktCnt = 0;
+    TmpAddr = (VOID*) &NicDevice->BulkInbuf[LengthInBytes];
+    OrigTmpLen = TmpLen;
+    Status = UsbIo->UsbBulkTransfer (UsbIo,
+                          USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
+                          TmpAddr,
+                          &TmpLen,
+                          BULKIN_TIMEOUT,
+                          &TransferStatus);
+
+    if (OrigTmpLen == TmpLen) {
+      Status = EFI_NOT_READY;
+      goto no_pkt;
+    }
+
+    if ((!EFI_ERROR (Status)) &&
+        (!EFI_ERROR (TransferStatus)) &&
+        TmpLen != 0) {
+
+      LengthInBytes += TmpLen;
+      CURBufSize = CURBufSize - TmpLen;
+      TmpLen = CURBufSize;
+      do {
+        TmpLen2 = *TmpHdr;
+        TmpLenBar = *(TmpHdr + 1);
+        TmpTotalLen += ((TmpLen2 + 4 + 1) & 0xfffe);
+
+        if (((TmpLen2 ^ TmpLenBar) == 0xffff))  {
+          if (TmpTotalLen == LengthInBytes) {
+            TmpPktCnt++;
+            Status = EFI_SUCCESS;
+            goto done;
+          } else if (TmpTotalLen > LengthInBytes) {
+            break;
+          }
+        } else if (((TmpLen2 ^ TmpLenBar) != 0xffff)) {
+          if (TmpPktCnt != 0) {
+            Status = EFI_SUCCESS;
+            goto done;
+          }
+          Status = EFI_NOT_READY;
+          goto no_pkt;
+        }
+        TmpHdr += (TmpTotalLen / 2);
+        TmpPktCnt++;
+      } while (TmpTotalLen < LengthInBytes);
+    } else if ((!EFI_ERROR (Status)) &&
+               (!EFI_ERROR (TransferStatus)) &&
+               (TmpLen == 0)) {
+      if (TmpPktCnt != 0) {
+        Status = EFI_SUCCESS;
+        goto done;
+      }
+      Status = EFI_NOT_READY;
+      goto no_pkt;
+    } else if (EFI_TIMEOUT == Status && EFI_USB_ERR_TIMEOUT == TransferStatus) {
+      if (TmpPktCnt != 0) {
+        Status = EFI_SUCCESS;
+        goto done;
+      }
+      Status = EFI_NOT_READY;
+      goto no_pkt;
+    } else {
+      if (TmpPktCnt != 0) {
+        Status = EFI_SUCCESS;
+        goto done;
+      }
+      Status = EFI_DEVICE_ERROR;
+      goto no_pkt;
+    }
+  }
+done:
+  NicDevice->PktCnt = TmpPktCnt;
+  NicDevice->CurPktHdrOff = NicDevice->BulkInbuf;
+  NicDevice->CurPktOff = 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  gComponentName = {
+  GetDriverName,
+  GetControllerName,
+  "eng"
+};
+
+/**
+  EFI Component Name 2 Protocol declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
+  "en"
+};
+
+
+/**
+  Driver name table declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
+mDriverNameTable[] = {
+  {"eng;en", L"ASIX AX88772B Ethernet Driver 2.8.0"},
+  {NULL,  NULL}
+};
+
+/**
+  Controller name table declaration
+**/
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
+mControllerNameTable[] = {
+  {"eng;en", L"ASIX AX88772B USB Fast Ethernet Controller"},
+  {NULL,  NULL}
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] Language         A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 3066 or ISO 639-2 language code format.
+  @param [out] 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 specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+GetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
+  IN  CHAR8                       *Language,
+  OUT CHAR16                      **DriverName
+  )
+{
+  EFI_STATUS Status;
+
+
+  Status = LookupUnicodeString2 (
+             Language,
+             This->SupportedLanguages,
+             mDriverNameTable,
+             DriverName,
+             (BOOLEAN)(This == &gComponentName)
+             );
+
+  return Status;
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+  @param [in] ControllerHandle  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+  @param [in] ChildHandle       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+  @param [in] Language         A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 3066 or ISO 639-2 language code format.
+  @param [out] 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 driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+
+
+
+EFI_STATUS
+EFIAPI
+GetControllerName (
+  IN          EFI_COMPONENT_NAME_PROTOCOL *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 != NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check Controller's handle
+  //
+  Status = 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 != EFI_ALREADY_STARTED) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status =  LookupUnicodeString2 (
+           Language,
+            This->SupportedLanguages,
+           mControllerNameTable,
+           ControllerName,
+           (BOOLEAN)(This == &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 = 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 transport
+    //  protocol handler.
+    //
+    Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &Device);
+    if (EFI_ERROR(Status)) {
+      Status = EFI_UNSUPPORTED;
+    } else {
+      //
+      //  Validate the adapter
+      //
+      if (VENDOR_ID == Device.IdVendor) {
+        if (PRODUCT_AX88772B_ID != Device.IdProduct) {
+        } else if (PRODUCT_AX88772B_ASUS_ID == Device.IdProduct) {
+        } else if (PRODUCT_AX88772A_ID == Device.IdProduct) {
+        } else if (PRODUCT_ID == Device.IdProduct) {
+        } else {
+          Status = EFI_UNSUPPORTED;
+        }
+      } else if (VENDOR_AX88772B_LENOVO_ID == Device.IdVendor) {
+        if (PRODUCT_AX88772B_LENOVO_ID != Device.IdProduct) {
+          Status = EFI_UNSUPPORTED;
+        }
+      } else {
+        Status = 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 protocols.
+  Initialize PXE structures, create a copy of the Controller Device Path with the
+  NIC's MAC address apEnded to it, install the NetworkInterfaceIdentifier 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 = NULL;
+  MAC_ADDR_DEVICE_PATH      MacDeviceNode;
+  EFI_USB_DEVICE_DESCRIPTOR Device;
+
+  //
+  //  Allocate the device structure
+  //
+  LengthInBytes = sizeof (*NicDevice);
+  Status = gBS->AllocatePool (
+                  EfiBootServicesData,
+                  LengthInBytes,
+                  (VOID **) &NicDevice
+                  );
+
+  if (EFI_ERROR (Status)) {
+    goto ERR;
+  }
+
+  //
+  //  Set the structure signature
+  //
+  ZeroMem (NicDevice, LengthInBytes);
+  NicDevice->Signature = DEV_SIGNATURE;
+
+  Status = gBS->OpenProtocol (
+                    Controller,
+                    &gEfiUsbIoProtocolGuid,
+                    (VOID **) &NicDevice->UsbIo,
+                    This->DriverBindingHandle,
+                    Controller,
+                    EFI_OPEN_PROTOCOL_BY_DRIVER
+                    );
+
+  if (EFI_ERROR (Status)) {
+    goto ERR;
+  }
+
+  NicDevice->Flag772A = FALSE;
+  NicDevice->UsbIo->UsbGetDeviceDescriptor (NicDevice->UsbIo, &Device);
+  if ((PRODUCT_AX88772A_ID == Device.IdProduct) ||
+      (PRODUCT_ID == Device.IdProduct))
+    NicDevice->Flag772A = TRUE;
+  //
+  //  Initialize the simple network protocol
+  //
+  Status = SN_Setup (NicDevice);
+
+  if (EFI_ERROR(Status)){
+    gBS->CloseProtocol (
+              Controller,
+              &gEfiUsbIoProtocolGuid,
+              This->DriverBindingHandle,
+              Controller
+              );
+    goto ERR;
+  }
+
+  //
+  // Set Device Path
+  //
+  Status = 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 = MESSAGING_DEVICE_PATH;
+  MacDeviceNode.Header.SubType = MSG_MAC_ADDR_DP;
+
+  SetDevicePathNodeLength (&MacDeviceNode.Header, sizeof (MAC_ADDR_DEVICE_PATH));
+
+  CopyMem (&MacDeviceNode.MacAddress,
+           &NicDevice->SimpleNetworkData.CurrentAddress,
+           PXE_HWADDR_LEN_ETHER);
+
+  MacDeviceNode.IfType = NicDevice->SimpleNetworkData.IfType;
+
+  NicDevice->MyDevPath = AppendDevicePathNode (
+                                          ParentDevicePath,
+                                          (EFI_DEVICE_PATH_PROTOCOL *) &MacDeviceNode
+                                          );
+
+  NicDevice->Controller = NULL;
+
+  //
+  //  Install both the simple network and device path protocols.
+  //
+  Status = 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 = 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 != NULL) {
+    gBS->FreePool (NicDevice->BulkInbuf);
+  }
+
+  if (NicDevice->TxTest != NULL) {
+    gBS->FreePool (NicDevice->TxTest);
+  }
+
+  if (NicDevice->MyDevPath != NULL) {
+    gBS->FreePool (NicDevice->MyDevPath);
+  }
+
+  if (NicDevice != 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 device.
+
+**/
+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 = 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 == 0) {
+    Status = 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 devicepath
+      // and usbio protocol.
+      //
+      gBS->CloseProtocol (
+                Controller,
+                &gEfiDevicePathProtocolGuid,
+                This->DriverBindingHandle,
+                Controller
+                );
+      gBS->CloseProtocol (
+                Controller,
+                &gEfiUsbIoProtocolGuid,
+                This->DriverBindingHandle,
+                Controller
+                );
+      return EFI_SUCCESS;
+    }
+
+    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+    Status = gBS->UninstallMultipleProtocolInterfaces (
+                          Controller,
+                          &gEfiCallerIdGuid,
+                          NicDevice,
+                          &gEfiSimpleNetworkProtocolGuid,
+                          &NicDevice->SimpleNetwork,
+                          &gEfiDevicePathProtocolGuid,
+                          NicDevice->MyDevPath,
+                          NULL
+                          );
+
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+    //
+    // Close the bus driver
+    //
+    Status = gBS->CloseProtocol (
+                       Controller,
+                       &gEfiDevicePathProtocolGuid,
+                       This->DriverBindingHandle,
+                       Controller
+                       );
+
+    Status = gBS->CloseProtocol (
+                       Controller,
+                       &gEfiUsbIoProtocolGuid,
+                       This->DriverBindingHandle,
+                       Controller
+                       );
+
+    return EFI_SUCCESS;
+  }
+
+  AllChildrenStopped = TRUE;
+
+  for (Index = 0; Index < NumberOfChildren; Index++) {
+    Status = gBS->OpenProtocol (
+                      ChildHandleBuffer[Index],
+                      &gEfiSimpleNetworkProtocolGuid,
+                      (VOID **) &SimpleNetwork,
+                      This->DriverBindingHandle,
+                      Controller,
+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                      );
+
+    if (EFI_ERROR (Status)) {
+      AllChildrenStopped = FALSE;
+      continue;
+    }
+
+    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+    gBS->CloseProtocol (
+              Controller,
+              &gEfiUsbIoProtocolGuid,
+              This->DriverBindingHandle,
+              ChildHandleBuffer[Index]
+              );
+
+    Status = gBS->UninstallMultipleProtocolInterfaces (
+                          ChildHandleBuffer[Index],
+                          &gEfiCallerIdGuid,
+                          NicDevice,
+                          &gEfiSimpleNetworkProtocolGuid,
+                          &NicDevice->SimpleNetwork,
+                          &gEfiDevicePathProtocolGuid,
+                          NicDevice->MyDevPath,
+                          NULL
+                          );
+
+    if (EFI_ERROR (Status)) {
+      Status = gBS->OpenProtocol (
+                        Controller,
+                        &gEfiUsbIoProtocolGuid,
+                        (VOID **) &NicDevice->UsbIo,
+                        This->DriverBindingHandle,
+                        ChildHandleBuffer[Index],
+                        EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+                        );
+    } else {
+      if (NicDevice->BulkInbuf != NULL) {
+        gBS->FreePool (NicDevice->BulkInbuf);
+      }
+
+      if (NicDevice->TxTest != NULL) {
+        gBS->FreePool (NicDevice->TxTest);
+      }
+
+      if (NicDevice->MyDevPath != NULL) {
+        gBS->FreePool (NicDevice->MyDevPath);
+      }
+
+      if (NicDevice != NULL) {
+        gBS->FreePool (NicDevice);
+      }
+    }
+  }
+
+  if (!AllChildrenStopped) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Driver binding protocol declaration
+**/
+EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
+  DriverSupported,
+  DriverStart,
+  DriverStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+
+/**
+  Ax88772 driver unload routine.
+
+  @param [in] ImageHandle       Handle for the image.
+
+  @retval EFI_SUCCESS           Image may be unloaded
+
+**/
+EFI_STATUS
+EFIAPI
+DriverUnload (
+  IN EFI_HANDLE ImageHandle
+  )
+{
+  UINTN       BufferSize;
+  UINTN       Index;
+  UINTN       Max;
+  EFI_HANDLE  *Handle;
+  EFI_STATUS  Status;
+
+  //
+  //  Determine which devices are using this driver
+  //
+  BufferSize = 0;
+  Handle = NULL;
+  Status = gBS->LocateHandle (
+                  ByProtocol,
+                  &gEfiCallerIdGuid,
+                  NULL,
+                  &BufferSize,
+                  NULL);
+  if (EFI_BUFFER_TOO_SMALL == Status) {
+    for (; ;) {
+      //
+      //  One or more block IO devices are present
+      //
+      Status = gBS->AllocatePool (
+                      EfiBootServicesData,
+                      BufferSize,
+                      (VOID **) &Handle
+                      );
+      if (EFI_ERROR (Status)) {
+        break;
+      }
+
+      //
+      //  Locate the block IO devices
+      //
+      Status = gBS->LocateHandle (
+                      ByProtocol,
+                      &gEfiCallerIdGuid,
+                      NULL,
+                      &BufferSize,
+                      Handle);
+      if (EFI_ERROR (Status)) {
+        //
+        //  Error getting handles
+        //
+
+        break;
+      }
+
+      //
+      //  Remove any use of the driver
+      //
+      Max = BufferSize / sizeof (Handle[0]);
+      for (Index = 0; Max > Index; Index++) {
+        Status = DriverStop (&gDriverBinding,
+                              Handle[Index],
+                              0,
+                              NULL);
+        if (EFI_ERROR (Status)) {
+          break;
+        }
+      }
+      break;
+    }
+  } else {
+    if (EFI_NOT_FOUND == Status) {
+      //
+      //  No devices were found
+      //
+      Status = EFI_SUCCESS;
+    }
+  }
+
+  //
+  //  Free the handle array
+  //
+  if (Handle != 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 = gBS->HandleProtocol (
+                  gImageHandle,
+                  &gEfiLoadedImageProtocolGuid,
+                  (VOID **)&LoadedImage
+                  );
+  if (!EFI_ERROR (Status)) {
+    LoadedImage->Unload = DriverUnload;
+  }
+
+  //
+  //  Add the driver to the list of drivers
+  //
+  Status = 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 network 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 = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+  Mode = SimpleNetwork->Mode;
+  //
+  // Clear the multicast hash table
+  //
+  Ax88772MulticastClear (NicDevice);
+
+  //
+  // Load the multicast hash table
+  //
+  if ((Mode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
+    for (Index = 0; Index < Mode->MCastFilterCount; Index++) {
+      //
+      // Enable the next multicast address
+      //
+      Ax88772MulticastSet (NicDevice,
+                            &Mode->MCastFilter[Index].Addr[0]);
+    }
+  }
+
+    Status = 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 will not be read from
+                                the device.  If this is not NULL, the interrupt status will
+                                be read from teh device.  When the interrupt status is read,
+                                it will also be cleared.  Clearing the transmit interrupt
+                                does not empty the recycled transmit buffer array.
+  @param [out] TxBuf          Recycled transmit buffer address.  The network interface will
+                                not transmit if its internal recycled transmit buffer array is
+                                full.  Reading the transmit buffer does not clear the transmit
+                                interrupt.  If this is NULL, then the transmit buffer status
+                                will not be read.  If there are not transmit buffers to recycle
+                                and TxBuf is not NULL, *TxBuf will be set to NULL.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER 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 network 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 = NULL;
+  EFI_STATUS              Status = EFI_SUCCESS;
+  EFI_TPL                 TplPrevious;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // Return the transmit buffer
+    //
+    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+    if ((TxBuf != NULL) && (NicDevice->TxBuffer != NULL)) {
+      *TxBuf = NicDevice->TxBuffer;
+      NicDevice->TxBuffer = NULL;
+    }
+
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      if ((TxBuf == NULL) && (InterruptStatus == NULL)) {
+        Status = EFI_INVALID_PARAMETER;
+        goto EXIT;
+      }
+
+#if REPORTLINK
+#else
+      if (!NicDevice->LinkUp || !NicDevice->Complete) {
+#endif
+        Status = Ax88772NegotiateLinkComplete (NicDevice,
+                                                &NicDevice->PollCount,
+                                                &NicDevice->Complete,
+                                                &NicDevice->LinkUp,
+                                                &NicDevice->LinkSpeed100Mbps,
+                                                &NicDevice->FullDuplex);
+
+        if (EFI_ERROR(Status))
+          goto EXIT;
+#if REPORTLINK
+        if (NicDevice->LinkUp && NicDevice->Complete) {
+          Mode->MediaPresent = TRUE;
+          Status = ReceiveFilterUpdate (SimpleNetwork);
+        } else {
+          Mode->MediaPresent = FALSE;
+        }
+#else
+        if (NicDevice->LinkUp && NicDevice->Complete) {
+          Mode->MediaPresent = TRUE;
+          Mode->MediaPresentSupported = FALSE;
+          Status = ReceiveFilterUpdate (SimpleNetwork);
+        }
+      }
+#endif
+    } else {
+      if (EfiSimpleNetworkStarted == Mode->State) {
+        Status = EFI_DEVICE_ERROR;
+      } else {
+        Status = EFI_NOT_STARTED ;
+      }
+    }
+  } else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+  if (InterruptStatus != NULL) {
+    *InterruptStatus = 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 write operations.
+  @param [in] Offset            Byte offset in the NVRAM device at which to start the
+                                read or write operation.  This must be a multiple of
+                                NvRamAccessSize and less than NvRamSize.
+  @param [in] BufferSize        The number of bytes to read or write from the NVRAM device.
+                                This must also be a multiple of NvramAccessSize.
+  @param [in, out] 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 network 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 = EFI_INVALID_PARAMETER;
+  EFI_TPL                 TplPrevious;
+  EFI_SIMPLE_NETWORK_MODE *Mode;
+  NIC_DEVICE              *NicDevice;
+  UINTN                   Index;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  if ((SimpleNetwork == NULL) || (SimpleNetwork->Mode == NULL)) {
+    Status = EFI_INVALID_PARAMETER;
+    goto  EXIT;
+  }
+
+  NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+  Mode = SimpleNetwork->Mode;
+
+  if (EfiSimpleNetworkInitialized != Mode->State) {
+    Status = EFI_NOT_STARTED;
+    goto  EXIT;
+  }
+
+  if (Offset != 0) {
+    if (((Offset % Mode->NvRamAccessSize) != 0) ||
+        (Offset >= Mode->NvRamSize)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto  EXIT;
+    }
+  }
+  //
+  // Offset must be a multiple of NvRamAccessSize and less than NvRamSize.
+  //
+  if ((BufferSize % Mode->NvRamAccessSize) != 0) {
+    Status = EFI_INVALID_PARAMETER;
+    goto  EXIT;
+  }
+
+  if (BufferSize + Offset > Mode->NvRamSize) {
+    Status = EFI_INVALID_PARAMETER;
+    goto  EXIT;
+  }
+
+  if (Buffer == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto  EXIT;
+  }
+
+  //
+  // ReadWrite: TRUE FOR READ FALSE FOR WRITE
+  //
+  if (ReadWrite) {
+    for (Index = 0; Index < BufferSize / 2; Index++) {
+      Status = Ax88772SromRead (NicDevice,
+                                 (UINT32)(Offset/2 + Index),
+                                 (((UINT16*)Buffer) + Index));
+    }
+  } else {
+    Status = Ax88772EnableSromWrite(NicDevice);
+    if (EFI_ERROR(Status))
+      goto EXIT;
+
+    for (Index = 0; Index < BufferSize / 2; Index++) {
+      Status = Ax88772SromWrite (NicDevice,
+                                  (UINT32)(Offset/2 + Index),
+                                  (((UINT16*)Buffer) + Index));
+    }
+
+    Status = Ax88772DisableSromWrite(NicDevice);
+
+    if (BufferSize == 272)
+      Status = Ax88772ReloadSrom(NicDevice);
+  }
+
+  //
+  // Return the operation status
+  //
+EXIT:
+  gBS->RestoreTPL (TplPrevious);
+  return Status;
+}
+
+/**
+  Resets the network adapter and allocates the transmit and receive buffers
+  required by the network interface; optionally, also requests allocation of
+  additional transmit and receive buffers.  This routine must be called before
+  any other routine in the Simple Network protocol is called.
+
+  @param [in] SimpleNetwork    Protocol instance pointer
+  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
+  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and receive buffers
+  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL (TPL_CALLBACK);
+
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // Determine if the interface is already started
+    //
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkStarted == Mode->State) {
+      if ((0 == ExtraRxBufferSize) && (0 == ExtraTxBufferSize)) {
+        //
+        // Start the adapter
+        //
+        TmpState = Mode->State;
+        Mode->State = EfiSimpleNetworkInitialized;
+        Status = SN_Reset (SimpleNetwork, FALSE);
+        if (EFI_ERROR (Status)) {
+          //
+          // Update the network state
+          //
+          Mode->State = TmpState; // EfiSimpleNetworkInitialized;
+        } else {
+          Mode->MediaPresentSupported = TRUE;
+          NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+          Mode->MediaPresent = Ax88772GetLinkStatus (NicDevice);
+        }
+      } else {
+        Status = EFI_UNSUPPORTED;
+      }
+    } else {
+      Status = EFI_NOT_STARTED;
+    }
+  } else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Return the operation status
+  //
+  gBS->RestoreTPL (TplPrevious);
+  return Status;
+}
+
+
+/**
+  This function converts a multicast IP address to a multicast HW MAC address
+  for all packet transactions.
+
+  @param [in] SimpleNetwork    Protocol instance pointer
+  @param [in] IPv6             Set to TRUE if the multicast IP address is IPv6 [RFC2460].
+                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
+  @param [in] IP               The multicast IP address that is to be converted to a
+                                multicast HW MAC address.
+  @param [in] MAC              The multicast HW MAC address that is to be generated from IP.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // The interface must be running
+    //
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      if (IP == NULL || MAC == NULL) {
+        Status = EFI_INVALID_PARAMETER;
+        goto EXIT;
+      }
+      if (IPv6) {
+        Status = EFI_UNSUPPORTED;
+        goto EXIT;
+      } else {
+        //
+        // check if the ip given is a mcast IP
+        //
+        if ((IP->v4.Addr[0] & 0xF0) != 0xE0) {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        } else {
+          MAC->Addr[0] = 0x01;
+          MAC->Addr[1] = 0x00;
+          MAC->Addr[2] = 0x5e;
+          MAC->Addr[3] = (UINT8) (IP->v4.Addr[1] & 0x7f);
+          MAC->Addr[4] = (UINT8) IP->v4.Addr[2];
+          MAC->Addr[5] = (UINT8) IP->v4.Addr[3];
+          Status = EFI_SUCCESS;
+        }
+      }
+    } else {
+      if (EfiSimpleNetworkStarted == Mode->State) {
+        Status = EFI_DEVICE_ERROR;
+      } else {
+        Status = EFI_NOT_STARTED ;
+      }
+    }
+  } else {
+    Status = 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 network
+  interface.  If there are no packets on the receive queue, then EFI_NOT_READY
+  will be returned.  If there is a packet on the receive queue, and the size
+  of the packet is smaller than BufferSize, then the contents of the packet
+  will be placed in Buffer, and BufferSize will be udpated with the actual
+  size of the packet.  In addition, if SrcAddr, DestAddr, and Protocol are
+  not NULL, then these values will be extracted from the media header and
+  returned.  If BufferSize is smaller than the received packet, then the
+  size of the receive packet will be placed in BufferSize and
+  EFI_BUFFER_TOO_SMALL will be returned.
+
+  This routine calls ::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 to be filled in by
+                                the Transmit() function.  If HeaderSize is non-zero, then
+                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
+                                and DestAddr and Protocol parameters must not be NULL.
+  @param [out] BufferSize      The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [out] Buffer          A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [out] SrcAddr         The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [out] DestAddr        The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [out] Protocol        The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         No packets have been received on the network interface.
+  @retval EFI_BUFFER_TOO_SMALL  The packet is larger than BufferSize bytes.
+  @retval EFI_INVALID_PARAMETER 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 network 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 = NULL;
+  EFI_STATUS              Status;
+  EFI_TPL                 TplPrevious;
+  UINT16                  Type;
+  UINT16                  CurrentPktLen;
+
+
+  TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // The interface must be running
+    //
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      if ((BufferSize == NULL) || (Buffer == NULL)) {
+        Status = EFI_INVALID_PARAMETER;
+        gBS->RestoreTPL (TplPrevious);
+        return Status;
+      }
+
+      //
+      // Update the link status
+      //
+      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+      if (NicDevice->LinkUp && NicDevice->Complete) {
+        if ((HeaderSize != NULL) && (*HeaderSize == 7720)) {
+          NicDevice->Grub_f = TRUE;
+        }
+
+        if ((NicDevice->Grub_f) && (*HeaderSize != 7720)) {
+          gBS->RestoreTPL (TplPrevious);
+          return EFI_NOT_READY;
+        }
+
+        //
+        //  Attempt to receive a packet
+        //
+        if (0 == NicDevice->PktCnt) {
+          Status = Ax88772BulkIn(NicDevice);
+          if (EFI_ERROR(Status)) {
+            goto  no_pkt;
+          }
+        }
+
+        CurrentPktLen = *((UINT16*) (NicDevice->CurPktHdrOff));
+        CurrentPktLen &=  0x7ff;
+
+        if ((60 <= CurrentPktLen) &&
+            (CurrentPktLen - 14 <= MAX_ETHERNET_PKT_SIZE)) {
+            if (*BufferSize < (UINTN)CurrentPktLen) {
+              gBS->RestoreTPL (TplPrevious);
+              return EFI_BUFFER_TOO_SMALL;
+            }
+
+            *BufferSize = CurrentPktLen;
+            CopyMem (Buffer, NicDevice->CurPktOff, CurrentPktLen);
+            Header = (ETHERNET_HEADER *) NicDevice->CurPktOff;
+
+            if ((HeaderSize != NULL)  && (*HeaderSize != 7720)) {
+              *HeaderSize = sizeof (*Header);
+            }
+            if (DestAddr != NULL) {
+              CopyMem (DestAddr, &Header->DestAddr, PXE_HWADDR_LEN_ETHER);
+            }
+            if (SrcAddr != NULL) {
+              CopyMem (SrcAddr, &Header->SrcAddr, PXE_HWADDR_LEN_ETHER);
+            }
+            if (Protocol != NULL) {
+              Type = Header->Type;
+              Type = (UINT16)((Type >> 8) | (Type << 8));
+              *Protocol = Type;
+            }
+            NicDevice->PktCnt--;
+            NicDevice->CurPktHdrOff += (CurrentPktLen + 4 + 1) & 0xfffe;
+            NicDevice->CurPktOff = NicDevice->CurPktHdrOff + 4;
+            Status = EFI_SUCCESS;
+        } else {
+          NicDevice->PktCnt = 0;
+          Status = EFI_DEVICE_ERROR;
+        }
+      } else {
+        //
+        //  Link no up
+        //
+        Status = EFI_NOT_READY;
+      }
+    } else {
+      if (EfiSimpleNetworkStarted == Mode->State) {
+        Status = EFI_DEVICE_ERROR;
+      } else {
+        Status = EFI_NOT_STARTED;
+      }
+    }
+  } else {
+    Status = 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 hardware
+        a more liberal setting is selected.
+
+  If the same bits are set in the Enable and Disable parameters, then the bits
+  in the Disable parameter takes precedence.
+
+  If the ResetMCastFilter parameter is TRUE, then the multicast address list
+  filter is disabled (irregardless of what other multicast bits are set in
+  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount field
+  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
+
+  After enableing or disabling receive filter settings, software should
+  verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
+  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
+
+  Note: Some network drivers and/or devices will automatically promote
+  receive filter settings if the requested setting can not be honored.
+  For example, if a request for four multicast addresses is made and
+  the underlying hardware only supports two multicast addresses the
+  driver might set the promiscuous or promiscuous multicast receive filters
+  instead.  The receiving software is responsible for discarding any extra
+  packets that get through the hardware receive filters.
+
+  If ResetMCastFilter is TRUE, then the multicast receive filter list
+  on the network interface will be reset to the default multicast receive
+  filter list.  If ResetMCastFilter is FALSE, and this network interface
+  allows the multicast receive filter list to be modified, then the
+  MCastFilterCnt and MCastFilter are used to update the current multicast
+  receive filter list.  The modified receive filter list settings can be
+  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
+
+  This routine calls ::ReceiveFilterUpdate to update the receive
+  state in the network adapter.
+
+  @param [in] 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 TRUE.
+  @param [in] ResetMCastFilter Set to TRUE to reset the contents of the multicast receive
+                                filters on the network interface to their default values.
+  @param [in] MCastFilterCnt    Number of multicast HW MAC address in the new MCastFilter list.
+                                This value must be less than or equal to the MaxMCastFilterCnt
+                                field of EFI_SIMPLE_NETWORK_MODE.  This field is optional if
+                                ResetMCastFilter is TRUE.
+  @param [in] MCastFilter      A pointer to a list of new multicast receive filter HW MAC
+                                addresses.  This list will replace any existing multicast
+                                HW MAC address list.  This field is optional if ResetMCastFilter
+                                is TRUE.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER 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 network 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 = EFI_SUCCESS;
+  EFI_TPL                 TplPrevious;
+  UINTN                   Index;
+  UINT8                   Temp;
+
+  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
+  Mode = SimpleNetwork->Mode;
+
+  if (SimpleNetwork == NULL) {
+    gBS->RestoreTPL(TplPrevious);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (Mode->State) {
+  case EfiSimpleNetworkInitialized:
+    break;
+
+  case EfiSimpleNetworkStopped:
+    Status = EFI_NOT_STARTED;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+
+  default:
+    Status = 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) != 0) ||
+      ((Disable &~Mode->ReceiveFilterMask) != 0)) {
+    Status = EFI_INVALID_PARAMETER;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+  }
+
+  if (ResetMCastFilter) {
+    if ((0 == (Mode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST)) &&
+          Enable == 0 &&
+          Disable == 2) {
+      gBS->RestoreTPL(TplPrevious);
+      return EFI_SUCCESS;
+    }
+    Mode->MCastFilterCount = 0;
+    SetMem (&Mode->MCastFilter[0],
+             sizeof(EFI_MAC_ADDRESS) * MAX_MCAST_FILTER_CNT,
+             0);
+  } else {
+    if (MCastFilterCnt != 0) {
+      EFI_MAC_ADDRESS * MulticastAddress;
+      MulticastAddress =  MCastFilter;
+
+      if ((MCastFilterCnt > Mode->MaxMCastFilterCount) ||
+          (MCastFilter == NULL)) {
+        Status = EFI_INVALID_PARAMETER;
+        gBS->RestoreTPL(TplPrevious);
+        return Status;
+      }
+
+      for (Index = 0 ; Index < MCastFilterCnt ; Index++) {
+          Temp = MulticastAddress->Addr[0];
+          if ((Temp & 0x01) != 0x01) {
+            gBS->RestoreTPL(TplPrevious);
+            return EFI_INVALID_PARAMETER;
+          }
+          MulticastAddress++;
+      }
+
+      Mode->MCastFilterCount = (UINT32)MCastFilterCnt;
+      CopyMem (&Mode->MCastFilter[0],
+               MCastFilter,
+               MCastFilterCnt * sizeof (EFI_MAC_ADDRESS));
+    }
+  }
+
+  if (Enable == 0 && Disable == 0 && !ResetMCastFilter && MCastFilterCnt == 0) {
+    Status = EFI_SUCCESS;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+  }
+
+  if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
+    Status = EFI_INVALID_PARAMETER;
+    gBS->RestoreTPL(TplPrevious);
+    return Status;
+  }
+
+  Mode->ReceiveFilterSetting |= Enable;
+  Mode->ReceiveFilterSetting &= ~Disable;
+
+  Status = ReceiveFilterUpdate (SimpleNetwork);
+
+  if (EFI_DEVICE_ERROR == Status || EFI_INVALID_PARAMETER == Status)
+    Status = 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 perform a more
+                                exhaustive verification operation of the device
+                                during reset.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  //  Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      //
+      //  Update the device state
+      //
+      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+      //
+      //  Reset the device
+      //
+      if (!NicDevice->FirstRst) {
+        Status = EFI_SUCCESS;
+      } else {
+        Status = Ax88772Reset (NicDevice);
+        if (!EFI_ERROR (Status)) {
+          Status = ReceiveFilterUpdate (SimpleNetwork);
+          if (!EFI_ERROR (Status) && !NicDevice->LinkUp && NicDevice->FirstRst) {
+            Status = Ax88772NegotiateLinkStart (NicDevice);
+            NicDevice->FirstRst = FALSE;
+          }
+        }
+      }
+    } else {
+      Status = EFI_NOT_STARTED;
+    }
+  } else {
+    Status = 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 = &NicDevice->SimpleNetwork;
+  SimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
+  SimpleNetwork->Start = SN_Start;
+  SimpleNetwork->Stop = SN_Stop;
+  SimpleNetwork->Initialize = SN_Initialize;
+  SimpleNetwork->Reset = SN_Reset;
+  SimpleNetwork->Shutdown = SN_Shutdown;
+  SimpleNetwork->ReceiveFilters = SN_ReceiveFilters;
+  SimpleNetwork->StationAddress = SN_StationAddress;
+  SimpleNetwork->Statistics = SN_Statistics;
+  SimpleNetwork->MCastIpToMac = SN_MCastIPtoMAC;
+  SimpleNetwork->NvData = SN_NvData;
+  SimpleNetwork->GetStatus = SN_GetStatus;
+  SimpleNetwork->Transmit = SN_Transmit;
+  SimpleNetwork->Receive = SN_Receive;
+  SimpleNetwork->WaitForPacket = NULL;
+  Mode = &NicDevice->SimpleNetworkData;
+  SimpleNetwork->Mode = Mode;
+  Mode->State = EfiSimpleNetworkStopped;
+  Mode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
+  Mode->MediaHeaderSize = sizeof (ETHERNET_HEADER);
+  Mode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
+  Mode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
+                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
+                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
+  Mode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
+  Mode->MaxMCastFilterCount = ASIX_MCAST_FILTER_CNT;
+  Mode->MCastFilterCount = 0;
+  Mode->NvRamSize = 512;
+  Mode->NvRamAccessSize = 2;
+  SetMem (&Mode->BroadcastAddress,
+           PXE_HWADDR_LEN_ETHER,
+           0xff);
+
+  SetMem (&Mode->MCastFilter[0],
+           sizeof(EFI_MAC_ADDRESS) * MAX_MCAST_FILTER_CNT,
+           0);
+
+  Mode->IfType = NET_IFTYPE_ETHERNET;
+  Mode->MacAddressChangeable = TRUE;
+  Mode->MultipleTxSupported = FALSE;
+  Mode->MediaPresentSupported = TRUE;
+  Mode->MediaPresent = FALSE;
+
+  //
+  //  Read the MAC address
+  //
+  NicDevice->PhyId = PHY_ID_INTERNAL;
+  NicDevice->LinkSpeed100Mbps = TRUE;
+  NicDevice->FullDuplex = TRUE;
+  NicDevice->Complete = FALSE;
+  NicDevice->LinkUp = FALSE;
+  NicDevice->Grub_f = FALSE;
+  NicDevice->FirstRst = TRUE;
+  NicDevice->PktCnt = 0;
+
+  Status = 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 = gBS->AllocatePool (EfiBootServicesData,
+                                   AX88772_MAX_BULKIN_SIZE,
+                                   (VOID **) &NicDevice->BulkInbuf);
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = 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 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  Status = EFI_INVALID_PARAMETER;
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkStopped == Mode->State) {
+      //
+      // Initialize the mode structure
+      // NVRAM access is not supported
+      //
+      ZeroMem (Mode, sizeof (*Mode));
+
+      Mode->State = EfiSimpleNetworkStarted;
+      Mode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
+      Mode->MediaHeaderSize = sizeof (ETHERNET_HEADER);
+      Mode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
+      Mode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
+                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
+                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
+      Mode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
+      Mode->MaxMCastFilterCount = ASIX_MCAST_FILTER_CNT;
+      Mode->MCastFilterCount = 0;
+
+      SetMem (&Mode->MCastFilter[0],
+               sizeof(EFI_MAC_ADDRESS) * MAX_MCAST_FILTER_CNT,
+               0);
+
+      Mode->NvRamSize = 512;
+      Mode->NvRamAccessSize = 2;
+      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+      Status = Ax88772MacAddressGet (NicDevice, &Mode->PermanentAddress.Addr[0]);
+      CopyMem (&Mode->CurrentAddress,
+                &Mode->PermanentAddress,
+                sizeof (Mode->CurrentAddress));
+      SetMem(&Mode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
+      Mode->IfType = NET_IFTYPE_ETHERNET;
+      Mode->MacAddressChangeable = TRUE;
+      Mode->MultipleTxSupported = FALSE;
+      Mode->MediaPresentSupported = TRUE;
+      Mode->MediaPresent = FALSE;
+
+    } else {
+      Status = 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 FALSE
+  then the current station address is changed to the address specified by
+  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 network
+                                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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) &&
+      (SimpleNetwork->Mode != NULL) &&
+      ((!Reset) || (Reset && (New != NULL)))) {
+    //
+    // Verify that the adapter is already started
+    //
+    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == 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 = Ax88772MacAddressSet (NicDevice, &Mode->CurrentAddress.Addr[0]);
+    } else {
+      if (EfiSimpleNetworkStarted == Mode->State) {
+        Status = EFI_DEVICE_ERROR; ;
+      } else {
+        Status = EFI_NOT_STARTED ;
+      }
+    }
+  } else {
+    Status = 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 the network interface.
+  @param [in, out] StatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
+                                the size, in bytes, of the resulting table of statistics.
+  @param [out] StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+                                conains the statistics.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_BUFFER_TOO_SMALL  The StatisticsTable is NULL or the buffer 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  Mode = SimpleNetwork->Mode;
+
+  if (EfiSimpleNetworkInitialized == Mode->State) {
+    if ((StatisticsSize != NULL) && (*StatisticsSize == 0)) {
+      Status = EFI_BUFFER_TOO_SMALL;
+      goto EXIT;
+    }
+
+    if(Reset) {
+      Status = EFI_SUCCESS;
+    } else {
+      Status = EFI_SUCCESS;
+    }
+  } else {
+    if (EfiSimpleNetworkStarted == Mode->State) {
+      Status = EFI_DEVICE_ERROR; ;
+    } else {
+      Status = 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // Determine if the interface is started
+    //
+    Mode = SimpleNetwork->Mode;
+
+    if (EfiSimpleNetworkStarted == Mode->State) {
+        Mode->State = EfiSimpleNetworkStopped;
+        Status = EFI_SUCCESS;
+    } else {
+        Status = EFI_NOT_STARTED;
+    }
+  } else {
+    Status = 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // Determine if the interface is already started
+    //
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      //
+      // Stop the adapter
+      //
+      RxFilter = Mode->ReceiveFilterSetting;
+      Mode->ReceiveFilterSetting = 0;
+      Status = SN_Reset (SimpleNetwork, FALSE);
+      Mode->ReceiveFilterSetting = RxFilter;
+      if (!EFI_ERROR (Status)) {
+        //
+        // Update the network state
+        //
+        Mode->State = EfiSimpleNetworkStarted;
+      } else if (EFI_DEVICE_ERROR == Status) {
+        Mode->State = EfiSimpleNetworkStopped;
+      }
+
+    } else {
+      Status = EFI_NOT_STARTED;
+    }
+  } else {
+    Status = 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 must not be NULL.
+  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
+                                data) to be transmitted through the network interface.
+  @param [in] Buffer           A pointer to the packet (media header followed by data) to
+                                to be transmitted.  This parameter can not be NULL.  If
+                                HeaderSize is zero, then the media header is Buffer must
+                                already be filled in by the caller.  If HeaderSize is nonzero,
+                                then the media header will be filled in by the Transmit()
+                                function.
+  @param [in] SrcAddr          The source HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.  If HeaderSize is nonzero and
+                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
+                                is used for the source HW MAC address.
+  @param [in] DestAddr         The destination HW MAC address.  If HeaderSize is zero, then
+                                this parameter is ignored.
+  @param [in] Protocol         The type of header to build.  If HeaderSize is zero, then
+                                this parameter is ignored.
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
+  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
+  //
+  // Verify the parameters
+  //
+  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
+    //
+    // The interface must be running
+    //
+    Mode = SimpleNetwork->Mode;
+    if (EfiSimpleNetworkInitialized == Mode->State) {
+      //
+      // Update the link status
+      //
+      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
+
+      //
+      //  Release the synchronization with Ax88772Timer
+      //
+      if (NicDevice->LinkUp && NicDevice->Complete) {
+        //
+        //  Copy the packet into the USB buffer
+        //
+
+        if ((HeaderSize != 0) && (Mode->MediaHeaderSize != HeaderSize))  {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        }
+        if (BufferSize <  Mode->MediaHeaderSize) {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        }
+        if (Buffer == NULL) {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        }
+        if ((HeaderSize != 0) && (DestAddr == NULL)) {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        }
+        if ((HeaderSize != 0) && (Protocol == NULL)) {
+          Status = EFI_INVALID_PARAMETER;
+          goto EXIT;
+        }
+
+        CopyMem (&NicDevice->TxTest->Data[0], Buffer, BufferSize);
+        NicDevice->TxTest->Length = (UINT16) BufferSize;
+
+        //
+        //  Transmit the packet
+        //
+        Header = (ETHERNET_HEADER *) &NicDevice->TxTest->Data[0];
+        if (HeaderSize != 0) {
+          if (DestAddr != NULL) {
+            CopyMem (&Header->DestAddr, DestAddr, PXE_HWADDR_LEN_ETHER);
+          }
+          if (SrcAddr != NULL) {
+            CopyMem (&Header->SrcAddr, SrcAddr, PXE_HWADDR_LEN_ETHER);
+          } else {
+            CopyMem (&Header->SrcAddr, &Mode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER);
+          }
+          if (Protocol != NULL) {
+            Type = *Protocol;
+          } else {
+            Type = NicDevice->TxTest->Length;
+          }
+          Type = (UINT16)((Type >> 8) | (Type << 8));
+          Header->Type = Type;
+        }
+
+
+        if (NicDevice->TxTest->Length < MIN_ETHERNET_PKT_SIZE) {
+          NicDevice->TxTest->Length = MIN_ETHERNET_PKT_SIZE;
+          ZeroMem (&NicDevice->TxTest->Data[BufferSize],
+                    NicDevice->TxTest->Length - BufferSize);
+        }
+
+        NicDevice->TxTest->LengthBar = ~(NicDevice->TxTest->Length);
+        TransferLength = sizeof (NicDevice->TxTest->Length)
+                       + sizeof (NicDevice->TxTest->LengthBar)
+                       + NicDevice->TxTest->Length;
+
+        if (TransferLength % 512 == 0 || TransferLength % 1024 == 0)
+          TransferLength +=4;
+#if RXTHOU
+        if (NicDevice->RxBurst == 1)
+          NicDevice->RxBurst--;
+#endif
+        //
+        //  Work around USB bus driver bug where a timeout set by receive
+        //  succeeds but the timeout expires immediately after, causing the
+        //  transmit operation to timeout.
+        //
+        UsbIo = NicDevice->UsbIo;
+        Status = UsbIo->UsbBulkTransfer (UsbIo,
+                                           BULK_OUT_ENDPOINT,
+                                           &NicDevice->TxTest->Length,
+                                           &TransferLength,
+                                           0xfffffffe,
+                                           &TransferStatus);
+        if (EFI_SUCCESS == Status) {
+          Status = TransferStatus;
+        }
+        if (EFI_SUCCESS == Status && EFI_SUCCESS == TransferStatus) {
+          NicDevice->TxBuffer = Buffer;
+        } else {
+          if (EFI_DEVICE_ERROR == Status) {
+            SN_Reset (SimpleNetwork, FALSE);
+          }
+          Status = EFI_NOT_READY;
+        }
+      } else {
+        //
+        // No packets available.
+        //
+        Status = EFI_NOT_READY;
+      }
+    } else {
+      if (EfiSimpleNetworkStarted == Mode->State) {
+        Status = EFI_DEVICE_ERROR;
+      } else {
+        Status = EFI_NOT_STARTED;
+      }
+    }
+  } else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+EXIT:
+  gBS->RestoreTPL (TplPrevious);
+  return Status;
+}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [edk2-platform][PATCH v3 4/6] Platform/RaspberryPi: Switch RPi3 USB NIC driver to Ax88772c
  2020-06-08 13:38 [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Samer El-Haj-Mahmoud
                   ` (2 preceding siblings ...)
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 3/6] Drivers/ASIX: Add ASIX Ax88772c driver Samer El-Haj-Mahmoud
@ 2020-06-08 13:38 ` Samer El-Haj-Mahmoud
  2020-07-08 14:55   ` Ard Biesheuvel
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 5/6] Platform/HiSilicon: Switch HiKey " Samer El-Haj-Mahmoud
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Samer El-Haj-Mahmoud @ 2020-06-08 13:38 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Pete Batard, Andrei Warkentin, Leif Lindholm

Switch the ASIX USB NIC driver used in the RPi3 to the new Ax88772c.

Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Pete Batard <pete@akeo.ie>
Cc: Andrei Warkentin <andrey.warkentin@gmail.com>
Cc: Leif Lindholm <leif@nuviainc.com>

Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
---
 Platform/RaspberryPi/RPi3/RPi3.dsc | 2 +-
 Platform/RaspberryPi/RPi3/RPi3.fdf | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Platform/RaspberryPi/RPi3/RPi3.dsc b/Platform/RaspberryPi/RPi3/RPi3.dsc
index 059d16a912ab..b6c568f400ef 100644
--- a/Platform/RaspberryPi/RPi3/RPi3.dsc
+++ b/Platform/RaspberryPi/RPi3/RPi3.dsc
@@ -656,7 +656,7 @@ [Components.common]
   MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
   MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
   MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
-  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
+  Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf
 
   #
   # SD/MMC support
diff --git a/Platform/RaspberryPi/RPi3/RPi3.fdf b/Platform/RaspberryPi/RPi3/RPi3.fdf
index e854cd214153..3c569f57740b 100644
--- a/Platform/RaspberryPi/RPi3/RPi3.fdf
+++ b/Platform/RaspberryPi/RPi3/RPi3.fdf
@@ -289,7 +289,7 @@ [FV.FvMain]
   INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
   INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
   INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
-  INF Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
+  INF Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf
 
   #
   # SD/MMC support
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [edk2-platform][PATCH v3 5/6] Platform/HiSilicon: Switch HiKey USB NIC driver to Ax88772c
  2020-06-08 13:38 [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Samer El-Haj-Mahmoud
                   ` (3 preceding siblings ...)
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 4/6] Platform/RaspberryPi: Switch RPi3 USB NIC driver to Ax88772c Samer El-Haj-Mahmoud
@ 2020-06-08 13:38 ` Samer El-Haj-Mahmoud
  2020-07-08 14:55   ` Ard Biesheuvel
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 6/6] Drivers/OptionRomPkg: Remove old ASIX NIC drivers Samer El-Haj-Mahmoud
  2020-07-08 14:56 ` [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Ard Biesheuvel
  6 siblings, 1 reply; 14+ messages in thread
From: Samer El-Haj-Mahmoud @ 2020-06-08 13:38 UTC (permalink / raw)
  To: devel; +Cc: Ard Biesheuvel, Andrei Warkentin

Switch the ASIX USB NIC driver used in HiKey to the new Ax88772c.

Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Andrei Warkentin <andrey.warkentin@gmail.com>

Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
---
 Platform/Hisilicon/HiKey/HiKey.dsc | 2 +-
 Platform/Hisilicon/HiKey/HiKey.fdf | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Platform/Hisilicon/HiKey/HiKey.dsc b/Platform/Hisilicon/HiKey/HiKey.dsc
index 600f19a30762..83c901cf470c 100644
--- a/Platform/Hisilicon/HiKey/HiKey.dsc
+++ b/Platform/Hisilicon/HiKey/HiKey.dsc
@@ -247,7 +247,7 @@ [Components.common]
   #
   # AX88772 Ethernet Driver
   #
-  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
+  Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf
 
   #
   # FAT filesystem + GPT/MBR partitioning
diff --git a/Platform/Hisilicon/HiKey/HiKey.fdf b/Platform/Hisilicon/HiKey/HiKey.fdf
index 657e6c8ef2ec..d9fe481527fb 100644
--- a/Platform/Hisilicon/HiKey/HiKey.fdf
+++ b/Platform/Hisilicon/HiKey/HiKey.fdf
@@ -158,7 +158,7 @@ [FV.FvMain]
   #
   # AX88772 Ethernet Driver for Apple Ethernet Adapter
   #
-  INF Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
+  INF Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf
 
   #
   # FAT filesystem + GPT/MBR partitioning
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [edk2-platform][PATCH v3 6/6] Drivers/OptionRomPkg: Remove old ASIX NIC drivers
  2020-06-08 13:38 [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Samer El-Haj-Mahmoud
                   ` (4 preceding siblings ...)
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 5/6] Platform/HiSilicon: Switch HiKey " Samer El-Haj-Mahmoud
@ 2020-06-08 13:38 ` Samer El-Haj-Mahmoud
  2020-06-09  0:36   ` Ni, Ray
  2020-07-08 14:56 ` [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Ard Biesheuvel
  6 siblings, 1 reply; 14+ messages in thread
From: Samer El-Haj-Mahmoud @ 2020-06-08 13:38 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Leif Lindholm, Ard Biesheuvel, Michael D Kinney

Remove the olf ASIX Ax88772 and Ax88772b USB networking drivers.
These are now replaced with the new version of the driver (Ax88772c)
under Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c

Cc: Ray Ni <ray.ni@intel.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>

Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
---
 Drivers/OptionRomPkg/OptionRomPkg.dsc                               |    3 +-
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf      |   61 -
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf    |   61 -
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h        |  969 ------------
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h       | 1026 ------------
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c        | 1318 ----------------
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c  |  178 ---
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c  |  507 ------
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c  | 1503 ------------------
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c       |  875 -----------
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c |  175 ---
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c |  696 --------
 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c | 1657 --------------------
 13 files changed, 1 insertion(+), 9028 deletions(-)

diff --git a/Drivers/OptionRomPkg/OptionRomPkg.dsc b/Drivers/OptionRomPkg/OptionRomPkg.dsc
index bea64b585ec6..8a13cc54e6ae 100644
--- a/Drivers/OptionRomPkg/OptionRomPkg.dsc
+++ b/Drivers/OptionRomPkg/OptionRomPkg.dsc
@@ -8,6 +8,7 @@
 #
 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
 # Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+# Copyright (c) 2020, ARM Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -106,8 +107,6 @@ [Components]
   OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
   OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
   OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
-  OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
-  OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
 
 [Components.IA32, Components.X64]
   OptionRomPkg/Application/BltLibSample/BltLibSample.inf
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
deleted file mode 100644
index 12e7ebc5a2cd..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
+++ /dev/null
@@ -1,61 +0,0 @@
-## @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.<BR>
-#
-#  SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
-  INF_VERSION                    = 0x00010018
-  BASE_NAME                      = Ax88772
-  FILE_GUID                      = B15239D6-6A01-4808-A0F7-B7F20F073555
-  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
-  VERSION_STRING                 = 1.0
-
-  ENTRY_POINT                    = EntryPoint
-
-#
-#  VALID_ARCHITECTURES           = IA32 X64 EBC
-#
-
-[Sources.common]
-  Ax88772.h
-  Ax88772.c
-  ComponentName.c
-  DriverBinding.c
-  SimpleNetwork.c
-
-
-[Packages]
-  MdePkg/MdePkg.dec
-  MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
-  UefiLib
-  UefiBootServicesTableLib
-  BaseMemoryLib
-  DebugLib
-  UefiRuntimeLib
-  UefiDriverEntryPoint
-
-[Protocols]
-  gEfiDevicePathProtocolGuid           ## BY_START
-  gEfiSimpleNetworkProtocolGuid        ## BY_START
-  gEfiUsbIoProtocolGuid                ## TO_START
-
-[Depex]
-  gEfiBdsArchProtocolGuid AND
-  gEfiCpuArchProtocolGuid AND
-  gEfiMetronomeArchProtocolGuid AND
-  gEfiMonotonicCounterArchProtocolGuid AND
-  gEfiRealTimeClockArchProtocolGuid AND
-  gEfiResetArchProtocolGuid AND
-  gEfiRuntimeArchProtocolGuid AND
-  gEfiSecurityArchProtocolGuid AND
-  gEfiTimerArchProtocolGuid AND
-  gEfiVariableWriteArchProtocolGuid AND
-  gEfiVariableArchProtocolGuid AND
-  gEfiWatchdogTimerArchProtocolGuid
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
deleted file mode 100644
index 60e43fd2756b..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
+++ /dev/null
@@ -1,61 +0,0 @@
-## @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.<BR>
-#
-#  SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
-  INF_VERSION                    = 0x00010018
-  BASE_NAME                      = Ax88772b
-  FILE_GUID                      = 95C8D770-E1A4-4422-B263-E32F14FD8186
-  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
-  VERSION_STRING                 = 1.0
-
-  ENTRY_POINT                    = EntryPoint
-
-#
-#  VALID_ARCHITECTURES           = IA32 X64 EBC
-#
-
-[Sources.common]
-  Ax88772.h
-  Ax88772.c
-  ComponentName.c
-  DriverBinding.c
-  SimpleNetwork.c
-
-
-[Packages]
-  MdePkg/MdePkg.dec
-  MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
-  UefiLib
-  UefiBootServicesTableLib
-  BaseMemoryLib
-  DebugLib
-  UefiRuntimeLib
-  UefiDriverEntryPoint
-
-[Protocols]  
-  gEfiDevicePathProtocolGuid           ## BY_START
-  gEfiSimpleNetworkProtocolGuid        ## BY_START
-  gEfiUsbIoProtocolGuid                ## TO_START
-
-[Depex]
-  gEfiBdsArchProtocolGuid AND
-  gEfiCpuArchProtocolGuid AND
-  gEfiMetronomeArchProtocolGuid AND
-  gEfiMonotonicCounterArchProtocolGuid AND
-  gEfiRealTimeClockArchProtocolGuid AND
-  gEfiResetArchProtocolGuid AND
-  gEfiRuntimeArchProtocolGuid AND
-  gEfiSecurityArchProtocolGuid AND
-  gEfiTimerArchProtocolGuid AND
-  gEfiVariableWriteArchProtocolGuid AND
-  gEfiVariableArchProtocolGuid AND
-  gEfiWatchdogTimerArchProtocolGuid
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
deleted file mode 100644
index 8840a4f46429..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
+++ /dev/null
@@ -1,969 +0,0 @@
-/** @file
-  Definitions for ASIX AX88772 Ethernet adapter.
-
-  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _AX88772_H_
-#define _AX88772_H_
-
-#include <Uefi.h>
-
-#include <Guid/EventGroup.h>
-
-#include <IndustryStandard/Pci.h>
-
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiRuntimeLib.h>
-
-#include <Protocol/DevicePath.h>
-#include <Protocol/LoadedImage.h>
-#include <Protocol/NetworkInterfaceIdentifier.h>
-#include <Protocol/SimpleNetwork.h>
-#include <Protocol/UsbIo.h>
-
-//------------------------------------------------------------------------------
-//  Macros
-//------------------------------------------------------------------------------
-//
-//Too many output debug info hangs system in Debug tip
-//
-//#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */
-//#define DBG_ENTER()             DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry
-//#define DBG_EXIT()              DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit
-//#define DBG_EXIT_DEC(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with decimal value
-//#define DBG_EXIT_HEX(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with hex value
-//#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with status value
-//#define DBG_EXIT_TF(Status)     DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" ))  ///<  Display routine with TRUE/FALSE value
-//#else   //  _MSC_VER
-#define DBG_ENTER()               ///<  Display routine entry
-#define DBG_EXIT()                ///<  Display routine exit
-#define DBG_EXIT_DEC(Status)      ///<  Display routine exit with decimal value
-#define DBG_EXIT_HEX(Status)      ///<  Display routine exit with hex value
-#define DBG_EXIT_STATUS(Status)   ///<  Display routine exit with status value
-#define DBG_EXIT_TF(Status)       ///<  Display routine with TRUE/FALSE value
-//#endif  //  _MSC_VER
-
-#define USB_IS_IN_ENDPOINT(EndPointAddr)      (((EndPointAddr) & BIT7) != 0)  ///<  Return TRUE/FALSE for IN direction
-#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7) == 0)  ///<  Return TRUE/FALSE for OUT direction
-#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_BULK)      ///<  Return TRUE/FALSE for BULK type
-#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) ///<  Return TRUE/FALSE for INTERRUPT type
-
-//------------------------------------------------------------------------------
-//  Constants
-//------------------------------------------------------------------------------
-
-#define DEBUG_RX_BROADCAST  0x40000000  ///<  Display RX broadcast messages
-#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast messages
-#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast messages
-#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 values
-#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
-
-#define AX88772_MAX_PKT_SIZE  ( 2048 - 4 )  ///< Maximum packet size
-#define ETHERNET_HEADER_SIZE  sizeof ( ETHERNET_HEADER )  ///<  Size in bytes 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 packet size
-#define MAX_BULKIN_SIZE       2048  ///<  Maximum size of one UsbBulk 
-
-
-#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 the NIC
-#define TPL_AX88772         TPL_CALLBACK    ///<  TPL for routine synchronization
-
-/**
-  Verify new TPL value
-
-  This macro which is enabled when debug is enabled verifies that
-  the new TPL value is >= 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 = 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 <= tpl );                \
-  }                                               \
-}
-
-#else   //  MDEPKG_NDEBUG
-
-#define VERIFY_TPL(tpl)
-
-#endif  //  MDEPKG_NDEBUG
-
-//------------------------------------------------------------------------------
-//  Hardware Definition
-//------------------------------------------------------------------------------
-
-#define DEV_SIGNATURE     SIGNATURE_32 ('A','X','8','8')  ///<  Signature of data structures in memory
-
-#define VENDOR_ID         0x0b95  ///<  Vendor ID for Asix
-#define PRODUCT_ID        0x7720  ///<  Product ID for the AX88772 USB 10/100 Ethernet controller
-
-#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 address hash table
-#define RXC_AP            0x0020  ///<  Accept physical address from Multicast 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
-
-//
-//  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=100, 0=10 Mbps
-#define MS_SBP            0x0800  ///<  Stop back pressure
-#define MS_SM             0x1000  ///<  Super MAC support
-
-//
-//  Software PHY Select register
-//
-
-#define SPHY_PSEL         0x01    ///<  Select internal PHY
-#define SPHY_ASEL         0x02    ///<  1=Auto select, 0=Manual select
-
-//
-//  Software Reset register
-//
-
-#define SRR_RR            0x01    ///<  Clear receive frame length error
-#define SRR_RT            0x02    ///<  Clear transmit frame length error
-#define SRR_PRTE          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_RX_CONTROL_WRITE      0x10  ///<  Set the RX control register, Value: New value
-#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value: 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_WRITE  0x16  ///<  Write the multicast hash table, Data: New 8 byte value
-#define CMD_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status register, Data: Register value
-#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status register, Value: New value
-#define CMD_RESET                 0x20  ///<  Reset register, Value: New value
-#define CMD_PHY_SELECT            0x22  ///<  PHY select register, Value: New value
-
-//------------------------------
-//  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 advertisement register
-#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter ability register
-#define PHY_ANER                        6       ///<  Autonegotiation expansion register
-
-//  BMCR - Register 0
-
-#define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears after reset
-#define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
-#define BMCR_100MBPS                    0x2000  ///<  100 Mbits/Sec
-#define BMCR_10MBPS                     0       ///<  10 Mbits/Sec
-#define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable autonegotiation
-#define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
-#define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
-#define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart autonegotiation
-#define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
-#define BMCR_HALF_DUPLEX                0       ///<  Half duplex operation
-#define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test enabled
-
-//  BSMR - Register 1
-
-#define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
-#define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full duplex
-#define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half duplex
-#define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
-#define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half duplex
-#define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with preamble suppressed
-#define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation complete
-#define BMSR_RF                         0x0010  ///<  1 = Remote fault
-#define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform autonegotiation
-#define BMSR_LINKST                     0x0004  ///<  1 = Link up
-#define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition detected
-#define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended register capable
-
-//  ANAR and ANLPAR Registers 4, 5
-
-#define AN_NP                           0x8000  ///<  1 = Next page available
-#define AN_ACK                          0x4000  ///<  1 = Link partner acknowledged
-#define AN_RF                           0x2000  ///<  1 = Remote fault indicated by link partner
-#define AN_FCS                          0x0400  ///<  1 = Flow control ability
-#define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
-#define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
-#define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
-#define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
-#define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
-#define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/CD support
-
-//------------------------------------------------------------------------------
-//  Data Types
-//------------------------------------------------------------------------------
-
-/**
-  Ethernet header layout
-
-  IEEE 802.3-2002 Part 3 specification, section 3.1.1.
-**/
-#pragma pack(1)
-typedef struct {
-  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];  ///<  Destination LAN address
-  UINT8 src_addr[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 * pNext;       ///<  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 identification
-
-  //
-  //  USB data
-  //
-  EFI_HANDLE Controller;        ///<  Controller handle
-  EFI_USB_IO_PROTOCOL * pUsbIo; ///<  USB driver interface
-
-  //
-  //  Simple network protocol data
-  //
-  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;  ///<  Driver's network stack interface
-  EFI_SIMPLE_NETWORK_MODE SimpleNetworkData;  ///<  Data for simple network
-
-  //
-  // Ethernet controller data
-  //
-  BOOLEAN bInitialized;     ///<  Controller initialized
-  VOID * pTxBuffer;         ///<  Last transmit buffer
-  UINT16 PhyId;             ///<  PHY ID
-
-  //
-  //  Link state
-  //
-  BOOLEAN b100Mbps;         ///<  Current link speed, FALSE = 10 Mbps
-  BOOLEAN bComplete;        ///<  Current state of auto-negotiation
-  BOOLEAN bFullDuplex;      ///<  Current duplex
-  BOOLEAN bLinkUp;          ///<  Current link state
-  BOOLEAN bLinkIdle;        ///<  TRUE = No received traffic
-  EFI_EVENT Timer;          ///<  Timer to monitor link state and receive packets
-  UINTN PollCount;          ///<  Number of times the autonegotiation status was polled
-
-  //
-  //  Receive buffer list
-  //
-  RX_TX_PACKET * pRxHead;   ///<  Head of receive packet list
-  RX_TX_PACKET * pRxTail;   ///<  Tail of receive packet list
-  RX_TX_PACKET * pRxFree;   ///<  Free packet list
-  INT32 MulticastHash[2];   ///<  Hash table for multicast destination addresses
-  UINT8 * pBulkInBuff;      ///<  Buffer for Usb Bulk
-} NIC_DEVICE;
-
-#define DEV_FROM_SIMPLE_NETWORK(a)  CR (a, NIC_DEVICE, SimpleNetwork, DEV_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] pSimpleNetwork    Protocol instance pointer
-  @param [in] bExtendedVerification  Indicates that the driver may perform a more
-                                exhaustive verification operation of the device
-                                during reset.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Reset (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bExtendedVerification
-  );
-
-/**
-  Initialize the simple network protocol.
-
-  This routine calls ::Ax88772MacAddressGet to obtain the
-  MAC address.
-
-  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
-
-  @retval EFI_SUCCESS     Setup was successful
-
-**/
-EFI_STATUS
-SN_Setup (
-  IN NIC_DEVICE * pNicDevice
-  );
-
-/**
-  This routine starts the network interface.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_ALREADY_STARTED   The network interface was already started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Start (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  );
-
-/**
-  Set the MAC address.
-  
-  This function modifies or resets the current station address of a
-  network interface.  If Reset is TRUE, then the current station address
-  is set ot the network interface's permanent address.  If Reset if FALSE
-  then the current station address is changed to the address specified by
-  pNew.
-
-  This routine calls ::Ax88772MacAddressSet to update the MAC address
-  in the network adapter.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] bReset            Flag used to reset the station address to the
-                                network interface's permanent address.
-  @param [in] pNew              New station address to be used for the network
-                                interface.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_StationAddress (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bReset,
-  IN EFI_MAC_ADDRESS * pNew
-  );
-
-/**
-  This function resets or collects the statistics on a network interface.
-  If the size of the statistics table specified by StatisticsSize is not
-  big enough for all of the statistics that are collected by the network
-  interface, then a partial buffer of statistics is returned in
-  StatisticsTable.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
-  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
-                                the size, in bytes, of the resulting table of statistics.
-  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
-                                conains the statistics.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Statistics (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bReset,
-  IN OUT UINTN * pStatisticsSize,
-  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
-  );
-
-/**
-  This function stops a network interface.  This call is only valid
-  if the network interface is in the started state.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Stop (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  );
-
-/**
-  This function releases the memory buffers assigned in the Initialize() call.
-  Pending transmits and receives are lost, and interrupts are cleared and disabled.
-  After this call, only Initialize() and Stop() calls may be used.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Shutdown (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  );
-
-/**
-  Send a packet over the network.
-
-  This function places the packet specified by Header and Buffer on
-  the transmit queue.  This function performs a non-blocking transmit
-  operation.  When the transmit is complete, the buffer is returned
-  via the GetStatus() call.
-
-  This routine calls ::Ax88772Rx to empty the network adapter of
-  receive packets.  The routine then passes the transmit packet
-  to the network adapter.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
-                                the Transmit() function.  If HeaderSize is non-zero, then
-                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
-                                and DestAddr and Protocol parameters must not be NULL.
-  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
-                                data) to be transmitted through the network interface.
-  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
-                                to be transmitted.  This parameter can not be NULL.  If
-                                HeaderSize is zero, then the media header is Buffer must
-                                already be filled in by the caller.  If HeaderSize is nonzero,
-                                then the media header will be filled in by the Transmit()
-                                function.
-  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
-                                this parameter is ignored.  If HeaderSize is nonzero and
-                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
-                                is used for the source HW MAC address.
-  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
-                                this parameter is ignored.
-  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
-                                this parameter is ignored.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
-  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Transmit (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN UINTN HeaderSize,
-  IN UINTN BufferSize,
-  IN VOID * pBuffer,
-  IN EFI_MAC_ADDRESS * pSrcAddr,
-  IN EFI_MAC_ADDRESS * pDestAddr,
-  IN UINT16 * pProtocol
-  );
-
-//------------------------------------------------------------------------------
-// Support Routines
-//------------------------------------------------------------------------------
-
-/**
-  Get the MAC address
-
-  This routine calls ::Ax88772UsbCommand to request the MAC
-  address from the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772MacAddressGet (
-  IN NIC_DEVICE * pNicDevice,
-  OUT UINT8 * pMacAddress
-  );
-
-/**
-  Set the MAC address
-
-  This routine calls ::Ax88772UsbCommand to set the MAC address
-  in the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
-
-  @retval EFI_SUCCESS          The MAC address was set.
-  @retval other                The MAC address was not set.
-
-**/
-EFI_STATUS
-Ax88772MacAddressSet (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 * pMacAddress
-  );
-
-/**
-  Clear the multicast hash table
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-**/
-VOID
-Ax88772MulticastClear (
-  IN NIC_DEVICE * pNicDevice
-  );
-
-/**
-  Enable a multicast address in the multicast hash table
-
-  This routine calls ::Ax88772Crc to compute the hash bit for
-  this MAC address.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
-
-**/
-VOID
-Ax88772MulticastSet (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 * pMacAddress
-  );
-
-/**
-  Start the link negotiation
-
-  This routine calls ::Ax88772PhyWrite to start the PHY's link
-  negotiation.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-  @retval EFI_SUCCESS          The link negotiation was started.
-  @retval other                Failed to start the link negotiation.
-
-**/
-EFI_STATUS
-Ax88772NegotiateLinkStart (
-  IN NIC_DEVICE * pNicDevice
-  );
-
-/**
-  Complete the negotiation of the PHY link
-
-  This routine calls ::Ax88772PhyRead to determine if the
-  link negotiation is complete.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in, out] pPollCount  Address of number of times this routine was polled
-  @param [out] pbComplete      Address of boolean to receive complate status.
-  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
-  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
-  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772NegotiateLinkComplete (
-  IN NIC_DEVICE * pNicDevice,
-  IN OUT UINTN * pPollCount,
-  OUT BOOLEAN * pbComplete,
-  OUT BOOLEAN * pbLinkUp,
-  OUT BOOLEAN * pbHiSpeed,
-  OUT BOOLEAN * pbFullDuplex
-  );
-
-/**
-  Read a register from the PHY
-
-  This routine calls ::Ax88772UsbCommand to read a PHY register.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RegisterAddress  Number of the register to read.
-  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
-
-  @retval EFI_SUCCESS          The PHY data is available.
-  @retval other                The PHY data is not valid.
-
-**/
-EFI_STATUS
-Ax88772PhyRead (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 RegisterAddress,
-  IN OUT UINT16 * pPhyData
-  );
-
-/**
-  Write to a PHY register
-
-  This routine calls ::Ax88772UsbCommand to write a PHY register.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RegisterAddress  Number of the register to read.
-  @param [in] PhyData          Address of a buffer to receive the PHY register value
-
-  @retval EFI_SUCCESS          The PHY data was written.
-  @retval other                Failed to wwrite the PHY register.
-
-**/
-EFI_STATUS
-Ax88772PhyWrite (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 RegisterAddress,
-  IN UINT16 PhyData
-  );
-
-/**
-  Reset the AX88772
-
-  This routine uses ::Ax88772UsbCommand to reset the network
-  adapter.  This routine also uses ::Ax88772PhyWrite to reset
-  the PHY.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772Reset (
-  IN NIC_DEVICE * pNicDevice
-  );
-
-/**
-  Receive a frame from the network.
-
-  This routine polls the USB receive interface for a packet.  If a packet
-  is available, this routine adds the receive packet to the list of
-  pending 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] pNicDevice  Pointer to the NIC_DEVICE structure
-  @param [in] bUpdateLink TRUE = Update link status
-
-**/
-VOID
-Ax88772Rx (
-  IN NIC_DEVICE * pNicDevice,
-  IN BOOLEAN bUpdateLink
-  );
-
-/**
-  Enable or disable the receiver
-
-  This routine calls ::Ax88772UsbCommand to update the
-  receiver state.  This routine also calls ::Ax88772MacAddressSet
-  to establish the MAC address for the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RxFilter         Simple network RX filter mask value
-
-  @retval EFI_SUCCESS          The MAC address was set.
-  @retval other                The MAC address was not set.
-
-**/
-EFI_STATUS
-Ax88772RxControl (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT32 RxFilter
-  );
-
-/**
-  Read an SROM location
-
-  This routine calls ::Ax88772UsbCommand to read data from the
-  SROM.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] Address          SROM address
-  @param [out] pData           Buffer to receive the data
-
-  @retval EFI_SUCCESS          The read was successful
-  @retval other                The read failed
-
-**/
-EFI_STATUS
-Ax88772SromRead (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT32 Address,
-  OUT UINT16 * pData
-  );
-
-/**
-  This routine is called at a regular interval to poll for
-  receive packets.
-
-  This routine polls the link state and gets any receive packets
-  by calling ::Ax88772Rx.
-
-  @param [in] Event            Timer event
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-**/
-VOID
-Ax88772Timer (
-  IN EFI_EVENT Event,
-  IN NIC_DEVICE * pNicDevice
-  );
-
-/**
-  Send a command to the USB device.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pRequest         Pointer to the request structure
-  @param [in, out] pBuffer     Data buffer address
-
-  @retval EFI_SUCCESS          The USB transfer was successful
-  @retval other                The USB transfer failed
-
-**/
-EFI_STATUS
-Ax88772UsbCommand (
-  IN NIC_DEVICE * pNicDevice,
-  IN USB_DEVICE_REQUEST * pRequest,
-  IN OUT VOID * pBuffer
-  );
-
-//------------------------------------------------------------------------------
-// EFI Component Name Protocol Support
-//------------------------------------------------------------------------------
-
-extern EFI_COMPONENT_NAME_PROTOCOL   gComponentName;  ///<  Component name protocol declaration
-extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<  Component name 2 protocol declaration
-
-/**
-  Retrieves a Unicode string that is the user readable name of the driver.
-
-  This function retrieves the user readable name of a driver in the form of a
-  Unicode string. If the driver specified by This has a user readable name in
-  the language specified by Language, then a pointer to the driver name is
-  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
-  by This does not support the language specified by Language,
-  then EFI_UNSUPPORTED is returned.
-
-  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
-                                EFI_COMPONENT_NAME_PROTOCOL instance.
-  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
-                                array indicating the language. This is the
-                                language of the driver name that the caller is
-                                requesting, and it must match one of the
-                                languages specified in SupportedLanguages. The
-                                number of languages supported by a driver is up
-                                to the driver writer. Language is specified
-                                in RFC 3066 or ISO 639-2 language code format.
-  @param [out] ppDriverName     A pointer to the Unicode string to return.
-                                This Unicode string is the name of the
-                                driver specified by This in the language
-                                specified by Language.
-
-  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
-                                This and the language specified by Language was
-                                returned in DriverName.
-  @retval EFI_INVALID_PARAMETER Language is NULL.
-  @retval EFI_INVALID_PARAMETER DriverName is NULL.
-  @retval EFI_UNSUPPORTED       The driver specified by This does not support
-                                the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-GetDriverName (
-  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
-  IN  CHAR8 * pLanguage,
-  OUT CHAR16 ** ppDriverName
-  );
-
-
-/**
-  Retrieves a Unicode string that is the user readable name of the controller
-  that is being managed by a driver.
-
-  This function retrieves the user readable name of the controller specified by
-  ControllerHandle and ChildHandle in the form of a Unicode string. If the
-  driver specified by This has a user readable name in the language specified by
-  Language, then a pointer to the controller name is returned in ControllerName,
-  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
-  managing the controller specified by ControllerHandle and ChildHandle,
-  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
-  support the language specified by Language, then EFI_UNSUPPORTED is returned.
-
-  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
-                                EFI_COMPONENT_NAME_PROTOCOL instance.
-  @param [in] ControllerHandle  The handle of a controller that the driver
-                                specified by This is managing.  This handle
-                                specifies the controller whose name is to be
-                                returned.
-  @param [in] ChildHandle       The handle of the child controller to retrieve
-                                the name of.  This is an optional parameter that
-                                may be NULL.  It will be NULL for device
-                                drivers.  It will also be NULL for a bus drivers
-                                that wish to retrieve the name of the bus
-                                controller.  It will not be NULL for a bus
-                                driver that wishes to retrieve the name of a
-                                child controller.
-  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
-                                array indicating the language.  This is the
-                                language of the driver name that the caller is
-                                requesting, and it must match one of the
-                                languages specified in SupportedLanguages. The
-                                number of languages supported by a driver is up
-                                to the driver writer. Language is specified in
-                                RFC 3066 or ISO 639-2 language code format.
-  @param [out] ppControllerName A pointer to the Unicode string to return.
-                                This Unicode string is the name of the
-                                controller specified by ControllerHandle and
-                                ChildHandle in the language specified by
-                                Language from the point of view of the driver
-                                specified by This.
-
-  @retval EFI_SUCCESS           The Unicode string for the user readable name in
-                                the language specified by Language for the
-                                driver specified by This was returned in
-                                DriverName.
-  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
-  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
-                                EFI_HANDLE.
-  @retval EFI_INVALID_PARAMETER Language is NULL.
-  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
-  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
-                                managing the controller specified by
-                                ControllerHandle and ChildHandle.
-  @retval EFI_UNSUPPORTED       The driver specified by This does not support
-                                the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-GetControllerName (
-  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
-  IN  EFI_HANDLE ControllerHandle,
-  IN OPTIONAL EFI_HANDLE ChildHandle,
-  IN  CHAR8 * pLanguage,
-  OUT CHAR16 ** ppControllerName
-  );
-
-//------------------------------------------------------------------------------
-
-#endif  //  _AX88772_H_
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
deleted file mode 100644
index 365929489b8b..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
+++ /dev/null
@@ -1,1026 +0,0 @@
-/** @file
-  Definitions for ASIX AX88772 Ethernet adapter.
-
-  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _AX88772_H_
-#define _AX88772_H_
-
-#include <Uefi.h>
-
-#include <Guid/EventGroup.h>
-
-#include <IndustryStandard/Pci.h>
-
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiRuntimeLib.h>
-
-#include <Protocol/DevicePath.h>
-#include <Protocol/LoadedImage.h>
-#include <Protocol/NetworkInterfaceIdentifier.h>
-#include <Protocol/SimpleNetwork.h>
-#include <Protocol/UsbIo.h>
-
-#define MAX_QUEUE_SIZE 50
-#define MAX_BULKIN_SIZE 16384
-#define HW_HDR_LENGTH 8
-
-
-#define MAX_LINKIDLE_THRESHOLD  20000
-
-
-
-//------------------------------------------------------------------------------
-//  Macros
-//------------------------------------------------------------------------------
-
-#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */
-#define DBG_ENTER()             DEBUG (( 0xffffffff, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry
-#define DBG_EXIT()              DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit
-#define DBG_EXIT_DEC(Status)    DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with decimal value
-#define DBG_EXIT_HEX(Status)    DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with hex value
-#define DBG_EXIT_STATUS(Status) DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with status value
-#define DBG_EXIT_TF(Status)     DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ? L"FALSE" : L"TRUE" ))  ///<  Display routine with TRUE/FALSE value
-#else   //  _MSC_VER
-#define DBG_ENTER()               ///<  Display routine entry
-#define DBG_EXIT()                ///<  Display routine exit
-#define DBG_EXIT_DEC(Status)      ///<  Display routine exit with decimal value
-#define DBG_EXIT_HEX(Status)      ///<  Display routine exit with hex value
-#define DBG_EXIT_STATUS(Status)   ///<  Display routine exit with status value
-#define DBG_EXIT_TF(Status)       ///<  Display routine with TRUE/FALSE value
-#endif  //  _MSC_VER
-
-#define USB_IS_IN_ENDPOINT(EndPointAddr)      (((EndPointAddr) & BIT7) != 0)  ///<  Return TRUE/FALSE for IN direction
-#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7) == 0)  ///<  Return TRUE/FALSE for OUT direction
-#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_BULK)      ///<  Return TRUE/FALSE for BULK type
-#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 | BIT1)) == 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 messages
-#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast messages
-#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast messages
-#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 values
-#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
-
-#define AX88772_MAX_PKT_SIZE  2048  ///< Maximum packet size
-
-#define ETHERNET_HEADER_SIZE  sizeof ( ETHERNET_HEADER )  ///<  Size in bytes 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 packet 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 the NIC
-//#define TPL_AX88772         TPL_CALLBACK    ///<  TPL for routine synchronization
-
-#define HC_DEBUG  0
-#define BULKIN_TIMEOUT  20
-#define AUTONEG_DELAY   500000
-#define AUTONEG_POLLCNT 20
-
-/**
-  Verify new TPL value
-
-  This macro which is enabled when debug is enabled verifies that
-  the new TPL value is >= 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 = 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 <= 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')  ///<  Signature of data structures in memory
-
-#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 address hash table
-#define RXC_AP            0x0020  ///<  Accept physical address from Multicast 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
-
-/*Freddy*/
-#define RXC_RH1M          0x0100  ///<  Rx header 1
-#define RXC_RH2M          0x0200  ///<  Rx header 2
-#define RXC_RH3M          0x0400  ///<  Rx header 3
-/*Freddy*/
-
-//
-//  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=100, 0=10 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=Auto select, 0=Manual select
-
-//
-//  Software Reset register
-//
-
-#define SRR_RR            0x01    ///<  Clear receive frame length error
-#define SRR_RT            0x02    ///<  Clear transmit frame length error
-#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_RX_CONTROL_WRITE      0x10  ///<  Set the RX control register, Value: New value
-#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value: 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_WRITE  0x16  ///<  Write the multicast hash table, Data: New 8 byte value
-#define CMD_MULTICAST_HASH_READ  0x16  ///<  Read the multicast hash table
-#define CMD_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status register, Data: Register value
-#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status register, 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
-
-/*Freddy*/
-#define CMD_RXQTC                 0x2a  ///<  RX Queue Cascade Threshold Control Register
-/*Freddy*/
-
-//------------------------------
-//  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 advertisement register
-#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter ability register
-#define PHY_ANER                        6       ///<  Autonegotiation expansion register
-
-//  BMCR - Register 0
-
-#define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears after reset
-#define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
-#define BMCR_100MBPS                    0x2000  ///<  100 Mbits/Sec
-#define BMCR_10MBPS                     0       ///<  10 Mbits/Sec
-#define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable autonegotiation
-#define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
-#define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
-#define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart autonegotiation
-#define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
-#define BMCR_HALF_DUPLEX                0       ///<  Half duplex operation
-#define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test enabled
-
-//  BSMR - Register 1
-
-#define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
-#define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full duplex
-#define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half duplex
-#define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
-#define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half duplex
-#define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with preamble suppressed
-#define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation complete
-#define BMSR_RF                         0x0010  ///<  1 = Remote fault
-#define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform autonegotiation
-#define BMSR_LINKST                     0x0004  ///<  1 = Link up
-#define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition detected
-#define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended register capable
-
-//  ANAR and ANLPAR Registers 4, 5
-
-#define AN_NP                           0x8000  ///<  1 = Next page available
-#define AN_ACK                          0x4000  ///<  1 = Link partner acknowledged
-#define AN_RF                           0x2000  ///<  1 = Remote fault indicated by link partner
-#define AN_FCS                          0x0400  ///<  1 = Flow control ability
-#define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
-#define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
-#define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
-#define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
-#define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
-#define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/CD support
-
-// asix_flags defines
-#define FLAG_NONE               0
-#define FLAG_TYPE_AX88172       BIT0
-#define FLAG_TYPE_AX88772       BIT1
-#define FLAG_TYPE_AX88772B      BIT2
-#define FLAG_EEPROM_MAC         BIT3  // initial mac address in eeprom
-
-//------------------------------------------------------------------------------
-//  Data Types
-//------------------------------------------------------------------------------
-
-typedef struct {
-   UINT16  VendorId;
-   UINT16  ProductId;
-   INT32   Flags;
-}ASIX_DONGLE;
-
-/**
-  Ethernet header layout
-
-  IEEE 802.3-2002 Part 3 specification, section 3.1.1.
-**/
-#pragma pack(1)
-typedef struct {
-  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];  ///<  Destination LAN address
-  UINT8 src_addr[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 * pNext;       ///<  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()
-
-
-#pragma pack(1)
-typedef struct _RX_PKT {
-  struct _RX_PKT *pNext;
-  BOOLEAN f_Used;
-  UINT16 Length;
-  UINT8 Data [AX88772_MAX_PKT_SIZE] ;
-} RX_PKT;
-#pragma pack()
-
-/**
-  AX88772 control structure
-
-  The driver uses this structure to manage the Asix AX88772 10/100
-  Ethernet controller.
-**/
-typedef struct {
-  UINTN Signature;          ///<  Structure identification
-
-  //
-  //  USB data
-  //
-  EFI_HANDLE Controller;        ///<  Controller handle
-  EFI_USB_IO_PROTOCOL * pUsbIo;  ///<  USB driver interface
-
-  //
-  //  Simple network protocol data
-  //
-  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;  ///<  Driver's network stack interface
-  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork_Backup;
-  EFI_SIMPLE_NETWORK_MODE SimpleNetworkData;  ///<  Data for simple network
-
-  //
-  // Ethernet controller data
-  //
-  BOOLEAN bInitialized;     ///<  Controller initialized
-  VOID * pTxBuffer;         ///<  Last transmit buffer
-  UINT16 PhyId;             ///<  PHY ID
-
-  //
-  //  Link state
-  //
-  BOOLEAN b100Mbps;         ///<  Current link speed, FALSE = 10 Mbps
-  BOOLEAN bComplete;        ///<  Current state of auto-negotiation
-  BOOLEAN bFullDuplex;      ///<  Current duplex
-  BOOLEAN bLinkUp;          ///<  Current link state
-  UINTN  LinkIdleCnt;
-  UINTN PollCount;          ///<  Number of times the autonegotiation status was polled
-  UINT16 CurRxControl;
-  //
-  //  Receive buffer list
-  //
-  RX_TX_PACKET * pRxTest;
-  RX_TX_PACKET * pTxTest;
-
-  INT8 MulticastHash[8];
-  EFI_MAC_ADDRESS MAC;
-  BOOLEAN bHavePkt;
- 
-  EFI_DEVICE_PATH_PROTOCOL                  *MyDevPath;
-  
-  EFI_DRIVER_BINDING_PROTOCOL * DrvBind;
-  
-  RX_PKT * QueueHead;
-  RX_PKT * pNextFill;
-  RX_PKT * pFirstFill;
-  UINTN   PktCntInQueue;
-  UINT8 * pBulkInBuff;
-
-  INT32 Flags;
-
-} NIC_DEVICE;
-
-#define DEV_FROM_SIMPLE_NETWORK(a)  CR (a, NIC_DEVICE, SimpleNetwork, DEV_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] pSimpleNetwork    Protocol instance pointer
-  @param [in] bExtendedVerification  Indicates that the driver may perform a more
-                                exhaustive verification operation of the device
-                                during reset.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Reset (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bExtendedVerification
-  );
-
-/**
-  Initialize the simple network protocol.
-
-  This routine calls ::Ax88772MacAddressGet to obtain the
-  MAC address.
-
-  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
-
-  @retval EFI_SUCCESS     Setup was successful
-
-**/
-EFI_STATUS
-SN_Setup (
-  IN NIC_DEVICE * pNicDevice
-  );
-
-/**
-  This routine starts the network interface.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_ALREADY_STARTED   The network interface was already started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Start (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  );
-
-/**
-  Set the MAC address.
-  
-  This function modifies or resets the current station address of a
-  network interface.  If Reset is TRUE, then the current station address
-  is set ot the network interface's permanent address.  If Reset if FALSE
-  then the current station address is changed to the address specified by
-  pNew.
-
-  This routine calls ::Ax88772MacAddressSet to update the MAC address
-  in the network adapter.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] bReset            Flag used to reset the station address to the
-                                network interface's permanent address.
-  @param [in] pNew              New station address to be used for the network
-                                interface.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_StationAddress (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bReset,
-  IN EFI_MAC_ADDRESS * pNew
-  );
-
-/**
-  This function resets or collects the statistics on a network interface.
-  If the size of the statistics table specified by StatisticsSize is not
-  big enough for all of the statistics that are collected by the network
-  interface, then a partial buffer of statistics is returned in
-  StatisticsTable.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
-  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
-                                the size, in bytes, of the resulting table of statistics.
-  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
-                                conains the statistics.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Statistics (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bReset,
-  IN OUT UINTN * pStatisticsSize,
-  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
-  );
-
-/**
-  This function stops a network interface.  This call is only valid
-  if the network interface is in the started state.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Stop (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  );
-
-/**
-  This function releases the memory buffers assigned in the Initialize() call.
-  Pending transmits and receives are lost, and interrupts are cleared and disabled.
-  After this call, only Initialize() and Stop() calls may be used.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Shutdown (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  );
-
-/**
-  Send a packet over the network.
-
-  This function places the packet specified by Header and Buffer on
-  the transmit queue.  This function performs a non-blocking transmit
-  operation.  When the transmit is complete, the buffer is returned
-  via the GetStatus() call.
-
-  This routine calls ::Ax88772Rx to empty the network adapter of
-  receive packets.  The routine then passes the transmit packet
-  to the network adapter.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
-                                the Transmit() function.  If HeaderSize is non-zero, then
-                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
-                                and DestAddr and Protocol parameters must not be NULL.
-  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
-                                data) to be transmitted through the network interface.
-  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
-                                to be transmitted.  This parameter can not be NULL.  If
-                                HeaderSize is zero, then the media header is Buffer must
-                                already be filled in by the caller.  If HeaderSize is nonzero,
-                                then the media header will be filled in by the Transmit()
-                                function.
-  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
-                                this parameter is ignored.  If HeaderSize is nonzero and
-                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
-                                is used for the source HW MAC address.
-  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
-                                this parameter is ignored.
-  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
-                                this parameter is ignored.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
-  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Transmit (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN UINTN HeaderSize,
-  IN UINTN BufferSize,
-  IN VOID * pBuffer,
-  IN EFI_MAC_ADDRESS * pSrcAddr,
-  IN EFI_MAC_ADDRESS * pDestAddr,
-  IN UINT16 * pProtocol
-  );
-
-//------------------------------------------------------------------------------
-// Support Routines
-//------------------------------------------------------------------------------
-
-/**
-  Get the MAC address
-
-  This routine calls ::Ax88772UsbCommand to request the MAC
-  address from the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772MacAddressGet (
-  IN NIC_DEVICE * pNicDevice,
-  OUT UINT8 * pMacAddress
-  );
-
-/**
-  Set the MAC address
-
-  This routine calls ::Ax88772UsbCommand to set the MAC address
-  in the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
-
-  @retval EFI_SUCCESS          The MAC address was set.
-  @retval other                The MAC address was not set.
-
-**/
-EFI_STATUS
-Ax88772MacAddressSet (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 * pMacAddress
-  );
-
-/**
-  Clear the multicast hash table
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-**/
-VOID
-Ax88772MulticastClear (
-  IN NIC_DEVICE * pNicDevice
-  );
-
-/**
-  Enable a multicast address in the multicast hash table
-
-  This routine calls ::Ax88772Crc to compute the hash bit for
-  this MAC address.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
-
-**/
-VOID
-Ax88772MulticastSet (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 * pMacAddress
-  );
-
-/**
-  Start the link negotiation
-
-  This routine calls ::Ax88772PhyWrite to start the PHY's link
-  negotiation.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-  @retval EFI_SUCCESS          The link negotiation was started.
-  @retval other                Failed to start the link negotiation.
-
-**/
-EFI_STATUS
-Ax88772NegotiateLinkStart (
-  IN NIC_DEVICE * pNicDevice
-  );
-
-/**
-  Complete the negotiation of the PHY link
-
-  This routine calls ::Ax88772PhyRead to determine if the
-  link negotiation is complete.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in, out] pPollCount  Address of number of times this routine was polled
-  @param [out] pbComplete      Address of boolean to receive complate status.
-  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
-  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
-  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772NegotiateLinkComplete (
-  IN NIC_DEVICE * pNicDevice,
-  IN OUT UINTN * pPollCount,
-  OUT BOOLEAN * pbComplete,
-  OUT BOOLEAN * pbLinkUp,
-  OUT BOOLEAN * pbHiSpeed,
-  OUT BOOLEAN * pbFullDuplex
-  );
-
-/**
-  Read a register from the PHY
-
-  This routine calls ::Ax88772UsbCommand to read a PHY register.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RegisterAddress  Number of the register to read.
-  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
-
-  @retval EFI_SUCCESS          The PHY data is available.
-  @retval other                The PHY data is not valid.
-
-**/
-EFI_STATUS
-Ax88772PhyRead (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 RegisterAddress,
-  IN OUT UINT16 * pPhyData
-  );
-
-/**
-  Write to a PHY register
-
-  This routine calls ::Ax88772UsbCommand to write a PHY register.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RegisterAddress  Number of the register to read.
-  @param [in] PhyData          Address of a buffer to receive the PHY register value
-
-  @retval EFI_SUCCESS          The PHY data was written.
-  @retval other                Failed to wwrite the PHY register.
-
-**/
-EFI_STATUS
-Ax88772PhyWrite (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 RegisterAddress,
-  IN UINT16 PhyData
-  );
-
-/**
-  Reset the AX88772
-
-  This routine uses ::Ax88772UsbCommand to reset the network
-  adapter.  This routine also uses ::Ax88772PhyWrite to reset
-  the PHY.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772Reset (
-  IN NIC_DEVICE * pNicDevice
-  );
-
-VOID
-Ax88772ChkLink (
-  IN NIC_DEVICE * pNicDevice,
-  IN BOOLEAN bUpdateLink
-  );
-
-/**
-  Receive a frame from the network.
-
-  This routine polls the USB receive interface for a packet.  If a packet
-  is available, this routine adds the receive packet to the list of
-  pending 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] pNicDevice  Pointer to the NIC_DEVICE structure
-  @param [in] bUpdateLink TRUE = Update link status
-
-**/
-VOID
-Ax88772Rx (
-  IN NIC_DEVICE * pNicDevice,
-  IN BOOLEAN bUpdateLink
-  );
-
-/**
-  Enable or disable the receiver
-
-  This routine calls ::Ax88772UsbCommand to update the
-  receiver state.  This routine also calls ::Ax88772MacAddressSet
-  to establish the MAC address for the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RxFilter         Simple network RX filter mask value
-
-  @retval EFI_SUCCESS          The MAC address was set.
-  @retval other                The MAC address was not set.
-
-**/
-EFI_STATUS
-Ax88772RxControl (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT32 RxFilter
-  );
-
-/**
-  Read an SROM location
-
-  This routine calls ::Ax88772UsbCommand to read data from the
-  SROM.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] Address          SROM address
-  @param [out] pData           Buffer to receive the data
-
-  @retval EFI_SUCCESS          The read was successful
-  @retval other                The read failed
-
-**/
-EFI_STATUS
-Ax88772SromRead (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT32 Address,
-  OUT UINT16 * pData
-  );
-
-/**
-  Send a command to the USB device.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pRequest         Pointer to the request structure
-  @param [in, out] pBuffer     Data buffer address
-
-  @retval EFI_SUCCESS          The USB transfer was successful
-  @retval other                The USB transfer failed
-
-**/
-EFI_STATUS
-Ax88772UsbCommand (
-  IN NIC_DEVICE * pNicDevice,
-  IN USB_DEVICE_REQUEST * pRequest,
-  IN OUT VOID * pBuffer
-  );
-
-//------------------------------------------------------------------------------
-// EFI Component Name Protocol Support
-//------------------------------------------------------------------------------
-
-extern EFI_COMPONENT_NAME_PROTOCOL   gComponentName;  ///<  Component name protocol declaration
-extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<  Component name 2 protocol declaration
-
-/**
-  Retrieves a Unicode string that is the user readable name of the driver.
-
-  This function retrieves the user readable name of a driver in the form of a
-  Unicode string. If the driver specified by This has a user readable name in
-  the language specified by Language, then a pointer to the driver name is
-  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
-  by This does not support the language specified by Language,
-  then EFI_UNSUPPORTED is returned.
-
-  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
-                                EFI_COMPONENT_NAME_PROTOCOL instance.
-  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
-                                array indicating the language. This is the
-                                language of the driver name that the caller is
-                                requesting, and it must match one of the
-                                languages specified in SupportedLanguages. The
-                                number of languages supported by a driver is up
-                                to the driver writer. Language is specified
-                                in RFC 3066 or ISO 639-2 language code format.
-  @param [out] ppDriverName     A pointer to the Unicode string to return.
-                                This Unicode string is the name of the
-                                driver specified by This in the language
-                                specified by Language.
-
-  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
-                                This and the language specified by Language was
-                                returned in DriverName.
-  @retval EFI_INVALID_PARAMETER Language is NULL.
-  @retval EFI_INVALID_PARAMETER DriverName is NULL.
-  @retval EFI_UNSUPPORTED       The driver specified by This does not support
-                                the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-GetDriverName (
-  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
-  IN  CHAR8 * pLanguage,
-  OUT CHAR16 ** ppDriverName
-  );
-
-
-/**
-  Retrieves a Unicode string that is the user readable name of the controller
-  that is being managed by a driver.
-
-  This function retrieves the user readable name of the controller specified by
-  ControllerHandle and ChildHandle in the form of a Unicode string. If the
-  driver specified by This has a user readable name in the language specified by
-  Language, then a pointer to the controller name is returned in ControllerName,
-  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
-  managing the controller specified by ControllerHandle and ChildHandle,
-  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
-  support the language specified by Language, then EFI_UNSUPPORTED is returned.
-
-  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
-                                EFI_COMPONENT_NAME_PROTOCOL instance.
-  @param [in] ControllerHandle  The handle of a controller that the driver
-                                specified by This is managing.  This handle
-                                specifies the controller whose name is to be
-                                returned.
-  @param [in] ChildHandle       The handle of the child controller to retrieve
-                                the name of.  This is an optional parameter that
-                                may be NULL.  It will be NULL for device
-                                drivers.  It will also be NULL for a bus drivers
-                                that wish to retrieve the name of the bus
-                                controller.  It will not be NULL for a bus
-                                driver that wishes to retrieve the name of a
-                                child controller.
-  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
-                                array indicating the language.  This is the
-                                language of the driver name that the caller is
-                                requesting, and it must match one of the
-                                languages specified in SupportedLanguages. The
-                                number of languages supported by a driver is up
-                                to the driver writer. Language is specified in
-                                RFC 3066 or ISO 639-2 language code format.
-  @param [out] ppControllerName A pointer to the Unicode string to return.
-                                This Unicode string is the name of the
-                                controller specified by ControllerHandle and
-                                ChildHandle in the language specified by
-                                Language from the point of view of the driver
-                                specified by This.
-
-  @retval EFI_SUCCESS           The Unicode string for the user readable name in
-                                the language specified by Language for the
-                                driver specified by This was returned in
-                                DriverName.
-  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
-  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
-                                EFI_HANDLE.
-  @retval EFI_INVALID_PARAMETER Language is NULL.
-  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
-  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
-                                managing the controller specified by
-                                ControllerHandle and ChildHandle.
-  @retval EFI_UNSUPPORTED       The driver specified by This does not support
-                                the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-GetControllerName (
-  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
-  IN  EFI_HANDLE ControllerHandle,
-  IN OPTIONAL EFI_HANDLE ChildHandle,
-  IN  CHAR8 * pLanguage,
-  OUT CHAR16 ** ppControllerName
-  );
-  
-VOID 
-FillPkt2Queue (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN UINTN BufLength);
-
-//------------------------------------------------------------------------------
-
-#endif  //  _AX88772_H_
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
deleted file mode 100644
index c9329f506d5d..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
+++ /dev/null
@@ -1,1318 +0,0 @@
-/** @file
-  Implement the interface to the AX88772 Ethernet controller.
-
-  This module implements the interface to the ASIX AX88772
-  USB to Ethernet MAC with integrated 10/100 PHY.  Note that this implementation
-  only supports the integrated PHY since no other test cases were available.
-
-  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Ax88772.h"
-
-
-/**
-  Compute the CRC
-
-  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
-
-  @returns The CRC-32 value associated with this MAC address
-
-**/
-UINT32
-Ax88772Crc (
-  IN UINT8 * pMacAddress
-  )
-{
-  UINT32 BitNumber;
-  INT32 Carry;
-  INT32 Crc;
-  UINT32 Data;
-  UINT8 * pEnd;
-
-  DBG_ENTER ( );
-
-  //
-  //  Walk the MAC address
-  //
-  Crc = -1;
-  pEnd = &pMacAddress[ PXE_HWADDR_LEN_ETHER ];
-  while ( pEnd > pMacAddress ) {
-    Data = *pMacAddress++;
-    
-    
-    //
-    //  CRC32: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
-    //
-    //          1 0000 0100 1100 0001 0001 1101 1011 0111
-    //
-    for ( BitNumber = 0; 8 > BitNumber; BitNumber++ ) {
-      Carry = (( Crc >> 31 ) & 1 ) ^ ( Data & 1 );
-      Crc <<= 1;
-      if ( 0 != Carry ) {
-        Crc ^= 0x04c11db7;
-      }
-      Data >>= 1;
-    }
-  }
-
-  //
-  //  Return the CRC value
-  //
-  DBG_EXIT_HEX ( Crc );
-  return (UINT32) Crc;
-}
-
-
-/**
-  Get the MAC address
-
-  This routine calls ::Ax88772UsbCommand to request the MAC
-  address from the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772MacAddressGet (
-  IN NIC_DEVICE * pNicDevice,
-  OUT UINT8 * pMacAddress
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-  
-  DBG_ENTER ( );
-  
-  //
-  //  Set the register address.
-  //
-  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
-                       | USB_REQ_TYPE_VENDOR
-                       | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_MAC_ADDRESS_READ;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
-
-  //
-  //  Read the PHY register
-  //
-  Status = Ax88772UsbCommand ( pNicDevice,
-                               &SetupMsg,
-                               pMacAddress );
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Set the MAC address
-
-  This routine calls ::Ax88772UsbCommand to set the MAC address
-  in the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
-
-  @retval EFI_SUCCESS          The MAC address was set.
-  @retval other                The MAC address was not set.
-
-**/
-EFI_STATUS
-Ax88772MacAddressSet (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 * pMacAddress
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-  
-  DBG_ENTER ( );
-  
-  //
-  //  Set the register address.
-  //
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                       | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
-  
-  //
-  //  Read the PHY register
-  //
-  Status = Ax88772UsbCommand ( pNicDevice,
-                               &SetupMsg,
-                               pMacAddress );
-  
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Clear the multicast hash table
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-**/
-VOID
-Ax88772MulticastClear (
-  IN NIC_DEVICE * pNicDevice
-  )
-{
-  DBG_ENTER ( );
-
-  //
-  // Clear the multicast hash table
-  //
-  pNicDevice->MulticastHash[0] = 0;
-  pNicDevice->MulticastHash[1] = 0;
-
-  DBG_EXIT ( );
-}
-
-
-/**
-  Enable a multicast address in the multicast hash table
-
-  This routine calls ::Ax88772Crc to compute the hash bit for
-  this MAC address.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
-
-**/
-VOID
-Ax88772MulticastSet (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 * pMacAddress
-  )
-{
-  UINT32 BitNumber;
-  UINT32 Crc;
-  UINT32 Mask;
-
-  DBG_ENTER ( );
-
-  //
-  //  Compute the CRC on the destination address
-  //
-  Crc = Ax88772Crc ( pMacAddress );
-
-  //
-  //  Set the bit corresponding to the destination address
-  //
-  BitNumber = Crc >> 26;
-  if ( 32 > BitNumber ) {
-    Mask = 1 << BitNumber;
-    pNicDevice->MulticastHash[0] |= Mask;
-  }
-  else {
-    Mask = 1 << ( BitNumber - 32 );
-    pNicDevice->MulticastHash[1] |= Mask;
-  }
-
-  //
-  //  Display the multicast address
-  //
-  DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
-            "Enable multicast: 0x%02x-%02x-%02x-%02x-%02x-%02x, CRC: 0x%08x, Bit number: 0x%02x\r\n",
-            pMacAddress[0],
-            pMacAddress[1],
-            pMacAddress[2],
-            pMacAddress[3],
-            pMacAddress[4],
-            pMacAddress[5],
-            Crc,
-            BitNumber ));
-
-  DBG_EXIT ( );
-}
-
-
-/**
-  Start the link negotiation
-
-  This routine calls ::Ax88772PhyWrite to start the PHY's link
-  negotiation.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-  @retval EFI_SUCCESS          The link negotiation was started.
-  @retval other                Failed to start the link negotiation.
-
-**/
-EFI_STATUS
-Ax88772NegotiateLinkStart (
-  IN NIC_DEVICE * pNicDevice
-  )
-{
-  UINT16 Control;
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  // Set the supported capabilities.
-  //
-  Status = Ax88772PhyWrite ( pNicDevice,
-                             PHY_ANAR,
-                             AN_CSMA_CD
-                             | AN_TX_FDX | AN_TX_HDX
-                             | AN_10_FDX | AN_10_HDX );
-  if ( !EFI_ERROR ( Status )) {
-    //
-    // Set the link speed and duplex
-    //
-    Control = BMCR_AUTONEGOTIATION_ENABLE
-            | BMCR_RESTART_AUTONEGOTIATION;
-    if ( pNicDevice->b100Mbps ) {
-      Control |= BMCR_100MBPS;
-    }
-    if ( pNicDevice->bFullDuplex ) {
-      Control |= BMCR_FULL_DUPLEX;
-    }
-    Status = Ax88772PhyWrite ( pNicDevice, PHY_BMCR, Control );
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Complete the negotiation of the PHY link
-
-  This routine calls ::Ax88772PhyRead to determine if the
-  link negotiation is complete.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in, out] pPollCount  Address of number of times this routine was polled
-  @param [out] pbComplete      Address of boolean to receive complate status.
-  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
-  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
-  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772NegotiateLinkComplete (
-  IN NIC_DEVICE * pNicDevice,
-  IN OUT UINTN * pPollCount,
-  OUT BOOLEAN * pbComplete,
-  OUT BOOLEAN * pbLinkUp,
-  OUT BOOLEAN * pbHiSpeed,
-  OUT BOOLEAN * pbFullDuplex
-  )
-{
-  UINT16 Mask;
-  UINT16 PhyData;
-  EFI_STATUS  Status;
-
-  DBG_ENTER ( );
-  
-  //
-  //  Determine if the link is up.
-  //
-  *pbComplete = FALSE;
-
-  //
-  //  Get the link status
-  //
-  Status = Ax88772PhyRead ( pNicDevice,
-                            PHY_BMSR,
-                            &PhyData );
-  if ( !EFI_ERROR ( Status )) {
-    //
-    //  Determine if the autonegotiation is complete.
-    //
-    *pbLinkUp = (BOOLEAN)( 0 != ( PhyData & BMSR_LINKST ));
-    *pbComplete = *pbLinkUp;
-    if ( 0 != *pbComplete ) {
-      //
-      //  Get the partners capabilities.
-      //
-      Status = Ax88772PhyRead ( pNicDevice,
-                                PHY_ANLPAR,
-                                &PhyData );
-      if ( !EFI_ERROR ( Status )) {
-        //
-        //  Autonegotiation is complete
-        //  Determine the link speed.
-        //
-        *pbHiSpeed = (BOOLEAN)( 0 != ( PhyData & ( AN_TX_FDX | AN_TX_HDX )));
-
-        //
-        //  Determine the link duplex.
-        //
-        Mask = ( *pbHiSpeed ) ? AN_TX_FDX : AN_10_FDX;
-        *pbFullDuplex = (BOOLEAN)( 0 != ( PhyData & Mask ));
-      }
-    }
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Read a register from the PHY
-
-  This routine calls ::Ax88772UsbCommand to read a PHY register.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RegisterAddress  Number of the register to read.
-  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
-
-  @retval EFI_SUCCESS          The PHY data is available.
-  @retval other                The PHY data is not valid.
-
-**/
-EFI_STATUS
-Ax88772PhyRead (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 RegisterAddress,
-  IN OUT UINT16 * pPhyData
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  //  Request access to the PHY
-  //
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                       | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                               &SetupMsg,
-                               NULL );
-  if ( !EFI_ERROR ( Status )) {
-    //
-    //  Read the PHY register address.
-    //
-    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
-                         | USB_REQ_TYPE_VENDOR
-                         | USB_TARGET_DEVICE;
-    SetupMsg.Request = CMD_PHY_REG_READ;
-    SetupMsg.Value = pNicDevice->PhyId;
-    SetupMsg.Index = RegisterAddress;
-    SetupMsg.Length = sizeof ( *pPhyData );
-    Status = Ax88772UsbCommand ( pNicDevice,
-                                 &SetupMsg,
-                                 pPhyData );
-    if ( !EFI_ERROR ( Status )) {
-      DEBUG (( DEBUG_PHY | DEBUG_INFO,
-                "PHY %d: 0x%02x --> 0x%04x\r\n",
-                pNicDevice->PhyId,
-                RegisterAddress,
-                *pPhyData ));
-
-      //
-      //  Release the PHY to the hardware
-      //
-      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                           | USB_TARGET_DEVICE;
-      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
-      SetupMsg.Value = 0;
-      SetupMsg.Index = 0;
-      SetupMsg.Length = 0;
-      Status = Ax88772UsbCommand ( pNicDevice,
-                                   &SetupMsg,
-                                   NULL );
-    }
-  }
-
-  //
-  //  Return the operation status.
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Write to a PHY register
-
-  This routine calls ::Ax88772UsbCommand to write a PHY register.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RegisterAddress  Number of the register to read.
-  @param [in] PhyData          Address of a buffer to receive the PHY register value
-
-  @retval EFI_SUCCESS          The PHY data was written.
-  @retval other                Failed to wwrite the PHY register.
-
-**/
-EFI_STATUS
-Ax88772PhyWrite (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 RegisterAddress,
-  IN UINT16 PhyData
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-  
-  DBG_ENTER ( );
-  
-  //
-  //  Request access to the PHY
-  //
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                       | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                               &SetupMsg,
-                               NULL );
-  if ( !EFI_ERROR ( Status )) {
-    //
-    //  Write the PHY register
-    //
-    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                         | USB_TARGET_DEVICE;
-    SetupMsg.Request = CMD_PHY_REG_WRITE;
-    SetupMsg.Value = pNicDevice->PhyId;
-    SetupMsg.Index = RegisterAddress;
-    SetupMsg.Length = sizeof ( PhyData );
-    Status = Ax88772UsbCommand ( pNicDevice,
-                                 &SetupMsg,
-                                 &PhyData );
-    if ( !EFI_ERROR ( Status )) {
-      DEBUG (( DEBUG_PHY | DEBUG_INFO,
-                "PHY %d: 0x%02x <-- 0x%04x\r\n",
-                pNicDevice->PhyId,
-                RegisterAddress,
-                PhyData ));
-
-      //
-      //  Release the PHY to the hardware
-      //
-      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                           | USB_TARGET_DEVICE;
-      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
-      SetupMsg.Value = 0;
-      SetupMsg.Index = 0;
-      SetupMsg.Length = 0;
-      Status = Ax88772UsbCommand ( pNicDevice,
-                                   &SetupMsg,
-                                   NULL );
-    }
-  }
-
-  //
-  //  Return the operation status.
-  //
-  DBG_EXIT_STATUS ( 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] pNicDevice       Pointer to the NIC_DEVICE structure
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772Reset (
-  IN NIC_DEVICE * pNicDevice
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-  
-  DBG_ENTER ( );
-
-  //
-  //  Turn off the MAC
-  //
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                       | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_RX_CONTROL_WRITE;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                               &SetupMsg,
-                               NULL );
-  if ( !EFI_ERROR ( Status )) {
-    DEBUG (( DEBUG_PHY | DEBUG_RX_BROADCAST | DEBUG_RX_MULTICAST
-              | DEBUG_RX_UNICAST | DEBUG_TX | DEBUG_INFO,
-              "MAC reset\r\n" ));
-
-    //
-    //  The link is now idle
-    //
-    pNicDevice->bLinkIdle = TRUE;
-
-    //
-    //  Delay for a bit
-    //
-    gBS->Stall ( RESET_MSEC );
-
-    //
-    //  Select the internal PHY
-    //
-    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                         | USB_TARGET_DEVICE;
-    SetupMsg.Request = CMD_PHY_SELECT;
-    SetupMsg.Value = SPHY_PSEL;
-    SetupMsg.Index = 0;
-    SetupMsg.Length = 0;
-    Status = Ax88772UsbCommand ( pNicDevice,
-                                 &SetupMsg,
-                                 NULL );
-    if ( !EFI_ERROR ( Status )) {
-      //
-      //  Delay for a bit
-      //
-      gBS->Stall ( PHY_RESET_MSEC );
-
-      //
-      //  Clear the internal PHY reset
-      //
-      SetupMsg.Request = CMD_RESET;
-      SetupMsg.Value = SRR_IPRL | SRR_PRL;
-      Status = Ax88772UsbCommand ( pNicDevice,
-                                   &SetupMsg,
-                                   NULL );
-      if ( !EFI_ERROR ( Status )) {
-        //
-        //  Reset the PHY
-        //
-        Status = Ax88772PhyWrite ( pNicDevice,
-                                   PHY_BMCR,
-                                   BMCR_RESET );
-        if ( !EFI_ERROR ( Status )) {
-          //
-          //  Set the gaps
-          //
-          SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                               | USB_TARGET_DEVICE;
-          SetupMsg.Request = CMD_GAPS_WRITE;
-          SetupMsg.Value = 0x0c15;
-          SetupMsg.Index = 0x0e;
-          SetupMsg.Length = 0;
-          Status = Ax88772UsbCommand ( pNicDevice,
-                                       &SetupMsg,
-                                       NULL );
-        }
-      }
-    }
-  }
-
-  //
-  //  Return the operation status.
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-VOID 
-FillPkt2Queue (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINTN BufLength)
-{
-
-  UINT16 * pLength;
-  UINT16 * pLengthBar;
-  UINT8* pData;
-  UINT32 offset;
-  RX_TX_PACKET * pRxPacket;
-  EFI_STATUS Status;
-  
-  for ( offset = 0; offset < BufLength; ){
-    pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);
-    pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);
-    
-    *pLength &= 0x7ff;
-    *pLengthBar &= 0x7ff;
-    *pLengthBar |= 0xf800;
-      
-    if ((*pLength ^ *pLengthBar ) != 0xFFFF) {
-      DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n", BufLength));
-      return;
-    }
-      
-    pRxPacket = pNicDevice->pRxFree;
-    if ( NULL == pRxPacket ) {
-      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
-                                   sizeof( RX_TX_PACKET ),
-                                   (VOID **) &pRxPacket );
-      if ( !EFI_ERROR ( Status )) {
-        //
-        //  Add this packet to the free packet list
-        //
-        pNicDevice->pRxFree = pRxPacket;
-        pRxPacket->pNext = NULL;
-      }
-      else {
-        //
-        //  Use the discard packet buffer
-        //
-        //pRxPacket = &Packet;
-      }
-    }
-      
-
-    pData = pNicDevice->pBulkInBuff + offset + 4;
-    pRxPacket->Length = *pLength;
-    pRxPacket->LengthBar = *(UINT16*) (pNicDevice->pBulkInBuff + offset +2);
-    CopyMem (&pRxPacket->Data[0], pData, *pLength);
-    //DEBUG((DEBUG_INFO, "Packet [%d]\n", *pLength));
-    
-    pNicDevice->pRxFree = pRxPacket->pNext;
-    pRxPacket->pNext = NULL;
-    
-    if ( NULL == pNicDevice->pRxTail ) {
-      pNicDevice->pRxHead = pRxPacket;
-    }
-    else {
-      pNicDevice->pRxTail->pNext = pRxPacket;
-    }
-    pNicDevice->pRxTail = pRxPacket;
-    offset += (*pLength + 4);
-              
-  }
-}
-
-
-
-/**
-  Receive a frame from the network.
-
-  This routine polls the USB receive interface for a packet.  If a packet
-  is available, this routine adds the receive packet to the list of
-  pending 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] pNicDevice  Pointer to the NIC_DEVICE structure
-  @param [in] bUpdateLink TRUE = Update link status
-
-**/
-VOID
-Ax88772Rx (
-  IN NIC_DEVICE * pNicDevice,
-  IN BOOLEAN bUpdateLink
-  )
-{
-  BOOLEAN bFullDuplex;
-  BOOLEAN bLinkUp;
-  BOOLEAN bRxPacket;
-  BOOLEAN bSpeed100;
-  UINTN LengthInBytes;
-  RX_TX_PACKET Packet;
-  RX_TX_PACKET * pRxPacket;
-  EFI_USB_IO_PROTOCOL *pUsbIo;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-  UINT32 TransferStatus;
-
-  //
-  //  Synchronize with Ax88772Timer
-  //
-  VERIFY_TPL ( TPL_AX88772 );
-  TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
-  DEBUG (( DEBUG_TPL | DEBUG_INFO,
-            "%d: TPL\r\n",
-            TPL_AX88772 ));
-
-  //
-  //  Get the link status
-  //
-  if ( bUpdateLink ) {
-    bLinkUp = pNicDevice->bLinkUp;
-    bSpeed100 = pNicDevice->b100Mbps;
-    bFullDuplex = pNicDevice->bFullDuplex;
-    Status = Ax88772NegotiateLinkComplete ( pNicDevice,
-                                            &pNicDevice->PollCount,
-                                            &pNicDevice->bComplete,
-                                            &pNicDevice->bLinkUp,
-                                            &pNicDevice->b100Mbps,
-                                            &pNicDevice->bFullDuplex );
-
-    //
-    // Determine if the autonegotiation is complete
-    //
-    if ( pNicDevice->bComplete ) {
-      if ( pNicDevice->bLinkUp ) {
-        if (( bSpeed100 && ( !pNicDevice->b100Mbps ))
-          || (( !bSpeed100 ) && pNicDevice->b100Mbps )
-          || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))
-          || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {
-          pNicDevice->PollCount = 0;
-          DEBUG (( DEBUG_LINK | DEBUG_INFO,
-                    "Reset to establish proper link setup: %d Mbps, %s duplex\r\n",
-                    pNicDevice->b100Mbps ? 100 : 10,
-                    pNicDevice->bFullDuplex ? L"Full" : L"Half" ));
-          Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );
-        }
-        if (( !bLinkUp ) && pNicDevice->bLinkUp ) {
-          //
-          // Display the autonegotiation status
-          //
-          DEBUG (( DEBUG_LINK | DEBUG_INFO,
-                    "Link: Up, %d Mbps, %s duplex\r\n",
-                    pNicDevice->b100Mbps ? 100 : 10,
-                    pNicDevice->bFullDuplex ? L"Full" : L"Half" ));
-        }
-      }
-    }
-
-    //
-    //  Update the link status
-    //
-    if ( bLinkUp && ( !pNicDevice->bLinkUp )) {
-      DEBUG (( DEBUG_LINK | DEBUG_INFO, "Link: Down\r\n" ));
-    }
-  }
-
-  //
-  //  Loop until all the packets are emptied from the receiver
-  //
-  do {
-    bRxPacket = FALSE;
-
-    //
-    //  Locate a packet for use
-    //
-    pRxPacket = pNicDevice->pRxFree;
-    LengthInBytes = MAX_BULKIN_SIZE;
-    if ( NULL == pRxPacket ) {
-      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
-                                   sizeof ( *pRxPacket ),
-                                   (VOID **) &pRxPacket );
-      if ( !EFI_ERROR ( Status )) {
-        //
-        //  Add this packet to the free packet list
-        //
-        pNicDevice->pRxFree = pRxPacket;
-        pRxPacket->pNext = NULL;
-      }
-      else {
-        //
-        //  Use the discard packet buffer
-        //
-        pRxPacket = &Packet;
-      }
-    }
-
-    //
-    //  Attempt to receive a packet
-    //
-    SetMem (&pNicDevice->pBulkInBuff[0], MAX_BULKIN_SIZE, 0);
-    pUsbIo = pNicDevice->pUsbIo;
-    Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
-                                       USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
-                                       &pNicDevice->pBulkInBuff[0],
-                                       &LengthInBytes,
-                                       2,
-                                       &TransferStatus );
-    if ( LengthInBytes > 0 ) {
-      FillPkt2Queue(pNicDevice, LengthInBytes);
-    }
-    pRxPacket = pNicDevice->pRxHead;
-    if (( !EFI_ERROR ( Status ))
-      && ( 0 < pRxPacket->Length )
-      && ( pRxPacket->Length <= sizeof ( pRxPacket->Data ))
-      && ( LengthInBytes > 0)) {
-
-      //
-      //  Determine if the packet should be received
-      //
-      bRxPacket = TRUE;
-      LengthInBytes = pRxPacket->Length;
-      pNicDevice->bLinkIdle = FALSE;
-      if ( pNicDevice->pRxFree == pRxPacket ) {
-        //
-        //  Display the received packet
-        //
-        if ( 0 != ( pRxPacket->Data[0] & 1 )) {
-          if (( 0xff == pRxPacket->Data[0])
-            && ( 0xff == pRxPacket->Data[1])
-            && ( 0xff == pRxPacket->Data[2])
-            && ( 0xff == pRxPacket->Data[3])
-            && ( 0xff == pRxPacket->Data[4])
-            && ( 0xff == pRxPacket->Data[5])) {
-            DEBUG (( DEBUG_RX_BROADCAST | DEBUG_INFO,
-                      "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
-                      pRxPacket->Data[0],
-                      pRxPacket->Data[1],
-                      pRxPacket->Data[2],
-                      pRxPacket->Data[3],
-                      pRxPacket->Data[4],
-                      pRxPacket->Data[5],
-                      pRxPacket->Data[6],
-                      pRxPacket->Data[7],
-                      pRxPacket->Data[8],
-                      pRxPacket->Data[9],
-                      pRxPacket->Data[10],
-                      pRxPacket->Data[11],
-                      pRxPacket->Data[12],
-                      pRxPacket->Data[13],
-                      LengthInBytes ));
-          }
-          else {
-            DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
-                      "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
-                      pRxPacket->Data[0],
-                      pRxPacket->Data[1],
-                      pRxPacket->Data[2],
-                      pRxPacket->Data[3],
-                      pRxPacket->Data[4],
-                      pRxPacket->Data[5],
-                      pRxPacket->Data[6],
-                      pRxPacket->Data[7],
-                      pRxPacket->Data[8],
-                      pRxPacket->Data[9],
-                      pRxPacket->Data[10],
-                      pRxPacket->Data[11],
-                      pRxPacket->Data[12],
-                      pRxPacket->Data[13],
-                      LengthInBytes ));
-          }
-        }
-        else {
-          DEBUG (( DEBUG_RX_UNICAST | DEBUG_INFO,
-                    "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
-                    pRxPacket->Data[0],
-                    pRxPacket->Data[1],
-                    pRxPacket->Data[2],
-                    pRxPacket->Data[3],
-                    pRxPacket->Data[4],
-                    pRxPacket->Data[5],
-                    pRxPacket->Data[6],
-                    pRxPacket->Data[7],
-                    pRxPacket->Data[8],
-                    pRxPacket->Data[9],
-                    pRxPacket->Data[10],
-                    pRxPacket->Data[11],
-                    pRxPacket->Data[12],
-                    pRxPacket->Data[13],
-                    LengthInBytes ));
-        }
-        
-      }
-      else {
-        //
-        //  Error, not enough buffers for this packet, discard packet
-        //
-        DEBUG (( DEBUG_WARN | DEBUG_INFO,
-                  "WARNING - No buffer, discarding RX packet: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
-                  pRxPacket->Data[0],
-                  pRxPacket->Data[1],
-                  pRxPacket->Data[2],
-                  pRxPacket->Data[3],
-                  pRxPacket->Data[4],
-                  pRxPacket->Data[5],
-                  pRxPacket->Data[6],
-                  pRxPacket->Data[7],
-                  pRxPacket->Data[8],
-                  pRxPacket->Data[9],
-                  pRxPacket->Data[10],
-                  pRxPacket->Data[11],
-                  pRxPacket->Data[12],
-                  pRxPacket->Data[13],
-                  LengthInBytes ));
-      }
-    }
-  }while ( bRxPacket );
-
-  //
-  //  Release the synchronization withhe Ax88772Timer
-  //
-  gBS->RestoreTPL ( TplPrevious );
-  DEBUG (( DEBUG_TPL | DEBUG_INFO,
-            "%d: TPL\r\n",
-            TplPrevious ));
-}
-
-
-/**
-  Enable or disable the receiver
-
-  This routine calls ::Ax88772UsbCommand to update the
-  receiver state.  This routine also calls ::Ax88772MacAddressSet
-  to establish the MAC address for the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RxFilter         Simple network RX filter mask value
-
-  @retval EFI_SUCCESS          The MAC address was set.
-  @retval other                The MAC address was not set.
-
-**/
-EFI_STATUS
-Ax88772RxControl (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT32 RxFilter
-  )
-{
-  UINT16 MediumStatus;
-  INT32 MulticastHash[2];
-  UINT16 RxControl;
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  //  Disable all multicast
-  //
-  MulticastHash[0] = 0;
-  MulticastHash[1] = 0;
-
-  //
-  // Enable the receiver if something is to be received
-  //
-  Status = EFI_SUCCESS;
-  RxControl = RXC_SO | RXC_MFB_16384;
-  if ( 0 != RxFilter ) {
-    //
-    //  Enable the receiver
-    //
-    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
-                         | USB_REQ_TYPE_VENDOR
-                         | USB_TARGET_DEVICE;
-    SetupMsg.Request = CMD_MEDIUM_STATUS_READ;
-    SetupMsg.Value = 0;
-    SetupMsg.Index = 0;
-    SetupMsg.Length = sizeof ( MediumStatus );
-    Status = Ax88772UsbCommand ( pNicDevice,
-                                 &SetupMsg,
-                                 &MediumStatus );
-    if ( !EFI_ERROR ( Status )) {
-      if ( 0 == ( MediumStatus & MS_RE )) {
-        MediumStatus |= MS_RE | MS_ONE;
-        if ( pNicDevice->bFullDuplex ) {
-          MediumStatus |= MS_TFC | MS_RFC;
-        }
-        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                             | USB_TARGET_DEVICE;
-        SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
-        SetupMsg.Value = MediumStatus;
-        SetupMsg.Index = 0;
-        SetupMsg.Length = 0;
-        Status = Ax88772UsbCommand ( pNicDevice,
-                                     &SetupMsg,
-                                     NULL );
-        if ( EFI_ERROR ( Status )) {
-          DEBUG (( DEBUG_ERROR | DEBUG_INFO,
-                    "ERROR - Failed to enable receiver, Status: %r\r\n",
-                    Status ));
-        }
-      }
-    }
-    else {
-      DEBUG (( DEBUG_ERROR | DEBUG_INFO,
-                "ERROR - Failed to read receiver status, Status: %r\r\n",
-                Status ));
-    }
-
-    //
-    //  Enable multicast if requested
-    //
-    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
-      RxControl |= RXC_AM;
-      MulticastHash[0] = pNicDevice->MulticastHash[0];
-      MulticastHash[1] = pNicDevice->MulticastHash[1];
-    }
-
-    //
-    //  Enable all multicast if requested
-    //
-    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST )) {
-      RxControl |= RXC_AMALL;
-      MulticastHash[0] = -1;
-      MulticastHash[1] = -1;
-    }
-
-    //
-    //  Enable broadcast if requested
-    //
-    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST )) {
-      RxControl |= RXC_AB;
-    }
-
-    //
-    //  Enable promiscuous mode if requested
-    //
-    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS )) {
-      RxControl |= RXC_PRO;
-      MulticastHash[0] = -1;
-      MulticastHash[1] = -1;
-    }
-  }
-
-  //
-  //  Update the MAC address
-  //
-  if ( !EFI_ERROR ( Status )) {
-    Status = Ax88772MacAddressSet ( pNicDevice, &pNicDevice->SimpleNetworkData.CurrentAddress.Addr[0]);
-  }
-
-  //
-  //  Update the receiver control
-  //
-  if ( !EFI_ERROR ( Status )) {
-    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                         | USB_TARGET_DEVICE;
-    SetupMsg.Request = CMD_RX_CONTROL_WRITE;
-    SetupMsg.Value = RxControl;
-    SetupMsg.Index = 0;
-    SetupMsg.Length = 0;
-    Status = Ax88772UsbCommand ( pNicDevice,
-                                 &SetupMsg,
-                                 NULL );
-    if ( !EFI_ERROR ( Status )) {
-      DEBUG (( DEBUG_RX_BROADCAST | DEBUG_RX_MULTICAST | DEBUG_RX_UNICAST | DEBUG_INFO,
-                "RxControl: 0x%04x\r\n",
-                RxControl ));
-
-      //
-      //  Update the multicast hash table
-      //
-      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                           | USB_TARGET_DEVICE;
-      SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
-      SetupMsg.Value = 0;
-      SetupMsg.Index = 0;
-      SetupMsg.Length = sizeof ( pNicDevice ->MulticastHash );
-      Status = Ax88772UsbCommand ( pNicDevice,
-                                   &SetupMsg,
-                                   &pNicDevice->MulticastHash );
-      if ( !EFI_ERROR ( Status )) {
-        DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
-                  "Multicast Hash: 0x%02x %02x %02x %02x %02x %02x %02x %02x\r\n",
-                  (UINT8) MulticastHash[0],
-                  (UINT8)( MulticastHash[0] >> 8 ),
-                  (UINT8)( MulticastHash[0] >> 16 ),
-                  (UINT8)( MulticastHash[0] >> 24 ),
-                  (UINT8) MulticastHash[1],
-                  (UINT8)( MulticastHash[1] >> 8 ),
-                  (UINT8)( MulticastHash[1] >> 16 ),
-                  (UINT8)( MulticastHash[1] >> 24 )));
-      }
-      else {
-        DEBUG (( DEBUG_ERROR | DEBUG_INFO,
-                  "ERROR - Failed to update multicast hash table, Status: %r\r\n",
-                  Status ));
-      }
-    }
-    else {
-      DEBUG (( DEBUG_ERROR | DEBUG_INFO,
-                "ERROR - Failed to set receiver control, Status: %r\r\n",
-                Status ));
-    }
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Read an SROM location
-
-  This routine calls ::Ax88772UsbCommand to read data from the
-  SROM.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] Address          SROM address
-  @param [out] pData           Buffer to receive the data
-
-  @retval EFI_SUCCESS          The read was successful
-  @retval other                The read failed
-
-**/
-EFI_STATUS
-Ax88772SromRead (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT32 Address,
-  OUT UINT16 * pData
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  //  Read a value from the SROM
-  //
-  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
-                       | USB_REQ_TYPE_VENDOR
-                       | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_SROM_READ;
-  SetupMsg.Value = (UINT16) Address;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = sizeof ( *pData );
-  Status = Ax88772UsbCommand ( pNicDevice,
-                               &SetupMsg,
-                               pData );
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  This routine is called at a regular interval to poll for
-  receive packets.
-
-  This routine polls the link state and gets any receive packets
-  by calling ::Ax88772Rx.
-
-  @param [in] Event            Timer event
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-**/
-VOID
-Ax88772Timer (
-  IN EFI_EVENT Event,
-  IN NIC_DEVICE * pNicDevice
-  )
-{
-  //
-  //  Use explicit DEBUG messages since the output frequency is too
-  //  high for DEBUG_INFO to keep up and have spare cycles for the
-  //  shell
-  //
-  DEBUG (( DEBUG_TIMER, "Entering Ax88772Timer\r\n" ));
-
-  //
-  //  Poll the link state and get any receive packets
-  //
-  Ax88772Rx ( pNicDevice, FALSE );
-
-  DEBUG (( DEBUG_TIMER, "Exiting Ax88772Timer\r\n" ));
-}
-
-
-/**
-  Send a command to the USB device.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pRequest         Pointer to the request structure
-  @param [in, out] pBuffer     Data buffer address
-
-  @retval EFI_SUCCESS          The USB transfer was successful
-  @retval other                The USB transfer failed
-
-**/
-EFI_STATUS
-Ax88772UsbCommand (
-  IN NIC_DEVICE * pNicDevice,
-  IN USB_DEVICE_REQUEST * pRequest,
-  IN OUT VOID * pBuffer
-  )
-{
-  UINT32 CmdStatus;
-  EFI_USB_DATA_DIRECTION Direction;
-  EFI_USB_IO_PROTOCOL * pUsbIo;
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  // Determine the transfer direction
-  //
-  Direction = EfiUsbNoData;
-  if ( 0 != pRequest->Length ) {
-    Direction = ( 0 != ( pRequest->RequestType & USB_ENDPOINT_DIR_IN ))
-              ? EfiUsbDataIn : EfiUsbDataOut;
-  }
-
-  //
-  // Issue the command
-  //
-  pUsbIo = pNicDevice->pUsbIo;
-  Status = pUsbIo->UsbControlTransfer ( pUsbIo,
-                                        pRequest,
-                                        Direction,
-                                        USB_BUS_TIMEOUT,
-                                        pBuffer,
-                                        pRequest->Length,
-                                        &CmdStatus );
-
-  //
-  // Determine the operation status
-  //
-  if ( !EFI_ERROR ( Status )) {
-    Status = CmdStatus;
-  }
-  else {
-    //
-    // Display any errors
-    //
-    DEBUG (( DEBUG_INFO,
-              "Ax88772UsbCommand - Status: %r\n",
-              Status ));
-
-    //
-    // Only use status values associated with the Simple Network protocol
-    //
-    if ( EFI_TIMEOUT == Status ) {
-      Status = EFI_DEVICE_ERROR;
-    }
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c
deleted file mode 100644
index b6dce7e7cbc4..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/** @file
-  UEFI Component Name(2) protocol implementation.
-
-  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Ax88772.h"
-
-/**
-  EFI Component Name Protocol declaration
-**/
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {
-  GetDriverName,
-  GetControllerName,
-  "eng"
-};
-
-/**
-  EFI Component Name 2 Protocol declaration
-**/
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
-  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
-  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
-  "en"
-};
-
-
-/**
-  Driver name table declaration
-**/
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
-mDriverNameTable[] = {
-  {"eng;en", L"AX88772 Ethernet Driver"},
-  {NULL,  NULL}
-};
-
-/**
-  Retrieves a Unicode string that is the user readable name of the driver.
-
-  This function retrieves the user readable name of a driver in the form of a
-  Unicode string. If the driver specified by This has a user readable name in
-  the language specified by Language, then a pointer to the driver name is
-  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
-  by This does not support the language specified by Language,
-  then EFI_UNSUPPORTED is returned.
-
-  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
-                                EFI_COMPONENT_NAME_PROTOCOL instance.
-  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
-                                array indicating the language. This is the
-                                language of the driver name that the caller is
-                                requesting, and it must match one of the
-                                languages specified in SupportedLanguages. The
-                                number of languages supported by a driver is up
-                                to the driver writer. Language is specified
-                                in RFC 3066 or ISO 639-2 language code format.
-  @param [out] ppDriverName     A pointer to the Unicode string to return.
-                                This Unicode string is the name of the
-                                driver specified by This in the language
-                                specified by Language.
-
-  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
-                                This and the language specified by Language was
-                                returned in DriverName.
-  @retval EFI_INVALID_PARAMETER Language is NULL.
-  @retval EFI_INVALID_PARAMETER DriverName is NULL.
-  @retval EFI_UNSUPPORTED       The driver specified by This does not support
-                                the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-GetDriverName (
-  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
-  IN  CHAR8 * pLanguage,
-  OUT CHAR16 ** ppDriverName
-  )
-{
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-  Status = LookupUnicodeString2 (
-             pLanguage,
-             pThis->SupportedLanguages,
-             mDriverNameTable,
-             ppDriverName,
-             (BOOLEAN)(pThis == &gComponentName)
-             );
-  DBG_EXIT_HEX ( Status );
-  return Status;
-}
-
-/**
-  Retrieves a Unicode string that is the user readable name of the controller
-  that is being managed by a driver.
-
-  This function retrieves the user readable name of the controller specified by
-  ControllerHandle and ChildHandle in the form of a Unicode string. If the
-  driver specified by This has a user readable name in the language specified by
-  Language, then a pointer to the controller name is returned in ControllerName,
-  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
-  managing the controller specified by ControllerHandle and ChildHandle,
-  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
-  support the language specified by Language, then EFI_UNSUPPORTED is returned.
-
-  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
-                                EFI_COMPONENT_NAME_PROTOCOL instance.
-  @param [in] ControllerHandle  The handle of a controller that the driver
-                                specified by This is managing.  This handle
-                                specifies the controller whose name is to be
-                                returned.
-  @param [in] ChildHandle       The handle of the child controller to retrieve
-                                the name of.  This is an optional parameter that
-                                may be NULL.  It will be NULL for device
-                                drivers.  It will also be NULL for a bus drivers
-                                that wish to retrieve the name of the bus
-                                controller.  It will not be NULL for a bus
-                                driver that wishes to retrieve the name of a
-                                child controller.
-  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
-                                array indicating the language.  This is the
-                                language of the driver name that the caller is
-                                requesting, and it must match one of the
-                                languages specified in SupportedLanguages. The
-                                number of languages supported by a driver is up
-                                to the driver writer. Language is specified in
-                                RFC 3066 or ISO 639-2 language code format.
-  @param [out] ppControllerName A pointer to the Unicode string to return.
-                                This Unicode string is the name of the
-                                controller specified by ControllerHandle and
-                                ChildHandle in the language specified by
-                                Language from the point of view of the driver
-                                specified by This.
-
-  @retval EFI_SUCCESS           The Unicode string for the user readable name in
-                                the language specified by Language for the
-                                driver specified by This was returned in
-                                DriverName.
-  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
-  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
-                                EFI_HANDLE.
-  @retval EFI_INVALID_PARAMETER Language is NULL.
-  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
-  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
-                                managing the controller specified by
-                                ControllerHandle and ChildHandle.
-  @retval EFI_UNSUPPORTED       The driver specified by This does not support
-                                the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-GetControllerName (
-  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
-  IN  EFI_HANDLE ControllerHandle,
-  IN OPTIONAL EFI_HANDLE ChildHandle,
-  IN  CHAR8 * pLanguage,
-  OUT CHAR16 ** ppControllerName
-  )
-{
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  // Set the controller name
-  //
-  *ppControllerName = L"AX88772 10/100 Ethernet";
-  Status = EFI_SUCCESS;
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_HEX ( Status );
-  return Status;
-}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
deleted file mode 100644
index 5bcde4b21163..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/** @file
-  Implement the driver binding protocol for Asix AX88772 Ethernet driver.
-
-  Copyright (c) 2011-2013, Intel Corporation. All rights reserved.<BR>
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Ax88772.h"
-
-/**
-  Verify the controller type
-
-  @param [in] pThis                Protocol instance pointer.
-  @param [in] Controller           Handle of device to test.
-  @param [in] pRemainingDevicePath Not used.
-
-  @retval EFI_SUCCESS          This driver supports this device.
-  @retval other                This driver does not support this device.
-
-**/
-EFI_STATUS
-EFIAPI
-DriverSupported (
-  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
-  IN EFI_HANDLE Controller,
-  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
-  )
-{
-  EFI_USB_DEVICE_DESCRIPTOR Device;
-  EFI_USB_IO_PROTOCOL * pUsbIo;
-  EFI_STATUS Status;
-
-  //
-  //  Connect to the USB stack
-  //
-  Status = gBS->OpenProtocol (
-                  Controller,
-                  &gEfiUsbIoProtocolGuid,
-                  (VOID **) &pUsbIo,
-                  pThis->DriverBindingHandle,
-                  Controller,
-                  EFI_OPEN_PROTOCOL_BY_DRIVER
-                  );
-  if (!EFI_ERROR ( Status )) {
-
-    //
-    //  Get the interface descriptor to check the USB class and find a transport
-    //  protocol handler.
-    //
-    Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
-    if (!EFI_ERROR ( Status )) {
-
-      //
-      //  Validate the adapter
-      //
-      if (( VENDOR_ID != Device.IdVendor )
-        || ( PRODUCT_ID != Device.IdProduct )) {
-        Status = EFI_UNSUPPORTED;
-      }
-    }
-
-    //
-    //  Done with the USB stack
-    //
-    gBS->CloseProtocol (
-           Controller,
-           &gEfiUsbIoProtocolGuid,
-           pThis->DriverBindingHandle,
-           Controller
-           );
-  }
-
-  //
-  //  Return the device supported status
-  //
-  return Status;
-}
-
-
-/**
-  Start this driver on Controller by opening UsbIo and DevicePath protocols.
-  Initialize PXE structures, create a copy of the Controller Device Path with the
-  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
-  on the newly created Device Path.
-
-  @param [in] pThis                Protocol instance pointer.
-  @param [in] Controller           Handle of device to work with.
-  @param [in] pRemainingDevicePath Not used, always produce all possible children.
-
-  @retval EFI_SUCCESS          This driver is added to Controller.
-  @retval other                This driver does not support this device.
-
-**/
-EFI_STATUS
-EFIAPI
-DriverStart (
-  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
-  IN EFI_HANDLE Controller,
-  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
-  )
-{
-  EFI_STATUS Status;
-  NIC_DEVICE * pNicDevice;
-  UINTN LengthInBytes;
-
-  DBG_ENTER ( );
-
-  //
-  //  Allocate the device structure
-  //
-  LengthInBytes = sizeof ( *pNicDevice );
-  Status = gBS->AllocatePool (
-                  EfiRuntimeServicesData,
-                  LengthInBytes,
-                  (VOID **) &pNicDevice
-                  );
-  if ( !EFI_ERROR ( Status )) {
-    DEBUG (( DEBUG_POOL | DEBUG_INIT,
-              "0x%08x: Allocate pNicDevice, %d bytes\r\n",
-              pNicDevice,
-              sizeof ( *pNicDevice )));
-
-    //
-    //  Set the structure signature
-    //
-    ZeroMem ( pNicDevice, LengthInBytes );
-    pNicDevice->Signature = DEV_SIGNATURE;
-
-    //
-    //  Connect to the USB I/O protocol
-    //
-    Status = gBS->OpenProtocol (
-                    Controller,
-                    &gEfiUsbIoProtocolGuid,
-                    (VOID **) &pNicDevice->pUsbIo,
-                    pThis->DriverBindingHandle,
-                    Controller,
-                    EFI_OPEN_PROTOCOL_BY_DRIVER
-                    );
-
-    if ( !EFI_ERROR ( Status )) {
-      //
-      //  Allocate the necessary events
-      //
-      Status = gBS->CreateEvent ( EVT_TIMER,
-                                  TPL_AX88772,
-                                  (EFI_EVENT_NOTIFY)Ax88772Timer,
-                                  pNicDevice,
-                                  (VOID **)&pNicDevice->Timer );
-      if ( !EFI_ERROR ( Status )) {
-        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-                  "0x%08x: Allocated timer\r\n",
-                  pNicDevice->Timer ));
-
-        //
-        //  Initialize the simple network protocol
-        //
-        pNicDevice->Controller = Controller;
-        SN_Setup ( pNicDevice );
-
-        //
-        //  Start the timer
-        //
-        Status = gBS->SetTimer ( pNicDevice->Timer,
-                                 TimerPeriodic,
-                                 TIMER_MSEC );
-        if ( !EFI_ERROR ( Status )) {
-          //
-          //  Install both the simple network and device path protocols.
-          //
-          Status = gBS->InstallMultipleProtocolInterfaces (
-                          &Controller,
-                          &gEfiCallerIdGuid,
-                          pNicDevice,
-                          &gEfiSimpleNetworkProtocolGuid,
-                          &pNicDevice->SimpleNetwork,
-                          NULL
-                          );
-
-          if ( !EFI_ERROR ( Status )) {
-            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-                      "Installed: gEfiCallerIdGuid on   0x%08x\r\n",
-                      Controller ));
-            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-                      "Installed: gEfiSimpleNetworkProtocolGuid on   0x%08x\r\n",
-                      Controller ));
-            DBG_EXIT_STATUS ( Status );
-            return Status;
-          }
-          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
-                    "ERROR - Failed to install gEfiSimpleNetworkProtocol on 0x%08x\r\n",
-                    Controller ));
-        }
-        else {
-          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
-                    "ERROR - Failed to start the timer, Status: %r\r\n",
-                    Status ));
-        }
-      }
-      else {
-        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
-                  "ERROR - Failed to create timer event, Status: %r\r\n",
-                  Status ));
-      }
-
-      //
-      //  Done with the USB stack
-      //
-      gBS->CloseProtocol (
-             Controller,
-             &gEfiUsbIoProtocolGuid,
-             pThis->DriverBindingHandle,
-             Controller
-             );
-    }
-
-    //
-    //  Done with the device
-    //
-    gBS->FreePool ( pNicDevice );
-  }
-
-  //
-  //  Display the driver start status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
-  closing the DevicePath and PciIo protocols on Controller.
-
-  @param [in] pThis                Protocol instance pointer.
-  @param [in] Controller           Handle of device to stop driver on.
-  @param [in] NumberOfChildren     How many children need to be stopped.
-  @param [in] pChildHandleBuffer   Not used.
-
-  @retval EFI_SUCCESS          This driver is removed Controller.
-  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
-  @retval other                This driver was not removed from this device.
-
-**/
-EFI_STATUS
-EFIAPI
-DriverStop (
-  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
-  IN  EFI_HANDLE Controller,
-  IN  UINTN NumberOfChildren,
-  IN  EFI_HANDLE * pChildHandleBuffer
-  )
-{
-  NIC_DEVICE * pNicDevice;
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  //  Determine if this driver is already attached
-  //
-  Status = gBS->OpenProtocol (
-                  Controller,
-                  &gEfiCallerIdGuid,
-                  (VOID **) &pNicDevice,
-                  pThis->DriverBindingHandle,
-                  Controller,
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
-                  );
-  if ( !EFI_ERROR ( Status )) {
-    //
-    //  AX88772 driver is no longer running on this device
-    //
-    gBS->UninstallMultipleProtocolInterfaces (
-              Controller,
-              &gEfiSimpleNetworkProtocolGuid,
-              &pNicDevice->SimpleNetwork,
-              &gEfiCallerIdGuid,
-              pNicDevice,
-              NULL );
-    DEBUG (( DEBUG_POOL | DEBUG_INIT,
-                "Removed:   gEfiSimpleNetworkProtocolGuid from 0x%08x\r\n",
-                Controller ));
-    DEBUG (( DEBUG_POOL | DEBUG_INIT,
-                "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",
-                Controller ));
-
-    //
-    //  Stop the timer
-    //
-    if ( NULL != pNicDevice->Timer ) {
-      gBS->SetTimer ( pNicDevice->Timer, TimerCancel, 0 );
-      gBS->CloseEvent ( pNicDevice->Timer );
-      DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-                "0x%08x: Released timer\r\n",
-                pNicDevice->Timer ));
-    }
-
-    //
-    //  Done with the device context
-    //
-    DEBUG (( DEBUG_POOL | DEBUG_INIT,
-              "0x%08x: Free pNicDevice, %d bytes\r\n",
-              pNicDevice,
-              sizeof ( *pNicDevice )));
-    gBS->FreePool ( pNicDevice );
-  }
-
-  //
-  //  Return the shutdown status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Driver binding protocol declaration
-**/
-EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
-  DriverSupported,
-  DriverStart,
-  DriverStop,
-  0xa,
-  NULL,
-  NULL
-};
-
-
-/**
-  Ax88772 driver unload routine.
-
-  @param [in] ImageHandle       Handle for the image.
-
-  @retval EFI_SUCCESS           Image may be unloaded
-
-**/
-EFI_STATUS
-EFIAPI
-DriverUnload (
-  IN EFI_HANDLE ImageHandle
-  )
-{
-  UINTN BufferSize;
-  UINTN Index;
-  UINTN Max;
-  EFI_HANDLE * pHandle;
-  EFI_STATUS Status;
-
-  //
-  //  Determine which devices are using this driver
-  //
-  BufferSize = 0;
-  pHandle = NULL;
-  Status = gBS->LocateHandle (
-                  ByProtocol,
-                  &gEfiCallerIdGuid,
-                  NULL,
-                  &BufferSize,
-                  NULL );
-  if ( EFI_BUFFER_TOO_SMALL == Status ) {
-    for ( ; ; ) {
-      //
-      //  One or more block IO devices are present
-      //
-      Status = gBS->AllocatePool (
-                      EfiRuntimeServicesData,
-                      BufferSize,
-                      (VOID **) &pHandle
-                      );
-      if ( EFI_ERROR ( Status )) {
-        DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-                  "Insufficient memory, failed handle buffer allocation\r\n" ));
-        break;
-      }
-
-      //
-      //  Locate the block IO devices
-      //
-      Status = gBS->LocateHandle (
-                      ByProtocol,
-                      &gEfiCallerIdGuid,
-                      NULL,
-                      &BufferSize,
-                      pHandle );
-      if ( EFI_ERROR ( Status )) {
-        //
-        //  Error getting handles
-        //
-        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
-                "Failure getting Telnet handles\r\n" ));
-        break;
-      }
-      
-      //
-      //  Remove any use of the driver
-      //
-      Max = BufferSize / sizeof ( pHandle[ 0 ]);
-      for ( Index = 0; Max > Index; Index++ ) {
-        Status = DriverStop ( &gDriverBinding,
-                              pHandle[ Index ],
-                              0,
-                              NULL );
-        if ( EFI_ERROR ( Status )) {
-          DEBUG (( DEBUG_WARN | DEBUG_INIT | DEBUG_INFO,
-                    "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));
-          break;
-        }
-      }
-      break;
-    }
-  }
-  else {
-    if ( EFI_NOT_FOUND == Status ) {
-      //
-      //  No devices were found
-      //
-      Status = EFI_SUCCESS;
-    }
-  }
-
-  //
-  //  Free the handle array
-  //
-  if ( NULL != pHandle ) {
-    gBS->FreePool ( pHandle );
-  }
-
-  //
-  //  Remove the protocols installed by the EntryPoint routine.
-  //
-  if ( !EFI_ERROR ( Status )) {
-    gBS->UninstallMultipleProtocolInterfaces (
-            ImageHandle,
-            &gEfiDriverBindingProtocolGuid,
-            &gDriverBinding,
-            &gEfiComponentNameProtocolGuid,
-            &gComponentName,
-            &gEfiComponentName2ProtocolGuid,
-            &gComponentName2,
-            NULL
-            );
-    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-            "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
-            ImageHandle ));
-    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-              "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
-              ImageHandle ));
-    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-              "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
-              ImageHandle ));
-  }
-
-  //
-  //  Return the unload status
-  //
-  return Status;
-}
-
-
-/**
-Ax88772 driver entry point.
-
-@param [in] ImageHandle       Handle for the image.
-@param [in] pSystemTable      Address of the system table.
-
-@retval EFI_SUCCESS           Image successfully loaded.
-
-**/
-EFI_STATUS
-EFIAPI
-EntryPoint (
-  IN EFI_HANDLE ImageHandle,
-  IN EFI_SYSTEM_TABLE * pSystemTable
-  )
-{
-  EFI_STATUS    Status;
-
-  DBG_ENTER ( );
-
-  //
-  //  Add the driver to the list of drivers
-  //
-  Status = EfiLibInstallDriverBindingComponentName2 (
-             ImageHandle,
-             pSystemTable,
-             &gDriverBinding,
-             ImageHandle,
-             &gComponentName,
-             &gComponentName2
-             );
-  ASSERT_EFI_ERROR (Status);
-  if ( !EFI_ERROR ( Status )) {
-    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-              "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",
-              ImageHandle ));
-    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-              "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",
-              ImageHandle ));
-    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-              "Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",
-              ImageHandle ));
-  }
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
deleted file mode 100644
index 0105d04f5d61..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
+++ /dev/null
@@ -1,1503 +0,0 @@
-/** @file
-  Provides the Simple Network functions.
-
-  Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
-  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] pSimpleNetwork    Simple network mode pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-ReceiveFilterUpdate (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  NIC_DEVICE * pNicDevice;
-  EFI_STATUS Status;
-  UINT32 Index;
-
-  DBG_ENTER ( );
-
-  //
-  // Set the MAC address
-  //
-  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-  pMode = pSimpleNetwork->Mode;
-  Status = Ax88772MacAddressSet ( pNicDevice,
-                                  &pMode->CurrentAddress.Addr[0]);
-  if ( !EFI_ERROR ( Status )) {
-    //
-    // Clear the multicast hash table
-    //
-    Ax88772MulticastClear ( pNicDevice );
-
-    //
-    // Load the multicast hash table
-    //
-    if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
-      for ( Index = 0;
-            ( !EFI_ERROR ( Status )) && ( Index < pMode->MCastFilterCount );
-            Index++ ) {
-        //
-        // Enable the next multicast address
-        //
-        Ax88772MulticastSet ( pNicDevice,
-                              &pMode->MCastFilter[ Index ].Addr[0]);
-      }
-    }
-
-    //
-    // Enable the receiver
-    //
-    if ( !EFI_ERROR ( Status )) {
-      Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
-    }
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  This function updates the SNP driver status.
-  
-  This function gets the current interrupt and recycled transmit
-  buffer status from the network interface.  The interrupt status
-  and the media status are returned as a bit mask in InterruptStatus.
-  If InterruptStatus is NULL, the interrupt status will not be read.
-  Upon successful return of the media status, the MediaPresent field
-  of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
-  of media status.  If TxBuf is not NULL, a recycled transmit buffer
-  address will be retrived.  If a recycled transmit buffer address
-  is returned in TxBuf, then the buffer has been successfully
-  transmitted, and the status for that buffer is cleared.
-
-  This function calls ::Ax88772Rx to update the media status and
-  queue any receive packets.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] pInterruptStatus  A pointer to the bit mask of the current active interrupts.
-                                If this is NULL, the interrupt status will not be read from
-                                the device.  If this is not NULL, the interrupt status will
-                                be read from teh device.  When the interrupt status is read,
-                                it will also be cleared.  Clearing the transmit interrupt
-                                does not empty the recycled transmit buffer array.
-  @param [out] ppTxBuf          Recycled transmit buffer address.  The network interface will
-                                not transmit if its internal recycled transmit buffer array is
-                                full.  Reading the transmit buffer does not clear the transmit
-                                interrupt.  If this is NULL, then the transmit buffer status
-                                will not be read.  If there are not transmit buffers to recycle
-                                and TxBuf is not NULL, *TxBuf will be set to NULL.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_GetStatus (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  OUT UINT32 * pInterruptStatus,
-  OUT VOID ** ppTxBuf
-  )
-{
-  BOOLEAN bLinkIdle;
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  NIC_DEVICE * pNicDevice;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-
-  DBG_ENTER ( );
-
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    // Return the transmit buffer
-    //
-    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-    if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
-      *ppTxBuf = pNicDevice->pTxBuffer;
-      pNicDevice->pTxBuffer = NULL;
-    }
-
-    //
-    // Determine if interface is running
-    //
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkStopped != pMode->State ) {
-      //
-      //  Synchronize with Ax88772Timer
-      //
-      VERIFY_TPL ( TPL_AX88772 );
-      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
-
-      //
-      // Update the link status
-      //
-      bLinkIdle = pNicDevice->bLinkIdle;
-      pNicDevice->bLinkIdle = TRUE;
-      Ax88772Rx ( pNicDevice, bLinkIdle );
-      pMode->MediaPresent = pNicDevice->bLinkUp;
-
-      //
-      //  Release the synchronization with Ax88772Timer
-      //
-      gBS->RestoreTPL ( TplPrevious );
-
-      //
-      // Return the interrupt status
-      //
-      if ( NULL != pInterruptStatus ) {
-        *pInterruptStatus = 0;
-      }
-      Status = EFI_SUCCESS;
-    }
-    else {
-      Status = EFI_NOT_STARTED;
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Resets the network adapter and allocates the transmit and receive buffers
-  required by the network interface; optionally, also requests allocation of
-  additional transmit and receive buffers.  This routine must be called before
-  any other routine in the Simple Network protocol is called.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
-  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and receive buffers
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Initialize (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN UINTN ExtraRxBufferSize,
-  IN UINTN ExtraTxBufferSize
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-  
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    // Determine if the interface is already started
-    //
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkStarted == pMode->State ) {
-      if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
-        //
-        // Start the adapter
-        //
-        Status = SN_Reset ( pSimpleNetwork, FALSE );
-        if ( !EFI_ERROR ( Status )) {
-          //
-          // Update the network state
-          //
-          pMode->State = EfiSimpleNetworkInitialized;
-        }
-      }
-      else {
-        Status = EFI_UNSUPPORTED;
-      }
-    }
-    else {
-      Status = EFI_NOT_STARTED;
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-  
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  This function converts a multicast IP address to a multicast HW MAC address
-  for all packet transactions.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] bIPv6             Set to TRUE if the multicast IP address is IPv6 [RFC2460].
-                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
-  @param [in] pIP               The multicast IP address that is to be converted to a
-                                multicast HW MAC address.
-  @param [in] pMAC              The multicast HW MAC address that is to be generated from IP.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_MCastIPtoMAC (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bIPv6,
-  IN EFI_IP_ADDRESS * pIP,
-  IN EFI_MAC_ADDRESS * pMAC
-  )
-{
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  // This is not currently supported
-  //
-  Status = EFI_UNSUPPORTED;
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  This function performs read and write operations on the NVRAM device
-  attached to a network interface.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] ReadWrite         TRUE for read operations, FALSE for write operations.
-  @param [in] Offset            Byte offset in the NVRAM device at which to start the
-                                read or write operation.  This must be a multiple of
-                                NvRamAccessSize and less than NvRamSize.
-  @param [in] BufferSize        The number of bytes to read or write from the NVRAM device.
-                                This must also be a multiple of NvramAccessSize.
-  @param [in, out] pBuffer      A pointer to the data buffer.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_NvData (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN ReadWrite,
-  IN UINTN Offset,
-  IN UINTN BufferSize,
-  IN OUT VOID * pBuffer
-  )
-{
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  // This is not currently supported
-  //
-  Status = EFI_UNSUPPORTED;
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Attempt to receive a packet from the network adapter.
-
-  This function retrieves one packet from the receive queue of the network
-  interface.  If there are no packets on the receive queue, then EFI_NOT_READY
-  will be returned.  If there is a packet on the receive queue, and the size
-  of the packet is smaller than BufferSize, then the contents of the packet
-  will be placed in Buffer, and BufferSize will be udpated with the actual
-  size of the packet.  In addition, if SrcAddr, DestAddr, and Protocol are
-  not NULL, then these values will be extracted from the media header and
-  returned.  If BufferSize is smaller than the received packet, then the
-  size of the receive packet will be placed in BufferSize and
-  EFI_BUFFER_TOO_SMALL will be returned.
-
-  This routine calls ::Ax88772Rx to update the media status and
-  empty the network adapter of receive packets.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [out] pHeaderSize      The size, in bytes, of the media header to be filled in by
-                                the Transmit() function.  If HeaderSize is non-zero, then
-                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
-                                and DestAddr and Protocol parameters must not be NULL.
-  @param [out] pBufferSize      The size, in bytes, of the entire packet (media header and
-                                data) to be transmitted through the network interface.
-  @param [out] pBuffer          A pointer to the packet (media header followed by data) to
-                                to be transmitted.  This parameter can not be NULL.  If
-                                HeaderSize is zero, then the media header is Buffer must
-                                already be filled in by the caller.  If HeaderSize is nonzero,
-                                then the media header will be filled in by the Transmit()
-                                function.
-  @param [out] pSrcAddr         The source HW MAC address.  If HeaderSize is zero, then
-                                this parameter is ignored.  If HeaderSize is nonzero and
-                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
-                                is used for the source HW MAC address.
-  @param [out] pDestAddr        The destination HW MAC address.  If HeaderSize is zero, then
-                                this parameter is ignored.
-  @param [out] pProtocol        The type of header to build.  If HeaderSize is zero, then
-                                this parameter is ignored.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_NOT_READY         No packets have been received on the network interface.
-  @retval EFI_BUFFER_TOO_SMALL  The packet is larger than BufferSize bytes.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Receive (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  OUT UINTN                      * pHeaderSize,
-  OUT UINTN                      * pBufferSize,
-  OUT VOID                       * pBuffer,
-  OUT EFI_MAC_ADDRESS            * pSrcAddr,
-  OUT EFI_MAC_ADDRESS            * pDestAddr,
-  OUT UINT16                     * pProtocol
-  )
-{
-  ETHERNET_HEADER * pHeader;
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  NIC_DEVICE * pNicDevice;
-  RX_TX_PACKET * pRxPacket;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-  UINT16 Type;
-
-  DBG_ENTER ( );
-
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    // The interface must be running
-    //
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkInitialized == pMode->State ) {
-      //
-      //  Synchronize with Ax88772Timer
-      //
-      VERIFY_TPL ( TPL_AX88772 );
-      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
-
-      //
-      // Update the link status
-      //
-      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-      Ax88772Rx ( pNicDevice, FALSE );
-      pMode->MediaPresent = pNicDevice->bLinkUp;
-      if ( pMode->MediaPresent ) {
-        //
-        //  Attempt to receive a packet
-        //
-        pRxPacket = pNicDevice->pRxHead;
-        if ( NULL != pRxPacket ) {
-          pNicDevice->pRxHead = pRxPacket->pNext;
-          if ( NULL == pNicDevice->pRxHead ) {
-            pNicDevice->pRxTail = NULL;
-          }
-
-          //
-          // Copy the received packet into the receive buffer
-          //
-          *pBufferSize = pRxPacket->Length;
-          CopyMem ( pBuffer, &pRxPacket->Data[0], pRxPacket->Length );
-          pHeader = (ETHERNET_HEADER *) &pRxPacket->Data[0];
-          if ( NULL != pHeaderSize ) {
-            *pHeaderSize = sizeof ( *pHeader );
-          }
-          if ( NULL != pDestAddr ) {
-            CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );
-          }
-          if ( NULL != pSrcAddr ) {
-            CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );
-          }
-          if ( NULL != pProtocol ) {
-            Type = pHeader->type;
-            Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
-            *pProtocol = Type;
-          }
-          Status = EFI_SUCCESS;
-        }
-        else {
-          //
-          //  No receive packets available
-          //
-          Status = EFI_NOT_READY;
-        }
-      }
-      else {
-        //
-        //  Link no up
-        //
-        Status = EFI_NOT_READY;
-      }
-
-      //
-      //  Release the synchronization with Ax88772Timer
-      //
-      gBS->RestoreTPL ( TplPrevious );
-    }
-    else {
-      Status = EFI_NOT_STARTED;
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  This function is used to enable and disable the hardware and software receive
-  filters for the underlying network device.
-
-  The receive filter change is broken down into three steps:
-
-    1.  The filter mask bits that are set (ON) in the Enable parameter
-        are added to the current receive filter settings.
-
-    2.  The filter mask bits that are set (ON) in the Disable parameter
-        are subtracted from the updated receive filter settins.
-
-    3.  If the resulting filter settigns is not supported by the hardware
-        a more liberal setting is selected.
-
-  If the same bits are set in the Enable and Disable parameters, then the bits
-  in the Disable parameter takes precedence.
-
-  If the ResetMCastFilter parameter is TRUE, then the multicast address list
-  filter is disabled (irregardless of what other multicast bits are set in
-  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount field
-  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
-
-  After enableing or disabling receive filter settings, software should
-  verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
-  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
-
-  Note: Some network drivers and/or devices will automatically promote
-  receive filter settings if the requested setting can not be honored.
-  For example, if a request for four multicast addresses is made and
-  the underlying hardware only supports two multicast addresses the
-  driver might set the promiscuous or promiscuous multicast receive filters
-  instead.  The receiving software is responsible for discarding any extra
-  packets that get through the hardware receive filters.
-
-  If ResetMCastFilter is TRUE, then the multicast receive filter list
-  on the network interface will be reset to the default multicast receive
-  filter list.  If ResetMCastFilter is FALSE, and this network interface
-  allows the multicast receive filter list to be modified, then the
-  MCastFilterCnt and MCastFilter are used to update the current multicast
-  receive filter list.  The modified receive filter list settings can be
-  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
-
-  This routine calls ::ReceiveFilterUpdate to update the receive
-  state in the network adapter.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] Enable            A bit mask of receive filters to enable on the network interface.
-  @param [in] Disable           A bit mask of receive filters to disable on the network interface.
-                                For backward compatibility with EFI 1.1 platforms, the
-                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
-                                when the ResetMCastFilter parameter is TRUE.
-  @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
-                                filters on the network interface to their default values.
-  @param [in] MCastFilterCnt    Number of multicast HW MAC address in the new MCastFilter list.
-                                This value must be less than or equal to the MaxMCastFilterCnt
-                                field of EFI_SIMPLE_NETWORK_MODE.  This field is optional if
-                                ResetMCastFilter is TRUE.
-  @param [in] pMCastFilter      A pointer to a list of new multicast receive filter HW MAC
-                                addresses.  This list will replace any existing multicast
-                                HW MAC address list.  This field is optional if ResetMCastFilter
-                                is TRUE.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_ReceiveFilters (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN UINT32 Enable,
-  IN UINT32 Disable,
-  IN BOOLEAN bResetMCastFilter,
-  IN UINTN MCastFilterCnt,
-  IN EFI_MAC_ADDRESS * pMCastFilter
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_MAC_ADDRESS * pMulticastAddress;
-  EFI_MAC_ADDRESS * pTableEnd;
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  // Verify the parameters
-  //
-  Status = EFI_INVALID_PARAMETER;
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    pMode = pSimpleNetwork->Mode;
-
-    //
-    //  Update the multicast list if necessary
-    //
-    if ( !bResetMCastFilter ) {
-      if ( 0 != MCastFilterCnt ) {
-        if (( MAX_MCAST_FILTER_CNT >= MCastFilterCnt )
-          && ( NULL != pMCastFilter )) {
-          //
-          // Verify the multicast addresses
-          //
-          pMulticastAddress = pMCastFilter;
-          pTableEnd = pMulticastAddress + MCastFilterCnt;
-          while ( pTableEnd > pMulticastAddress ) {
-            //
-            // The first digit of the multicast address must have the LSB set
-            //
-            if ( 0 == ( pMulticastAddress->Addr[0] & 1 )) {
-              //
-              // Invalid multicast address
-              //
-              break;
-            }
-            pMulticastAddress += 1;
-          }
-          if ( pTableEnd == pMulticastAddress ) {
-            //
-            // Update the multicast filter list.
-            //
-            CopyMem (&pMode->MCastFilter[0],
-                     pMCastFilter,
-                     MCastFilterCnt * sizeof ( *pMCastFilter ));
-            Status = EFI_SUCCESS;
-          }
-        }
-      }
-      else {
-        Status = EFI_SUCCESS;
-      }
-    }
-    else {
-      //
-      // No multicast address list is specified
-      //
-      MCastFilterCnt = 0;
-      Status = EFI_SUCCESS;
-    }
-    if ( !EFI_ERROR ( Status )) {
-      //
-      // The parameters are valid!
-      //
-      pMode->ReceiveFilterSetting |= Enable;
-      pMode->ReceiveFilterSetting &= ~Disable;
-      pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
-
-      //
-      // Update the receive filters in the adapter
-      //
-      Status = ReceiveFilterUpdate ( pSimpleNetwork );
-    }
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Reset the network adapter.
-
-  Resets a network adapter and reinitializes it with the parameters that
-  were provided in the previous call to Initialize ().  The transmit and
-  receive queues are cleared.  Receive filters, the station address, the
-  statistics, and the multicast-IP-to-HW MAC addresses are not reset by
-  this call.
-
-  This routine calls ::Ax88772Reset to perform the adapter specific
-  reset operation.  This routine also starts the link negotiation
-  by calling ::Ax88772NegotiateLinkStart.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] bExtendedVerification  Indicates that the driver may perform a more
-                                exhaustive verification operation of the device
-                                during reset.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Reset (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bExtendedVerification
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  NIC_DEVICE * pNicDevice;
-  RX_TX_PACKET * pRxPacket;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-
-  DBG_ENTER ( );
-
-  //
-  //  Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    //  Synchronize with Ax88772Timer
-    //
-    VERIFY_TPL ( TPL_AX88772 );
-    TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
-
-    //
-    //  Update the device state
-    //
-    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-    pNicDevice->bComplete = FALSE;
-    pNicDevice->bLinkUp = FALSE;
-
-    pMode = pSimpleNetwork->Mode;
-    pMode->MediaPresent = FALSE;
-
-    //
-    //  Discard any received packets
-    //
-    while ( NULL != pNicDevice->pRxHead ) {
-      //
-      //  Remove the packet from the received packet list
-      //
-      pRxPacket = pNicDevice->pRxHead;
-      pNicDevice->pRxHead = pRxPacket->pNext;
-
-      //
-      //  Queue the packet to the free list
-      //
-      pRxPacket->pNext = pNicDevice->pRxFree;
-      pNicDevice->pRxFree = pRxPacket;
-    }
-    pNicDevice->pRxTail = NULL;
-
-    //
-    //  Reset the device
-    //
-    Status = Ax88772Reset ( pNicDevice );
-    if ( !EFI_ERROR ( Status )) {
-      //
-      //  Update the receive filters in the adapter
-      //
-      Status = ReceiveFilterUpdate ( pSimpleNetwork );
-
-      //
-      //  Try to get a connection to the network
-      //
-      if ( !EFI_ERROR ( Status )) {
-        //
-        //  Start the autonegotiation
-        //
-        Status = Ax88772NegotiateLinkStart ( pNicDevice );
-      }
-    }
-
-    //
-    //  Release the synchronization with Ax88772Timer
-    //
-    gBS->RestoreTPL ( TplPrevious );
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Initialize the simple network protocol.
-
-  This routine calls ::Ax88772MacAddressGet to obtain the
-  MAC address.
-
-  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
-
-  @retval EFI_SUCCESS     Setup was successful
-
-**/
-EFI_STATUS
-SN_Setup (
-  IN NIC_DEVICE * pNicDevice
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  // Initialize the simple network protocol
-  //
-  pSimpleNetwork = &pNicDevice->SimpleNetwork;
-  pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
-  pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
-  pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
-  pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
-  pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
-  pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
-  pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
-  pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
-  pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
-  pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
-  pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
-  pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
-  pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
-  pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
-  pSimpleNetwork->WaitForPacket = NULL;
-  pMode = &pNicDevice->SimpleNetworkData;
-  pSimpleNetwork->Mode = pMode;
-
-  pMode->State = EfiSimpleNetworkStopped;
-  pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
-  pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
-  pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
-  pMode->NvRamSize = 0;
-  pMode->NvRamAccessSize = 0;
-  pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
-                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
-                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
-                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
-                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
-  pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
-                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
-  pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
-  pMode->MCastFilterCount = 0;
-  SetMem ( &pMode->BroadcastAddress,
-           PXE_HWADDR_LEN_ETHER,
-           0xff );
-  pMode->IfType = EfiNetworkInterfaceUndi;
-  pMode->MacAddressChangeable = TRUE;
-  pMode->MultipleTxSupported = TRUE;
-  pMode->MediaPresentSupported = TRUE;
-  pMode->MediaPresent = FALSE;
-
-  //
-  //  Read the MAC address
-  //
-  pNicDevice->PhyId = PHY_ID_INTERNAL;
-  pNicDevice->b100Mbps = TRUE;
-  pNicDevice->bFullDuplex = TRUE;
-
-  Status = gBS->AllocatePool ( EfiRuntimeServicesData, 
-                               MAX_BULKIN_SIZE,
-                               (VOID **) &pNicDevice->pBulkInBuff);
-  if ( EFI_ERROR(Status)) {
-    DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
-    return Status;
-  }
-        
-  Status = Ax88772MacAddressGet (
-                pNicDevice,
-                &pMode->PermanentAddress.Addr[0]);
-  if ( !EFI_ERROR ( Status )) {
-    //
-    //  Display the MAC address
-    //
-    DEBUG (( DEBUG_MAC_ADDRESS | DEBUG_INFO,
-              "MAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
-              pMode->PermanentAddress.Addr[0],
-              pMode->PermanentAddress.Addr[1],
-              pMode->PermanentAddress.Addr[2],
-              pMode->PermanentAddress.Addr[3],
-              pMode->PermanentAddress.Addr[4],
-              pMode->PermanentAddress.Addr[5]));
-
-    //
-    //  Use the hardware address as the current address
-    //
-    CopyMem ( &pMode->CurrentAddress,
-              &pMode->PermanentAddress,
-              PXE_HWADDR_LEN_ETHER );
-  }
-
-  //
-  //  Return the setup status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  This routine starts the network interface.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_ALREADY_STARTED   The network interface was already started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Start (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  )
-{
-  NIC_DEVICE * pNicDevice;
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_STATUS Status;
-  
-  DBG_ENTER ( );
-  
-  //
-  // Verify the parameters
-  //
-  Status = EFI_INVALID_PARAMETER;
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkStopped == pMode->State ) {
-      //
-      // Initialize the mode structure
-      // NVRAM access is not supported
-      //
-      ZeroMem ( pMode, sizeof ( *pMode ));
-  
-      pMode->State = EfiSimpleNetworkStarted;
-      pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
-      pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
-      pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
-      pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
-                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
-                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
-                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
-                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
-      pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
-      pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
-      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-      Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
-      CopyMem ( &pMode->CurrentAddress,
-                &pMode->PermanentAddress,
-                sizeof ( pMode->CurrentAddress ));
-      pMode->BroadcastAddress.Addr[0] = 0xff;
-      pMode->BroadcastAddress.Addr[1] = 0xff;
-      pMode->BroadcastAddress.Addr[2] = 0xff;
-      pMode->BroadcastAddress.Addr[3] = 0xff;
-      pMode->BroadcastAddress.Addr[4] = 0xff;
-      pMode->BroadcastAddress.Addr[5] = 0xff;
-      pMode->IfType = 1;
-      pMode->MacAddressChangeable = TRUE;
-      pMode->MultipleTxSupported = TRUE;
-      pMode->MediaPresentSupported = TRUE;
-      pMode->MediaPresent = FALSE;
-    }
-    else {
-      Status = EFI_ALREADY_STARTED;
-    }
-  }
-  
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Set the MAC address.
-  
-  This function modifies or resets the current station address of a
-  network interface.  If Reset is TRUE, then the current station address
-  is set ot the network interface's permanent address.  If Reset if FALSE
-  then the current station address is changed to the address specified by
-  pNew.
-
-  This routine calls ::Ax88772MacAddressSet to update the MAC address
-  in the network adapter.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] bReset            Flag used to reset the station address to the
-                                network interface's permanent address.
-  @param [in] pNew              New station address to be used for the network
-                                interface.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_StationAddress (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bReset,
-  IN EFI_MAC_ADDRESS * pNew
-  )
-{
-  NIC_DEVICE * pNicDevice;
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork )
-    && ( NULL != pSimpleNetwork->Mode )
-    && (( !bReset ) || ( bReset && ( NULL != pNew )))) {
-    //
-    // Verify that the adapter is already started
-    //
-    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkStarted == pMode->State ) {
-      //
-      // Determine the adapter MAC address
-      //
-      if ( bReset ) {
-        //
-        // Use the permanent address
-        //
-        CopyMem ( &pMode->CurrentAddress,
-                  &pMode->PermanentAddress,
-                  sizeof ( pMode->CurrentAddress ));
-      }
-      else {
-        //
-        // Use the specified address
-        //
-        CopyMem ( &pMode->CurrentAddress,
-                  pNew,
-                  sizeof ( pMode->CurrentAddress ));
-      }
-
-      //
-      // Update the address on the adapter
-      //
-      Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
-    }
-    else {
-      Status = EFI_NOT_STARTED;
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  This function resets or collects the statistics on a network interface.
-  If the size of the statistics table specified by StatisticsSize is not
-  big enough for all of the statistics that are collected by the network
-  interface, then a partial buffer of statistics is returned in
-  StatisticsTable.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
-  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
-                                the size, in bytes, of the resulting table of statistics.
-  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
-                                conains the statistics.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Statistics (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bReset,
-  IN OUT UINTN * pStatisticsSize,
-  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
-  )
-{
-  EFI_STATUS Status;
-
-  DBG_ENTER ( );
-
-  //
-  // This is not currently supported
-  //
-  Status = EFI_UNSUPPORTED;
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  This function stops a network interface.  This call is only valid
-  if the network interface is in the started state.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Stop (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_STATUS Status;
-  
-  DBG_ENTER ( );
-  
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    // Determine if the interface is started
-    //
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkStopped != pMode->State ) {
-      if ( EfiSimpleNetworkStarted == pMode->State ) {
-        //
-        //  Release the resources acquired in SN_Start
-        //
-
-        //
-        //  Mark the adapter as stopped
-        //
-        pMode->State = EfiSimpleNetworkStopped;
-        Status = EFI_SUCCESS;
-      }
-      else {
-        Status = EFI_UNSUPPORTED;
-      }
-    }
-    else {
-      Status = EFI_NOT_STARTED;
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-  
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  This function releases the memory buffers assigned in the Initialize() call.
-  Pending transmits and receives are lost, and interrupts are cleared and disabled.
-  After this call, only Initialize() and Stop() calls may be used.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Shutdown (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  UINT32 RxFilter;
-  EFI_STATUS Status;
-  
-  DBG_ENTER ( );
-  
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    // Determine if the interface is already started
-    //
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkInitialized == pMode->State ) {
-      //
-      // Stop the adapter
-      //
-      RxFilter = pMode->ReceiveFilterSetting;
-      pMode->ReceiveFilterSetting = 0;
-      Status = SN_Reset ( pSimpleNetwork, FALSE );
-      pMode->ReceiveFilterSetting = RxFilter;
-      if ( !EFI_ERROR ( Status )) {
-        //
-        // Release the resources acquired by SN_Initialize
-        //
-
-        //
-        // Update the network state
-        //
-        pMode->State = EfiSimpleNetworkStarted;
-      }
-    }
-    else {
-      Status = EFI_NOT_STARTED;
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-  
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
-
-
-/**
-  Send a packet over the network.
-
-  This function places the packet specified by Header and Buffer on
-  the transmit queue.  This function performs a non-blocking transmit
-  operation.  When the transmit is complete, the buffer is returned
-  via the GetStatus() call.
-
-  This routine calls ::Ax88772Rx to empty the network adapter of
-  receive packets.  The routine then passes the transmit packet
-  to the network adapter.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
-                                the Transmit() function.  If HeaderSize is non-zero, then
-                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
-                                and DestAddr and Protocol parameters must not be NULL.
-  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
-                                data) to be transmitted through the network interface.
-  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
-                                to be transmitted.  This parameter can not be NULL.  If
-                                HeaderSize is zero, then the media header is Buffer must
-                                already be filled in by the caller.  If HeaderSize is nonzero,
-                                then the media header will be filled in by the Transmit()
-                                function.
-  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
-                                this parameter is ignored.  If HeaderSize is nonzero and
-                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
-                                is used for the source HW MAC address.
-  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
-                                this parameter is ignored.
-  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
-                                this parameter is ignored.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
-  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Transmit (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN UINTN HeaderSize,
-  IN UINTN BufferSize,
-  IN VOID * pBuffer,
-  IN EFI_MAC_ADDRESS * pSrcAddr,
-  IN EFI_MAC_ADDRESS * pDestAddr,
-  IN UINT16 * pProtocol
-  )
-{
-  RX_TX_PACKET Packet;
-  ETHERNET_HEADER * pHeader;
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  NIC_DEVICE * pNicDevice;
-  EFI_USB_IO_PROTOCOL * pUsbIo;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-  UINTN TransferLength;
-  UINT32 TransferStatus;
-  UINT16 Type;
-
-  DBG_ENTER ( );
-
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    // The interface must be running
-    //
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkInitialized == pMode->State ) {
-      //
-      //  Synchronize with Ax88772Timer
-      //
-      VERIFY_TPL ( TPL_AX88772 );
-      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
-
-      //
-      // Update the link status
-      //
-      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-
-      //
-      //No need to call receive to receive packet
-      //
-      //Ax88772Rx ( pNicDevice, FALSE );
-      pMode->MediaPresent = pNicDevice->bLinkUp;
-
-      //
-      //  Release the synchronization with Ax88772Timer
-      //
-      gBS->RestoreTPL ( TplPrevious );
-      if ( pMode->MediaPresent ) {
-        //
-        //  Copy the packet into the USB buffer
-        //
-        CopyMem ( &Packet.Data[0], pBuffer, BufferSize );
-        Packet.Length = (UINT16) BufferSize;
-
-        //
-        //  Transmit the packet
-        //
-        pHeader = (ETHERNET_HEADER *) &Packet.Data[0];
-        if ( 0 != HeaderSize ) {
-          if ( NULL != pDestAddr ) {
-            CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
-          }
-          if ( NULL != pSrcAddr ) {
-            CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
-          }
-          else {
-            CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
-          }
-          if ( NULL != pProtocol ) {
-            Type = *pProtocol;
-          }
-          else {
-            Type = Packet.Length;
-          }
-          Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
-          pHeader->type = Type;
-        }
-        if ( Packet.Length < MIN_ETHERNET_PKT_SIZE ) {
-          Packet.Length = MIN_ETHERNET_PKT_SIZE;
-          ZeroMem ( &Packet.Data[ BufferSize ],
-                    Packet.Length - BufferSize );
-        }
-        DEBUG (( DEBUG_TX | DEBUG_INFO,
-                  "TX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
-                  Packet.Data[0],
-                  Packet.Data[1],
-                  Packet.Data[2],
-                  Packet.Data[3],
-                  Packet.Data[4],
-                  Packet.Data[5],
-                  Packet.Data[6],
-                  Packet.Data[7],
-                  Packet.Data[8],
-                  Packet.Data[9],
-                  Packet.Data[10],
-                  Packet.Data[11],
-                  Packet.Data[12],
-                  Packet.Data[13],
-                  Packet.Length ));
-        Packet.LengthBar = ~Packet.Length;
-        TransferLength = sizeof ( Packet.Length )
-                       + sizeof ( Packet.LengthBar )
-                       + Packet.Length;
-
-        //
-        //  Work around USB bus driver bug where a timeout set by receive
-        //  succeeds but the timeout expires immediately after, causing the
-        //  transmit operation to timeout.
-        //
-        pUsbIo = pNicDevice->pUsbIo;
-        Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
-                                           BULK_OUT_ENDPOINT,
-                                           &Packet.Length,
-                                           &TransferLength,
-                                           0xfffffffe,
-                                           &TransferStatus );
-        if ( !EFI_ERROR ( Status )) {
-          Status = TransferStatus;
-        }
-        if (( !EFI_ERROR ( Status ))
-          && ( TransferLength != (UINTN)( Packet.Length + 4 ))) {
-          Status = EFI_WARN_WRITE_FAILURE;
-        }
-        if ( EFI_SUCCESS == Status ) {
-          pNicDevice->pTxBuffer = pBuffer;
-        }
-        else {
-          DEBUG (( DEBUG_ERROR | DEBUG_INFO,
-                    "Ax88772 USB transmit error, TransferLength: %d, Status: %r\r\n",
-                    sizeof ( Packet.Length ) + Packet.Length,
-                    Status ));
-          //
-          //  Reset the controller to fix the error
-          //
-          if ( EFI_DEVICE_ERROR == Status ) {
-            SN_Reset ( pSimpleNetwork, FALSE );
-          }
-        }
-      }
-      else {
-        //
-        // No packets available.
-        //
-        Status = EFI_NOT_READY;
-      }
-    }
-    else {
-      Status = EFI_NOT_STARTED;
-    }
-  }
-  else {
-    DEBUG (( DEBUG_ERROR | DEBUG_INFO,
-              "Ax88772 invalid transmit parameter\r\n"
-              "  0x%08x: HeaderSize\r\n"
-              "  0x%08x: BufferSize\r\n"
-              "  0x%08x: Buffer\r\n"
-              "  0x%08x: SrcAddr\r\n"
-              "  0x%08x: DestAddr\r\n"
-              "  0x%04x:     Protocol\r\n",
-              HeaderSize,
-              BufferSize,
-              pBuffer,
-              pSrcAddr,
-              pDestAddr,
-              pProtocol ));
-    Status = EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Return the operation status
-  //
-  DBG_EXIT_STATUS ( Status );
-  return Status;
-}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
deleted file mode 100644
index 12684a6bd16b..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
+++ /dev/null
@@ -1,875 +0,0 @@
-/** @file
-  Implement the interface to the AX88772 Ethernet controller.
-
-  This module implements the interface to the ASIX AX88772
-  USB to Ethernet MAC with integrated 10/100 PHY.  Note that this implementation
-  only supports the integrated PHY since no other test cases were available.
-
-  Copyright (c) 2011, Intel Corporation. All rights reserved.
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Ax88772.h"
-
-
-/**
-  Compute the CRC 
-
-  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
-
-  @returns The CRC-32 value associated with this MAC address
-
-**/
-UINT32
-Ax88772Crc (
-  IN UINT8 * pMacAddress
-  )
-{
-  UINT32 BitNumber;
-  INT32 Carry;
-  INT32 Crc;
-  UINT32 Data;
-  UINT8 * pEnd;
-
-  //
-  //  Walk the MAC address
-  //
-  Crc = -1;
-  pEnd = &pMacAddress[ PXE_HWADDR_LEN_ETHER ];
-  while ( pEnd > pMacAddress ) {
-    Data = *pMacAddress++;
-    //
-    //  CRC32: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
-    //
-    //          1 0000 0100 1100 0001 0001 1101 1011 0111
-    //
-    for ( BitNumber = 0; 8 > BitNumber; BitNumber++ ) {
-      Carry = (( Crc >> 31 ) & 1 ) ^ ( Data & 1 );
-      Crc <<= 1;
-      if ( 0 != Carry ) {
-        Crc ^= 0x04c11db7;
-      }
-      Data >>= 1;
-    }
-  }
-  //
-  //  Return the CRC value
-  //
-  return (UINT32) Crc;
-}
-
-
-/**
-  Get the MAC address
-
-  This routine calls ::Ax88772UsbCommand to request the MAC
-  address from the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772MacAddressGet (
-  IN NIC_DEVICE * pNicDevice,
-  OUT UINT8 * pMacAddress
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-
-  //
-  //  Set the register address.
-  //
-  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
-                       | USB_REQ_TYPE_VENDOR
-                       | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_MAC_ADDRESS_READ;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
-
-  //
-  //  Read the PHY register
-  //
-  Status = Ax88772UsbCommand ( pNicDevice,
-                               &SetupMsg,
-                               pMacAddress );
-  return Status;
-}
-
-
-/**
-  Set the MAC address
-
-  This routine calls ::Ax88772UsbCommand to set the MAC address
-  in the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
-
-  @retval EFI_SUCCESS          The MAC address was set.
-  @retval other                The MAC address was not set.
-
-**/
-EFI_STATUS
-Ax88772MacAddressSet (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 * pMacAddress
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-
-  //
-  //  Set the register address.
-  //
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                       | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
-  
-  //
-  //  Read the PHY register
-  //
-  Status = Ax88772UsbCommand ( pNicDevice,
-                               &SetupMsg,
-                               pMacAddress );
-  return Status;
-}
-
-/**
-  Clear the multicast hash table
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-**/
-VOID
-Ax88772MulticastClear (
-  IN NIC_DEVICE * pNicDevice
-  )
-{
-  int i = 0;
-  //
-  // Clear the multicast hash table
-  //
-  for ( i = 0 ; i < 8 ; i ++ )
-     pNicDevice->MulticastHash[0] = 0;
-}
-
-/**
-  Enable a multicast address in the multicast hash table
-
-  This routine calls ::Ax88772Crc to compute the hash bit for
-  this MAC address.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
-
-**/
-VOID
-Ax88772MulticastSet (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 * pMacAddress
-  )
-{
-  UINT32 Crc;
-
-  //
-  //  Compute the CRC on the destination address
-  //
-  Crc = Ax88772Crc ( pMacAddress ) >> 26;
-
-  //
-  //  Set the bit corresponding to the destination address
-  //
-   pNicDevice->MulticastHash [ Crc >> 3 ] |= ( 1<< (Crc& 7));
-}
-
-/**
-  Start the link negotiation
-
-  This routine calls ::Ax88772PhyWrite to start the PHY's link
-  negotiation.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-  @retval EFI_SUCCESS          The link negotiation was started.
-  @retval other                Failed to start the link negotiation.
-
-**/
-EFI_STATUS
-Ax88772NegotiateLinkStart (
-  IN NIC_DEVICE * pNicDevice
-  )
-{
-  UINT16 Control;
-  EFI_STATUS Status;
-  int i; 
-  //
-  // Set the supported capabilities.
-  //
-  Status = Ax88772PhyWrite ( pNicDevice,
-                             PHY_ANAR,
-                             AN_CSMA_CD
-                             | AN_TX_FDX | AN_TX_HDX
-                             | AN_10_FDX | AN_10_HDX );
-  if ( !EFI_ERROR ( Status )) {
-    //
-    // Set the link speed and duplex
-    //
-    Control = BMCR_AUTONEGOTIATION_ENABLE
-            | BMCR_RESTART_AUTONEGOTIATION;
-    if ( pNicDevice->b100Mbps ) {
-      Control |= BMCR_100MBPS;
-    }
-    if ( pNicDevice->bFullDuplex ) {
-      Control |= BMCR_FULL_DUPLEX;
-    }
-    Status = Ax88772PhyWrite ( pNicDevice, PHY_BMCR, Control );
-  }
-  
-  if (!EFI_ERROR(Status)) {
-    i = 0;
-    do {
-      
-        if (pNicDevice->bComplete && pNicDevice->bLinkUp) {
-            pNicDevice->SimpleNetwork.Mode->MediaPresent 
-               = pNicDevice->bLinkUp & pNicDevice->bComplete;
-           break;
-       }
-       else {
-            gBS->Stall(AUTONEG_DELAY);
-            Status = Ax88772NegotiateLinkComplete ( pNicDevice,
-                                            &pNicDevice->PollCount,
-                                            &pNicDevice->bComplete,
-                                            &pNicDevice->bLinkUp,
-                                            &pNicDevice->b100Mbps,
-                                            &pNicDevice->bFullDuplex );
-            i++;
-        }
-    }while(!pNicDevice->bLinkUp && i < AUTONEG_POLLCNT);
-  }
-  return Status;
-}
-
-
-/**
-  Complete the negotiation of the PHY link
-
-  This routine calls ::Ax88772PhyRead to determine if the
-  link negotiation is complete.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in, out] pPollCount  Address of number of times this routine was polled
-  @param [out] pbComplete      Address of boolean to receive complate status.
-  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
-  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
-  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772NegotiateLinkComplete (
-  IN NIC_DEVICE * pNicDevice,
-  IN OUT UINTN * pPollCount,
-  OUT BOOLEAN * pbComplete,
-  OUT BOOLEAN * pbLinkUp,
-  OUT BOOLEAN * pbHiSpeed,
-  OUT BOOLEAN * pbFullDuplex
-  )
-{
-  UINT16 Mask;
-  UINT16 PhyData;
-  EFI_STATUS  Status;
- 
-  //
-  //  Determine if the link is up.
-  //
-  *pbComplete = FALSE;  
-
-  //
-  //  Get the link status
-  //
-  Status = Ax88772PhyRead ( pNicDevice,
-                            PHY_BMSR,
-                            &PhyData );
-
-  if ( !EFI_ERROR ( Status )) {
-      *pbLinkUp = (BOOLEAN)( 0 != ( PhyData & BMSR_LINKST ));
-      if ( 0 == *pbLinkUp ) {
-        DEBUG (( EFI_D_INFO, "Link Down\n" ));
-      }      
-      else {
-         *pbComplete = (BOOLEAN)( 0 != ( PhyData & 0x20 ));
-         if ( 0 == *pbComplete ) {
-              DEBUG (( EFI_D_INFO, "Autoneg is not yet Complete\n" ));
-        }
-        else {
-          Status = Ax88772PhyRead ( pNicDevice,
-                                PHY_ANLPAR,
-                                &PhyData );
-          if ( !EFI_ERROR ( Status )) {
-            //
-            //  Autonegotiation is complete
-            //  Determine the link speed.
-            //
-            *pbHiSpeed = (BOOLEAN)( 0 != ( PhyData & ( AN_TX_FDX | AN_TX_HDX )));
-
-            //
-            //  Determine the link duplex.
-            //
-            Mask = ( *pbHiSpeed ) ? AN_TX_FDX : AN_10_FDX;
-            *pbFullDuplex = (BOOLEAN)( 0 != ( PhyData & Mask ));
-          }
-        } 
-      }
-  } 
-  else {
-      DEBUG (( EFI_D_ERROR, "Failed to read BMCR\n" ));
-  }
-  return Status;
-}
-
-
-/**
-  Read a register from the PHY
-
-  This routine calls ::Ax88772UsbCommand to read a PHY register.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RegisterAddress  Number of the register to read.
-  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
-
-  @retval EFI_SUCCESS          The PHY data is available.
-  @retval other                The PHY data is not valid.
-
-**/
-EFI_STATUS
-Ax88772PhyRead (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 RegisterAddress,
-  IN OUT UINT16 * pPhyData
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-
-  //
-  //  Request access to the PHY
-  //
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                       | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;   
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                               &SetupMsg,
-                               NULL );
-  if ( !EFI_ERROR ( Status )) {
-    //
-    //  Read the PHY register address.
-    //
-    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
-                         | USB_REQ_TYPE_VENDOR
-                         | USB_TARGET_DEVICE;
-    SetupMsg.Request = CMD_PHY_REG_READ;
-    SetupMsg.Value = pNicDevice->PhyId;
-    SetupMsg.Index = RegisterAddress;
-    SetupMsg.Length = sizeof ( *pPhyData );
-    Status = Ax88772UsbCommand ( pNicDevice,
-                                 &SetupMsg,
-                                 pPhyData );
-    if ( !EFI_ERROR ( Status )) {
-
-      //
-      //  Release the PHY to the hardware
-      //
-      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                           | USB_TARGET_DEVICE;
-      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
-      SetupMsg.Value = 0;
-      SetupMsg.Index = 0;
-      SetupMsg.Length = 0;
-      Status = Ax88772UsbCommand ( pNicDevice,
-                                   &SetupMsg,
-                                   NULL );
-    }
-  }
-  return Status;
-}
-
-
-/**
-  Write to a PHY register
-
-  This routine calls ::Ax88772UsbCommand to write a PHY register.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RegisterAddress  Number of the register to read.
-  @param [in] PhyData          Address of a buffer to receive the PHY register value
-
-  @retval EFI_SUCCESS          The PHY data was written.
-  @retval other                Failed to wwrite the PHY register.
-
-**/
-EFI_STATUS
-Ax88772PhyWrite (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT8 RegisterAddress,
-  IN UINT16 PhyData
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-
-  //
-  //  Request access to the PHY
-  //
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                       | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                               &SetupMsg,
-                               NULL );
-  if ( !EFI_ERROR ( Status )) {
-    //
-    //  Write the PHY register
-    //
-    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                         | USB_TARGET_DEVICE;
-    SetupMsg.Request = CMD_PHY_REG_WRITE;
-    SetupMsg.Value = pNicDevice->PhyId;
-    SetupMsg.Index = RegisterAddress;
-    SetupMsg.Length = sizeof ( PhyData );
-    Status = Ax88772UsbCommand ( pNicDevice,
-                                 &SetupMsg,
-                                 &PhyData );
-    if ( !EFI_ERROR ( Status )) {
-
-      //
-      //  Release the PHY to the hardware
-      //
-      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                           | USB_TARGET_DEVICE;
-      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
-      SetupMsg.Value = 0;
-      SetupMsg.Index = 0;
-      SetupMsg.Length = 0;
-      Status = Ax88772UsbCommand ( pNicDevice,
-                                   &SetupMsg,
-                                   NULL );
-    }
-  }
-
-  return Status;
-}
-
-
-/**
-  Reset the AX88772
-
-  This routine uses ::Ax88772UsbCommand to reset the network
-  adapter.  This routine also uses ::Ax88772PhyWrite to reset
-  the PHY.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-
-  @retval EFI_SUCCESS          The MAC address is available.
-  @retval other                The MAC address is not valid.
-
-**/
-EFI_STATUS
-Ax88772Reset (
-  IN NIC_DEVICE * pNicDevice
-  )
-{
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-  
-  EFI_USB_IO_PROTOCOL *pUsbIo;
-  EFI_USB_DEVICE_DESCRIPTOR Device;
-  
-  pUsbIo = pNicDevice->pUsbIo;
-  Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
-
-	if (EFI_ERROR(Status)) goto err; 
-
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                           | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                                &SetupMsg,
-                                NULL );
-                                   
-  if (EFI_ERROR(Status)) goto err;                                 
-                                   
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                          | USB_TARGET_DEVICE;
-      SetupMsg.Request = CMD_PHY_SELECT;
-      SetupMsg.Value = SPHY_PSEL;
-      SetupMsg.Index = 0;
-      SetupMsg.Length = 0;
-      Status = Ax88772UsbCommand ( pNicDevice,
-                                    &SetupMsg,
-                                    NULL );
-                                    
-  if (EFI_ERROR(Status)) goto err;  
-                                     
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                          | USB_TARGET_DEVICE;                                
-  SetupMsg.Request = CMD_RESET;
-      SetupMsg.Value = SRR_IPRL ;
-      SetupMsg.Index = 0;
-      SetupMsg.Length = 0;
-      Status = Ax88772UsbCommand ( pNicDevice,
-                                   &SetupMsg,
-                                   NULL );  
-                                   
-  if (EFI_ERROR(Status)) goto err;  
-                                   
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                          | USB_TARGET_DEVICE;                                
-  SetupMsg.Request = CMD_RESET;
-        SetupMsg.Value = SRR_IPPD | SRR_IPRL ;
-        SetupMsg.Index = 0;
-        SetupMsg.Length = 0;
-        Status = Ax88772UsbCommand ( pNicDevice,
-                                    &SetupMsg,
-                                    NULL );
-                                   
-  gBS->Stall ( 200000 );
-    
-  if (EFI_ERROR(Status)) goto err;  
-    
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                          | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_RESET;
-  SetupMsg.Value =  SRR_IPRL  ;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                                &SetupMsg,
-                                NULL );   
-                                    
-  gBS->Stall ( 200000 ); 
-     
-  if (EFI_ERROR(Status)) goto err;  
-     
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                          | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_RESET;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                                    &SetupMsg,
-                                    NULL );
-                                    
-  if (EFI_ERROR(Status)) goto err;                                
-                                    
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                          | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_PHY_SELECT;
-  SetupMsg.Value = SPHY_PSEL;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                                    &SetupMsg,
-                                    NULL ); 
-                                    
-  if (EFI_ERROR(Status)) goto err;                                
-                                    
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                          | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_RESET;
-  SetupMsg.Value =  SRR_IPRL | SRR_BZ | SRR_BZTYPE;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                                    &SetupMsg,
-                                    NULL );
-                                    
-  if (EFI_ERROR(Status)) goto err;                                
-                                    
-  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                        | USB_TARGET_DEVICE;
-  SetupMsg.Request = CMD_RX_CONTROL_WRITE;
-  SetupMsg.Value = 0;
-  SetupMsg.Index = 0;
-  SetupMsg.Length = 0;
-  Status = Ax88772UsbCommand ( pNicDevice,
-                                  &SetupMsg,
-                                  NULL );
-                                  
-  if (EFI_ERROR(Status)) goto err;  
-
-  if (pNicDevice->Flags != FLAG_TYPE_AX88772) {
-        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                        | USB_TARGET_DEVICE;
-        SetupMsg.Request = CMD_RXQTC;
-        SetupMsg.Value = 0x8000;
-        SetupMsg.Index = 0x8001;
-        SetupMsg.Length = 0;
-        Status = Ax88772UsbCommand ( pNicDevice,
-                                  &SetupMsg,
-                                  NULL );
-  }
-
-err:
-  return Status;
-}
-
-/**
-  Enable or disable the receiver
-
-  This routine calls ::Ax88772UsbCommand to update the
-  receiver state.  This routine also calls ::Ax88772MacAddressSet
-  to establish the MAC address for the network adapter.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] RxFilter         Simple network RX filter mask value
-
-  @retval EFI_SUCCESS          The MAC address was set.
-  @retval other                The MAC address was not set.
-
-**/
-EFI_STATUS
-Ax88772RxControl (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT32 RxFilter
-  )
-{
-  UINT16 MediumStatus;
-  UINT16 RxControl;
-  USB_DEVICE_REQUEST SetupMsg;
-  EFI_STATUS Status;
-  EFI_USB_IO_PROTOCOL *pUsbIo;
-  EFI_USB_DEVICE_DESCRIPTOR Device;
-  
-  pUsbIo = pNicDevice->pUsbIo;
-  Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
-  
-  if (EFI_ERROR(Status)) {
-    DEBUG (( EFI_D_ERROR, "Failed to get device descriptor\n" ));
-    return Status;
-  }
-
-  //
-  // Enable the receiver if something is to be received
-  //
-  
-  if ( 0 != RxFilter ) {
-    //
-    //  Enable the receiver
-    //
-    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
-                         | USB_REQ_TYPE_VENDOR
-                         | USB_TARGET_DEVICE;
-    SetupMsg.Request = CMD_MEDIUM_STATUS_READ;    
-    SetupMsg.Value = 0;
-    SetupMsg.Index = 0;
-    SetupMsg.Length = sizeof ( MediumStatus );
-    Status = Ax88772UsbCommand ( pNicDevice,
-                                 &SetupMsg,
-                                 &MediumStatus );
-    if ( !EFI_ERROR ( Status )) {
-      if ( 0 == ( MediumStatus & MS_RE )) {
-        MediumStatus |= MS_RE | MS_ONE;
-        
-        if ( pNicDevice->bFullDuplex )
-          MediumStatus |= MS_TFC | MS_RFC | MS_FD;
-        else
-          MediumStatus &= ~(MS_TFC | MS_RFC | MS_FD);
-        
-        if ( pNicDevice->b100Mbps )
-          MediumStatus |= MS_PS;
-        else
-          MediumStatus &= ~MS_PS;
-        
-        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                             | USB_TARGET_DEVICE;
-        SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
-        SetupMsg.Value = MediumStatus;
-        SetupMsg.Index = 0;
-        SetupMsg.Length = 0;
-        Status = Ax88772UsbCommand ( pNicDevice,
-                                     &SetupMsg,
-                                     NULL );
-        if ( EFI_ERROR ( Status )) {
-            DEBUG (( EFI_D_ERROR, "Failed to enable receiver, Status: %r\r\n",
-              Status ));
-        }
-      }
-    }
-    else {
-        DEBUG (( EFI_D_ERROR, "Failed to read receiver status, Status: %r\r\n",
-              Status ));
-    }
-  }
-  
-  RxControl = RXC_SO | RXC_RH1M;  
-  //
-  //  Enable multicast if requested
-  //
-  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
-      RxControl |= RXC_AM;
-      //
-      //  Update the multicast hash table
-      //
-      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                           | USB_TARGET_DEVICE;
-      SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
-      SetupMsg.Value = 0;
-      SetupMsg.Index = 0;
-      SetupMsg.Length = sizeof ( pNicDevice ->MulticastHash );
-      Status = Ax88772UsbCommand ( pNicDevice,
-                                   &SetupMsg,
-                                   &pNicDevice->MulticastHash );
-  }
-  //
-  //  Enable all multicast if requested
-  //
-  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST )) {
-      RxControl |= RXC_AMALL;
-  }
-
-  //
-  //  Enable broadcast if requested
-  //
-  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST )) {
-      RxControl |= RXC_AB;
-  }
-
-  //
-  //  Enable promiscuous mode if requested
-  //
-  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS )) {
-      RxControl |= RXC_PRO;
-  }
-    
-  //
-  //  Update the receiver control
-  //
-  if (pNicDevice->CurRxControl != RxControl) {
-    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
-                         | USB_TARGET_DEVICE;
-    SetupMsg.Request = CMD_RX_CONTROL_WRITE;
-    SetupMsg.Value = RxControl;
-    SetupMsg.Index = 0;
-    SetupMsg.Length = 0;
-    Status = Ax88772UsbCommand ( pNicDevice,
-                                 &SetupMsg,
-                                 NULL );
-    if ( !EFI_ERROR ( Status )) {
-      pNicDevice->CurRxControl = RxControl;
-      
-    }
-    else {
-        DEBUG (( EFI_D_ERROR, "ERROR - Failed to set receiver control, Status: %r\r\n",
-            Status ));
-    }
-  }
-  return Status;
-}
-
-
-/**
-  Read an SROM location
-
-  This routine calls ::Ax88772UsbCommand to read data from the
-  SROM.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] Address          SROM address
-  @param [out] pData           Buffer to receive the data
-
-  @retval EFI_SUCCESS          The read was successful
-  @retval other                The read failed
-
-**/
-EFI_STATUS
-Ax88772SromRead (
-  IN NIC_DEVICE * pNicDevice,
-  IN UINT32 Address,
-  OUT UINT16 * pData
-  )
-{ 
-  return EFI_UNSUPPORTED;
-}
-
-/**
-  Send a command to the USB device.
-
-  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
-  @param [in] pRequest         Pointer to the request structure
-  @param [in, out] pBuffer     Data buffer address
-
-  @retval EFI_SUCCESS          The USB transfer was successful
-  @retval other                The USB transfer failed
-
-**/
-EFI_STATUS
-Ax88772UsbCommand (
-  IN NIC_DEVICE * pNicDevice,
-  IN USB_DEVICE_REQUEST * pRequest,
-  IN OUT VOID * pBuffer
-  )
-{
-  UINT32 CmdStatus;
-  EFI_USB_DATA_DIRECTION Direction;
-  EFI_USB_IO_PROTOCOL * pUsbIo;
-  EFI_STATUS Status;
-
-  //
-  // Determine the transfer direction
-  //
-  Direction = EfiUsbNoData;
-  if ( 0 != pRequest->Length ) {
-    Direction = ( 0 != ( pRequest->RequestType & USB_ENDPOINT_DIR_IN ))
-              ? EfiUsbDataIn : EfiUsbDataOut;
-  }
-
-  //
-  // Issue the command
-  //
-  pUsbIo = pNicDevice->pUsbIo;
-  Status = pUsbIo->UsbControlTransfer ( pUsbIo,
-                                        pRequest,
-                                        Direction,
-                                        USB_BUS_TIMEOUT,
-                                        pBuffer,
-                                        pRequest->Length,
-                                        &CmdStatus );
-  //
-  // Determine the operation status
-  //
-  if ( !EFI_ERROR ( Status )) {
-    Status = CmdStatus;
-  }
-  else {
-    //
-    // Only use status values associated with the Simple Network protocol
-    //
-    if ( EFI_TIMEOUT == Status ) {
-      Status = EFI_DEVICE_ERROR;
-    }
-  }
-  return Status;
-}
-
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c
deleted file mode 100644
index 76a732a7b007..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/** @file
-  UEFI Component Name(2) protocol implementation.
-
-  Copyright (c) 2011, Intel Corporation. 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  gComponentName = {
-  GetDriverName,
-  GetControllerName,
-  "eng"
-};
-
-/**
-  EFI Component Name 2 Protocol declaration
-**/
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
-  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
-  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
-  "en"
-};
-
-
-/**
-  Driver name table declaration
-**/
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
-mDriverNameTable[] = {
-  {"eng;en", L"ASIX AX88772B Ethernet Driver 1.0"},
-  {NULL,  NULL}
-};
-
-/**
-  Retrieves a Unicode string that is the user readable name of the driver.
-
-  This function retrieves the user readable name of a driver in the form of a
-  Unicode string. If the driver specified by This has a user readable name in
-  the language specified by Language, then a pointer to the driver name is
-  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
-  by This does not support the language specified by Language,
-  then EFI_UNSUPPORTED is returned.
-
-  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
-                                EFI_COMPONENT_NAME_PROTOCOL instance.
-  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
-                                array indicating the language. This is the
-                                language of the driver name that the caller is
-                                requesting, and it must match one of the
-                                languages specified in SupportedLanguages. The
-                                number of languages supported by a driver is up
-                                to the driver writer. Language is specified
-                                in RFC 3066 or ISO 639-2 language code format.
-  @param [out] ppDriverName     A pointer to the Unicode string to return.
-                                This Unicode string is the name of the
-                                driver specified by This in the language
-                                specified by Language.
-
-  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
-                                This and the language specified by Language was
-                                returned in DriverName.
-  @retval EFI_INVALID_PARAMETER Language is NULL.
-  @retval EFI_INVALID_PARAMETER DriverName is NULL.
-  @retval EFI_UNSUPPORTED       The driver specified by This does not support
-                                the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-GetDriverName (
-  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
-  IN  CHAR8 * pLanguage,
-  OUT CHAR16 ** ppDriverName
-  )
-{
-  EFI_STATUS Status;
-
-  Status = LookupUnicodeString2 (
-             pLanguage,
-             pThis->SupportedLanguages,
-             mDriverNameTable,
-             ppDriverName,
-             (BOOLEAN)(pThis == &gComponentName)
-             );
-
-  return Status;
-}
-
-/**
-  Retrieves a Unicode string that is the user readable name of the controller
-  that is being managed by a driver.
-
-  This function retrieves the user readable name of the controller specified by
-  ControllerHandle and ChildHandle in the form of a Unicode string. If the
-  driver specified by This has a user readable name in the language specified by
-  Language, then a pointer to the controller name is returned in ControllerName,
-  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
-  managing the controller specified by ControllerHandle and ChildHandle,
-  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
-  support the language specified by Language, then EFI_UNSUPPORTED is returned.
-
-  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
-                                EFI_COMPONENT_NAME_PROTOCOL instance.
-  @param [in] ControllerHandle  The handle of a controller that the driver
-                                specified by This is managing.  This handle
-                                specifies the controller whose name is to be
-                                returned.
-  @param [in] ChildHandle       The handle of the child controller to retrieve
-                                the name of.  This is an optional parameter that
-                                may be NULL.  It will be NULL for device
-                                drivers.  It will also be NULL for a bus drivers
-                                that wish to retrieve the name of the bus
-                                controller.  It will not be NULL for a bus
-                                driver that wishes to retrieve the name of a
-                                child controller.
-  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
-                                array indicating the language.  This is the
-                                language of the driver name that the caller is
-                                requesting, and it must match one of the
-                                languages specified in SupportedLanguages. The
-                                number of languages supported by a driver is up
-                                to the driver writer. Language is specified in
-                                RFC 3066 or ISO 639-2 language code format.
-  @param [out] ppControllerName A pointer to the Unicode string to return.
-                                This Unicode string is the name of the
-                                controller specified by ControllerHandle and
-                                ChildHandle in the language specified by
-                                Language from the point of view of the driver
-                                specified by This.
-
-  @retval EFI_SUCCESS           The Unicode string for the user readable name in
-                                the language specified by Language for the
-                                driver specified by This was returned in
-                                DriverName.
-  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
-  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
-                                EFI_HANDLE.
-  @retval EFI_INVALID_PARAMETER Language is NULL.
-  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
-  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
-                                managing the controller specified by
-                                ControllerHandle and ChildHandle.
-  @retval EFI_UNSUPPORTED       The driver specified by This does not support
-                                the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-GetControllerName (
-  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
-  IN  EFI_HANDLE ControllerHandle,
-  IN OPTIONAL EFI_HANDLE ChildHandle,
-  IN  CHAR8 * pLanguage,
-  OUT CHAR16 ** ppControllerName
-  )
-{
-  EFI_STATUS Status;
-
-  //
-  // Set the controller name
-  //
-  *ppControllerName = L"ASIX AX88772B USB Fast Ethernet Controller";
-  Status = EFI_SUCCESS;
-
-  //
-  // Return the operation status
-  //
-
-  return Status;
-}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
deleted file mode 100644
index 2bec94414000..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
+++ /dev/null
@@ -1,696 +0,0 @@
-/** @file
-  Implement the driver binding protocol for Asix AX88772 Ethernet driver.
-                     
-  Copyright (c) 2011-2013, Intel Corporation. All rights reserved.
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Ax88772.h"
-
-ASIX_DONGLE ASIX_DONGLES[] = {
-  { 0x05AC, 0x1402, FLAG_TYPE_AX88772 }, // Apple USB Ethernet Adapter
-  // ASIX 88772B
-  { 0x0B95, 0x772B, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
-  { 0x0000, 0x0000, FLAG_NONE }   // END - Do not remove
-};
-
-/**
-  Verify the controller type
-
-  @param [in] pThis                Protocol instance pointer.
-  @param [in] Controller           Handle of device to test.
-  @param [in] pRemainingDevicePath Not used.
-
-  @retval EFI_SUCCESS          This driver supports this device.
-  @retval other                This driver does not support this device.
-
-**/
-EFI_STATUS
-EFIAPI
-DriverSupported (
-  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
-  IN EFI_HANDLE Controller,
-  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
-  )
-{
-  EFI_USB_DEVICE_DESCRIPTOR Device;
-  EFI_USB_IO_PROTOCOL * pUsbIo;
-  EFI_STATUS Status;
-  UINT32 Index;
-
-  //
-  //  Connect to the USB stack
-  //
-  Status = gBS->OpenProtocol (
-                  Controller,
-                  &gEfiUsbIoProtocolGuid,
-                  (VOID **) &pUsbIo,
-                  pThis->DriverBindingHandle,         
-                  Controller,
-                  EFI_OPEN_PROTOCOL_BY_DRIVER
-                  );
-  if (!EFI_ERROR ( Status )) {
-
-    //
-    //  Get the interface descriptor to check the USB class and find a transport
-    //  protocol handler.
-    //
-    Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
-    if (EFI_ERROR ( Status )) {
-    	Status = EFI_UNSUPPORTED;
-    }
-    else {
-      //
-      //  Validate the adapter
-      //
-      for (Index = 0; ASIX_DONGLES[Index].VendorId != 0; Index++) {
-        if (ASIX_DONGLES[Index].VendorId == Device.IdVendor &&
-            ASIX_DONGLES[Index].ProductId == Device.IdProduct) {
-              DEBUG ((EFI_D_INFO, "Found the AX88772B\r\n"));
-              break;
-        }
-      }
-
-      if (ASIX_DONGLES[Index].VendorId == 0)
-         Status = EFI_UNSUPPORTED;
-    }
-   
-    //
-    //  Done with the USB stack
-    //
-    gBS->CloseProtocol (
-           Controller,
-           &gEfiUsbIoProtocolGuid,
-           pThis->DriverBindingHandle,
-           Controller
-           );
-  }
-  return Status;
-}
-
-
-/**
-  Start this driver on Controller by opening UsbIo and DevicePath protocols.
-  Initialize PXE structures, create a copy of the Controller Device Path with the
-  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
-  on the newly created Device Path.
-
-  @param [in] pThis                Protocol instance pointer.
-  @param [in] Controller           Handle of device to work with.
-  @param [in] pRemainingDevicePath Not used, always produce all possible children.
-
-  @retval EFI_SUCCESS          This driver is added to Controller.
-  @retval other                This driver does not support this device.
-
-**/
-EFI_STATUS
-EFIAPI
-DriverStart (
-  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
-  IN EFI_HANDLE Controller,
-  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
-  )
-{
-
-	EFI_STATUS						Status;
-	NIC_DEVICE						*pNicDevice;
-	UINTN							LengthInBytes;
-	EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath = NULL;
-	MAC_ADDR_DEVICE_PATH            MacDeviceNode;
-        EFI_USB_DEVICE_DESCRIPTOR       Device;
-        UINT32                          Index;
-
-  //
-	//  Allocate the device structure
-	//
-	LengthInBytes = sizeof ( *pNicDevice );
-	Status = gBS->AllocatePool (
-                  EfiRuntimeServicesData,
-                  LengthInBytes,
-                  (VOID **) &pNicDevice
-                  );
-
-	if (EFI_ERROR (Status)) {
-		DEBUG ((EFI_D_ERROR, "gBS->AllocatePool:pNicDevice ERROR Status = %r\n", Status));
-		goto EXIT;
-	}
-	
-	//
-  //  Set the structure signature
-  //
-  ZeroMem ( pNicDevice, LengthInBytes );
-  pNicDevice->Signature = DEV_SIGNATURE;
-
-	Status = gBS->OpenProtocol (
-                    Controller,
-                    &gEfiUsbIoProtocolGuid,
-                    (VOID **) &pNicDevice->pUsbIo,
-                    pThis->DriverBindingHandle,
-                    Controller,
-                    EFI_OPEN_PROTOCOL_BY_DRIVER
-                    );
-
-	if (EFI_ERROR (Status)) {
-		DEBUG ((EFI_D_ERROR, "gBS->OpenProtocol:EFI_USB_IO_PROTOCOL ERROR Status = %r\n", Status));
-		gBS->FreePool ( pNicDevice );
-		goto EXIT;
-	}
-
-	//
-  //  Initialize the simple network protocol
-  //
-	Status = SN_Setup ( pNicDevice );
-
-	if (EFI_ERROR(Status)){
-	   DEBUG ((EFI_D_ERROR, "SN_Setup ERROR Status = %r\n", Status));
-	   gBS->CloseProtocol (
-					Controller,
-					&gEfiUsbIoProtocolGuid,
-					pThis->DriverBindingHandle,
-					Controller
-					);
-		  gBS->FreePool ( pNicDevice );
-		  goto EXIT;
-  }
-
-  Status = pNicDevice->pUsbIo->UsbGetDeviceDescriptor ( pNicDevice->pUsbIo, &Device );
-  if (EFI_ERROR ( Status )) {
-     gBS->CloseProtocol (
-               Controller,
-               &gEfiUsbIoProtocolGuid,
-               pThis->DriverBindingHandle,
-               Controller
-               );
-     gBS->FreePool ( pNicDevice );
-              goto EXIT;
-  } else {
-      //
-      //  Validate the adapter
-      //
-      for (Index = 0; ASIX_DONGLES[Index].VendorId != 0; Index++) {
-          if (ASIX_DONGLES[Index].VendorId == Device.IdVendor &&
-              ASIX_DONGLES[Index].ProductId == Device.IdProduct) {
-                break;
-          }
-      }
-
-      if (ASIX_DONGLES[Index].VendorId == 0) {
-         gBS->CloseProtocol (
-                   Controller,
-                   &gEfiUsbIoProtocolGuid,
-                   pThis->DriverBindingHandle,
-                   Controller
-                   );
-          gBS->FreePool ( pNicDevice );
-                   goto EXIT;
-      }
-
-      pNicDevice->Flags = ASIX_DONGLES[Index].Flags;
-  }
-
-	//
-  // Set Device Path
-  //  			
-  Status = gBS->OpenProtocol (
-                  Controller,
-                  &gEfiDevicePathProtocolGuid,
-                  (VOID **) &ParentDevicePath,
-				          pThis->DriverBindingHandle,
-                  Controller,
-                  EFI_OPEN_PROTOCOL_BY_DRIVER
-                  );
-	if (EFI_ERROR(Status)) {
-        DEBUG ((EFI_D_ERROR, "gBS->OpenProtocol:EFI_DEVICE_PATH_PROTOCOL error. Status = %r\n",
-            Status));        
-		    gBS->CloseProtocol (
-					Controller,
-					&gEfiUsbIoProtocolGuid,
-					pThis->DriverBindingHandle,
-					Controller
-					);
-		  gBS->FreePool ( pNicDevice );
-		  goto EXIT;
-	}
-
-  ZeroMem (&MacDeviceNode, sizeof (MAC_ADDR_DEVICE_PATH));
-  MacDeviceNode.Header.Type = MESSAGING_DEVICE_PATH;
-  MacDeviceNode.Header.SubType = MSG_MAC_ADDR_DP;
-
-  SetDevicePathNodeLength (&MacDeviceNode.Header, sizeof (MAC_ADDR_DEVICE_PATH));
-      			
-  CopyMem (&MacDeviceNode.MacAddress,
-      								&pNicDevice->SimpleNetworkData.CurrentAddress,
-      								PXE_HWADDR_LEN_ETHER);
-      								
-  MacDeviceNode.IfType = pNicDevice->SimpleNetworkData.IfType;
-
-  pNicDevice->MyDevPath = AppendDevicePathNode (
-                                          ParentDevicePath,
-                                          (EFI_DEVICE_PATH_PROTOCOL *) &MacDeviceNode
-                                          );
-
-	pNicDevice->Controller = NULL;
-
-	//
-  //  Install both the simple network and device path protocols.
-  //
-  Status = gBS->InstallMultipleProtocolInterfaces (
-                          &pNicDevice->Controller,
-                          &gEfiCallerIdGuid,
-                          pNicDevice,
-                          &gEfiSimpleNetworkProtocolGuid,            
-                          &pNicDevice->SimpleNetwork,
-						              &gEfiDevicePathProtocolGuid,
-						              pNicDevice->MyDevPath,
-                          NULL
-                          );
-
-	if (EFI_ERROR(Status)){
-		DEBUG ((EFI_D_ERROR, "gBS->InstallMultipleProtocolInterfaces error. Status = %r\n",
-            Status)); 
-		gBS->CloseProtocol (
-					               Controller,
-					               &gEfiDevicePathProtocolGuid,
-					               pThis->DriverBindingHandle,
-					               Controller);
-	   gBS->CloseProtocol (
-					Controller,
-					&gEfiUsbIoProtocolGuid,
-					pThis->DriverBindingHandle,
-					Controller
-					);
-		  gBS->FreePool ( pNicDevice );
-		  goto EXIT;
-	}
-
-	//
-	// Open For Child Device
-	//
-	Status = gBS->OpenProtocol (                                                                         
-                  Controller,
-                  &gEfiUsbIoProtocolGuid,
-                  (VOID **) &pNicDevice->pUsbIo,
-                  pThis->DriverBindingHandle,
-                  pNicDevice->Controller,
-                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
-                  );
-
-	if (EFI_ERROR(Status)){
-	   gBS->UninstallMultipleProtocolInterfaces (
-              &pNicDevice->Controller,
-                          &gEfiCallerIdGuid,
-                          pNicDevice,
-                          &gEfiSimpleNetworkProtocolGuid,            
-                          &pNicDevice->SimpleNetwork,
-						              &gEfiDevicePathProtocolGuid,
-						              pNicDevice->MyDevPath,
-                          NULL
-                          );
-		gBS->CloseProtocol (
-					               Controller,
-					               &gEfiDevicePathProtocolGuid,
-					               pThis->DriverBindingHandle,
-					               Controller);
-	   gBS->CloseProtocol (
-					Controller,
-					&gEfiUsbIoProtocolGuid,
-					pThis->DriverBindingHandle,
-					Controller
-					);
-		  gBS->FreePool ( pNicDevice );
-	}
-
-EXIT:
-	return Status;
-
-}
-
-/**
-  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
-  closing the DevicePath and PciIo protocols on Controller.
-
-  @param [in] pThis                Protocol instance pointer.
-  @param [in] Controller           Handle of device to stop driver on.
-  @param [in] NumberOfChildren     How many children need to be stopped.
-  @param [in] pChildHandleBuffer   Not used.
-
-  @retval EFI_SUCCESS          This driver is removed Controller.
-  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
-  @retval other                This driver was not removed from this device.
-
-**/
-EFI_STATUS
-EFIAPI
-DriverStop (
-  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
-  IN  EFI_HANDLE Controller,
-  IN  UINTN NumberOfChildren,
-  IN  EFI_HANDLE * ChildHandleBuffer
-  )
-{
-		BOOLEAN                                   AllChildrenStopped;
-		UINTN                                     Index;
-		EFI_SIMPLE_NETWORK_PROTOCOL				  *SimpleNetwork;
-		EFI_STATUS                                Status = EFI_SUCCESS;
-		NIC_DEVICE								  *pNicDevice;
-		
-		//
-		// Complete all outstanding transactions to Controller.
-		// Don't allow any new transaction to Controller to be started.
-		//
-		if (NumberOfChildren == 0) {
-		
-		  Status = gBS->OpenProtocol (
-				                Controller,
-				                &gEfiSimpleNetworkProtocolGuid,
-				                (VOID **) &SimpleNetwork,
-				                pThis->DriverBindingHandle,
-				                Controller,
-				                EFI_OPEN_PROTOCOL_GET_PROTOCOL
-				                );
-				                
-			if (EFI_ERROR(Status)) {
-        //
-        // This is a 2nd type handle(multi-lun root), it needs to close devicepath
-        // and usbio protocol.
-        //
-        gBS->CloseProtocol (
-            Controller,
-            &gEfiDevicePathProtocolGuid,
-            pThis->DriverBindingHandle,
-            Controller
-            );
-        gBS->CloseProtocol (
-            Controller,
-            &gEfiUsbIoProtocolGuid,
-            pThis->DriverBindingHandle,
-            Controller
-            );
-        return EFI_SUCCESS;
-      }
-      
-      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork );
-      
-      Status = gBS->UninstallMultipleProtocolInterfaces (
-				                  Controller,				                  
-				                  &gEfiCallerIdGuid,
-                          pNicDevice,
-                          &gEfiSimpleNetworkProtocolGuid,            
-                          &pNicDevice->SimpleNetwork,
-						              &gEfiDevicePathProtocolGuid,
-						              pNicDevice->MyDevPath,
-                          NULL
-                          );
-                          
-      if (EFI_ERROR (Status)) {
-        return Status;
-      }
-		  //
-		  // Close the bus driver
-		  //
-		  Status = gBS->CloseProtocol (
-		                  Controller,
-		                  &gEfiDevicePathProtocolGuid,
-		                  pThis->DriverBindingHandle,
-		                  Controller
-		                  );
-
-		  if (EFI_ERROR(Status)){
-          DEBUG ((EFI_D_ERROR, "driver stop: gBS->CloseProtocol:EfiDevicePathProtocol error. Status %r\n", Status));
-		  }
-
-		  Status = gBS->CloseProtocol (
-		                  Controller,
-		                  &gEfiUsbIoProtocolGuid,
-		                  pThis->DriverBindingHandle,
-		                  Controller
-		                  );
-
-		  if (EFI_ERROR(Status)){
-          DEBUG ((EFI_D_ERROR, "driver stop: gBS->CloseProtocol:EfiUsbIoProtocol error. Status %r\n", Status));
-		  }
-      return EFI_SUCCESS;
-		} 
-		AllChildrenStopped = TRUE;
-
-		for (Index = 0; Index < NumberOfChildren; Index++) {
-
-				Status = gBS->OpenProtocol (
-				                ChildHandleBuffer[Index],
-				                &gEfiSimpleNetworkProtocolGuid,
-				                (VOID **) &SimpleNetwork,
-				                pThis->DriverBindingHandle,
-				                Controller,
-				                EFI_OPEN_PROTOCOL_GET_PROTOCOL
-				                );
-				                
-				if (EFI_ERROR (Status)) {
-          AllChildrenStopped = FALSE;
-          DEBUG ((EFI_D_ERROR, "Fail to stop No.%d multi-lun child handle when opening SimpleNetwork\n", (UINT32)Index));
-          continue;
-        } 
-        
-        pNicDevice = DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork );
-        
-        gBS->CloseProtocol (
-				                    Controller,
-				                    &gEfiUsbIoProtocolGuid,
-				                    pThis->DriverBindingHandle,
-				                    ChildHandleBuffer[Index]
-				                    ); 
-				                    
-				Status = gBS->UninstallMultipleProtocolInterfaces (
-				                  ChildHandleBuffer[Index],				                  
-				                  &gEfiCallerIdGuid,
-                          pNicDevice,
-                          &gEfiSimpleNetworkProtocolGuid,            
-                          &pNicDevice->SimpleNetwork,
-						              &gEfiDevicePathProtocolGuid,
-						              pNicDevice->MyDevPath,
-                          NULL
-                          );
-                          
-        if (EFI_ERROR (Status)) {
-            Status = gBS->OpenProtocol (                                                                         
-                  Controller,
-                  &gEfiUsbIoProtocolGuid,
-                  (VOID **) &pNicDevice->pUsbIo,
-                  pThis->DriverBindingHandle,
-                  ChildHandleBuffer[Index],
-                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
-                  );
-        }
-        else {
-            int i;
-            RX_PKT * pCurr = pNicDevice->QueueHead;
-            RX_PKT * pFree;
-            
-            for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
-                 if ( NULL != pCurr ) {
-                    pFree = pCurr;
-                    pCurr = pCurr->pNext;
-                    gBS->FreePool (pFree);
-                 }
-            }
-            
-            if ( NULL != pNicDevice->pRxTest)
-						    gBS->FreePool (pNicDevice->pRxTest);
-
-					 if ( NULL != pNicDevice->pTxTest)
-						    gBS->FreePool (pNicDevice->pTxTest);
-
-           if ( NULL != pNicDevice->MyDevPath)
-					       gBS->FreePool (pNicDevice->MyDevPath);
-		  
-				    if ( NULL != pNicDevice)
-                  gBS->FreePool (pNicDevice);
-        }
-    }
-        
-        if (!AllChildrenStopped) {
-                return EFI_DEVICE_ERROR;
-        }
-        return EFI_SUCCESS;
-}
-
-
-/**
-  Driver binding protocol declaration
-**/
-EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
-  DriverSupported,
-  DriverStart,
-  DriverStop,
-  0xa,
-  NULL,
-  NULL
-};
-
-
-/**
-  Ax88772 driver unload routine.
-
-  @param [in] ImageHandle       Handle for the image.
-
-  @retval EFI_SUCCESS           Image may be unloaded
-
-**/
-EFI_STATUS
-EFIAPI
-DriverUnload (
-  IN EFI_HANDLE ImageHandle
-  )
-{
-  UINTN BufferSize;
-  UINTN Index;
-  UINTN Max;
-  EFI_HANDLE * pHandle;
-  EFI_STATUS Status;
-
-  //
-  //  Determine which devices are using this driver
-  //
-  BufferSize = 0;
-  pHandle = NULL;
-  Status = gBS->LocateHandle (
-                  ByProtocol,
-                  &gEfiCallerIdGuid,
-                  NULL,
-                  &BufferSize,
-                  NULL );
-  if ( EFI_BUFFER_TOO_SMALL == Status ) {
-    for ( ; ; ) {
-      //
-      //  One or more block IO devices are present
-      //
-      Status = gBS->AllocatePool (
-                      EfiRuntimeServicesData,
-                      BufferSize,
-                      (VOID **) &pHandle
-                      );
-      if ( EFI_ERROR ( Status )) {
-        DEBUG ((EFI_D_ERROR, "Insufficient memory, failed handle buffer allocation\r\n"));
-        break;
-      }
-
-      //
-      //  Locate the block IO devices
-      //
-      Status = gBS->LocateHandle (
-                      ByProtocol,
-                      &gEfiCallerIdGuid,
-                      NULL,
-                      &BufferSize,
-                      pHandle );
-      if ( EFI_ERROR ( Status )) {
-        //
-        //  Error getting handles
-        //
-        break;
-      }
-      
-      //
-      //  Remove any use of the driver
-      //
-      Max = BufferSize / sizeof ( pHandle[ 0 ]);
-      for ( Index = 0; Max > Index; Index++ ) {
-        Status = DriverStop ( &gDriverBinding,
-                              pHandle[ Index ],
-                              0,
-                              NULL );
-        if ( EFI_ERROR ( Status )) {
-          DEBUG ((EFI_D_ERROR, "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));
-          break;
-        }
-      }
-      break;
-    }
-  }
-  else {
-    if ( EFI_NOT_FOUND == Status ) {
-      //
-      //  No devices were found
-      //
-      Status = EFI_SUCCESS;
-    }
-  }
-
-  //
-  //  Free the handle array          
-  //
-  if ( NULL != pHandle ) {
-    gBS->FreePool ( pHandle );
-  }
-
-  //
-  //  Remove the protocols installed by the EntryPoint routine.
-  //
-  if ( !EFI_ERROR ( Status )) {
-    gBS->UninstallMultipleProtocolInterfaces (
-            ImageHandle,
-            &gEfiDriverBindingProtocolGuid,
-            &gDriverBinding,                              
-            &gEfiComponentNameProtocolGuid,
-            &gComponentName,
-            &gEfiComponentName2ProtocolGuid,
-            &gComponentName2,
-            NULL
-            );
-
-    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-            "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
-            ImageHandle ));
-    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-              "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
-              ImageHandle ));
-    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
-              "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
-              ImageHandle ));
-
-  }
-
-  return Status;
-}
-
-
-/**
-Ax88772 driver entry point.
-
-@param [in] ImageHandle       Handle for the image.
-@param [in] pSystemTable      Address of the system table.
-
-@retval EFI_SUCCESS           Image successfully loaded.
-
-**/
-EFI_STATUS
-EFIAPI
-EntryPoint (
-  IN EFI_HANDLE ImageHandle,
-  IN EFI_SYSTEM_TABLE * pSystemTable
-  )
-{
-  EFI_STATUS    Status;
-
-  //
-  //  Add the driver to the list of drivers
-  //
-  Status = EfiLibInstallDriverBindingComponentName2 (
-             ImageHandle,
-             pSystemTable,
-             &gDriverBinding,
-             ImageHandle,
-             &gComponentName,
-             &gComponentName2
-             );
-  if ( !EFI_ERROR ( Status )) {
-    DEBUG ((EFI_D_INFO, "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",
-              ImageHandle));
-    DEBUG ((EFI_D_INFO, "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",
-              ImageHandle));
-    DEBUG ((EFI_D_INFO,"Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",
-              ImageHandle ));
-
-  }
-  return Status;
-}
diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
deleted file mode 100644
index 76babedb2001..000000000000
--- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
+++ /dev/null
@@ -1,1657 +0,0 @@
-/** @file
-  Provides the Simple Network functions.
-
-  Copyright (c) 2011 - 2016, Intel Corporation. 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] pSimpleNetwork    Simple network mode pointer  
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-ReceiveFilterUpdate (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  NIC_DEVICE * pNicDevice;
-  EFI_STATUS Status;
-  UINT32 Index;
-
-  //
-  // Set the MAC address
-  //
-  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-  pMode = pSimpleNetwork->Mode;
-
-  //
-  // Clear the multicast hash table
-  //
-  Ax88772MulticastClear ( pNicDevice );
-
-  //
-  // Load the multicast hash table
-  //
-  if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
-      for ( Index = 0; Index < pMode->MCastFilterCount; Index++ ) {
-        //
-        // Enable the next multicast address
-        //
-        Ax88772MulticastSet ( pNicDevice,
-                              &pMode->MCastFilter[ Index ].Addr[0]);
-      }
-  }
-
-  Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
-
-  return Status;
-}
-
-
-/**
-  This function updates the SNP driver status.
-  
-  This function gets the current interrupt and recycled transmit
-  buffer status from the network interface.  The interrupt status
-  and the media status are returned as a bit mask in InterruptStatus.
-  If InterruptStatus is NULL, the interrupt status will not be read.
-  Upon successful return of the media status, the MediaPresent field
-  of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
-  of media status.  If TxBuf is not NULL, a recycled transmit buffer
-  address will be retrived.  If a recycled transmit buffer address
-  is returned in TxBuf, then the buffer has been successfully
-  transmitted, and the status for that buffer is cleared.
-
-  This function calls ::Ax88772Rx to update the media status and
-  queue any receive packets.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] pInterruptStatus  A pointer to the bit mask of the current active interrupts.
-                                If this is NULL, the interrupt status will not be read from
-                                the device.  If this is not NULL, the interrupt status will
-                                be read from teh device.  When the interrupt status is read,
-                                it will also be cleared.  Clearing the transmit interrupt
-                                does not empty the recycled transmit buffer array.
-  @param [out] ppTxBuf          Recycled transmit buffer address.  The network interface will
-                                not transmit if its internal recycled transmit buffer array is
-                                full.  Reading the transmit buffer does not clear the transmit
-                                interrupt.  If this is NULL, then the transmit buffer status
-                                will not be read.  If there are not transmit buffers to recycle
-                                and TxBuf is not NULL, *TxBuf will be set to NULL.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_GetStatus (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  OUT UINT32 * pInterruptStatus,
-  OUT VOID ** ppTxBuf
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  NIC_DEVICE * pNicDevice;
-  EFI_STATUS Status;
-  BOOLEAN bFullDuplex;
-  BOOLEAN bLinkUp;
-  BOOLEAN bSpeed100;
-  EFI_TPL TplPrevious;
- 
-  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    // Return the transmit buffer
-    //
-    
-    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-    if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
-     		 *ppTxBuf = pNicDevice->pTxBuffer;
-     		 pNicDevice->pTxBuffer = NULL;
-   	}
-    
-    //
-    // Determine if interface is running
-    //
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkInitialized == pMode->State ) {
-
-      if ( pNicDevice->LinkIdleCnt > MAX_LINKIDLE_THRESHOLD) {
-
-          bLinkUp = pNicDevice->bLinkUp;
-          bSpeed100 = pNicDevice->b100Mbps;
-          bFullDuplex = pNicDevice->bFullDuplex;
-          Status = Ax88772NegotiateLinkComplete ( pNicDevice,
-                                            &pNicDevice->PollCount,
-                                            &pNicDevice->bComplete,
-                                            &pNicDevice->bLinkUp,
-                                            &pNicDevice->b100Mbps,
-                                            &pNicDevice->bFullDuplex );
-
-          //
-          // Determine if the autonegotiation is complete
-          //
-          if ( pNicDevice->bComplete ) {
-              if ( pNicDevice->bLinkUp ) {
-                  if (( bSpeed100 && ( !pNicDevice->b100Mbps ))
-                      || (( !bSpeed100 ) && pNicDevice->b100Mbps )
-                      || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))
-                      || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {
-                          pNicDevice->PollCount = 0;
-                          DEBUG (( EFI_D_INFO , "Reset to establish proper link setup: %d Mbps, %a duplex\r\n",
-                                    pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));
-                          Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );
-                  }
-                  if (( !bLinkUp ) && pNicDevice->bLinkUp ) {
-                      //
-                      // Display the autonegotiation status
-                      //
-                      DEBUG (( EFI_D_INFO , "Link: Up, %d Mbps, %a duplex\r\n",
-                                pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));
-
-                  }
-                  pNicDevice->LinkIdleCnt = 0;
-            }
-        }
-        //
-        //  Update the link status
-        //
-        if ( bLinkUp && ( !pNicDevice->bLinkUp )) {
-            DEBUG (( EFI_D_INFO , "Link: Down\r\n"));
-        }
-      }
-
-      pMode->MediaPresent = pNicDevice->bLinkUp;
-      //
-      // Return the interrupt status
-      //
-      if ( NULL != pInterruptStatus ) {
-        *pInterruptStatus = 0;
-      }   
-      Status = EFI_SUCCESS;
-    }
-    else {
-      if ( EfiSimpleNetworkStarted == pMode->State ) {
-        Status = EFI_DEVICE_ERROR;
-      }
-      else {
-        Status = EFI_NOT_STARTED;
-      }
-    }
-      
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-  gBS->RestoreTPL(TplPrevious) ;
-
-  return Status;
-}
-
-
-/**
-  Resets the network adapter and allocates the transmit and receive buffers
-  required by the network interface; optionally, also requests allocation of
-  additional transmit and receive buffers.  This routine must be called before
-  any other routine in the Simple Network protocol is called.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
-  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and receive buffers
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Initialize (                                              
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN UINTN ExtraRxBufferSize,
-  IN UINTN ExtraTxBufferSize
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_STATUS Status;
-  UINT32  TmpState;
-   EFI_TPL TplPrevious;
-   
-   TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    // Determine if the interface is already started
-    //
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkStarted == pMode->State ) {
-      if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
-        //
-        // Start the adapter
-        //
-        TmpState = pMode->State;
-        pMode->State = EfiSimpleNetworkInitialized;
-        Status = SN_Reset ( pSimpleNetwork, FALSE );
-        if ( EFI_ERROR ( Status )) {
-          //
-          // Update the network state
-          //
-          pMode->State = TmpState;
-          DEBUG (( EFI_D_ERROR , "SN_reset failed\n"));
-        }
-      }
-      else {
-        DEBUG (( EFI_D_ERROR , "Increase ExtraRxBufferSize = %d ExtraTxBufferSize=%d\n", 
-              ExtraRxBufferSize, ExtraTxBufferSize));
-        Status = EFI_UNSUPPORTED;
-      }
-    }
-    else {
-      Status = EFI_NOT_STARTED;
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-  gBS->RestoreTPL (TplPrevious);
-
-  return Status;
-}
-
-
-/**
-  This function converts a multicast IP address to a multicast HW MAC address
-  for all packet transactions.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] bIPv6             Set to TRUE if the multicast IP address is IPv6 [RFC2460].
-                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
-  @param [in] pIP               The multicast IP address that is to be converted to a
-                                multicast HW MAC address.
-  @param [in] pMAC              The multicast HW MAC address that is to be generated from IP.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_MCastIPtoMAC (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bIPv6,
-  IN EFI_IP_ADDRESS * pIP,
-  OUT EFI_MAC_ADDRESS * pMAC
-  )
-{
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-
-  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
-  //
-  // Get pointer to SNP driver instance for *this.
-  //
-  if (pSimpleNetwork == NULL) {
-    gBS->RestoreTPL(TplPrevious);
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (pIP == NULL || pMAC == NULL) {
-    gBS->RestoreTPL(TplPrevious);
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (bIPv6){
-    Status = EFI_UNSUPPORTED;
-  }  
-  else {
-      //
-      // check if the ip given is a mcast IP
-      //
-      if ((pIP->v4.Addr[0] & 0xF0) != 0xE0) {
-        gBS->RestoreTPL(TplPrevious);
-        return EFI_INVALID_PARAMETER;
-      }
-      else {
-        if (pSimpleNetwork->Mode->State == EfiSimpleNetworkInitialized)
-        {
-          pMAC->Addr[0] = 0x01;
-          pMAC->Addr[1] = 0x00;
-          pMAC->Addr[2] = 0x5e;
-          pMAC->Addr[3] = (UINT8) (pIP->v4.Addr[1] & 0x7f);
-          pMAC->Addr[4] = (UINT8) pIP->v4.Addr[2];
-          pMAC->Addr[5] = (UINT8) pIP->v4.Addr[3];
-          Status = EFI_SUCCESS;
-        }
-        else if (pSimpleNetwork->Mode->State == EfiSimpleNetworkStarted) {
-          Status = EFI_DEVICE_ERROR;
-        }
-        else {
-          Status = EFI_NOT_STARTED;
-        }
-        gBS->RestoreTPL(TplPrevious);
-      }
-  }
-  return Status;
-}
-
-
-/**
-  This function performs read and write operations on the NVRAM device
-  attached to a network interface.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] ReadWrite         TRUE for read operations, FALSE for write operations.
-  @param [in] Offset            Byte offset in the NVRAM device at which to start the
-                                read or write operation.  This must be a multiple of
-                                NvRamAccessSize and less than NvRamSize.
-  @param [in] BufferSize        The number of bytes to read or write from the NVRAM device.
-                                This must also be a multiple of NvramAccessSize.
-  @param [in, out] pBuffer      A pointer to the data buffer.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_NvData (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN ReadWrite,
-  IN UINTN Offset,
-  IN UINTN BufferSize,
-  IN OUT VOID * pBuffer
-  )
-{
-  EFI_STATUS Status;
-  //
-  // This is not currently supported
-  //
-  Status = EFI_UNSUPPORTED;
-  return Status;
-}
-
-VOID 
-FillPkt2Queue (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN UINTN BufLength)
-{
-
-  UINT16 * pLength;
-  UINT16 * pLengthBar;
-  UINT8* pData;
-  UINT32 offset;
-  NIC_DEVICE * pNicDevice;
-  
-  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork);
-  for ( offset = 0; offset < BufLength; ){
-      pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);
-      pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);
-      
-      *pLength &= 0x7ff;
-      *pLengthBar &= 0x7ff;
-      *pLengthBar |= 0xf800;
-      
-      if ((*pLength ^ *pLengthBar ) != 0xFFFF) {
-          DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n", BufLength));
-          return;
-      }          
-      
-      if (TRUE == pNicDevice->pNextFill->f_Used) {
-        return;
-      }
-      else {
-          pData = pNicDevice->pBulkInBuff + offset + 4;
-          pNicDevice->pNextFill->f_Used = TRUE;
-          pNicDevice->pNextFill->Length = *pLength;
-          CopyMem (&pNicDevice->pNextFill->Data[0], pData, *pLength);
-          
-          pNicDevice->pNextFill = pNicDevice->pNextFill->pNext;
-          offset += ((*pLength + HW_HDR_LENGTH - 1) &~3) + 1;
-          pNicDevice->PktCntInQueue++;
-      }
-              
-  }
-}
-
-EFI_STATUS
-EFIAPI
-SN_Receive (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  OUT UINTN                      * pHeaderSize,
-  OUT UINTN                      * pBufferSize,
-  OUT VOID                       * pBuffer,
-  OUT EFI_MAC_ADDRESS            * pSrcAddr,
-  OUT EFI_MAC_ADDRESS            * pDestAddr,
-  OUT UINT16                     * pProtocol
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  NIC_DEVICE * pNicDevice;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-  UINT16 Type;
-  EFI_USB_IO_PROTOCOL *pUsbIo;
-  UINTN LengthInBytes;
-  UINT32 TransferStatus;
-  RX_PKT * pFirstFill;
-  TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
-  
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && 
-    ( NULL != pSimpleNetwork->Mode ) && 
-    (NULL != pBufferSize) && 
-    (NULL != pBuffer)) {
-    //
-    // The interface must be running
-    //
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkInitialized == pMode->State ) {
-      //
-      // Update the link status
-      //
-      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-      pNicDevice->LinkIdleCnt++;
-      pMode->MediaPresent = pNicDevice->bLinkUp;
-      
-      if ( pMode->MediaPresent && pNicDevice->bComplete) {
-      
-      
-        if (pNicDevice->PktCntInQueue != 0 ) {
-            DEBUG (( EFI_D_INFO, "pNicDevice->PktCntInQueue = %d\n",
-                pNicDevice->PktCntInQueue));
-        }
-        
-        LengthInBytes = MAX_BULKIN_SIZE;
-        if (pNicDevice->PktCntInQueue == 0 ){
-            //
-            // Attempt to do bulk in
-            //
-            SetMem (&pNicDevice->pBulkInBuff[0], 4, 0);
-            pUsbIo = pNicDevice->pUsbIo;
-            Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
-                                       USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
-                                       &pNicDevice->pBulkInBuff[0],
-                                       &LengthInBytes,
-                                       BULKIN_TIMEOUT,
-                                       &TransferStatus );
-                                       
-            if (LengthInBytes != 0 && !EFI_ERROR(Status) && !EFI_ERROR(TransferStatus) ){
-                FillPkt2Queue(pSimpleNetwork, LengthInBytes);
-            }
-        }
-        
-        pFirstFill = pNicDevice->pFirstFill;
-         
-        if (TRUE == pFirstFill->f_Used) {
-            ETHERNET_HEADER * pHeader;
-            pNicDevice->LinkIdleCnt = 0;
-            CopyMem (pBuffer,  &pFirstFill->Data[0], pFirstFill->Length);
-            pHeader = (ETHERNET_HEADER *) &pFirstFill->Data[0];
-                     
-            DEBUG (( EFI_D_INFO, "RX: %02x-%02x-%02x-%02x-%02x-%02x " 
-                      "%02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
-                      pFirstFill->Data[0],
-                      pFirstFill->Data[1],
-                      pFirstFill->Data[2],
-                      pFirstFill->Data[3],
-                      pFirstFill->Data[4],
-                      pFirstFill->Data[5],
-                      pFirstFill->Data[6],
-                      pFirstFill->Data[7],
-                      pFirstFill->Data[8],
-                      pFirstFill->Data[9],
-                      pFirstFill->Data[10],
-                      pFirstFill->Data[11],
-                      pFirstFill->Data[12],
-                      pFirstFill->Data[13],
-                      pFirstFill->Length));   
-            
-            if ( NULL != pHeaderSize ) {
-              *pHeaderSize = sizeof ( *pHeader );
-            }
-            if ( NULL != pDestAddr ) {
-               CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );
-            }
-            if ( NULL != pSrcAddr ) {
-             CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );
-            }
-            if ( NULL != pProtocol ) {
-              Type = pHeader->type;
-              Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
-              *pProtocol = Type;
-            }
-            Status = EFI_SUCCESS;
-            if (*pBufferSize < pFirstFill->Length) {
-                  DEBUG (( EFI_D_ERROR, "RX: Buffer was too small"));
-                  Status = EFI_BUFFER_TOO_SMALL;
-            }
-            *pBufferSize =  pFirstFill->Length;
-            pFirstFill->f_Used = FALSE;
-            pNicDevice->pFirstFill = pFirstFill->pNext;
-            pNicDevice->PktCntInQueue--;
-        }
-        else {
-            pNicDevice->LinkIdleCnt++;
-            Status = EFI_NOT_READY;
-        }
-      }
-      else {
-        //
-        //  Link no up
-        //
-        pNicDevice->LinkIdleCnt++;
-        Status = EFI_NOT_READY; 
-      }
-      
-    }
-    else {
-      if (EfiSimpleNetworkStarted == pMode->State) {
-        Status = EFI_DEVICE_ERROR;
-      }
-      else {
-        Status = EFI_NOT_STARTED;
-      }
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }                              
-  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 hardware
-        a more liberal setting is selected.
-
-  If the same bits are set in the Enable and Disable parameters, then the bits
-  in the Disable parameter takes precedence.
-
-  If the ResetMCastFilter parameter is TRUE, then the multicast address list
-  filter is disabled (irregardless of what other multicast bits are set in
-  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount field
-  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
-
-  After enableing or disabling receive filter settings, software should
-  verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
-  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
-
-  Note: Some network drivers and/or devices will automatically promote
-  receive filter settings if the requested setting can not be honored.
-  For example, if a request for four multicast addresses is made and
-  the underlying hardware only supports two multicast addresses the
-  driver might set the promiscuous or promiscuous multicast receive filters
-  instead.  The receiving software is responsible for discarding any extra
-  packets that get through the hardware receive filters.
-
-  If ResetMCastFilter is TRUE, then the multicast receive filter list
-  on the network interface will be reset to the default multicast receive
-  filter list.  If ResetMCastFilter is FALSE, and this network interface
-  allows the multicast receive filter list to be modified, then the
-  MCastFilterCnt and MCastFilter are used to update the current multicast
-  receive filter list.  The modified receive filter list settings can be
-  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
-
-  This routine calls ::ReceiveFilterUpdate to update the receive
-  state in the network adapter.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] Enable            A bit mask of receive filters to enable on the network interface.
-  @param [in] Disable           A bit mask of receive filters to disable on the network interface.
-                                For backward compatibility with EFI 1.1 platforms, the
-                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
-                                when the ResetMCastFilter parameter is TRUE.
-  @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
-                                filters on the network interface to their default values.
-  @param [in] MCastFilterCnt    Number of multicast HW MAC address in the new MCastFilter list.
-                                This value must be less than or equal to the MaxMCastFilterCnt
-                                field of EFI_SIMPLE_NETWORK_MODE.  This field is optional if
-                                ResetMCastFilter is TRUE.
-  @param [in] pMCastFilter      A pointer to a list of new multicast receive filter HW MAC
-                                addresses.  This list will replace any existing multicast
-                                HW MAC address list.  This field is optional if ResetMCastFilter
-                                is TRUE.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_ReceiveFilters (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN UINT32 Enable,
-  IN UINT32 Disable,
-/*
-#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST               0x01
-#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST             0x02
-#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST             0x04
-#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS           0x08
-#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10
-*/
-  IN BOOLEAN bResetMCastFilter,
-  IN UINTN MCastFilterCnt,
-  IN EFI_MAC_ADDRESS * pMCastFilter
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_STATUS Status = EFI_SUCCESS;   
-  EFI_TPL TplPrevious; 
-
-  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
-  pMode = pSimpleNetwork->Mode;
-
-  if (pSimpleNetwork == NULL) {
-    gBS->RestoreTPL(TplPrevious);
-    return EFI_INVALID_PARAMETER;
-  }
-
-  switch (pMode->State) {
-    case EfiSimpleNetworkInitialized:
-      break;
-    case EfiSimpleNetworkStopped:
-      Status = EFI_NOT_STARTED;
-      gBS->RestoreTPL(TplPrevious);
-      return Status;
-    default:
-      Status = EFI_DEVICE_ERROR;
-      gBS->RestoreTPL(TplPrevious);
-      return Status;
-  }
-
-  //
-  // check if we are asked to enable or disable something that the UNDI
-  // does not even support!
-  //
-  if (((Enable &~pMode->ReceiveFilterMask) != 0) ||
-    ((Disable &~pMode->ReceiveFilterMask) != 0)) {
-    Status = EFI_INVALID_PARAMETER;
-    gBS->RestoreTPL(TplPrevious);
-    return Status;
-  }
-  
-  if (bResetMCastFilter) {
-    Disable |= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & pMode->ReceiveFilterMask);
-      pMode->MCastFilterCount = 0;
-      if ( (0 == (pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST)) 
-            && Enable == 0 && Disable == 2) {
-            gBS->RestoreTPL(TplPrevious);
-            return EFI_SUCCESS;
-      }
-  } 
-  else {
-    if (MCastFilterCnt != 0) {
-      UINTN i; 
-      EFI_MAC_ADDRESS * pMulticastAddress;
-      pMulticastAddress =  pMCastFilter;
-      
-      if ((MCastFilterCnt > pMode->MaxMCastFilterCount) ||
-          (pMCastFilter == NULL)) {
-        Status = EFI_INVALID_PARAMETER;
-        gBS->RestoreTPL(TplPrevious);
-        return Status;
-      }
-      
-      for ( i = 0 ; i < MCastFilterCnt ; i++ ) {
-          UINT8  tmp;
-          tmp = pMulticastAddress->Addr[0];
-          if ( (tmp & 0x01) != 0x01 ) {
-            gBS->RestoreTPL(TplPrevious);
-            return EFI_INVALID_PARAMETER;
-          }
-          pMulticastAddress++;
-      }
-      
-      pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
-      CopyMem (&pMode->MCastFilter[0],
-                     pMCastFilter,
-                     MCastFilterCnt * sizeof ( EFI_MAC_ADDRESS));
-    }
-  }
-  
-  if (Enable == 0 && Disable == 0 && !bResetMCastFilter && MCastFilterCnt == 0) {
-    Status = EFI_SUCCESS;
-    gBS->RestoreTPL(TplPrevious);
-    return Status;
-  }
-
-  if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
-    Status = EFI_INVALID_PARAMETER;
-    gBS->RestoreTPL(TplPrevious);
-    return Status;
-  }
-  
-  pMode->ReceiveFilterSetting |= Enable;
-  pMode->ReceiveFilterSetting &= ~Disable;
-  Status = ReceiveFilterUpdate (pSimpleNetwork);
-  
-  if (EFI_DEVICE_ERROR == Status || EFI_INVALID_PARAMETER == Status)
-      Status = 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] pSimpleNetwork    Protocol instance pointer
-  @param [in] bExtendedVerification  Indicates that the driver may perform a more
-                                exhaustive verification operation of the device
-                                during reset.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Reset (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bExtendedVerification
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  NIC_DEVICE * pNicDevice;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-
-  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
-  //
-  //  Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-		pMode = pSimpleNetwork->Mode;
-		if ( EfiSimpleNetworkInitialized == pMode->State ) {
-    	//
-    	//  Update the device state
-    	//
-    	pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-    	pNicDevice->bComplete = FALSE;
-    	pNicDevice->bLinkUp = FALSE; 
-    	pNicDevice->bHavePkt = FALSE;
-    	pMode = pSimpleNetwork->Mode;
-    	pMode->MediaPresent = FALSE;
-
-    	//
-   		//  Reset the device
-    	//
-    	Status = Ax88772Reset ( pNicDevice );
-    	if ( !EFI_ERROR ( Status )) {
-     	 	//
-     	 	//  Update the receive filters in the adapter
-     	 	//
-     	 	Status = ReceiveFilterUpdate ( pSimpleNetwork );
-
-     	 	//
-     		 //  Try to get a connection to the network
-     	 	//
-     	 	if ( !EFI_ERROR ( Status )) {
-        	//
-        	//  Start the autonegotiation
-       		//
-        	Status = Ax88772NegotiateLinkStart ( pNicDevice );
-     		}
-   	 	}
-   	}
-   	else {
-      if (EfiSimpleNetworkStarted == pMode->State) {
-        Status = EFI_DEVICE_ERROR;
-      }
-      else {
-        Status = EFI_NOT_STARTED;
-      }
-   	}  
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-  gBS->RestoreTPL ( TplPrevious );
-  return Status;
-}
-
-/**
-  Initialize the simple network protocol.
-
-  This routine calls ::Ax88772MacAddressGet to obtain the
-  MAC address.
-
-  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
-
-  @retval EFI_SUCCESS     Setup was successful
-
-**/
-EFI_STATUS
-SN_Setup (
-  IN NIC_DEVICE * pNicDevice
-  )
-{
-  
-
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
-  EFI_STATUS Status;
-  RX_PKT * pCurr = NULL;
-  RX_PKT * pPrev = NULL;
-
-	pSimpleNetwork = &pNicDevice->SimpleNetwork;  
-  pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
-  pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
-  pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
-  pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
-  pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
-  pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
-  pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
-  pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
-  pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
-  pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
-  pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
-  pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
-  pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
-  pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
-  pSimpleNetwork->WaitForPacket = NULL;
-  pMode = &pNicDevice->SimpleNetworkData;
-  pSimpleNetwork->Mode = pMode;
-  pMode->State = EfiSimpleNetworkStopped;
-  pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
-  pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
-  pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
-  pMode->NvRamSize = 0;
-  pMode->NvRamAccessSize = 0;
-  pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
-                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
-                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
-                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
-                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
-  pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
-                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
-  pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
-  pMode->MCastFilterCount = 0;
-  SetMem ( &pMode->BroadcastAddress,
-           PXE_HWADDR_LEN_ETHER,
-           0xff );
-  pMode->IfType = EfiNetworkInterfaceUndi;
-  pMode->MacAddressChangeable = TRUE;
-  pMode->MultipleTxSupported = FALSE;
-  pMode->MediaPresentSupported = TRUE;
-  pMode->MediaPresent = FALSE;
-  pNicDevice->LinkIdleCnt = 0;
-  //
-  //  Read the MAC address
-  //
-  pNicDevice->PhyId = PHY_ID_INTERNAL;
-  pNicDevice->b100Mbps = TRUE;
-  pNicDevice->bFullDuplex = TRUE;
-  
-  Status = Ax88772MacAddressGet (
-                pNicDevice,
-                &pMode->PermanentAddress.Addr[0]);
-
-  if ( !EFI_ERROR ( Status )) {
-    int i; 
-    //
-    //  Use the hardware address as the current address
-    //
-
-    CopyMem ( &pMode->CurrentAddress,
-              &pMode->PermanentAddress,
-              PXE_HWADDR_LEN_ETHER );
-              
-    CopyMem ( &pNicDevice->MAC,
-              &pMode->PermanentAddress,
-              PXE_HWADDR_LEN_ETHER );
-              
-    pNicDevice->PktCntInQueue = 0;
-    
-    for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
-        Status = gBS->AllocatePool ( EfiRuntimeServicesData, 
-                                      sizeof (RX_PKT),
-                                      (VOID **) &pCurr);
-        if ( EFI_ERROR(Status)) {
-            DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
-            return Status;
-        }                              
-        pCurr->f_Used = FALSE;
-        
-        if ( i ) {
-            pPrev->pNext = pCurr;
-        }
-        else {
-            pNicDevice->QueueHead = pCurr;
-        }
-        
-        if (MAX_QUEUE_SIZE - 1 == i) {
-            pCurr->pNext = pNicDevice->QueueHead;
-        }
-        
-        pPrev = pCurr;
-    }
-    
-    pNicDevice->pNextFill = pNicDevice->QueueHead;
-    pNicDevice->pFirstFill = pNicDevice->QueueHead;
-    
-    Status = gBS->AllocatePool (EfiRuntimeServicesData,
-                                MAX_BULKIN_SIZE,
-                                (VOID **) &pNicDevice->pBulkInBuff);
-                                
-    if (EFI_ERROR(Status)) {
-        DEBUG (( EFI_D_ERROR, "gBS->AllocatePool for pBulkInBuff error. Status = %r\n",
-              Status));
-        return Status;
-    }
-  }
-  else {
-    DEBUG (( EFI_D_ERROR, "Ax88772MacAddressGet error. Status = %r\n", Status));
-		return Status;
-  }
-  
-  Status = gBS->AllocatePool ( EfiRuntimeServicesData,
-                                   sizeof ( RX_TX_PACKET ),
-                                   (VOID **) &pNicDevice->pRxTest );
-
-  if (EFI_ERROR (Status)) {
-    DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pRxTest error. Status = %r\n",
-              Status));
-	  return Status;
-  }
-                                   
-  Status = gBS->AllocatePool ( EfiRuntimeServicesData,
-                                   sizeof ( RX_TX_PACKET ),
-                                   (VOID **) &pNicDevice->pTxTest );
-
-  if (EFI_ERROR (Status)) {
-    DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pTxTest error. Status = %r\n",
-              Status));
-	  gBS->FreePool (pNicDevice->pRxTest);
-  }
-
-  return Status;
-}
-
-
-/**
-  This routine starts the network interface.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_ALREADY_STARTED   The network interface was already started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Start (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  )
-{
-  NIC_DEVICE * pNicDevice;
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-  int i = 0;
-  RX_PKT * pCurr = NULL;
-
-  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
-  //
-  // Verify the parameters
-  //
-  Status = EFI_INVALID_PARAMETER;
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkStopped == pMode->State ) {
-      //
-      // Initialize the mode structuref
-      // NVRAM access is not supported
-      //
-      ZeroMem ( pMode, sizeof ( *pMode ));
-  
-      pMode->State = EfiSimpleNetworkStarted;
-      pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
-      pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
-      pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
-      pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
-                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
-                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
-                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
-                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
-      pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
-      pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
-      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-      Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
-      CopyMem ( &pMode->CurrentAddress,
-                &pMode->PermanentAddress,
-                sizeof ( pMode->CurrentAddress ));
-      SetMem(&pMode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
-      pMode->IfType = EfiNetworkInterfaceUndi;
-      pMode->MacAddressChangeable = TRUE;
-      pMode->MultipleTxSupported = FALSE;
-      pMode->MediaPresentSupported = TRUE;
-      pMode->MediaPresent = FALSE; 
-      pNicDevice->PktCntInQueue = 0;
-      pNicDevice->pNextFill = pNicDevice->QueueHead;
-      pNicDevice->pFirstFill = pNicDevice->QueueHead;
-      pCurr = pNicDevice->QueueHead;
-      
-      for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) { 
-        pCurr->f_Used = FALSE;
-        pCurr = pCurr->pNext;
-      }
-      
-    }
-    else {
-      Status = EFI_ALREADY_STARTED;
-    }
-  }
-  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 FALSE
-  then the current station address is changed to the address specified by
-  pNew.
-
-  This routine calls ::Ax88772MacAddressSet to update the MAC address
-  in the network adapter.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-  @param [in] bReset            Flag used to reset the station address to the
-                                network interface's permanent address.
-  @param [in] pNew              New station address to be used for the network
-                                interface.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_StationAddress (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bReset,
-  IN EFI_MAC_ADDRESS * pNew
-  )
-{
-  NIC_DEVICE * pNicDevice;
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-  
-  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork )
-    && ( NULL != pSimpleNetwork->Mode )
-    && (( bReset ) || ( ( !bReset) && ( NULL != pNew )))) {
-    //
-    // Verify that the adapter is already started
-    //
-    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkInitialized == pMode->State ) {
-      //
-      // Determine the adapter MAC address
-      //
-      if ( bReset ) {
-        //
-        // Use the permanent address
-        //
-        CopyMem ( &pMode->CurrentAddress,
-                  &pMode->PermanentAddress,
-                  sizeof ( pMode->CurrentAddress ));
-      }
-      else {
-        //
-        // Use the specified address
-        //
-        CopyMem ( &pMode->CurrentAddress,
-                  pNew,
-                  sizeof ( pMode->CurrentAddress ));
-      }
-
-      //
-      // Update the address on the adapter
-      //
-      Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
-    }
-    else {
-      if (EfiSimpleNetworkStarted == pMode->State) {
-        Status = EFI_DEVICE_ERROR;
-      }
-      else {
-        Status = EFI_NOT_STARTED;
-      }
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-  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] pSimpleNetwork    Protocol instance pointer
-  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
-  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
-                                the size, in bytes, of the resulting table of statistics.
-  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
-                                conains the statistics.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-  typedef struct {
-  UINT64 RxTotalFrames;
-  UINT64 RxGoodFrames;
-  UINT64 RxUndersizeFrames;
-  UINT64 RxOversizeFrames;
-  UINT64 RxDroppedFrames;
-  UINT64 RxUnicastFrames;
-  UINT64 RxBroadcastFrames;
-  UINT64 RxMulticastFrames;
-  UINT64 RxCrcErrorFrames;
-  UINT64 RxTotalBytes;
-  UINT64 TxTotalFrames;
-  UINT64 TxGoodFrames;
-  UINT64 TxUndersizeFrames;
-  UINT64 TxOversizeFrames;
-  UINT64 TxDroppedFrames;
-  UINT64 TxUnicastFrames;
-  UINT64 TxBroadcastFrames;
-  UINT64 TxMulticastFrames;
-  UINT64 TxCrcErrorFrames;
-  UINT64 TxTotalBytes;
-  UINT64 Collisions;
-  UINT64 UnsupportedProtocol;
-  } EFI_NETWORK_STATISTICS;
-**/
-EFI_STATUS
-EFIAPI
-SN_Statistics (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN BOOLEAN bReset,
-  IN OUT UINTN * pStatisticsSize,
-  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
-  )
-{
-  EFI_STATUS Status;
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  //
-  // Verify the prarameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    pMode = pSimpleNetwork->Mode;
-    //
-    // Determine if the interface is started 
-    //
-    if (EfiSimpleNetworkInitialized == pMode->State){
-      //
-      // Determine if the StatisticsSize is big enough
-      //
-      if (sizeof (EFI_NETWORK_STATISTICS) <= *pStatisticsSize){
-        if (bReset) {
-          Status = EFI_SUCCESS;
-        } 
-        else {
-          Status = EFI_UNSUPPORTED;
-        }
-      }
-      else {
-        Status = EFI_BUFFER_TOO_SMALL;
-      }
-    }
-    else{
-      if (EfiSimpleNetworkStarted == pMode->State) {
-        Status = EFI_DEVICE_ERROR;
-      }
-      else {
-        Status = EFI_NOT_STARTED;
-      }
-    }
-  }
-  else {
-  	Status = EFI_INVALID_PARAMETER;
-  }
-
-  return Status;
-}
-
-
-/**
-  This function stops a network interface.  This call is only valid
-  if the network interface is in the started state.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Stop (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-  
-  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    // Determine if the interface is started
-    //
-    pMode = pSimpleNetwork->Mode;   
-    if ( EfiSimpleNetworkStarted == pMode->State ) {
-        pMode->State = EfiSimpleNetworkStopped;
-        Status = EFI_SUCCESS; 
-    }
-    else {
-        Status = EFI_NOT_STARTED;
-    }
-  } 
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-  
-  gBS->RestoreTPL ( TplPrevious );
-  return Status;
-}
-
-
-/**
-  This function releases the memory buffers assigned in the Initialize() call.
-  Pending transmits and receives are lost, and interrupts are cleared and disabled.
-  After this call, only Initialize() and Stop() calls may be used.
-
-  @param [in] pSimpleNetwork    Protocol instance pointer
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Shutdown (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
-  )
-{
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  UINT32 RxFilter;
-  EFI_STATUS Status;
-  EFI_TPL TplPrevious;
-  
-  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
-  //
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
-    //
-    // Determine if the interface is already started
-    //
-    pMode = pSimpleNetwork->Mode;
-    if ( EfiSimpleNetworkInitialized == pMode->State ) {
-      //
-      // Stop the adapter
-      //
-      RxFilter = pMode->ReceiveFilterSetting;
-      pMode->ReceiveFilterSetting = 0;
-      Status = SN_Reset ( pSimpleNetwork, FALSE );
-      pMode->ReceiveFilterSetting = RxFilter;
-      if ( !EFI_ERROR ( Status )) {
-
-        //
-        // Update the network state
-        //
-        pMode->State = EfiSimpleNetworkStarted;
-      }
-      else if ( EFI_DEVICE_ERROR == Status ) {
-      	pMode->State = EfiSimpleNetworkStopped;
-      }
-    }
-    else {
-      Status = EFI_NOT_STARTED;
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-  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] pSimpleNetwork    Protocol instance pointer
-  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
-                                the Transmit() function.  If HeaderSize is non-zero, then
-                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
-                                and DestAddr and Protocol parameters must not be NULL.
-  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
-                                data) to be transmitted through the network interface.
-  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
-                                to be transmitted.  This parameter can not be NULL.  If
-                                HeaderSize is zero, then the media header is Buffer must
-                                already be filled in by the caller.  If HeaderSize is nonzero,
-                                then the media header will be filled in by the Transmit()
-                                function.
-  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
-                                this parameter is ignored.  If HeaderSize is nonzero and
-                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
-                                is used for the source HW MAC address.
-  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
-                                this parameter is ignored.
-  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
-                                this parameter is ignored.
-
-  @retval EFI_SUCCESS           This operation was successful.
-  @retval EFI_NOT_STARTED       The network interface was not started.
-  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
-  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
-  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
-                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
-  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
-
-**/
-EFI_STATUS
-EFIAPI
-SN_Transmit (
-  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
-  IN UINTN HeaderSize,
-  IN UINTN BufferSize,
-  IN VOID * pBuffer,
-  IN EFI_MAC_ADDRESS * pSrcAddr,
-  IN EFI_MAC_ADDRESS * pDestAddr,
-  IN UINT16 * pProtocol
-  )
-{
-  ETHERNET_HEADER * pHeader;
-  EFI_SIMPLE_NETWORK_MODE * pMode;
-  NIC_DEVICE * pNicDevice;
-  EFI_USB_IO_PROTOCOL * pUsbIo;
-  EFI_STATUS Status;
-  UINTN TransferLength;
-  UINT32 TransferStatus;
-  UINT16 Type;
-  EFI_TPL TplPrevious;
-
-  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
-
-  // Verify the parameters
-  //
-  if (( NULL != pSimpleNetwork ) && 
-      ( NULL != pSimpleNetwork->Mode ) && 
-      ( NULL != pBuffer) && 
-      ( (HeaderSize == 0) || ( (NULL != pDestAddr) && (NULL != pProtocol) ))) {
-    //
-    // The interface must be running
-    //
-    pMode = pSimpleNetwork->Mode;
-    //
-    // Verify parameter of HeaderSize
-    //
-    if ((HeaderSize == 0) || (HeaderSize == pMode->MediaHeaderSize)){
-      //
-      // Determine if BufferSize is big enough
-      //
-      if (BufferSize >= pMode->MediaHeaderSize){
-        if ( EfiSimpleNetworkInitialized == pMode->State ) {
-          //
-          // Update the link status
-          //
-          pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
-          pMode->MediaPresent = pNicDevice->bLinkUp;
-
-          //
-          //  Release the synchronization with Ax88772Timer
-          //      
-          if ( pMode->MediaPresent && pNicDevice->bComplete) {
-            //
-            //  Copy the packet into the USB buffer
-            //
-
-            CopyMem ( &pNicDevice->pTxTest->Data[0], pBuffer, BufferSize ); 
-            pNicDevice->pTxTest->Length = (UINT16) BufferSize;
-
-            //
-            //  Transmit the packet
-            //
-            pHeader = (ETHERNET_HEADER *) &pNicDevice->pTxTest->Data[0];
-            if ( 0 != HeaderSize ) {
-              if ( NULL != pDestAddr ) {
-                CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
-              }
-              if ( NULL != pSrcAddr ) {
-                CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
-              }
-              else {
-                CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
-              }
-              if ( NULL != pProtocol ) {
-                Type = *pProtocol;
-              }
-              else {
-                Type = pNicDevice->pTxTest->Length;
-              }
-              Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
-              pHeader->type = Type;
-            }
-            if ( pNicDevice->pTxTest->Length < MIN_ETHERNET_PKT_SIZE ) {
-              pNicDevice->pTxTest->Length = MIN_ETHERNET_PKT_SIZE;
-              ZeroMem ( &pNicDevice->pTxTest->Data[ BufferSize ],
-                        pNicDevice->pTxTest->Length - BufferSize );
-            }
-        
-            DEBUG ((EFI_D_INFO, "TX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x"
-                      "  %02x-%02x  %d bytes\r\n",
-                      pNicDevice->pTxTest->Data[0],
-                      pNicDevice->pTxTest->Data[1],
-                      pNicDevice->pTxTest->Data[2],
-                      pNicDevice->pTxTest->Data[3],
-                      pNicDevice->pTxTest->Data[4],
-                      pNicDevice->pTxTest->Data[5],
-                      pNicDevice->pTxTest->Data[6],
-                      pNicDevice->pTxTest->Data[7],
-                      pNicDevice->pTxTest->Data[8],
-                      pNicDevice->pTxTest->Data[9],
-                      pNicDevice->pTxTest->Data[10],
-                      pNicDevice->pTxTest->Data[11],
-                      pNicDevice->pTxTest->Data[12],
-                      pNicDevice->pTxTest->Data[13],
-                      pNicDevice->pTxTest->Length ));
-
-            pNicDevice->pTxTest->LengthBar = ~(pNicDevice->pTxTest->Length);
-            TransferLength = sizeof ( pNicDevice->pTxTest->Length )
-                           + sizeof ( pNicDevice->pTxTest->LengthBar )
-                           + pNicDevice->pTxTest->Length;
-                           
-            if (TransferLength % 512 == 0 || TransferLength % 1024 == 0)
-                TransferLength +=4;
-
-            //
-            //  Work around USB bus driver bug where a timeout set by receive
-            //  succeeds but the timeout expires immediately after, causing the
-            //  transmit operation to timeout.
-            //
-            pUsbIo = pNicDevice->pUsbIo;
-            Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
-                                               BULK_OUT_ENDPOINT,
-                                               &pNicDevice->pTxTest->Length,
-                                               &TransferLength,
-                                               0xfffffffe, 
-                                               &TransferStatus );
-            if ( !EFI_ERROR ( Status )) {
-              Status = TransferStatus;
-            }
-
-            if ( !EFI_ERROR ( Status )) {
-              pNicDevice->pTxBuffer = pBuffer;
-            }
-            else {
-              if ((TransferLength != (UINTN)( pNicDevice->pTxTest->Length + 4 )) &&
-                   (TransferLength != (UINTN)(( pNicDevice->pTxTest->Length + 4 ) + 4))) {
-                DEBUG ((EFI_D_INFO, "TransferLength didn't match Packet Length\n"));
-              }
-              //
-              //  Reset the controller to fix the error
-              //
-              if ( EFI_DEVICE_ERROR == Status ) {
-                SN_Reset ( pSimpleNetwork, FALSE );
-              }
-              Status = EFI_NOT_READY;
-            }
-          }
-          else {
-            //
-            // No packets available.
-            //
-            Status = EFI_NOT_READY;
-          }
-          
-        }
-        else {
-          if (EfiSimpleNetworkStarted == pMode->State) {
-            Status = EFI_DEVICE_ERROR;
-          }
-          else {
-            Status = EFI_NOT_STARTED ;
-          }
-        }
-      }
-      else {
-        Status = EFI_BUFFER_TOO_SMALL;
-      }
-    }
-    else {
-      Status = EFI_INVALID_PARAMETER;
-    }
-  }
-  else {
-    Status = EFI_INVALID_PARAMETER;
-  }
-  
-  gBS->RestoreTPL (TplPrevious);
-
-  return Status;
-}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [edk2-platform][PATCH v3 6/6] Drivers/OptionRomPkg: Remove old ASIX NIC drivers
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 6/6] Drivers/OptionRomPkg: Remove old ASIX NIC drivers Samer El-Haj-Mahmoud
@ 2020-06-09  0:36   ` Ni, Ray
  0 siblings, 0 replies; 14+ messages in thread
From: Ni, Ray @ 2020-06-09  0:36 UTC (permalink / raw)
  To: Samer El-Haj-Mahmoud, devel@edk2.groups.io
  Cc: Leif Lindholm, Ard Biesheuvel, Kinney, Michael D

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>
> Sent: Monday, June 8, 2020 9:39 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Leif Lindholm <leif@nuviainc.com>; Ard Biesheuvel <ard.biesheuvel@arm.com>; Kinney,
> Michael D <michael.d.kinney@intel.com>
> Subject: [edk2-platform][PATCH v3 6/6] Drivers/OptionRomPkg: Remove old ASIX NIC drivers
> 
> Remove the olf ASIX Ax88772 and Ax88772b USB networking drivers.
> These are now replaced with the new version of the driver (Ax88772c)
> under Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> 
> Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
> ---
>  Drivers/OptionRomPkg/OptionRomPkg.dsc                               |    3 +-
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf      |   61 -
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf    |   61 -
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h        |  969 ------------
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h       | 1026 ------------
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c        | 1318 ----------------
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c  |  178 ---
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c  |  507 ------
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c  | 1503 ------------------
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c       |  875 -----------
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c |  175 ---
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c |  696 --------
>  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c | 1657 --------------------
>  13 files changed, 1 insertion(+), 9028 deletions(-)
> 
> diff --git a/Drivers/OptionRomPkg/OptionRomPkg.dsc b/Drivers/OptionRomPkg/OptionRomPkg.dsc
> index bea64b585ec6..8a13cc54e6ae 100644
> --- a/Drivers/OptionRomPkg/OptionRomPkg.dsc
> +++ b/Drivers/OptionRomPkg/OptionRomPkg.dsc
> @@ -8,6 +8,7 @@
>  #
>  # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
>  # Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
> +# Copyright (c) 2020, ARM Limited. All rights reserved.
>  #
>  # SPDX-License-Identifier: BSD-2-Clause-Patent
>  #
> @@ -106,8 +107,6 @@ [Components]
>    OptionRomPkg/CirrusLogic5430Dxe/CirrusLogic5430Dxe.inf
>    OptionRomPkg/UndiRuntimeDxe/UndiRuntimeDxe.inf
>    OptionRomPkg/Bus/Usb/FtdiUsbSerialDxe/FtdiUsbSerialDxe.inf
> -  OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
> -  OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> 
>  [Components.IA32, Components.X64]
>    OptionRomPkg/Application/BltLibSample/BltLibSample.inf
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
> deleted file mode 100644
> index 12e7ebc5a2cd..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf
> +++ /dev/null
> @@ -1,61 +0,0 @@
> -## @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.<BR>
> -#
> -#  SPDX-License-Identifier: BSD-2-Clause-Patent
> -#
> -##
> -
> -[Defines]
> -  INF_VERSION                    = 0x00010018
> -  BASE_NAME                      = Ax88772
> -  FILE_GUID                      = B15239D6-6A01-4808-A0F7-B7F20F073555
> -  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> -  VERSION_STRING                 = 1.0
> -
> -  ENTRY_POINT                    = EntryPoint
> -
> -#
> -#  VALID_ARCHITECTURES           = IA32 X64 EBC
> -#
> -
> -[Sources.common]
> -  Ax88772.h
> -  Ax88772.c
> -  ComponentName.c
> -  DriverBinding.c
> -  SimpleNetwork.c
> -
> -
> -[Packages]
> -  MdePkg/MdePkg.dec
> -  MdeModulePkg/MdeModulePkg.dec
> -
> -[LibraryClasses]
> -  UefiLib
> -  UefiBootServicesTableLib
> -  BaseMemoryLib
> -  DebugLib
> -  UefiRuntimeLib
> -  UefiDriverEntryPoint
> -
> -[Protocols]
> -  gEfiDevicePathProtocolGuid           ## BY_START
> -  gEfiSimpleNetworkProtocolGuid        ## BY_START
> -  gEfiUsbIoProtocolGuid                ## TO_START
> -
> -[Depex]
> -  gEfiBdsArchProtocolGuid AND
> -  gEfiCpuArchProtocolGuid AND
> -  gEfiMetronomeArchProtocolGuid AND
> -  gEfiMonotonicCounterArchProtocolGuid AND
> -  gEfiRealTimeClockArchProtocolGuid AND
> -  gEfiResetArchProtocolGuid AND
> -  gEfiRuntimeArchProtocolGuid AND
> -  gEfiSecurityArchProtocolGuid AND
> -  gEfiTimerArchProtocolGuid AND
> -  gEfiVariableWriteArchProtocolGuid AND
> -  gEfiVariableArchProtocolGuid AND
> -  gEfiWatchdogTimerArchProtocolGuid
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> deleted file mode 100644
> index 60e43fd2756b..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> +++ /dev/null
> @@ -1,61 +0,0 @@
> -## @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.<BR>
> -#
> -#  SPDX-License-Identifier: BSD-2-Clause-Patent
> -#
> -##
> -
> -[Defines]
> -  INF_VERSION                    = 0x00010018
> -  BASE_NAME                      = Ax88772b
> -  FILE_GUID                      = 95C8D770-E1A4-4422-B263-E32F14FD8186
> -  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> -  VERSION_STRING                 = 1.0
> -
> -  ENTRY_POINT                    = EntryPoint
> -
> -#
> -#  VALID_ARCHITECTURES           = IA32 X64 EBC
> -#
> -
> -[Sources.common]
> -  Ax88772.h
> -  Ax88772.c
> -  ComponentName.c
> -  DriverBinding.c
> -  SimpleNetwork.c
> -
> -
> -[Packages]
> -  MdePkg/MdePkg.dec
> -  MdeModulePkg/MdeModulePkg.dec
> -
> -[LibraryClasses]
> -  UefiLib
> -  UefiBootServicesTableLib
> -  BaseMemoryLib
> -  DebugLib
> -  UefiRuntimeLib
> -  UefiDriverEntryPoint
> -
> -[Protocols]
> -  gEfiDevicePathProtocolGuid           ## BY_START
> -  gEfiSimpleNetworkProtocolGuid        ## BY_START
> -  gEfiUsbIoProtocolGuid                ## TO_START
> -
> -[Depex]
> -  gEfiBdsArchProtocolGuid AND
> -  gEfiCpuArchProtocolGuid AND
> -  gEfiMetronomeArchProtocolGuid AND
> -  gEfiMonotonicCounterArchProtocolGuid AND
> -  gEfiRealTimeClockArchProtocolGuid AND
> -  gEfiResetArchProtocolGuid AND
> -  gEfiRuntimeArchProtocolGuid AND
> -  gEfiSecurityArchProtocolGuid AND
> -  gEfiTimerArchProtocolGuid AND
> -  gEfiVariableWriteArchProtocolGuid AND
> -  gEfiVariableArchProtocolGuid AND
> -  gEfiWatchdogTimerArchProtocolGuid
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
> deleted file mode 100644
> index 8840a4f46429..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h
> +++ /dev/null
> @@ -1,969 +0,0 @@
> -/** @file
> -  Definitions for ASIX AX88772 Ethernet adapter.
> -
> -  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef _AX88772_H_
> -#define _AX88772_H_
> -
> -#include <Uefi.h>
> -
> -#include <Guid/EventGroup.h>
> -
> -#include <IndustryStandard/Pci.h>
> -
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/DevicePathLib.h>
> -#include <Library/UefiBootServicesTableLib.h>
> -#include <Library/UefiDriverEntryPoint.h>
> -#include <Library/UefiLib.h>
> -#include <Library/UefiRuntimeLib.h>
> -
> -#include <Protocol/DevicePath.h>
> -#include <Protocol/LoadedImage.h>
> -#include <Protocol/NetworkInterfaceIdentifier.h>
> -#include <Protocol/SimpleNetwork.h>
> -#include <Protocol/UsbIo.h>
> -
> -//------------------------------------------------------------------------------
> -//  Macros
> -//------------------------------------------------------------------------------
> -//
> -//Too many output debug info hangs system in Debug tip
> -//
> -//#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */
> -//#define DBG_ENTER()             DEBUG (( DEBUG_INFO, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry
> -//#define DBG_EXIT()              DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit
> -//#define DBG_EXIT_DEC(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<
> Display routine exit with decimal value
> -//#define DBG_EXIT_HEX(Status)    DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<
> Display routine exit with hex value
> -//#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<
> Display routine exit with status value
> -//#define DBG_EXIT_TF(Status)     DEBUG (( DEBUG_INFO, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ?
> L"FALSE" : L"TRUE" ))  ///<  Display routine with TRUE/FALSE value
> -//#else   //  _MSC_VER
> -#define DBG_ENTER()               ///<  Display routine entry
> -#define DBG_EXIT()                ///<  Display routine exit
> -#define DBG_EXIT_DEC(Status)      ///<  Display routine exit with decimal value
> -#define DBG_EXIT_HEX(Status)      ///<  Display routine exit with hex value
> -#define DBG_EXIT_STATUS(Status)   ///<  Display routine exit with status value
> -#define DBG_EXIT_TF(Status)       ///<  Display routine with TRUE/FALSE value
> -//#endif  //  _MSC_VER
> -
> -#define USB_IS_IN_ENDPOINT(EndPointAddr)      (((EndPointAddr) & BIT7) != 0)  ///<  Return TRUE/FALSE for IN direction
> -#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7) == 0)  ///<  Return TRUE/FALSE for OUT
> direction
> -#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_BULK)      ///<  Return
> TRUE/FALSE for BULK type
> -#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) ///<
> Return TRUE/FALSE for INTERRUPT type
> -
> -//------------------------------------------------------------------------------
> -//  Constants
> -//------------------------------------------------------------------------------
> -
> -#define DEBUG_RX_BROADCAST  0x40000000  ///<  Display RX broadcast messages
> -#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast messages
> -#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast messages
> -#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 values
> -#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
> -
> -#define AX88772_MAX_PKT_SIZE  ( 2048 - 4 )  ///< Maximum packet size
> -#define ETHERNET_HEADER_SIZE  sizeof ( ETHERNET_HEADER )  ///<  Size in bytes 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 packet size
> -#define MAX_BULKIN_SIZE       2048  ///<  Maximum size of one UsbBulk
> -
> -
> -#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 the NIC
> -#define TPL_AX88772         TPL_CALLBACK    ///<  TPL for routine synchronization
> -
> -/**
> -  Verify new TPL value
> -
> -  This macro which is enabled when debug is enabled verifies that
> -  the new TPL value is >= 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 = 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 <= tpl );                \
> -  }                                               \
> -}
> -
> -#else   //  MDEPKG_NDEBUG
> -
> -#define VERIFY_TPL(tpl)
> -
> -#endif  //  MDEPKG_NDEBUG
> -
> -//------------------------------------------------------------------------------
> -//  Hardware Definition
> -//------------------------------------------------------------------------------
> -
> -#define DEV_SIGNATURE     SIGNATURE_32 ('A','X','8','8')  ///<  Signature of data structures in memory
> -
> -#define VENDOR_ID         0x0b95  ///<  Vendor ID for Asix
> -#define PRODUCT_ID        0x7720  ///<  Product ID for the AX88772 USB 10/100 Ethernet controller
> -
> -#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 address hash table
> -#define RXC_AP            0x0020  ///<  Accept physical address from Multicast 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
> -
> -//
> -//  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=100, 0=10 Mbps
> -#define MS_SBP            0x0800  ///<  Stop back pressure
> -#define MS_SM             0x1000  ///<  Super MAC support
> -
> -//
> -//  Software PHY Select register
> -//
> -
> -#define SPHY_PSEL         0x01    ///<  Select internal PHY
> -#define SPHY_ASEL         0x02    ///<  1=Auto select, 0=Manual select
> -
> -//
> -//  Software Reset register
> -//
> -
> -#define SRR_RR            0x01    ///<  Clear receive frame length error
> -#define SRR_RT            0x02    ///<  Clear transmit frame length error
> -#define SRR_PRTE          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_RX_CONTROL_WRITE      0x10  ///<  Set the RX control register, Value: New value
> -#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value: 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_WRITE  0x16  ///<  Write the multicast hash table, Data: New 8 byte value
> -#define CMD_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status register, Data: Register value
> -#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status register, Value: New value
> -#define CMD_RESET                 0x20  ///<  Reset register, Value: New value
> -#define CMD_PHY_SELECT            0x22  ///<  PHY select register, Value: New value
> -
> -//------------------------------
> -//  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 advertisement register
> -#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter ability register
> -#define PHY_ANER                        6       ///<  Autonegotiation expansion register
> -
> -//  BMCR - Register 0
> -
> -#define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears after reset
> -#define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
> -#define BMCR_100MBPS                    0x2000  ///<  100 Mbits/Sec
> -#define BMCR_10MBPS                     0       ///<  10 Mbits/Sec
> -#define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable autonegotiation
> -#define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
> -#define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
> -#define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart autonegotiation
> -#define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
> -#define BMCR_HALF_DUPLEX                0       ///<  Half duplex operation
> -#define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test enabled
> -
> -//  BSMR - Register 1
> -
> -#define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
> -#define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full duplex
> -#define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half duplex
> -#define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
> -#define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half duplex
> -#define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with preamble suppressed
> -#define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation complete
> -#define BMSR_RF                         0x0010  ///<  1 = Remote fault
> -#define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform autonegotiation
> -#define BMSR_LINKST                     0x0004  ///<  1 = Link up
> -#define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition detected
> -#define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended register capable
> -
> -//  ANAR and ANLPAR Registers 4, 5
> -
> -#define AN_NP                           0x8000  ///<  1 = Next page available
> -#define AN_ACK                          0x4000  ///<  1 = Link partner acknowledged
> -#define AN_RF                           0x2000  ///<  1 = Remote fault indicated by link partner
> -#define AN_FCS                          0x0400  ///<  1 = Flow control ability
> -#define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
> -#define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
> -#define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
> -#define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
> -#define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
> -#define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/CD support
> -
> -//------------------------------------------------------------------------------
> -//  Data Types
> -//------------------------------------------------------------------------------
> -
> -/**
> -  Ethernet header layout
> -
> -  IEEE 802.3-2002 Part 3 specification, section 3.1.1.
> -**/
> -#pragma pack(1)
> -typedef struct {
> -  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];  ///<  Destination LAN address
> -  UINT8 src_addr[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 * pNext;       ///<  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 identification
> -
> -  //
> -  //  USB data
> -  //
> -  EFI_HANDLE Controller;        ///<  Controller handle
> -  EFI_USB_IO_PROTOCOL * pUsbIo; ///<  USB driver interface
> -
> -  //
> -  //  Simple network protocol data
> -  //
> -  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;  ///<  Driver's network stack interface
> -  EFI_SIMPLE_NETWORK_MODE SimpleNetworkData;  ///<  Data for simple network
> -
> -  //
> -  // Ethernet controller data
> -  //
> -  BOOLEAN bInitialized;     ///<  Controller initialized
> -  VOID * pTxBuffer;         ///<  Last transmit buffer
> -  UINT16 PhyId;             ///<  PHY ID
> -
> -  //
> -  //  Link state
> -  //
> -  BOOLEAN b100Mbps;         ///<  Current link speed, FALSE = 10 Mbps
> -  BOOLEAN bComplete;        ///<  Current state of auto-negotiation
> -  BOOLEAN bFullDuplex;      ///<  Current duplex
> -  BOOLEAN bLinkUp;          ///<  Current link state
> -  BOOLEAN bLinkIdle;        ///<  TRUE = No received traffic
> -  EFI_EVENT Timer;          ///<  Timer to monitor link state and receive packets
> -  UINTN PollCount;          ///<  Number of times the autonegotiation status was polled
> -
> -  //
> -  //  Receive buffer list
> -  //
> -  RX_TX_PACKET * pRxHead;   ///<  Head of receive packet list
> -  RX_TX_PACKET * pRxTail;   ///<  Tail of receive packet list
> -  RX_TX_PACKET * pRxFree;   ///<  Free packet list
> -  INT32 MulticastHash[2];   ///<  Hash table for multicast destination addresses
> -  UINT8 * pBulkInBuff;      ///<  Buffer for Usb Bulk
> -} NIC_DEVICE;
> -
> -#define DEV_FROM_SIMPLE_NETWORK(a)  CR (a, NIC_DEVICE, SimpleNetwork, DEV_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] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bExtendedVerification  Indicates that the driver may perform a more
> -                                exhaustive verification operation of the device
> -                                during reset.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Reset (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bExtendedVerification
> -  );
> -
> -/**
> -  Initialize the simple network protocol.
> -
> -  This routine calls ::Ax88772MacAddressGet to obtain the
> -  MAC address.
> -
> -  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
> -
> -  @retval EFI_SUCCESS     Setup was successful
> -
> -**/
> -EFI_STATUS
> -SN_Setup (
> -  IN NIC_DEVICE * pNicDevice
> -  );
> -
> -/**
> -  This routine starts the network interface.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_ALREADY_STARTED   The network interface was already started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Start (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  );
> -
> -/**
> -  Set the MAC address.
> -
> -  This function modifies or resets the current station address of a
> -  network interface.  If Reset is TRUE, then the current station address
> -  is set ot the network interface's permanent address.  If Reset if FALSE
> -  then the current station address is changed to the address specified by
> -  pNew.
> -
> -  This routine calls ::Ax88772MacAddressSet to update the MAC address
> -  in the network adapter.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bReset            Flag used to reset the station address to the
> -                                network interface's permanent address.
> -  @param [in] pNew              New station address to be used for the network
> -                                interface.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_StationAddress (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bReset,
> -  IN EFI_MAC_ADDRESS * pNew
> -  );
> -
> -/**
> -  This function resets or collects the statistics on a network interface.
> -  If the size of the statistics table specified by StatisticsSize is not
> -  big enough for all of the statistics that are collected by the network
> -  interface, then a partial buffer of statistics is returned in
> -  StatisticsTable.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
> -  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
> -                                the size, in bytes, of the resulting table of statistics.
> -  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
> -                                conains the statistics.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Statistics (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bReset,
> -  IN OUT UINTN * pStatisticsSize,
> -  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
> -  );
> -
> -/**
> -  This function stops a network interface.  This call is only valid
> -  if the network interface is in the started state.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Stop (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  );
> -
> -/**
> -  This function releases the memory buffers assigned in the Initialize() call.
> -  Pending transmits and receives are lost, and interrupts are cleared and disabled.
> -  After this call, only Initialize() and Stop() calls may be used.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Shutdown (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  );
> -
> -/**
> -  Send a packet over the network.
> -
> -  This function places the packet specified by Header and Buffer on
> -  the transmit queue.  This function performs a non-blocking transmit
> -  operation.  When the transmit is complete, the buffer is returned
> -  via the GetStatus() call.
> -
> -  This routine calls ::Ax88772Rx to empty the network adapter of
> -  receive packets.  The routine then passes the transmit packet
> -  to the network adapter.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
> -                                the Transmit() function.  If HeaderSize is non-zero, then
> -                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
> -                                and DestAddr and Protocol parameters must not be NULL.
> -  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
> -                                data) to be transmitted through the network interface.
> -  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
> -                                to be transmitted.  This parameter can not be NULL.  If
> -                                HeaderSize is zero, then the media header is Buffer must
> -                                already be filled in by the caller.  If HeaderSize is nonzero,
> -                                then the media header will be filled in by the Transmit()
> -                                function.
> -  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
> -                                this parameter is ignored.  If HeaderSize is nonzero and
> -                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> -                                is used for the source HW MAC address.
> -  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
> -                                this parameter is ignored.
> -  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
> -                                this parameter is ignored.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
> -  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Transmit (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN UINTN HeaderSize,
> -  IN UINTN BufferSize,
> -  IN VOID * pBuffer,
> -  IN EFI_MAC_ADDRESS * pSrcAddr,
> -  IN EFI_MAC_ADDRESS * pDestAddr,
> -  IN UINT16 * pProtocol
> -  );
> -
> -//------------------------------------------------------------------------------
> -// Support Routines
> -//------------------------------------------------------------------------------
> -
> -/**
> -  Get the MAC address
> -
> -  This routine calls ::Ax88772UsbCommand to request the MAC
> -  address from the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772MacAddressGet (
> -  IN NIC_DEVICE * pNicDevice,
> -  OUT UINT8 * pMacAddress
> -  );
> -
> -/**
> -  Set the MAC address
> -
> -  This routine calls ::Ax88772UsbCommand to set the MAC address
> -  in the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
> -
> -  @retval EFI_SUCCESS          The MAC address was set.
> -  @retval other                The MAC address was not set.
> -
> -**/
> -EFI_STATUS
> -Ax88772MacAddressSet (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 * pMacAddress
> -  );
> -
> -/**
> -  Clear the multicast hash table
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -**/
> -VOID
> -Ax88772MulticastClear (
> -  IN NIC_DEVICE * pNicDevice
> -  );
> -
> -/**
> -  Enable a multicast address in the multicast hash table
> -
> -  This routine calls ::Ax88772Crc to compute the hash bit for
> -  this MAC address.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
> -
> -**/
> -VOID
> -Ax88772MulticastSet (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 * pMacAddress
> -  );
> -
> -/**
> -  Start the link negotiation
> -
> -  This routine calls ::Ax88772PhyWrite to start the PHY's link
> -  negotiation.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -  @retval EFI_SUCCESS          The link negotiation was started.
> -  @retval other                Failed to start the link negotiation.
> -
> -**/
> -EFI_STATUS
> -Ax88772NegotiateLinkStart (
> -  IN NIC_DEVICE * pNicDevice
> -  );
> -
> -/**
> -  Complete the negotiation of the PHY link
> -
> -  This routine calls ::Ax88772PhyRead to determine if the
> -  link negotiation is complete.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in, out] pPollCount  Address of number of times this routine was polled
> -  @param [out] pbComplete      Address of boolean to receive complate status.
> -  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
> -  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
> -  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772NegotiateLinkComplete (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN OUT UINTN * pPollCount,
> -  OUT BOOLEAN * pbComplete,
> -  OUT BOOLEAN * pbLinkUp,
> -  OUT BOOLEAN * pbHiSpeed,
> -  OUT BOOLEAN * pbFullDuplex
> -  );
> -
> -/**
> -  Read a register from the PHY
> -
> -  This routine calls ::Ax88772UsbCommand to read a PHY register.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RegisterAddress  Number of the register to read.
> -  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
> -
> -  @retval EFI_SUCCESS          The PHY data is available.
> -  @retval other                The PHY data is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772PhyRead (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 RegisterAddress,
> -  IN OUT UINT16 * pPhyData
> -  );
> -
> -/**
> -  Write to a PHY register
> -
> -  This routine calls ::Ax88772UsbCommand to write a PHY register.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RegisterAddress  Number of the register to read.
> -  @param [in] PhyData          Address of a buffer to receive the PHY register value
> -
> -  @retval EFI_SUCCESS          The PHY data was written.
> -  @retval other                Failed to wwrite the PHY register.
> -
> -**/
> -EFI_STATUS
> -Ax88772PhyWrite (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 RegisterAddress,
> -  IN UINT16 PhyData
> -  );
> -
> -/**
> -  Reset the AX88772
> -
> -  This routine uses ::Ax88772UsbCommand to reset the network
> -  adapter.  This routine also uses ::Ax88772PhyWrite to reset
> -  the PHY.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772Reset (
> -  IN NIC_DEVICE * pNicDevice
> -  );
> -
> -/**
> -  Receive a frame from the network.
> -
> -  This routine polls the USB receive interface for a packet.  If a packet
> -  is available, this routine adds the receive packet to the list of
> -  pending 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] pNicDevice  Pointer to the NIC_DEVICE structure
> -  @param [in] bUpdateLink TRUE = Update link status
> -
> -**/
> -VOID
> -Ax88772Rx (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN BOOLEAN bUpdateLink
> -  );
> -
> -/**
> -  Enable or disable the receiver
> -
> -  This routine calls ::Ax88772UsbCommand to update the
> -  receiver state.  This routine also calls ::Ax88772MacAddressSet
> -  to establish the MAC address for the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RxFilter         Simple network RX filter mask value
> -
> -  @retval EFI_SUCCESS          The MAC address was set.
> -  @retval other                The MAC address was not set.
> -
> -**/
> -EFI_STATUS
> -Ax88772RxControl (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT32 RxFilter
> -  );
> -
> -/**
> -  Read an SROM location
> -
> -  This routine calls ::Ax88772UsbCommand to read data from the
> -  SROM.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] Address          SROM address
> -  @param [out] pData           Buffer to receive the data
> -
> -  @retval EFI_SUCCESS          The read was successful
> -  @retval other                The read failed
> -
> -**/
> -EFI_STATUS
> -Ax88772SromRead (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT32 Address,
> -  OUT UINT16 * pData
> -  );
> -
> -/**
> -  This routine is called at a regular interval to poll for
> -  receive packets.
> -
> -  This routine polls the link state and gets any receive packets
> -  by calling ::Ax88772Rx.
> -
> -  @param [in] Event            Timer event
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -**/
> -VOID
> -Ax88772Timer (
> -  IN EFI_EVENT Event,
> -  IN NIC_DEVICE * pNicDevice
> -  );
> -
> -/**
> -  Send a command to the USB device.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pRequest         Pointer to the request structure
> -  @param [in, out] pBuffer     Data buffer address
> -
> -  @retval EFI_SUCCESS          The USB transfer was successful
> -  @retval other                The USB transfer failed
> -
> -**/
> -EFI_STATUS
> -Ax88772UsbCommand (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN USB_DEVICE_REQUEST * pRequest,
> -  IN OUT VOID * pBuffer
> -  );
> -
> -//------------------------------------------------------------------------------
> -// EFI Component Name Protocol Support
> -//------------------------------------------------------------------------------
> -
> -extern EFI_COMPONENT_NAME_PROTOCOL   gComponentName;  ///<  Component name protocol declaration
> -extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<  Component name 2 protocol declaration
> -
> -/**
> -  Retrieves a Unicode string that is the user readable name of the driver.
> -
> -  This function retrieves the user readable name of a driver in the form of a
> -  Unicode string. If the driver specified by This has a user readable name in
> -  the language specified by Language, then a pointer to the driver name is
> -  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> -  by This does not support the language specified by Language,
> -  then EFI_UNSUPPORTED is returned.
> -
> -  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> -                                EFI_COMPONENT_NAME_PROTOCOL instance.
> -  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> -                                array indicating the language. This is the
> -                                language of the driver name that the caller is
> -                                requesting, and it must match one of the
> -                                languages specified in SupportedLanguages. The
> -                                number of languages supported by a driver is up
> -                                to the driver writer. Language is specified
> -                                in RFC 3066 or ISO 639-2 language code format.
> -  @param [out] ppDriverName     A pointer to the Unicode string to return.
> -                                This Unicode string is the name of the
> -                                driver specified by This in the language
> -                                specified by Language.
> -
> -  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> -                                This and the language specified by Language was
> -                                returned in DriverName.
> -  @retval EFI_INVALID_PARAMETER Language is NULL.
> -  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> -  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> -                                the language specified by Language.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -GetDriverName (
> -  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> -  IN  CHAR8 * pLanguage,
> -  OUT CHAR16 ** ppDriverName
> -  );
> -
> -
> -/**
> -  Retrieves a Unicode string that is the user readable name of the controller
> -  that is being managed by a driver.
> -
> -  This function retrieves the user readable name of the controller specified by
> -  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> -  driver specified by This has a user readable name in the language specified by
> -  Language, then a pointer to the controller name is returned in ControllerName,
> -  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> -  managing the controller specified by ControllerHandle and ChildHandle,
> -  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> -  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> -
> -  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> -                                EFI_COMPONENT_NAME_PROTOCOL instance.
> -  @param [in] ControllerHandle  The handle of a controller that the driver
> -                                specified by This is managing.  This handle
> -                                specifies the controller whose name is to be
> -                                returned.
> -  @param [in] ChildHandle       The handle of the child controller to retrieve
> -                                the name of.  This is an optional parameter that
> -                                may be NULL.  It will be NULL for device
> -                                drivers.  It will also be NULL for a bus drivers
> -                                that wish to retrieve the name of the bus
> -                                controller.  It will not be NULL for a bus
> -                                driver that wishes to retrieve the name of a
> -                                child controller.
> -  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> -                                array indicating the language.  This is the
> -                                language of the driver name that the caller is
> -                                requesting, and it must match one of the
> -                                languages specified in SupportedLanguages. The
> -                                number of languages supported by a driver is up
> -                                to the driver writer. Language is specified in
> -                                RFC 3066 or ISO 639-2 language code format.
> -  @param [out] ppControllerName A pointer to the Unicode string to return.
> -                                This Unicode string is the name of the
> -                                controller specified by ControllerHandle and
> -                                ChildHandle in the language specified by
> -                                Language from the point of view of the driver
> -                                specified by This.
> -
> -  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> -                                the language specified by Language for the
> -                                driver specified by This was returned in
> -                                DriverName.
> -  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
> -  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> -                                EFI_HANDLE.
> -  @retval EFI_INVALID_PARAMETER Language is NULL.
> -  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> -  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> -                                managing the controller specified by
> -                                ControllerHandle and ChildHandle.
> -  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> -                                the language specified by Language.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -GetControllerName (
> -  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> -  IN  EFI_HANDLE ControllerHandle,
> -  IN OPTIONAL EFI_HANDLE ChildHandle,
> -  IN  CHAR8 * pLanguage,
> -  OUT CHAR16 ** ppControllerName
> -  );
> -
> -//------------------------------------------------------------------------------
> -
> -#endif  //  _AX88772_H_
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
> deleted file mode 100644
> index 365929489b8b..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.h
> +++ /dev/null
> @@ -1,1026 +0,0 @@
> -/** @file
> -  Definitions for ASIX AX88772 Ethernet adapter.
> -
> -  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef _AX88772_H_
> -#define _AX88772_H_
> -
> -#include <Uefi.h>
> -
> -#include <Guid/EventGroup.h>
> -
> -#include <IndustryStandard/Pci.h>
> -
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/DevicePathLib.h>
> -#include <Library/UefiBootServicesTableLib.h>
> -#include <Library/UefiDriverEntryPoint.h>
> -#include <Library/UefiLib.h>
> -#include <Library/UefiRuntimeLib.h>
> -
> -#include <Protocol/DevicePath.h>
> -#include <Protocol/LoadedImage.h>
> -#include <Protocol/NetworkInterfaceIdentifier.h>
> -#include <Protocol/SimpleNetwork.h>
> -#include <Protocol/UsbIo.h>
> -
> -#define MAX_QUEUE_SIZE 50
> -#define MAX_BULKIN_SIZE 16384
> -#define HW_HDR_LENGTH 8
> -
> -
> -#define MAX_LINKIDLE_THRESHOLD  20000
> -
> -
> -
> -//------------------------------------------------------------------------------
> -//  Macros
> -//------------------------------------------------------------------------------
> -
> -#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */
> -#define DBG_ENTER()             DEBUG (( 0xffffffff, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry
> -#define DBG_EXIT()              DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit
> -#define DBG_EXIT_DEC(Status)    DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display
> routine exit with decimal value
> -#define DBG_EXIT_HEX(Status)    DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display
> routine exit with hex value
> -#define DBG_EXIT_STATUS(Status) DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display
> routine exit with status value
> -#define DBG_EXIT_TF(Status)     DEBUG (( 0xffffffff, "Exiting " __FUNCTION__ ", returning %s\n", (FALSE == Status) ?
> L"FALSE" : L"TRUE" ))  ///<  Display routine with TRUE/FALSE value
> -#else   //  _MSC_VER
> -#define DBG_ENTER()               ///<  Display routine entry
> -#define DBG_EXIT()                ///<  Display routine exit
> -#define DBG_EXIT_DEC(Status)      ///<  Display routine exit with decimal value
> -#define DBG_EXIT_HEX(Status)      ///<  Display routine exit with hex value
> -#define DBG_EXIT_STATUS(Status)   ///<  Display routine exit with status value
> -#define DBG_EXIT_TF(Status)       ///<  Display routine with TRUE/FALSE value
> -#endif  //  _MSC_VER
> -
> -#define USB_IS_IN_ENDPOINT(EndPointAddr)      (((EndPointAddr) & BIT7) != 0)  ///<  Return TRUE/FALSE for IN direction
> -#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7) == 0)  ///<  Return TRUE/FALSE for OUT
> direction
> -#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_BULK)      ///<  Return
> TRUE/FALSE for BULK type
> -#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 | BIT1)) == 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 messages
> -#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast messages
> -#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast messages
> -#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 values
> -#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
> -
> -#define AX88772_MAX_PKT_SIZE  2048  ///< Maximum packet size
> -
> -#define ETHERNET_HEADER_SIZE  sizeof ( ETHERNET_HEADER )  ///<  Size in bytes 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 packet 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 the NIC
> -//#define TPL_AX88772         TPL_CALLBACK    ///<  TPL for routine synchronization
> -
> -#define HC_DEBUG  0
> -#define BULKIN_TIMEOUT  20
> -#define AUTONEG_DELAY   500000
> -#define AUTONEG_POLLCNT 20
> -
> -/**
> -  Verify new TPL value
> -
> -  This macro which is enabled when debug is enabled verifies that
> -  the new TPL value is >= 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 = 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 <= 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')  ///<  Signature of data structures in memory
> -
> -#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 address hash table
> -#define RXC_AP            0x0020  ///<  Accept physical address from Multicast 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
> -
> -/*Freddy*/
> -#define RXC_RH1M          0x0100  ///<  Rx header 1
> -#define RXC_RH2M          0x0200  ///<  Rx header 2
> -#define RXC_RH3M          0x0400  ///<  Rx header 3
> -/*Freddy*/
> -
> -//
> -//  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=100, 0=10 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=Auto select, 0=Manual select
> -
> -//
> -//  Software Reset register
> -//
> -
> -#define SRR_RR            0x01    ///<  Clear receive frame length error
> -#define SRR_RT            0x02    ///<  Clear transmit frame length error
> -#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_RX_CONTROL_WRITE      0x10  ///<  Set the RX control register, Value: New value
> -#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value: 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_WRITE  0x16  ///<  Write the multicast hash table, Data: New 8 byte value
> -#define CMD_MULTICAST_HASH_READ  0x16  ///<  Read the multicast hash table
> -#define CMD_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status register, Data: Register value
> -#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status register, 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
> -
> -/*Freddy*/
> -#define CMD_RXQTC                 0x2a  ///<  RX Queue Cascade Threshold Control Register
> -/*Freddy*/
> -
> -//------------------------------
> -//  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 advertisement register
> -#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter ability register
> -#define PHY_ANER                        6       ///<  Autonegotiation expansion register
> -
> -//  BMCR - Register 0
> -
> -#define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears after reset
> -#define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
> -#define BMCR_100MBPS                    0x2000  ///<  100 Mbits/Sec
> -#define BMCR_10MBPS                     0       ///<  10 Mbits/Sec
> -#define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable autonegotiation
> -#define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
> -#define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
> -#define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart autonegotiation
> -#define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
> -#define BMCR_HALF_DUPLEX                0       ///<  Half duplex operation
> -#define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test enabled
> -
> -//  BSMR - Register 1
> -
> -#define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
> -#define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full duplex
> -#define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half duplex
> -#define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
> -#define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half duplex
> -#define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with preamble suppressed
> -#define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation complete
> -#define BMSR_RF                         0x0010  ///<  1 = Remote fault
> -#define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform autonegotiation
> -#define BMSR_LINKST                     0x0004  ///<  1 = Link up
> -#define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition detected
> -#define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended register capable
> -
> -//  ANAR and ANLPAR Registers 4, 5
> -
> -#define AN_NP                           0x8000  ///<  1 = Next page available
> -#define AN_ACK                          0x4000  ///<  1 = Link partner acknowledged
> -#define AN_RF                           0x2000  ///<  1 = Remote fault indicated by link partner
> -#define AN_FCS                          0x0400  ///<  1 = Flow control ability
> -#define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
> -#define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
> -#define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
> -#define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
> -#define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
> -#define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/CD support
> -
> -// asix_flags defines
> -#define FLAG_NONE               0
> -#define FLAG_TYPE_AX88172       BIT0
> -#define FLAG_TYPE_AX88772       BIT1
> -#define FLAG_TYPE_AX88772B      BIT2
> -#define FLAG_EEPROM_MAC         BIT3  // initial mac address in eeprom
> -
> -//------------------------------------------------------------------------------
> -//  Data Types
> -//------------------------------------------------------------------------------
> -
> -typedef struct {
> -   UINT16  VendorId;
> -   UINT16  ProductId;
> -   INT32   Flags;
> -}ASIX_DONGLE;
> -
> -/**
> -  Ethernet header layout
> -
> -  IEEE 802.3-2002 Part 3 specification, section 3.1.1.
> -**/
> -#pragma pack(1)
> -typedef struct {
> -  UINT8 dest_addr[PXE_HWADDR_LEN_ETHER];  ///<  Destination LAN address
> -  UINT8 src_addr[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 * pNext;       ///<  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()
> -
> -
> -#pragma pack(1)
> -typedef struct _RX_PKT {
> -  struct _RX_PKT *pNext;
> -  BOOLEAN f_Used;
> -  UINT16 Length;
> -  UINT8 Data [AX88772_MAX_PKT_SIZE] ;
> -} RX_PKT;
> -#pragma pack()
> -
> -/**
> -  AX88772 control structure
> -
> -  The driver uses this structure to manage the Asix AX88772 10/100
> -  Ethernet controller.
> -**/
> -typedef struct {
> -  UINTN Signature;          ///<  Structure identification
> -
> -  //
> -  //  USB data
> -  //
> -  EFI_HANDLE Controller;        ///<  Controller handle
> -  EFI_USB_IO_PROTOCOL * pUsbIo;  ///<  USB driver interface
> -
> -  //
> -  //  Simple network protocol data
> -  //
> -  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;  ///<  Driver's network stack interface
> -  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork_Backup;
> -  EFI_SIMPLE_NETWORK_MODE SimpleNetworkData;  ///<  Data for simple network
> -
> -  //
> -  // Ethernet controller data
> -  //
> -  BOOLEAN bInitialized;     ///<  Controller initialized
> -  VOID * pTxBuffer;         ///<  Last transmit buffer
> -  UINT16 PhyId;             ///<  PHY ID
> -
> -  //
> -  //  Link state
> -  //
> -  BOOLEAN b100Mbps;         ///<  Current link speed, FALSE = 10 Mbps
> -  BOOLEAN bComplete;        ///<  Current state of auto-negotiation
> -  BOOLEAN bFullDuplex;      ///<  Current duplex
> -  BOOLEAN bLinkUp;          ///<  Current link state
> -  UINTN  LinkIdleCnt;
> -  UINTN PollCount;          ///<  Number of times the autonegotiation status was polled
> -  UINT16 CurRxControl;
> -  //
> -  //  Receive buffer list
> -  //
> -  RX_TX_PACKET * pRxTest;
> -  RX_TX_PACKET * pTxTest;
> -
> -  INT8 MulticastHash[8];
> -  EFI_MAC_ADDRESS MAC;
> -  BOOLEAN bHavePkt;
> -
> -  EFI_DEVICE_PATH_PROTOCOL                  *MyDevPath;
> -
> -  EFI_DRIVER_BINDING_PROTOCOL * DrvBind;
> -
> -  RX_PKT * QueueHead;
> -  RX_PKT * pNextFill;
> -  RX_PKT * pFirstFill;
> -  UINTN   PktCntInQueue;
> -  UINT8 * pBulkInBuff;
> -
> -  INT32 Flags;
> -
> -} NIC_DEVICE;
> -
> -#define DEV_FROM_SIMPLE_NETWORK(a)  CR (a, NIC_DEVICE, SimpleNetwork, DEV_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] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bExtendedVerification  Indicates that the driver may perform a more
> -                                exhaustive verification operation of the device
> -                                during reset.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Reset (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bExtendedVerification
> -  );
> -
> -/**
> -  Initialize the simple network protocol.
> -
> -  This routine calls ::Ax88772MacAddressGet to obtain the
> -  MAC address.
> -
> -  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
> -
> -  @retval EFI_SUCCESS     Setup was successful
> -
> -**/
> -EFI_STATUS
> -SN_Setup (
> -  IN NIC_DEVICE * pNicDevice
> -  );
> -
> -/**
> -  This routine starts the network interface.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_ALREADY_STARTED   The network interface was already started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Start (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  );
> -
> -/**
> -  Set the MAC address.
> -
> -  This function modifies or resets the current station address of a
> -  network interface.  If Reset is TRUE, then the current station address
> -  is set ot the network interface's permanent address.  If Reset if FALSE
> -  then the current station address is changed to the address specified by
> -  pNew.
> -
> -  This routine calls ::Ax88772MacAddressSet to update the MAC address
> -  in the network adapter.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bReset            Flag used to reset the station address to the
> -                                network interface's permanent address.
> -  @param [in] pNew              New station address to be used for the network
> -                                interface.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_StationAddress (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bReset,
> -  IN EFI_MAC_ADDRESS * pNew
> -  );
> -
> -/**
> -  This function resets or collects the statistics on a network interface.
> -  If the size of the statistics table specified by StatisticsSize is not
> -  big enough for all of the statistics that are collected by the network
> -  interface, then a partial buffer of statistics is returned in
> -  StatisticsTable.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
> -  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
> -                                the size, in bytes, of the resulting table of statistics.
> -  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
> -                                conains the statistics.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Statistics (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bReset,
> -  IN OUT UINTN * pStatisticsSize,
> -  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
> -  );
> -
> -/**
> -  This function stops a network interface.  This call is only valid
> -  if the network interface is in the started state.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Stop (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  );
> -
> -/**
> -  This function releases the memory buffers assigned in the Initialize() call.
> -  Pending transmits and receives are lost, and interrupts are cleared and disabled.
> -  After this call, only Initialize() and Stop() calls may be used.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Shutdown (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  );
> -
> -/**
> -  Send a packet over the network.
> -
> -  This function places the packet specified by Header and Buffer on
> -  the transmit queue.  This function performs a non-blocking transmit
> -  operation.  When the transmit is complete, the buffer is returned
> -  via the GetStatus() call.
> -
> -  This routine calls ::Ax88772Rx to empty the network adapter of
> -  receive packets.  The routine then passes the transmit packet
> -  to the network adapter.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
> -                                the Transmit() function.  If HeaderSize is non-zero, then
> -                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
> -                                and DestAddr and Protocol parameters must not be NULL.
> -  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
> -                                data) to be transmitted through the network interface.
> -  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
> -                                to be transmitted.  This parameter can not be NULL.  If
> -                                HeaderSize is zero, then the media header is Buffer must
> -                                already be filled in by the caller.  If HeaderSize is nonzero,
> -                                then the media header will be filled in by the Transmit()
> -                                function.
> -  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
> -                                this parameter is ignored.  If HeaderSize is nonzero and
> -                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> -                                is used for the source HW MAC address.
> -  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
> -                                this parameter is ignored.
> -  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
> -                                this parameter is ignored.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
> -  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Transmit (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN UINTN HeaderSize,
> -  IN UINTN BufferSize,
> -  IN VOID * pBuffer,
> -  IN EFI_MAC_ADDRESS * pSrcAddr,
> -  IN EFI_MAC_ADDRESS * pDestAddr,
> -  IN UINT16 * pProtocol
> -  );
> -
> -//------------------------------------------------------------------------------
> -// Support Routines
> -//------------------------------------------------------------------------------
> -
> -/**
> -  Get the MAC address
> -
> -  This routine calls ::Ax88772UsbCommand to request the MAC
> -  address from the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772MacAddressGet (
> -  IN NIC_DEVICE * pNicDevice,
> -  OUT UINT8 * pMacAddress
> -  );
> -
> -/**
> -  Set the MAC address
> -
> -  This routine calls ::Ax88772UsbCommand to set the MAC address
> -  in the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
> -
> -  @retval EFI_SUCCESS          The MAC address was set.
> -  @retval other                The MAC address was not set.
> -
> -**/
> -EFI_STATUS
> -Ax88772MacAddressSet (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 * pMacAddress
> -  );
> -
> -/**
> -  Clear the multicast hash table
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -**/
> -VOID
> -Ax88772MulticastClear (
> -  IN NIC_DEVICE * pNicDevice
> -  );
> -
> -/**
> -  Enable a multicast address in the multicast hash table
> -
> -  This routine calls ::Ax88772Crc to compute the hash bit for
> -  this MAC address.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
> -
> -**/
> -VOID
> -Ax88772MulticastSet (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 * pMacAddress
> -  );
> -
> -/**
> -  Start the link negotiation
> -
> -  This routine calls ::Ax88772PhyWrite to start the PHY's link
> -  negotiation.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -  @retval EFI_SUCCESS          The link negotiation was started.
> -  @retval other                Failed to start the link negotiation.
> -
> -**/
> -EFI_STATUS
> -Ax88772NegotiateLinkStart (
> -  IN NIC_DEVICE * pNicDevice
> -  );
> -
> -/**
> -  Complete the negotiation of the PHY link
> -
> -  This routine calls ::Ax88772PhyRead to determine if the
> -  link negotiation is complete.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in, out] pPollCount  Address of number of times this routine was polled
> -  @param [out] pbComplete      Address of boolean to receive complate status.
> -  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
> -  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
> -  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772NegotiateLinkComplete (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN OUT UINTN * pPollCount,
> -  OUT BOOLEAN * pbComplete,
> -  OUT BOOLEAN * pbLinkUp,
> -  OUT BOOLEAN * pbHiSpeed,
> -  OUT BOOLEAN * pbFullDuplex
> -  );
> -
> -/**
> -  Read a register from the PHY
> -
> -  This routine calls ::Ax88772UsbCommand to read a PHY register.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RegisterAddress  Number of the register to read.
> -  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
> -
> -  @retval EFI_SUCCESS          The PHY data is available.
> -  @retval other                The PHY data is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772PhyRead (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 RegisterAddress,
> -  IN OUT UINT16 * pPhyData
> -  );
> -
> -/**
> -  Write to a PHY register
> -
> -  This routine calls ::Ax88772UsbCommand to write a PHY register.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RegisterAddress  Number of the register to read.
> -  @param [in] PhyData          Address of a buffer to receive the PHY register value
> -
> -  @retval EFI_SUCCESS          The PHY data was written.
> -  @retval other                Failed to wwrite the PHY register.
> -
> -**/
> -EFI_STATUS
> -Ax88772PhyWrite (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 RegisterAddress,
> -  IN UINT16 PhyData
> -  );
> -
> -/**
> -  Reset the AX88772
> -
> -  This routine uses ::Ax88772UsbCommand to reset the network
> -  adapter.  This routine also uses ::Ax88772PhyWrite to reset
> -  the PHY.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772Reset (
> -  IN NIC_DEVICE * pNicDevice
> -  );
> -
> -VOID
> -Ax88772ChkLink (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN BOOLEAN bUpdateLink
> -  );
> -
> -/**
> -  Receive a frame from the network.
> -
> -  This routine polls the USB receive interface for a packet.  If a packet
> -  is available, this routine adds the receive packet to the list of
> -  pending 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] pNicDevice  Pointer to the NIC_DEVICE structure
> -  @param [in] bUpdateLink TRUE = Update link status
> -
> -**/
> -VOID
> -Ax88772Rx (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN BOOLEAN bUpdateLink
> -  );
> -
> -/**
> -  Enable or disable the receiver
> -
> -  This routine calls ::Ax88772UsbCommand to update the
> -  receiver state.  This routine also calls ::Ax88772MacAddressSet
> -  to establish the MAC address for the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RxFilter         Simple network RX filter mask value
> -
> -  @retval EFI_SUCCESS          The MAC address was set.
> -  @retval other                The MAC address was not set.
> -
> -**/
> -EFI_STATUS
> -Ax88772RxControl (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT32 RxFilter
> -  );
> -
> -/**
> -  Read an SROM location
> -
> -  This routine calls ::Ax88772UsbCommand to read data from the
> -  SROM.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] Address          SROM address
> -  @param [out] pData           Buffer to receive the data
> -
> -  @retval EFI_SUCCESS          The read was successful
> -  @retval other                The read failed
> -
> -**/
> -EFI_STATUS
> -Ax88772SromRead (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT32 Address,
> -  OUT UINT16 * pData
> -  );
> -
> -/**
> -  Send a command to the USB device.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pRequest         Pointer to the request structure
> -  @param [in, out] pBuffer     Data buffer address
> -
> -  @retval EFI_SUCCESS          The USB transfer was successful
> -  @retval other                The USB transfer failed
> -
> -**/
> -EFI_STATUS
> -Ax88772UsbCommand (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN USB_DEVICE_REQUEST * pRequest,
> -  IN OUT VOID * pBuffer
> -  );
> -
> -//------------------------------------------------------------------------------
> -// EFI Component Name Protocol Support
> -//------------------------------------------------------------------------------
> -
> -extern EFI_COMPONENT_NAME_PROTOCOL   gComponentName;  ///<  Component name protocol declaration
> -extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<  Component name 2 protocol declaration
> -
> -/**
> -  Retrieves a Unicode string that is the user readable name of the driver.
> -
> -  This function retrieves the user readable name of a driver in the form of a
> -  Unicode string. If the driver specified by This has a user readable name in
> -  the language specified by Language, then a pointer to the driver name is
> -  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> -  by This does not support the language specified by Language,
> -  then EFI_UNSUPPORTED is returned.
> -
> -  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> -                                EFI_COMPONENT_NAME_PROTOCOL instance.
> -  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> -                                array indicating the language. This is the
> -                                language of the driver name that the caller is
> -                                requesting, and it must match one of the
> -                                languages specified in SupportedLanguages. The
> -                                number of languages supported by a driver is up
> -                                to the driver writer. Language is specified
> -                                in RFC 3066 or ISO 639-2 language code format.
> -  @param [out] ppDriverName     A pointer to the Unicode string to return.
> -                                This Unicode string is the name of the
> -                                driver specified by This in the language
> -                                specified by Language.
> -
> -  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> -                                This and the language specified by Language was
> -                                returned in DriverName.
> -  @retval EFI_INVALID_PARAMETER Language is NULL.
> -  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> -  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> -                                the language specified by Language.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -GetDriverName (
> -  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> -  IN  CHAR8 * pLanguage,
> -  OUT CHAR16 ** ppDriverName
> -  );
> -
> -
> -/**
> -  Retrieves a Unicode string that is the user readable name of the controller
> -  that is being managed by a driver.
> -
> -  This function retrieves the user readable name of the controller specified by
> -  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> -  driver specified by This has a user readable name in the language specified by
> -  Language, then a pointer to the controller name is returned in ControllerName,
> -  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> -  managing the controller specified by ControllerHandle and ChildHandle,
> -  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> -  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> -
> -  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> -                                EFI_COMPONENT_NAME_PROTOCOL instance.
> -  @param [in] ControllerHandle  The handle of a controller that the driver
> -                                specified by This is managing.  This handle
> -                                specifies the controller whose name is to be
> -                                returned.
> -  @param [in] ChildHandle       The handle of the child controller to retrieve
> -                                the name of.  This is an optional parameter that
> -                                may be NULL.  It will be NULL for device
> -                                drivers.  It will also be NULL for a bus drivers
> -                                that wish to retrieve the name of the bus
> -                                controller.  It will not be NULL for a bus
> -                                driver that wishes to retrieve the name of a
> -                                child controller.
> -  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> -                                array indicating the language.  This is the
> -                                language of the driver name that the caller is
> -                                requesting, and it must match one of the
> -                                languages specified in SupportedLanguages. The
> -                                number of languages supported by a driver is up
> -                                to the driver writer. Language is specified in
> -                                RFC 3066 or ISO 639-2 language code format.
> -  @param [out] ppControllerName A pointer to the Unicode string to return.
> -                                This Unicode string is the name of the
> -                                controller specified by ControllerHandle and
> -                                ChildHandle in the language specified by
> -                                Language from the point of view of the driver
> -                                specified by This.
> -
> -  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> -                                the language specified by Language for the
> -                                driver specified by This was returned in
> -                                DriverName.
> -  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
> -  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> -                                EFI_HANDLE.
> -  @retval EFI_INVALID_PARAMETER Language is NULL.
> -  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> -  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> -                                managing the controller specified by
> -                                ControllerHandle and ChildHandle.
> -  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> -                                the language specified by Language.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -GetControllerName (
> -  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> -  IN  EFI_HANDLE ControllerHandle,
> -  IN OPTIONAL EFI_HANDLE ChildHandle,
> -  IN  CHAR8 * pLanguage,
> -  OUT CHAR16 ** ppControllerName
> -  );
> -
> -VOID
> -FillPkt2Queue (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN UINTN BufLength);
> -
> -//------------------------------------------------------------------------------
> -
> -#endif  //  _AX88772_H_
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
> deleted file mode 100644
> index c9329f506d5d..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
> +++ /dev/null
> @@ -1,1318 +0,0 @@
> -/** @file
> -  Implement the interface to the AX88772 Ethernet controller.
> -
> -  This module implements the interface to the ASIX AX88772
> -  USB to Ethernet MAC with integrated 10/100 PHY.  Note that this implementation
> -  only supports the integrated PHY since no other test cases were available.
> -
> -  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include "Ax88772.h"
> -
> -
> -/**
> -  Compute the CRC
> -
> -  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
> -
> -  @returns The CRC-32 value associated with this MAC address
> -
> -**/
> -UINT32
> -Ax88772Crc (
> -  IN UINT8 * pMacAddress
> -  )
> -{
> -  UINT32 BitNumber;
> -  INT32 Carry;
> -  INT32 Crc;
> -  UINT32 Data;
> -  UINT8 * pEnd;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Walk the MAC address
> -  //
> -  Crc = -1;
> -  pEnd = &pMacAddress[ PXE_HWADDR_LEN_ETHER ];
> -  while ( pEnd > pMacAddress ) {
> -    Data = *pMacAddress++;
> -
> -
> -    //
> -    //  CRC32: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
> -    //
> -    //          1 0000 0100 1100 0001 0001 1101 1011 0111
> -    //
> -    for ( BitNumber = 0; 8 > BitNumber; BitNumber++ ) {
> -      Carry = (( Crc >> 31 ) & 1 ) ^ ( Data & 1 );
> -      Crc <<= 1;
> -      if ( 0 != Carry ) {
> -        Crc ^= 0x04c11db7;
> -      }
> -      Data >>= 1;
> -    }
> -  }
> -
> -  //
> -  //  Return the CRC value
> -  //
> -  DBG_EXIT_HEX ( Crc );
> -  return (UINT32) Crc;
> -}
> -
> -
> -/**
> -  Get the MAC address
> -
> -  This routine calls ::Ax88772UsbCommand to request the MAC
> -  address from the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772MacAddressGet (
> -  IN NIC_DEVICE * pNicDevice,
> -  OUT UINT8 * pMacAddress
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Set the register address.
> -  //
> -  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> -                       | USB_REQ_TYPE_VENDOR
> -                       | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_MAC_ADDRESS_READ;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
> -
> -  //
> -  //  Read the PHY register
> -  //
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                               &SetupMsg,
> -                               pMacAddress );
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Set the MAC address
> -
> -  This routine calls ::Ax88772UsbCommand to set the MAC address
> -  in the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
> -
> -  @retval EFI_SUCCESS          The MAC address was set.
> -  @retval other                The MAC address was not set.
> -
> -**/
> -EFI_STATUS
> -Ax88772MacAddressSet (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 * pMacAddress
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Set the register address.
> -  //
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                       | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
> -
> -  //
> -  //  Read the PHY register
> -  //
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                               &SetupMsg,
> -                               pMacAddress );
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Clear the multicast hash table
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -**/
> -VOID
> -Ax88772MulticastClear (
> -  IN NIC_DEVICE * pNicDevice
> -  )
> -{
> -  DBG_ENTER ( );
> -
> -  //
> -  // Clear the multicast hash table
> -  //
> -  pNicDevice->MulticastHash[0] = 0;
> -  pNicDevice->MulticastHash[1] = 0;
> -
> -  DBG_EXIT ( );
> -}
> -
> -
> -/**
> -  Enable a multicast address in the multicast hash table
> -
> -  This routine calls ::Ax88772Crc to compute the hash bit for
> -  this MAC address.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
> -
> -**/
> -VOID
> -Ax88772MulticastSet (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 * pMacAddress
> -  )
> -{
> -  UINT32 BitNumber;
> -  UINT32 Crc;
> -  UINT32 Mask;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Compute the CRC on the destination address
> -  //
> -  Crc = Ax88772Crc ( pMacAddress );
> -
> -  //
> -  //  Set the bit corresponding to the destination address
> -  //
> -  BitNumber = Crc >> 26;
> -  if ( 32 > BitNumber ) {
> -    Mask = 1 << BitNumber;
> -    pNicDevice->MulticastHash[0] |= Mask;
> -  }
> -  else {
> -    Mask = 1 << ( BitNumber - 32 );
> -    pNicDevice->MulticastHash[1] |= Mask;
> -  }
> -
> -  //
> -  //  Display the multicast address
> -  //
> -  DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
> -            "Enable multicast: 0x%02x-%02x-%02x-%02x-%02x-%02x, CRC: 0x%08x, Bit number: 0x%02x\r\n",
> -            pMacAddress[0],
> -            pMacAddress[1],
> -            pMacAddress[2],
> -            pMacAddress[3],
> -            pMacAddress[4],
> -            pMacAddress[5],
> -            Crc,
> -            BitNumber ));
> -
> -  DBG_EXIT ( );
> -}
> -
> -
> -/**
> -  Start the link negotiation
> -
> -  This routine calls ::Ax88772PhyWrite to start the PHY's link
> -  negotiation.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -  @retval EFI_SUCCESS          The link negotiation was started.
> -  @retval other                Failed to start the link negotiation.
> -
> -**/
> -EFI_STATUS
> -Ax88772NegotiateLinkStart (
> -  IN NIC_DEVICE * pNicDevice
> -  )
> -{
> -  UINT16 Control;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Set the supported capabilities.
> -  //
> -  Status = Ax88772PhyWrite ( pNicDevice,
> -                             PHY_ANAR,
> -                             AN_CSMA_CD
> -                             | AN_TX_FDX | AN_TX_HDX
> -                             | AN_10_FDX | AN_10_HDX );
> -  if ( !EFI_ERROR ( Status )) {
> -    //
> -    // Set the link speed and duplex
> -    //
> -    Control = BMCR_AUTONEGOTIATION_ENABLE
> -            | BMCR_RESTART_AUTONEGOTIATION;
> -    if ( pNicDevice->b100Mbps ) {
> -      Control |= BMCR_100MBPS;
> -    }
> -    if ( pNicDevice->bFullDuplex ) {
> -      Control |= BMCR_FULL_DUPLEX;
> -    }
> -    Status = Ax88772PhyWrite ( pNicDevice, PHY_BMCR, Control );
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Complete the negotiation of the PHY link
> -
> -  This routine calls ::Ax88772PhyRead to determine if the
> -  link negotiation is complete.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in, out] pPollCount  Address of number of times this routine was polled
> -  @param [out] pbComplete      Address of boolean to receive complate status.
> -  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
> -  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
> -  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772NegotiateLinkComplete (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN OUT UINTN * pPollCount,
> -  OUT BOOLEAN * pbComplete,
> -  OUT BOOLEAN * pbLinkUp,
> -  OUT BOOLEAN * pbHiSpeed,
> -  OUT BOOLEAN * pbFullDuplex
> -  )
> -{
> -  UINT16 Mask;
> -  UINT16 PhyData;
> -  EFI_STATUS  Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Determine if the link is up.
> -  //
> -  *pbComplete = FALSE;
> -
> -  //
> -  //  Get the link status
> -  //
> -  Status = Ax88772PhyRead ( pNicDevice,
> -                            PHY_BMSR,
> -                            &PhyData );
> -  if ( !EFI_ERROR ( Status )) {
> -    //
> -    //  Determine if the autonegotiation is complete.
> -    //
> -    *pbLinkUp = (BOOLEAN)( 0 != ( PhyData & BMSR_LINKST ));
> -    *pbComplete = *pbLinkUp;
> -    if ( 0 != *pbComplete ) {
> -      //
> -      //  Get the partners capabilities.
> -      //
> -      Status = Ax88772PhyRead ( pNicDevice,
> -                                PHY_ANLPAR,
> -                                &PhyData );
> -      if ( !EFI_ERROR ( Status )) {
> -        //
> -        //  Autonegotiation is complete
> -        //  Determine the link speed.
> -        //
> -        *pbHiSpeed = (BOOLEAN)( 0 != ( PhyData & ( AN_TX_FDX | AN_TX_HDX )));
> -
> -        //
> -        //  Determine the link duplex.
> -        //
> -        Mask = ( *pbHiSpeed ) ? AN_TX_FDX : AN_10_FDX;
> -        *pbFullDuplex = (BOOLEAN)( 0 != ( PhyData & Mask ));
> -      }
> -    }
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Read a register from the PHY
> -
> -  This routine calls ::Ax88772UsbCommand to read a PHY register.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RegisterAddress  Number of the register to read.
> -  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
> -
> -  @retval EFI_SUCCESS          The PHY data is available.
> -  @retval other                The PHY data is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772PhyRead (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 RegisterAddress,
> -  IN OUT UINT16 * pPhyData
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Request access to the PHY
> -  //
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                       | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                               &SetupMsg,
> -                               NULL );
> -  if ( !EFI_ERROR ( Status )) {
> -    //
> -    //  Read the PHY register address.
> -    //
> -    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> -                         | USB_REQ_TYPE_VENDOR
> -                         | USB_TARGET_DEVICE;
> -    SetupMsg.Request = CMD_PHY_REG_READ;
> -    SetupMsg.Value = pNicDevice->PhyId;
> -    SetupMsg.Index = RegisterAddress;
> -    SetupMsg.Length = sizeof ( *pPhyData );
> -    Status = Ax88772UsbCommand ( pNicDevice,
> -                                 &SetupMsg,
> -                                 pPhyData );
> -    if ( !EFI_ERROR ( Status )) {
> -      DEBUG (( DEBUG_PHY | DEBUG_INFO,
> -                "PHY %d: 0x%02x --> 0x%04x\r\n",
> -                pNicDevice->PhyId,
> -                RegisterAddress,
> -                *pPhyData ));
> -
> -      //
> -      //  Release the PHY to the hardware
> -      //
> -      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                           | USB_TARGET_DEVICE;
> -      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> -      SetupMsg.Value = 0;
> -      SetupMsg.Index = 0;
> -      SetupMsg.Length = 0;
> -      Status = Ax88772UsbCommand ( pNicDevice,
> -                                   &SetupMsg,
> -                                   NULL );
> -    }
> -  }
> -
> -  //
> -  //  Return the operation status.
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Write to a PHY register
> -
> -  This routine calls ::Ax88772UsbCommand to write a PHY register.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RegisterAddress  Number of the register to read.
> -  @param [in] PhyData          Address of a buffer to receive the PHY register value
> -
> -  @retval EFI_SUCCESS          The PHY data was written.
> -  @retval other                Failed to wwrite the PHY register.
> -
> -**/
> -EFI_STATUS
> -Ax88772PhyWrite (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 RegisterAddress,
> -  IN UINT16 PhyData
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Request access to the PHY
> -  //
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                       | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                               &SetupMsg,
> -                               NULL );
> -  if ( !EFI_ERROR ( Status )) {
> -    //
> -    //  Write the PHY register
> -    //
> -    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                         | USB_TARGET_DEVICE;
> -    SetupMsg.Request = CMD_PHY_REG_WRITE;
> -    SetupMsg.Value = pNicDevice->PhyId;
> -    SetupMsg.Index = RegisterAddress;
> -    SetupMsg.Length = sizeof ( PhyData );
> -    Status = Ax88772UsbCommand ( pNicDevice,
> -                                 &SetupMsg,
> -                                 &PhyData );
> -    if ( !EFI_ERROR ( Status )) {
> -      DEBUG (( DEBUG_PHY | DEBUG_INFO,
> -                "PHY %d: 0x%02x <-- 0x%04x\r\n",
> -                pNicDevice->PhyId,
> -                RegisterAddress,
> -                PhyData ));
> -
> -      //
> -      //  Release the PHY to the hardware
> -      //
> -      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                           | USB_TARGET_DEVICE;
> -      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> -      SetupMsg.Value = 0;
> -      SetupMsg.Index = 0;
> -      SetupMsg.Length = 0;
> -      Status = Ax88772UsbCommand ( pNicDevice,
> -                                   &SetupMsg,
> -                                   NULL );
> -    }
> -  }
> -
> -  //
> -  //  Return the operation status.
> -  //
> -  DBG_EXIT_STATUS ( 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] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772Reset (
> -  IN NIC_DEVICE * pNicDevice
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Turn off the MAC
> -  //
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                       | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_RX_CONTROL_WRITE;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                               &SetupMsg,
> -                               NULL );
> -  if ( !EFI_ERROR ( Status )) {
> -    DEBUG (( DEBUG_PHY | DEBUG_RX_BROADCAST | DEBUG_RX_MULTICAST
> -              | DEBUG_RX_UNICAST | DEBUG_TX | DEBUG_INFO,
> -              "MAC reset\r\n" ));
> -
> -    //
> -    //  The link is now idle
> -    //
> -    pNicDevice->bLinkIdle = TRUE;
> -
> -    //
> -    //  Delay for a bit
> -    //
> -    gBS->Stall ( RESET_MSEC );
> -
> -    //
> -    //  Select the internal PHY
> -    //
> -    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                         | USB_TARGET_DEVICE;
> -    SetupMsg.Request = CMD_PHY_SELECT;
> -    SetupMsg.Value = SPHY_PSEL;
> -    SetupMsg.Index = 0;
> -    SetupMsg.Length = 0;
> -    Status = Ax88772UsbCommand ( pNicDevice,
> -                                 &SetupMsg,
> -                                 NULL );
> -    if ( !EFI_ERROR ( Status )) {
> -      //
> -      //  Delay for a bit
> -      //
> -      gBS->Stall ( PHY_RESET_MSEC );
> -
> -      //
> -      //  Clear the internal PHY reset
> -      //
> -      SetupMsg.Request = CMD_RESET;
> -      SetupMsg.Value = SRR_IPRL | SRR_PRL;
> -      Status = Ax88772UsbCommand ( pNicDevice,
> -                                   &SetupMsg,
> -                                   NULL );
> -      if ( !EFI_ERROR ( Status )) {
> -        //
> -        //  Reset the PHY
> -        //
> -        Status = Ax88772PhyWrite ( pNicDevice,
> -                                   PHY_BMCR,
> -                                   BMCR_RESET );
> -        if ( !EFI_ERROR ( Status )) {
> -          //
> -          //  Set the gaps
> -          //
> -          SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                               | USB_TARGET_DEVICE;
> -          SetupMsg.Request = CMD_GAPS_WRITE;
> -          SetupMsg.Value = 0x0c15;
> -          SetupMsg.Index = 0x0e;
> -          SetupMsg.Length = 0;
> -          Status = Ax88772UsbCommand ( pNicDevice,
> -                                       &SetupMsg,
> -                                       NULL );
> -        }
> -      }
> -    }
> -  }
> -
> -  //
> -  //  Return the operation status.
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -VOID
> -FillPkt2Queue (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINTN BufLength)
> -{
> -
> -  UINT16 * pLength;
> -  UINT16 * pLengthBar;
> -  UINT8* pData;
> -  UINT32 offset;
> -  RX_TX_PACKET * pRxPacket;
> -  EFI_STATUS Status;
> -
> -  for ( offset = 0; offset < BufLength; ){
> -    pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);
> -    pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);
> -
> -    *pLength &= 0x7ff;
> -    *pLengthBar &= 0x7ff;
> -    *pLengthBar |= 0xf800;
> -
> -    if ((*pLength ^ *pLengthBar ) != 0xFFFF) {
> -      DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n", BufLength));
> -      return;
> -    }
> -
> -    pRxPacket = pNicDevice->pRxFree;
> -    if ( NULL == pRxPacket ) {
> -      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> -                                   sizeof( RX_TX_PACKET ),
> -                                   (VOID **) &pRxPacket );
> -      if ( !EFI_ERROR ( Status )) {
> -        //
> -        //  Add this packet to the free packet list
> -        //
> -        pNicDevice->pRxFree = pRxPacket;
> -        pRxPacket->pNext = NULL;
> -      }
> -      else {
> -        //
> -        //  Use the discard packet buffer
> -        //
> -        //pRxPacket = &Packet;
> -      }
> -    }
> -
> -
> -    pData = pNicDevice->pBulkInBuff + offset + 4;
> -    pRxPacket->Length = *pLength;
> -    pRxPacket->LengthBar = *(UINT16*) (pNicDevice->pBulkInBuff + offset +2);
> -    CopyMem (&pRxPacket->Data[0], pData, *pLength);
> -    //DEBUG((DEBUG_INFO, "Packet [%d]\n", *pLength));
> -
> -    pNicDevice->pRxFree = pRxPacket->pNext;
> -    pRxPacket->pNext = NULL;
> -
> -    if ( NULL == pNicDevice->pRxTail ) {
> -      pNicDevice->pRxHead = pRxPacket;
> -    }
> -    else {
> -      pNicDevice->pRxTail->pNext = pRxPacket;
> -    }
> -    pNicDevice->pRxTail = pRxPacket;
> -    offset += (*pLength + 4);
> -
> -  }
> -}
> -
> -
> -
> -/**
> -  Receive a frame from the network.
> -
> -  This routine polls the USB receive interface for a packet.  If a packet
> -  is available, this routine adds the receive packet to the list of
> -  pending 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] pNicDevice  Pointer to the NIC_DEVICE structure
> -  @param [in] bUpdateLink TRUE = Update link status
> -
> -**/
> -VOID
> -Ax88772Rx (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN BOOLEAN bUpdateLink
> -  )
> -{
> -  BOOLEAN bFullDuplex;
> -  BOOLEAN bLinkUp;
> -  BOOLEAN bRxPacket;
> -  BOOLEAN bSpeed100;
> -  UINTN LengthInBytes;
> -  RX_TX_PACKET Packet;
> -  RX_TX_PACKET * pRxPacket;
> -  EFI_USB_IO_PROTOCOL *pUsbIo;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -  UINT32 TransferStatus;
> -
> -  //
> -  //  Synchronize with Ax88772Timer
> -  //
> -  VERIFY_TPL ( TPL_AX88772 );
> -  TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
> -  DEBUG (( DEBUG_TPL | DEBUG_INFO,
> -            "%d: TPL\r\n",
> -            TPL_AX88772 ));
> -
> -  //
> -  //  Get the link status
> -  //
> -  if ( bUpdateLink ) {
> -    bLinkUp = pNicDevice->bLinkUp;
> -    bSpeed100 = pNicDevice->b100Mbps;
> -    bFullDuplex = pNicDevice->bFullDuplex;
> -    Status = Ax88772NegotiateLinkComplete ( pNicDevice,
> -                                            &pNicDevice->PollCount,
> -                                            &pNicDevice->bComplete,
> -                                            &pNicDevice->bLinkUp,
> -                                            &pNicDevice->b100Mbps,
> -                                            &pNicDevice->bFullDuplex );
> -
> -    //
> -    // Determine if the autonegotiation is complete
> -    //
> -    if ( pNicDevice->bComplete ) {
> -      if ( pNicDevice->bLinkUp ) {
> -        if (( bSpeed100 && ( !pNicDevice->b100Mbps ))
> -          || (( !bSpeed100 ) && pNicDevice->b100Mbps )
> -          || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))
> -          || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {
> -          pNicDevice->PollCount = 0;
> -          DEBUG (( DEBUG_LINK | DEBUG_INFO,
> -                    "Reset to establish proper link setup: %d Mbps, %s duplex\r\n",
> -                    pNicDevice->b100Mbps ? 100 : 10,
> -                    pNicDevice->bFullDuplex ? L"Full" : L"Half" ));
> -          Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );
> -        }
> -        if (( !bLinkUp ) && pNicDevice->bLinkUp ) {
> -          //
> -          // Display the autonegotiation status
> -          //
> -          DEBUG (( DEBUG_LINK | DEBUG_INFO,
> -                    "Link: Up, %d Mbps, %s duplex\r\n",
> -                    pNicDevice->b100Mbps ? 100 : 10,
> -                    pNicDevice->bFullDuplex ? L"Full" : L"Half" ));
> -        }
> -      }
> -    }
> -
> -    //
> -    //  Update the link status
> -    //
> -    if ( bLinkUp && ( !pNicDevice->bLinkUp )) {
> -      DEBUG (( DEBUG_LINK | DEBUG_INFO, "Link: Down\r\n" ));
> -    }
> -  }
> -
> -  //
> -  //  Loop until all the packets are emptied from the receiver
> -  //
> -  do {
> -    bRxPacket = FALSE;
> -
> -    //
> -    //  Locate a packet for use
> -    //
> -    pRxPacket = pNicDevice->pRxFree;
> -    LengthInBytes = MAX_BULKIN_SIZE;
> -    if ( NULL == pRxPacket ) {
> -      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> -                                   sizeof ( *pRxPacket ),
> -                                   (VOID **) &pRxPacket );
> -      if ( !EFI_ERROR ( Status )) {
> -        //
> -        //  Add this packet to the free packet list
> -        //
> -        pNicDevice->pRxFree = pRxPacket;
> -        pRxPacket->pNext = NULL;
> -      }
> -      else {
> -        //
> -        //  Use the discard packet buffer
> -        //
> -        pRxPacket = &Packet;
> -      }
> -    }
> -
> -    //
> -    //  Attempt to receive a packet
> -    //
> -    SetMem (&pNicDevice->pBulkInBuff[0], MAX_BULKIN_SIZE, 0);
> -    pUsbIo = pNicDevice->pUsbIo;
> -    Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
> -                                       USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
> -                                       &pNicDevice->pBulkInBuff[0],
> -                                       &LengthInBytes,
> -                                       2,
> -                                       &TransferStatus );
> -    if ( LengthInBytes > 0 ) {
> -      FillPkt2Queue(pNicDevice, LengthInBytes);
> -    }
> -    pRxPacket = pNicDevice->pRxHead;
> -    if (( !EFI_ERROR ( Status ))
> -      && ( 0 < pRxPacket->Length )
> -      && ( pRxPacket->Length <= sizeof ( pRxPacket->Data ))
> -      && ( LengthInBytes > 0)) {
> -
> -      //
> -      //  Determine if the packet should be received
> -      //
> -      bRxPacket = TRUE;
> -      LengthInBytes = pRxPacket->Length;
> -      pNicDevice->bLinkIdle = FALSE;
> -      if ( pNicDevice->pRxFree == pRxPacket ) {
> -        //
> -        //  Display the received packet
> -        //
> -        if ( 0 != ( pRxPacket->Data[0] & 1 )) {
> -          if (( 0xff == pRxPacket->Data[0])
> -            && ( 0xff == pRxPacket->Data[1])
> -            && ( 0xff == pRxPacket->Data[2])
> -            && ( 0xff == pRxPacket->Data[3])
> -            && ( 0xff == pRxPacket->Data[4])
> -            && ( 0xff == pRxPacket->Data[5])) {
> -            DEBUG (( DEBUG_RX_BROADCAST | DEBUG_INFO,
> -                      "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
> -                      pRxPacket->Data[0],
> -                      pRxPacket->Data[1],
> -                      pRxPacket->Data[2],
> -                      pRxPacket->Data[3],
> -                      pRxPacket->Data[4],
> -                      pRxPacket->Data[5],
> -                      pRxPacket->Data[6],
> -                      pRxPacket->Data[7],
> -                      pRxPacket->Data[8],
> -                      pRxPacket->Data[9],
> -                      pRxPacket->Data[10],
> -                      pRxPacket->Data[11],
> -                      pRxPacket->Data[12],
> -                      pRxPacket->Data[13],
> -                      LengthInBytes ));
> -          }
> -          else {
> -            DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
> -                      "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
> -                      pRxPacket->Data[0],
> -                      pRxPacket->Data[1],
> -                      pRxPacket->Data[2],
> -                      pRxPacket->Data[3],
> -                      pRxPacket->Data[4],
> -                      pRxPacket->Data[5],
> -                      pRxPacket->Data[6],
> -                      pRxPacket->Data[7],
> -                      pRxPacket->Data[8],
> -                      pRxPacket->Data[9],
> -                      pRxPacket->Data[10],
> -                      pRxPacket->Data[11],
> -                      pRxPacket->Data[12],
> -                      pRxPacket->Data[13],
> -                      LengthInBytes ));
> -          }
> -        }
> -        else {
> -          DEBUG (( DEBUG_RX_UNICAST | DEBUG_INFO,
> -                    "RX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
> -                    pRxPacket->Data[0],
> -                    pRxPacket->Data[1],
> -                    pRxPacket->Data[2],
> -                    pRxPacket->Data[3],
> -                    pRxPacket->Data[4],
> -                    pRxPacket->Data[5],
> -                    pRxPacket->Data[6],
> -                    pRxPacket->Data[7],
> -                    pRxPacket->Data[8],
> -                    pRxPacket->Data[9],
> -                    pRxPacket->Data[10],
> -                    pRxPacket->Data[11],
> -                    pRxPacket->Data[12],
> -                    pRxPacket->Data[13],
> -                    LengthInBytes ));
> -        }
> -
> -      }
> -      else {
> -        //
> -        //  Error, not enough buffers for this packet, discard packet
> -        //
> -        DEBUG (( DEBUG_WARN | DEBUG_INFO,
> -                  "WARNING - No buffer, discarding RX packet: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-
> %02x  %02x-%02x  %d bytes\r\n",
> -                  pRxPacket->Data[0],
> -                  pRxPacket->Data[1],
> -                  pRxPacket->Data[2],
> -                  pRxPacket->Data[3],
> -                  pRxPacket->Data[4],
> -                  pRxPacket->Data[5],
> -                  pRxPacket->Data[6],
> -                  pRxPacket->Data[7],
> -                  pRxPacket->Data[8],
> -                  pRxPacket->Data[9],
> -                  pRxPacket->Data[10],
> -                  pRxPacket->Data[11],
> -                  pRxPacket->Data[12],
> -                  pRxPacket->Data[13],
> -                  LengthInBytes ));
> -      }
> -    }
> -  }while ( bRxPacket );
> -
> -  //
> -  //  Release the synchronization withhe Ax88772Timer
> -  //
> -  gBS->RestoreTPL ( TplPrevious );
> -  DEBUG (( DEBUG_TPL | DEBUG_INFO,
> -            "%d: TPL\r\n",
> -            TplPrevious ));
> -}
> -
> -
> -/**
> -  Enable or disable the receiver
> -
> -  This routine calls ::Ax88772UsbCommand to update the
> -  receiver state.  This routine also calls ::Ax88772MacAddressSet
> -  to establish the MAC address for the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RxFilter         Simple network RX filter mask value
> -
> -  @retval EFI_SUCCESS          The MAC address was set.
> -  @retval other                The MAC address was not set.
> -
> -**/
> -EFI_STATUS
> -Ax88772RxControl (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT32 RxFilter
> -  )
> -{
> -  UINT16 MediumStatus;
> -  INT32 MulticastHash[2];
> -  UINT16 RxControl;
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Disable all multicast
> -  //
> -  MulticastHash[0] = 0;
> -  MulticastHash[1] = 0;
> -
> -  //
> -  // Enable the receiver if something is to be received
> -  //
> -  Status = EFI_SUCCESS;
> -  RxControl = RXC_SO | RXC_MFB_16384;
> -  if ( 0 != RxFilter ) {
> -    //
> -    //  Enable the receiver
> -    //
> -    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> -                         | USB_REQ_TYPE_VENDOR
> -                         | USB_TARGET_DEVICE;
> -    SetupMsg.Request = CMD_MEDIUM_STATUS_READ;
> -    SetupMsg.Value = 0;
> -    SetupMsg.Index = 0;
> -    SetupMsg.Length = sizeof ( MediumStatus );
> -    Status = Ax88772UsbCommand ( pNicDevice,
> -                                 &SetupMsg,
> -                                 &MediumStatus );
> -    if ( !EFI_ERROR ( Status )) {
> -      if ( 0 == ( MediumStatus & MS_RE )) {
> -        MediumStatus |= MS_RE | MS_ONE;
> -        if ( pNicDevice->bFullDuplex ) {
> -          MediumStatus |= MS_TFC | MS_RFC;
> -        }
> -        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                             | USB_TARGET_DEVICE;
> -        SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
> -        SetupMsg.Value = MediumStatus;
> -        SetupMsg.Index = 0;
> -        SetupMsg.Length = 0;
> -        Status = Ax88772UsbCommand ( pNicDevice,
> -                                     &SetupMsg,
> -                                     NULL );
> -        if ( EFI_ERROR ( Status )) {
> -          DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> -                    "ERROR - Failed to enable receiver, Status: %r\r\n",
> -                    Status ));
> -        }
> -      }
> -    }
> -    else {
> -      DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> -                "ERROR - Failed to read receiver status, Status: %r\r\n",
> -                Status ));
> -    }
> -
> -    //
> -    //  Enable multicast if requested
> -    //
> -    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
> -      RxControl |= RXC_AM;
> -      MulticastHash[0] = pNicDevice->MulticastHash[0];
> -      MulticastHash[1] = pNicDevice->MulticastHash[1];
> -    }
> -
> -    //
> -    //  Enable all multicast if requested
> -    //
> -    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST )) {
> -      RxControl |= RXC_AMALL;
> -      MulticastHash[0] = -1;
> -      MulticastHash[1] = -1;
> -    }
> -
> -    //
> -    //  Enable broadcast if requested
> -    //
> -    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST )) {
> -      RxControl |= RXC_AB;
> -    }
> -
> -    //
> -    //  Enable promiscuous mode if requested
> -    //
> -    if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS )) {
> -      RxControl |= RXC_PRO;
> -      MulticastHash[0] = -1;
> -      MulticastHash[1] = -1;
> -    }
> -  }
> -
> -  //
> -  //  Update the MAC address
> -  //
> -  if ( !EFI_ERROR ( Status )) {
> -    Status = Ax88772MacAddressSet ( pNicDevice, &pNicDevice->SimpleNetworkData.CurrentAddress.Addr[0]);
> -  }
> -
> -  //
> -  //  Update the receiver control
> -  //
> -  if ( !EFI_ERROR ( Status )) {
> -    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                         | USB_TARGET_DEVICE;
> -    SetupMsg.Request = CMD_RX_CONTROL_WRITE;
> -    SetupMsg.Value = RxControl;
> -    SetupMsg.Index = 0;
> -    SetupMsg.Length = 0;
> -    Status = Ax88772UsbCommand ( pNicDevice,
> -                                 &SetupMsg,
> -                                 NULL );
> -    if ( !EFI_ERROR ( Status )) {
> -      DEBUG (( DEBUG_RX_BROADCAST | DEBUG_RX_MULTICAST | DEBUG_RX_UNICAST | DEBUG_INFO,
> -                "RxControl: 0x%04x\r\n",
> -                RxControl ));
> -
> -      //
> -      //  Update the multicast hash table
> -      //
> -      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                           | USB_TARGET_DEVICE;
> -      SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
> -      SetupMsg.Value = 0;
> -      SetupMsg.Index = 0;
> -      SetupMsg.Length = sizeof ( pNicDevice ->MulticastHash );
> -      Status = Ax88772UsbCommand ( pNicDevice,
> -                                   &SetupMsg,
> -                                   &pNicDevice->MulticastHash );
> -      if ( !EFI_ERROR ( Status )) {
> -        DEBUG (( DEBUG_RX_MULTICAST | DEBUG_INFO,
> -                  "Multicast Hash: 0x%02x %02x %02x %02x %02x %02x %02x %02x\r\n",
> -                  (UINT8) MulticastHash[0],
> -                  (UINT8)( MulticastHash[0] >> 8 ),
> -                  (UINT8)( MulticastHash[0] >> 16 ),
> -                  (UINT8)( MulticastHash[0] >> 24 ),
> -                  (UINT8) MulticastHash[1],
> -                  (UINT8)( MulticastHash[1] >> 8 ),
> -                  (UINT8)( MulticastHash[1] >> 16 ),
> -                  (UINT8)( MulticastHash[1] >> 24 )));
> -      }
> -      else {
> -        DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> -                  "ERROR - Failed to update multicast hash table, Status: %r\r\n",
> -                  Status ));
> -      }
> -    }
> -    else {
> -      DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> -                "ERROR - Failed to set receiver control, Status: %r\r\n",
> -                Status ));
> -    }
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Read an SROM location
> -
> -  This routine calls ::Ax88772UsbCommand to read data from the
> -  SROM.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] Address          SROM address
> -  @param [out] pData           Buffer to receive the data
> -
> -  @retval EFI_SUCCESS          The read was successful
> -  @retval other                The read failed
> -
> -**/
> -EFI_STATUS
> -Ax88772SromRead (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT32 Address,
> -  OUT UINT16 * pData
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Read a value from the SROM
> -  //
> -  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> -                       | USB_REQ_TYPE_VENDOR
> -                       | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_SROM_READ;
> -  SetupMsg.Value = (UINT16) Address;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = sizeof ( *pData );
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                               &SetupMsg,
> -                               pData );
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  This routine is called at a regular interval to poll for
> -  receive packets.
> -
> -  This routine polls the link state and gets any receive packets
> -  by calling ::Ax88772Rx.
> -
> -  @param [in] Event            Timer event
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -**/
> -VOID
> -Ax88772Timer (
> -  IN EFI_EVENT Event,
> -  IN NIC_DEVICE * pNicDevice
> -  )
> -{
> -  //
> -  //  Use explicit DEBUG messages since the output frequency is too
> -  //  high for DEBUG_INFO to keep up and have spare cycles for the
> -  //  shell
> -  //
> -  DEBUG (( DEBUG_TIMER, "Entering Ax88772Timer\r\n" ));
> -
> -  //
> -  //  Poll the link state and get any receive packets
> -  //
> -  Ax88772Rx ( pNicDevice, FALSE );
> -
> -  DEBUG (( DEBUG_TIMER, "Exiting Ax88772Timer\r\n" ));
> -}
> -
> -
> -/**
> -  Send a command to the USB device.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pRequest         Pointer to the request structure
> -  @param [in, out] pBuffer     Data buffer address
> -
> -  @retval EFI_SUCCESS          The USB transfer was successful
> -  @retval other                The USB transfer failed
> -
> -**/
> -EFI_STATUS
> -Ax88772UsbCommand (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN USB_DEVICE_REQUEST * pRequest,
> -  IN OUT VOID * pBuffer
> -  )
> -{
> -  UINT32 CmdStatus;
> -  EFI_USB_DATA_DIRECTION Direction;
> -  EFI_USB_IO_PROTOCOL * pUsbIo;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Determine the transfer direction
> -  //
> -  Direction = EfiUsbNoData;
> -  if ( 0 != pRequest->Length ) {
> -    Direction = ( 0 != ( pRequest->RequestType & USB_ENDPOINT_DIR_IN ))
> -              ? EfiUsbDataIn : EfiUsbDataOut;
> -  }
> -
> -  //
> -  // Issue the command
> -  //
> -  pUsbIo = pNicDevice->pUsbIo;
> -  Status = pUsbIo->UsbControlTransfer ( pUsbIo,
> -                                        pRequest,
> -                                        Direction,
> -                                        USB_BUS_TIMEOUT,
> -                                        pBuffer,
> -                                        pRequest->Length,
> -                                        &CmdStatus );
> -
> -  //
> -  // Determine the operation status
> -  //
> -  if ( !EFI_ERROR ( Status )) {
> -    Status = CmdStatus;
> -  }
> -  else {
> -    //
> -    // Display any errors
> -    //
> -    DEBUG (( DEBUG_INFO,
> -              "Ax88772UsbCommand - Status: %r\n",
> -              Status ));
> -
> -    //
> -    // Only use status values associated with the Simple Network protocol
> -    //
> -    if ( EFI_TIMEOUT == Status ) {
> -      Status = EFI_DEVICE_ERROR;
> -    }
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c
> deleted file mode 100644
> index b6dce7e7cbc4..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/ComponentName.c
> +++ /dev/null
> @@ -1,178 +0,0 @@
> -/** @file
> -  UEFI Component Name(2) protocol implementation.
> -
> -  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include "Ax88772.h"
> -
> -/**
> -  EFI Component Name Protocol declaration
> -**/
> -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {
> -  GetDriverName,
> -  GetControllerName,
> -  "eng"
> -};
> -
> -/**
> -  EFI Component Name 2 Protocol declaration
> -**/
> -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
> -  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
> -  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
> -  "en"
> -};
> -
> -
> -/**
> -  Driver name table declaration
> -**/
> -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> -mDriverNameTable[] = {
> -  {"eng;en", L"AX88772 Ethernet Driver"},
> -  {NULL,  NULL}
> -};
> -
> -/**
> -  Retrieves a Unicode string that is the user readable name of the driver.
> -
> -  This function retrieves the user readable name of a driver in the form of a
> -  Unicode string. If the driver specified by This has a user readable name in
> -  the language specified by Language, then a pointer to the driver name is
> -  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> -  by This does not support the language specified by Language,
> -  then EFI_UNSUPPORTED is returned.
> -
> -  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> -                                EFI_COMPONENT_NAME_PROTOCOL instance.
> -  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> -                                array indicating the language. This is the
> -                                language of the driver name that the caller is
> -                                requesting, and it must match one of the
> -                                languages specified in SupportedLanguages. The
> -                                number of languages supported by a driver is up
> -                                to the driver writer. Language is specified
> -                                in RFC 3066 or ISO 639-2 language code format.
> -  @param [out] ppDriverName     A pointer to the Unicode string to return.
> -                                This Unicode string is the name of the
> -                                driver specified by This in the language
> -                                specified by Language.
> -
> -  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> -                                This and the language specified by Language was
> -                                returned in DriverName.
> -  @retval EFI_INVALID_PARAMETER Language is NULL.
> -  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> -  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> -                                the language specified by Language.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -GetDriverName (
> -  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> -  IN  CHAR8 * pLanguage,
> -  OUT CHAR16 ** ppDriverName
> -  )
> -{
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -  Status = LookupUnicodeString2 (
> -             pLanguage,
> -             pThis->SupportedLanguages,
> -             mDriverNameTable,
> -             ppDriverName,
> -             (BOOLEAN)(pThis == &gComponentName)
> -             );
> -  DBG_EXIT_HEX ( Status );
> -  return Status;
> -}
> -
> -/**
> -  Retrieves a Unicode string that is the user readable name of the controller
> -  that is being managed by a driver.
> -
> -  This function retrieves the user readable name of the controller specified by
> -  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> -  driver specified by This has a user readable name in the language specified by
> -  Language, then a pointer to the controller name is returned in ControllerName,
> -  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> -  managing the controller specified by ControllerHandle and ChildHandle,
> -  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> -  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> -
> -  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> -                                EFI_COMPONENT_NAME_PROTOCOL instance.
> -  @param [in] ControllerHandle  The handle of a controller that the driver
> -                                specified by This is managing.  This handle
> -                                specifies the controller whose name is to be
> -                                returned.
> -  @param [in] ChildHandle       The handle of the child controller to retrieve
> -                                the name of.  This is an optional parameter that
> -                                may be NULL.  It will be NULL for device
> -                                drivers.  It will also be NULL for a bus drivers
> -                                that wish to retrieve the name of the bus
> -                                controller.  It will not be NULL for a bus
> -                                driver that wishes to retrieve the name of a
> -                                child controller.
> -  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> -                                array indicating the language.  This is the
> -                                language of the driver name that the caller is
> -                                requesting, and it must match one of the
> -                                languages specified in SupportedLanguages. The
> -                                number of languages supported by a driver is up
> -                                to the driver writer. Language is specified in
> -                                RFC 3066 or ISO 639-2 language code format.
> -  @param [out] ppControllerName A pointer to the Unicode string to return.
> -                                This Unicode string is the name of the
> -                                controller specified by ControllerHandle and
> -                                ChildHandle in the language specified by
> -                                Language from the point of view of the driver
> -                                specified by This.
> -
> -  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> -                                the language specified by Language for the
> -                                driver specified by This was returned in
> -                                DriverName.
> -  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
> -  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> -                                EFI_HANDLE.
> -  @retval EFI_INVALID_PARAMETER Language is NULL.
> -  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> -  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> -                                managing the controller specified by
> -                                ControllerHandle and ChildHandle.
> -  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> -                                the language specified by Language.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -GetControllerName (
> -  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> -  IN  EFI_HANDLE ControllerHandle,
> -  IN OPTIONAL EFI_HANDLE ChildHandle,
> -  IN  CHAR8 * pLanguage,
> -  OUT CHAR16 ** ppControllerName
> -  )
> -{
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Set the controller name
> -  //
> -  *ppControllerName = L"AX88772 10/100 Ethernet";
> -  Status = EFI_SUCCESS;
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_HEX ( Status );
> -  return Status;
> -}
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
> deleted file mode 100644
> index 5bcde4b21163..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
> +++ /dev/null
> @@ -1,507 +0,0 @@
> -/** @file
> -  Implement the driver binding protocol for Asix AX88772 Ethernet driver.
> -
> -  Copyright (c) 2011-2013, Intel Corporation. All rights reserved.<BR>
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include "Ax88772.h"
> -
> -/**
> -  Verify the controller type
> -
> -  @param [in] pThis                Protocol instance pointer.
> -  @param [in] Controller           Handle of device to test.
> -  @param [in] pRemainingDevicePath Not used.
> -
> -  @retval EFI_SUCCESS          This driver supports this device.
> -  @retval other                This driver does not support this device.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -DriverSupported (
> -  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
> -  IN EFI_HANDLE Controller,
> -  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
> -  )
> -{
> -  EFI_USB_DEVICE_DESCRIPTOR Device;
> -  EFI_USB_IO_PROTOCOL * pUsbIo;
> -  EFI_STATUS Status;
> -
> -  //
> -  //  Connect to the USB stack
> -  //
> -  Status = gBS->OpenProtocol (
> -                  Controller,
> -                  &gEfiUsbIoProtocolGuid,
> -                  (VOID **) &pUsbIo,
> -                  pThis->DriverBindingHandle,
> -                  Controller,
> -                  EFI_OPEN_PROTOCOL_BY_DRIVER
> -                  );
> -  if (!EFI_ERROR ( Status )) {
> -
> -    //
> -    //  Get the interface descriptor to check the USB class and find a transport
> -    //  protocol handler.
> -    //
> -    Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
> -    if (!EFI_ERROR ( Status )) {
> -
> -      //
> -      //  Validate the adapter
> -      //
> -      if (( VENDOR_ID != Device.IdVendor )
> -        || ( PRODUCT_ID != Device.IdProduct )) {
> -        Status = EFI_UNSUPPORTED;
> -      }
> -    }
> -
> -    //
> -    //  Done with the USB stack
> -    //
> -    gBS->CloseProtocol (
> -           Controller,
> -           &gEfiUsbIoProtocolGuid,
> -           pThis->DriverBindingHandle,
> -           Controller
> -           );
> -  }
> -
> -  //
> -  //  Return the device supported status
> -  //
> -  return Status;
> -}
> -
> -
> -/**
> -  Start this driver on Controller by opening UsbIo and DevicePath protocols.
> -  Initialize PXE structures, create a copy of the Controller Device Path with the
> -  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
> -  on the newly created Device Path.
> -
> -  @param [in] pThis                Protocol instance pointer.
> -  @param [in] Controller           Handle of device to work with.
> -  @param [in] pRemainingDevicePath Not used, always produce all possible children.
> -
> -  @retval EFI_SUCCESS          This driver is added to Controller.
> -  @retval other                This driver does not support this device.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -DriverStart (
> -  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
> -  IN EFI_HANDLE Controller,
> -  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
> -  )
> -{
> -  EFI_STATUS Status;
> -  NIC_DEVICE * pNicDevice;
> -  UINTN LengthInBytes;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Allocate the device structure
> -  //
> -  LengthInBytes = sizeof ( *pNicDevice );
> -  Status = gBS->AllocatePool (
> -                  EfiRuntimeServicesData,
> -                  LengthInBytes,
> -                  (VOID **) &pNicDevice
> -                  );
> -  if ( !EFI_ERROR ( Status )) {
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT,
> -              "0x%08x: Allocate pNicDevice, %d bytes\r\n",
> -              pNicDevice,
> -              sizeof ( *pNicDevice )));
> -
> -    //
> -    //  Set the structure signature
> -    //
> -    ZeroMem ( pNicDevice, LengthInBytes );
> -    pNicDevice->Signature = DEV_SIGNATURE;
> -
> -    //
> -    //  Connect to the USB I/O protocol
> -    //
> -    Status = gBS->OpenProtocol (
> -                    Controller,
> -                    &gEfiUsbIoProtocolGuid,
> -                    (VOID **) &pNicDevice->pUsbIo,
> -                    pThis->DriverBindingHandle,
> -                    Controller,
> -                    EFI_OPEN_PROTOCOL_BY_DRIVER
> -                    );
> -
> -    if ( !EFI_ERROR ( Status )) {
> -      //
> -      //  Allocate the necessary events
> -      //
> -      Status = gBS->CreateEvent ( EVT_TIMER,
> -                                  TPL_AX88772,
> -                                  (EFI_EVENT_NOTIFY)Ax88772Timer,
> -                                  pNicDevice,
> -                                  (VOID **)&pNicDevice->Timer );
> -      if ( !EFI_ERROR ( Status )) {
> -        DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -                  "0x%08x: Allocated timer\r\n",
> -                  pNicDevice->Timer ));
> -
> -        //
> -        //  Initialize the simple network protocol
> -        //
> -        pNicDevice->Controller = Controller;
> -        SN_Setup ( pNicDevice );
> -
> -        //
> -        //  Start the timer
> -        //
> -        Status = gBS->SetTimer ( pNicDevice->Timer,
> -                                 TimerPeriodic,
> -                                 TIMER_MSEC );
> -        if ( !EFI_ERROR ( Status )) {
> -          //
> -          //  Install both the simple network and device path protocols.
> -          //
> -          Status = gBS->InstallMultipleProtocolInterfaces (
> -                          &Controller,
> -                          &gEfiCallerIdGuid,
> -                          pNicDevice,
> -                          &gEfiSimpleNetworkProtocolGuid,
> -                          &pNicDevice->SimpleNetwork,
> -                          NULL
> -                          );
> -
> -          if ( !EFI_ERROR ( Status )) {
> -            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -                      "Installed: gEfiCallerIdGuid on   0x%08x\r\n",
> -                      Controller ));
> -            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -                      "Installed: gEfiSimpleNetworkProtocolGuid on   0x%08x\r\n",
> -                      Controller ));
> -            DBG_EXIT_STATUS ( Status );
> -            return Status;
> -          }
> -          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
> -                    "ERROR - Failed to install gEfiSimpleNetworkProtocol on 0x%08x\r\n",
> -                    Controller ));
> -        }
> -        else {
> -          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
> -                    "ERROR - Failed to start the timer, Status: %r\r\n",
> -                    Status ));
> -        }
> -      }
> -      else {
> -        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
> -                  "ERROR - Failed to create timer event, Status: %r\r\n",
> -                  Status ));
> -      }
> -
> -      //
> -      //  Done with the USB stack
> -      //
> -      gBS->CloseProtocol (
> -             Controller,
> -             &gEfiUsbIoProtocolGuid,
> -             pThis->DriverBindingHandle,
> -             Controller
> -             );
> -    }
> -
> -    //
> -    //  Done with the device
> -    //
> -    gBS->FreePool ( pNicDevice );
> -  }
> -
> -  //
> -  //  Display the driver start status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
> -  closing the DevicePath and PciIo protocols on Controller.
> -
> -  @param [in] pThis                Protocol instance pointer.
> -  @param [in] Controller           Handle of device to stop driver on.
> -  @param [in] NumberOfChildren     How many children need to be stopped.
> -  @param [in] pChildHandleBuffer   Not used.
> -
> -  @retval EFI_SUCCESS          This driver is removed Controller.
> -  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
> -  @retval other                This driver was not removed from this device.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -DriverStop (
> -  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
> -  IN  EFI_HANDLE Controller,
> -  IN  UINTN NumberOfChildren,
> -  IN  EFI_HANDLE * pChildHandleBuffer
> -  )
> -{
> -  NIC_DEVICE * pNicDevice;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Determine if this driver is already attached
> -  //
> -  Status = gBS->OpenProtocol (
> -                  Controller,
> -                  &gEfiCallerIdGuid,
> -                  (VOID **) &pNicDevice,
> -                  pThis->DriverBindingHandle,
> -                  Controller,
> -                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> -                  );
> -  if ( !EFI_ERROR ( Status )) {
> -    //
> -    //  AX88772 driver is no longer running on this device
> -    //
> -    gBS->UninstallMultipleProtocolInterfaces (
> -              Controller,
> -              &gEfiSimpleNetworkProtocolGuid,
> -              &pNicDevice->SimpleNetwork,
> -              &gEfiCallerIdGuid,
> -              pNicDevice,
> -              NULL );
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT,
> -                "Removed:   gEfiSimpleNetworkProtocolGuid from 0x%08x\r\n",
> -                Controller ));
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT,
> -                "Removed:   gEfiCallerIdGuid from 0x%08x\r\n",
> -                Controller ));
> -
> -    //
> -    //  Stop the timer
> -    //
> -    if ( NULL != pNicDevice->Timer ) {
> -      gBS->SetTimer ( pNicDevice->Timer, TimerCancel, 0 );
> -      gBS->CloseEvent ( pNicDevice->Timer );
> -      DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -                "0x%08x: Released timer\r\n",
> -                pNicDevice->Timer ));
> -    }
> -
> -    //
> -    //  Done with the device context
> -    //
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT,
> -              "0x%08x: Free pNicDevice, %d bytes\r\n",
> -              pNicDevice,
> -              sizeof ( *pNicDevice )));
> -    gBS->FreePool ( pNicDevice );
> -  }
> -
> -  //
> -  //  Return the shutdown status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Driver binding protocol declaration
> -**/
> -EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
> -  DriverSupported,
> -  DriverStart,
> -  DriverStop,
> -  0xa,
> -  NULL,
> -  NULL
> -};
> -
> -
> -/**
> -  Ax88772 driver unload routine.
> -
> -  @param [in] ImageHandle       Handle for the image.
> -
> -  @retval EFI_SUCCESS           Image may be unloaded
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -DriverUnload (
> -  IN EFI_HANDLE ImageHandle
> -  )
> -{
> -  UINTN BufferSize;
> -  UINTN Index;
> -  UINTN Max;
> -  EFI_HANDLE * pHandle;
> -  EFI_STATUS Status;
> -
> -  //
> -  //  Determine which devices are using this driver
> -  //
> -  BufferSize = 0;
> -  pHandle = NULL;
> -  Status = gBS->LocateHandle (
> -                  ByProtocol,
> -                  &gEfiCallerIdGuid,
> -                  NULL,
> -                  &BufferSize,
> -                  NULL );
> -  if ( EFI_BUFFER_TOO_SMALL == Status ) {
> -    for ( ; ; ) {
> -      //
> -      //  One or more block IO devices are present
> -      //
> -      Status = gBS->AllocatePool (
> -                      EfiRuntimeServicesData,
> -                      BufferSize,
> -                      (VOID **) &pHandle
> -                      );
> -      if ( EFI_ERROR ( Status )) {
> -        DEBUG (( DEBUG_ERROR | DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -                  "Insufficient memory, failed handle buffer allocation\r\n" ));
> -        break;
> -      }
> -
> -      //
> -      //  Locate the block IO devices
> -      //
> -      Status = gBS->LocateHandle (
> -                      ByProtocol,
> -                      &gEfiCallerIdGuid,
> -                      NULL,
> -                      &BufferSize,
> -                      pHandle );
> -      if ( EFI_ERROR ( Status )) {
> -        //
> -        //  Error getting handles
> -        //
> -        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_INFO,
> -                "Failure getting Telnet handles\r\n" ));
> -        break;
> -      }
> -
> -      //
> -      //  Remove any use of the driver
> -      //
> -      Max = BufferSize / sizeof ( pHandle[ 0 ]);
> -      for ( Index = 0; Max > Index; Index++ ) {
> -        Status = DriverStop ( &gDriverBinding,
> -                              pHandle[ Index ],
> -                              0,
> -                              NULL );
> -        if ( EFI_ERROR ( Status )) {
> -          DEBUG (( DEBUG_WARN | DEBUG_INIT | DEBUG_INFO,
> -                    "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));
> -          break;
> -        }
> -      }
> -      break;
> -    }
> -  }
> -  else {
> -    if ( EFI_NOT_FOUND == Status ) {
> -      //
> -      //  No devices were found
> -      //
> -      Status = EFI_SUCCESS;
> -    }
> -  }
> -
> -  //
> -  //  Free the handle array
> -  //
> -  if ( NULL != pHandle ) {
> -    gBS->FreePool ( pHandle );
> -  }
> -
> -  //
> -  //  Remove the protocols installed by the EntryPoint routine.
> -  //
> -  if ( !EFI_ERROR ( Status )) {
> -    gBS->UninstallMultipleProtocolInterfaces (
> -            ImageHandle,
> -            &gEfiDriverBindingProtocolGuid,
> -            &gDriverBinding,
> -            &gEfiComponentNameProtocolGuid,
> -            &gComponentName,
> -            &gEfiComponentName2ProtocolGuid,
> -            &gComponentName2,
> -            NULL
> -            );
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -            "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
> -            ImageHandle ));
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -              "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
> -              ImageHandle ));
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -              "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
> -              ImageHandle ));
> -  }
> -
> -  //
> -  //  Return the unload status
> -  //
> -  return Status;
> -}
> -
> -
> -/**
> -Ax88772 driver entry point.
> -
> -@param [in] ImageHandle       Handle for the image.
> -@param [in] pSystemTable      Address of the system table.
> -
> -@retval EFI_SUCCESS           Image successfully loaded.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -EntryPoint (
> -  IN EFI_HANDLE ImageHandle,
> -  IN EFI_SYSTEM_TABLE * pSystemTable
> -  )
> -{
> -  EFI_STATUS    Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Add the driver to the list of drivers
> -  //
> -  Status = EfiLibInstallDriverBindingComponentName2 (
> -             ImageHandle,
> -             pSystemTable,
> -             &gDriverBinding,
> -             ImageHandle,
> -             &gComponentName,
> -             &gComponentName2
> -             );
> -  ASSERT_EFI_ERROR (Status);
> -  if ( !EFI_ERROR ( Status )) {
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -              "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",
> -              ImageHandle ));
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -              "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",
> -              ImageHandle ));
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -              "Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",
> -              ImageHandle ));
> -  }
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
> deleted file mode 100644
> index 0105d04f5d61..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
> +++ /dev/null
> @@ -1,1503 +0,0 @@
> -/** @file
> -  Provides the Simple Network functions.
> -
> -  Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
> -  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] pSimpleNetwork    Simple network mode pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -ReceiveFilterUpdate (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  NIC_DEVICE * pNicDevice;
> -  EFI_STATUS Status;
> -  UINT32 Index;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Set the MAC address
> -  //
> -  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -  pMode = pSimpleNetwork->Mode;
> -  Status = Ax88772MacAddressSet ( pNicDevice,
> -                                  &pMode->CurrentAddress.Addr[0]);
> -  if ( !EFI_ERROR ( Status )) {
> -    //
> -    // Clear the multicast hash table
> -    //
> -    Ax88772MulticastClear ( pNicDevice );
> -
> -    //
> -    // Load the multicast hash table
> -    //
> -    if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
> -      for ( Index = 0;
> -            ( !EFI_ERROR ( Status )) && ( Index < pMode->MCastFilterCount );
> -            Index++ ) {
> -        //
> -        // Enable the next multicast address
> -        //
> -        Ax88772MulticastSet ( pNicDevice,
> -                              &pMode->MCastFilter[ Index ].Addr[0]);
> -      }
> -    }
> -
> -    //
> -    // Enable the receiver
> -    //
> -    if ( !EFI_ERROR ( Status )) {
> -      Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
> -    }
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  This function updates the SNP driver status.
> -
> -  This function gets the current interrupt and recycled transmit
> -  buffer status from the network interface.  The interrupt status
> -  and the media status are returned as a bit mask in InterruptStatus.
> -  If InterruptStatus is NULL, the interrupt status will not be read.
> -  Upon successful return of the media status, the MediaPresent field
> -  of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
> -  of media status.  If TxBuf is not NULL, a recycled transmit buffer
> -  address will be retrived.  If a recycled transmit buffer address
> -  is returned in TxBuf, then the buffer has been successfully
> -  transmitted, and the status for that buffer is cleared.
> -
> -  This function calls ::Ax88772Rx to update the media status and
> -  queue any receive packets.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] pInterruptStatus  A pointer to the bit mask of the current active interrupts.
> -                                If this is NULL, the interrupt status will not be read from
> -                                the device.  If this is not NULL, the interrupt status will
> -                                be read from teh device.  When the interrupt status is read,
> -                                it will also be cleared.  Clearing the transmit interrupt
> -                                does not empty the recycled transmit buffer array.
> -  @param [out] ppTxBuf          Recycled transmit buffer address.  The network interface will
> -                                not transmit if its internal recycled transmit buffer array is
> -                                full.  Reading the transmit buffer does not clear the transmit
> -                                interrupt.  If this is NULL, then the transmit buffer status
> -                                will not be read.  If there are not transmit buffers to recycle
> -                                and TxBuf is not NULL, *TxBuf will be set to NULL.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_GetStatus (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  OUT UINT32 * pInterruptStatus,
> -  OUT VOID ** ppTxBuf
> -  )
> -{
> -  BOOLEAN bLinkIdle;
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  NIC_DEVICE * pNicDevice;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    // Return the transmit buffer
> -    //
> -    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -    if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
> -      *ppTxBuf = pNicDevice->pTxBuffer;
> -      pNicDevice->pTxBuffer = NULL;
> -    }
> -
> -    //
> -    // Determine if interface is running
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkStopped != pMode->State ) {
> -      //
> -      //  Synchronize with Ax88772Timer
> -      //
> -      VERIFY_TPL ( TPL_AX88772 );
> -      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
> -
> -      //
> -      // Update the link status
> -      //
> -      bLinkIdle = pNicDevice->bLinkIdle;
> -      pNicDevice->bLinkIdle = TRUE;
> -      Ax88772Rx ( pNicDevice, bLinkIdle );
> -      pMode->MediaPresent = pNicDevice->bLinkUp;
> -
> -      //
> -      //  Release the synchronization with Ax88772Timer
> -      //
> -      gBS->RestoreTPL ( TplPrevious );
> -
> -      //
> -      // Return the interrupt status
> -      //
> -      if ( NULL != pInterruptStatus ) {
> -        *pInterruptStatus = 0;
> -      }
> -      Status = EFI_SUCCESS;
> -    }
> -    else {
> -      Status = EFI_NOT_STARTED;
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Resets the network adapter and allocates the transmit and receive buffers
> -  required by the network interface; optionally, also requests allocation of
> -  additional transmit and receive buffers.  This routine must be called before
> -  any other routine in the Simple Network protocol is called.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
> -  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and receive buffers
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Initialize (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN UINTN ExtraRxBufferSize,
> -  IN UINTN ExtraTxBufferSize
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    // Determine if the interface is already started
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkStarted == pMode->State ) {
> -      if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
> -        //
> -        // Start the adapter
> -        //
> -        Status = SN_Reset ( pSimpleNetwork, FALSE );
> -        if ( !EFI_ERROR ( Status )) {
> -          //
> -          // Update the network state
> -          //
> -          pMode->State = EfiSimpleNetworkInitialized;
> -        }
> -      }
> -      else {
> -        Status = EFI_UNSUPPORTED;
> -      }
> -    }
> -    else {
> -      Status = EFI_NOT_STARTED;
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  This function converts a multicast IP address to a multicast HW MAC address
> -  for all packet transactions.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bIPv6             Set to TRUE if the multicast IP address is IPv6 [RFC2460].
> -                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
> -  @param [in] pIP               The multicast IP address that is to be converted to a
> -                                multicast HW MAC address.
> -  @param [in] pMAC              The multicast HW MAC address that is to be generated from IP.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_MCastIPtoMAC (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bIPv6,
> -  IN EFI_IP_ADDRESS * pIP,
> -  IN EFI_MAC_ADDRESS * pMAC
> -  )
> -{
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // This is not currently supported
> -  //
> -  Status = EFI_UNSUPPORTED;
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  This function performs read and write operations on the NVRAM device
> -  attached to a network interface.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] ReadWrite         TRUE for read operations, FALSE for write operations.
> -  @param [in] Offset            Byte offset in the NVRAM device at which to start the
> -                                read or write operation.  This must be a multiple of
> -                                NvRamAccessSize and less than NvRamSize.
> -  @param [in] BufferSize        The number of bytes to read or write from the NVRAM device.
> -                                This must also be a multiple of NvramAccessSize.
> -  @param [in, out] pBuffer      A pointer to the data buffer.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_NvData (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN ReadWrite,
> -  IN UINTN Offset,
> -  IN UINTN BufferSize,
> -  IN OUT VOID * pBuffer
> -  )
> -{
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // This is not currently supported
> -  //
> -  Status = EFI_UNSUPPORTED;
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Attempt to receive a packet from the network adapter.
> -
> -  This function retrieves one packet from the receive queue of the network
> -  interface.  If there are no packets on the receive queue, then EFI_NOT_READY
> -  will be returned.  If there is a packet on the receive queue, and the size
> -  of the packet is smaller than BufferSize, then the contents of the packet
> -  will be placed in Buffer, and BufferSize will be udpated with the actual
> -  size of the packet.  In addition, if SrcAddr, DestAddr, and Protocol are
> -  not NULL, then these values will be extracted from the media header and
> -  returned.  If BufferSize is smaller than the received packet, then the
> -  size of the receive packet will be placed in BufferSize and
> -  EFI_BUFFER_TOO_SMALL will be returned.
> -
> -  This routine calls ::Ax88772Rx to update the media status and
> -  empty the network adapter of receive packets.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [out] pHeaderSize      The size, in bytes, of the media header to be filled in by
> -                                the Transmit() function.  If HeaderSize is non-zero, then
> -                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
> -                                and DestAddr and Protocol parameters must not be NULL.
> -  @param [out] pBufferSize      The size, in bytes, of the entire packet (media header and
> -                                data) to be transmitted through the network interface.
> -  @param [out] pBuffer          A pointer to the packet (media header followed by data) to
> -                                to be transmitted.  This parameter can not be NULL.  If
> -                                HeaderSize is zero, then the media header is Buffer must
> -                                already be filled in by the caller.  If HeaderSize is nonzero,
> -                                then the media header will be filled in by the Transmit()
> -                                function.
> -  @param [out] pSrcAddr         The source HW MAC address.  If HeaderSize is zero, then
> -                                this parameter is ignored.  If HeaderSize is nonzero and
> -                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> -                                is used for the source HW MAC address.
> -  @param [out] pDestAddr        The destination HW MAC address.  If HeaderSize is zero, then
> -                                this parameter is ignored.
> -  @param [out] pProtocol        The type of header to build.  If HeaderSize is zero, then
> -                                this parameter is ignored.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_NOT_READY         No packets have been received on the network interface.
> -  @retval EFI_BUFFER_TOO_SMALL  The packet is larger than BufferSize bytes.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Receive (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  OUT UINTN                      * pHeaderSize,
> -  OUT UINTN                      * pBufferSize,
> -  OUT VOID                       * pBuffer,
> -  OUT EFI_MAC_ADDRESS            * pSrcAddr,
> -  OUT EFI_MAC_ADDRESS            * pDestAddr,
> -  OUT UINT16                     * pProtocol
> -  )
> -{
> -  ETHERNET_HEADER * pHeader;
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  NIC_DEVICE * pNicDevice;
> -  RX_TX_PACKET * pRxPacket;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -  UINT16 Type;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    // The interface must be running
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> -      //
> -      //  Synchronize with Ax88772Timer
> -      //
> -      VERIFY_TPL ( TPL_AX88772 );
> -      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
> -
> -      //
> -      // Update the link status
> -      //
> -      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -      Ax88772Rx ( pNicDevice, FALSE );
> -      pMode->MediaPresent = pNicDevice->bLinkUp;
> -      if ( pMode->MediaPresent ) {
> -        //
> -        //  Attempt to receive a packet
> -        //
> -        pRxPacket = pNicDevice->pRxHead;
> -        if ( NULL != pRxPacket ) {
> -          pNicDevice->pRxHead = pRxPacket->pNext;
> -          if ( NULL == pNicDevice->pRxHead ) {
> -            pNicDevice->pRxTail = NULL;
> -          }
> -
> -          //
> -          // Copy the received packet into the receive buffer
> -          //
> -          *pBufferSize = pRxPacket->Length;
> -          CopyMem ( pBuffer, &pRxPacket->Data[0], pRxPacket->Length );
> -          pHeader = (ETHERNET_HEADER *) &pRxPacket->Data[0];
> -          if ( NULL != pHeaderSize ) {
> -            *pHeaderSize = sizeof ( *pHeader );
> -          }
> -          if ( NULL != pDestAddr ) {
> -            CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );
> -          }
> -          if ( NULL != pSrcAddr ) {
> -            CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );
> -          }
> -          if ( NULL != pProtocol ) {
> -            Type = pHeader->type;
> -            Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
> -            *pProtocol = Type;
> -          }
> -          Status = EFI_SUCCESS;
> -        }
> -        else {
> -          //
> -          //  No receive packets available
> -          //
> -          Status = EFI_NOT_READY;
> -        }
> -      }
> -      else {
> -        //
> -        //  Link no up
> -        //
> -        Status = EFI_NOT_READY;
> -      }
> -
> -      //
> -      //  Release the synchronization with Ax88772Timer
> -      //
> -      gBS->RestoreTPL ( TplPrevious );
> -    }
> -    else {
> -      Status = EFI_NOT_STARTED;
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  This function is used to enable and disable the hardware and software receive
> -  filters for the underlying network device.
> -
> -  The receive filter change is broken down into three steps:
> -
> -    1.  The filter mask bits that are set (ON) in the Enable parameter
> -        are added to the current receive filter settings.
> -
> -    2.  The filter mask bits that are set (ON) in the Disable parameter
> -        are subtracted from the updated receive filter settins.
> -
> -    3.  If the resulting filter settigns is not supported by the hardware
> -        a more liberal setting is selected.
> -
> -  If the same bits are set in the Enable and Disable parameters, then the bits
> -  in the Disable parameter takes precedence.
> -
> -  If the ResetMCastFilter parameter is TRUE, then the multicast address list
> -  filter is disabled (irregardless of what other multicast bits are set in
> -  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount field
> -  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
> -
> -  After enableing or disabling receive filter settings, software should
> -  verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
> -  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
> -
> -  Note: Some network drivers and/or devices will automatically promote
> -  receive filter settings if the requested setting can not be honored.
> -  For example, if a request for four multicast addresses is made and
> -  the underlying hardware only supports two multicast addresses the
> -  driver might set the promiscuous or promiscuous multicast receive filters
> -  instead.  The receiving software is responsible for discarding any extra
> -  packets that get through the hardware receive filters.
> -
> -  If ResetMCastFilter is TRUE, then the multicast receive filter list
> -  on the network interface will be reset to the default multicast receive
> -  filter list.  If ResetMCastFilter is FALSE, and this network interface
> -  allows the multicast receive filter list to be modified, then the
> -  MCastFilterCnt and MCastFilter are used to update the current multicast
> -  receive filter list.  The modified receive filter list settings can be
> -  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
> -
> -  This routine calls ::ReceiveFilterUpdate to update the receive
> -  state in the network adapter.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] Enable            A bit mask of receive filters to enable on the network interface.
> -  @param [in] Disable           A bit mask of receive filters to disable on the network interface.
> -                                For backward compatibility with EFI 1.1 platforms, the
> -                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
> -                                when the ResetMCastFilter parameter is TRUE.
> -  @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
> -                                filters on the network interface to their default values.
> -  @param [in] MCastFilterCnt    Number of multicast HW MAC address in the new MCastFilter list.
> -                                This value must be less than or equal to the MaxMCastFilterCnt
> -                                field of EFI_SIMPLE_NETWORK_MODE.  This field is optional if
> -                                ResetMCastFilter is TRUE.
> -  @param [in] pMCastFilter      A pointer to a list of new multicast receive filter HW MAC
> -                                addresses.  This list will replace any existing multicast
> -                                HW MAC address list.  This field is optional if ResetMCastFilter
> -                                is TRUE.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_ReceiveFilters (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN UINT32 Enable,
> -  IN UINT32 Disable,
> -  IN BOOLEAN bResetMCastFilter,
> -  IN UINTN MCastFilterCnt,
> -  IN EFI_MAC_ADDRESS * pMCastFilter
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_MAC_ADDRESS * pMulticastAddress;
> -  EFI_MAC_ADDRESS * pTableEnd;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Verify the parameters
> -  //
> -  Status = EFI_INVALID_PARAMETER;
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    pMode = pSimpleNetwork->Mode;
> -
> -    //
> -    //  Update the multicast list if necessary
> -    //
> -    if ( !bResetMCastFilter ) {
> -      if ( 0 != MCastFilterCnt ) {
> -        if (( MAX_MCAST_FILTER_CNT >= MCastFilterCnt )
> -          && ( NULL != pMCastFilter )) {
> -          //
> -          // Verify the multicast addresses
> -          //
> -          pMulticastAddress = pMCastFilter;
> -          pTableEnd = pMulticastAddress + MCastFilterCnt;
> -          while ( pTableEnd > pMulticastAddress ) {
> -            //
> -            // The first digit of the multicast address must have the LSB set
> -            //
> -            if ( 0 == ( pMulticastAddress->Addr[0] & 1 )) {
> -              //
> -              // Invalid multicast address
> -              //
> -              break;
> -            }
> -            pMulticastAddress += 1;
> -          }
> -          if ( pTableEnd == pMulticastAddress ) {
> -            //
> -            // Update the multicast filter list.
> -            //
> -            CopyMem (&pMode->MCastFilter[0],
> -                     pMCastFilter,
> -                     MCastFilterCnt * sizeof ( *pMCastFilter ));
> -            Status = EFI_SUCCESS;
> -          }
> -        }
> -      }
> -      else {
> -        Status = EFI_SUCCESS;
> -      }
> -    }
> -    else {
> -      //
> -      // No multicast address list is specified
> -      //
> -      MCastFilterCnt = 0;
> -      Status = EFI_SUCCESS;
> -    }
> -    if ( !EFI_ERROR ( Status )) {
> -      //
> -      // The parameters are valid!
> -      //
> -      pMode->ReceiveFilterSetting |= Enable;
> -      pMode->ReceiveFilterSetting &= ~Disable;
> -      pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
> -
> -      //
> -      // Update the receive filters in the adapter
> -      //
> -      Status = ReceiveFilterUpdate ( pSimpleNetwork );
> -    }
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Reset the network adapter.
> -
> -  Resets a network adapter and reinitializes it with the parameters that
> -  were provided in the previous call to Initialize ().  The transmit and
> -  receive queues are cleared.  Receive filters, the station address, the
> -  statistics, and the multicast-IP-to-HW MAC addresses are not reset by
> -  this call.
> -
> -  This routine calls ::Ax88772Reset to perform the adapter specific
> -  reset operation.  This routine also starts the link negotiation
> -  by calling ::Ax88772NegotiateLinkStart.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bExtendedVerification  Indicates that the driver may perform a more
> -                                exhaustive verification operation of the device
> -                                during reset.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Reset (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bExtendedVerification
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  NIC_DEVICE * pNicDevice;
> -  RX_TX_PACKET * pRxPacket;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  //  Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    //  Synchronize with Ax88772Timer
> -    //
> -    VERIFY_TPL ( TPL_AX88772 );
> -    TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
> -
> -    //
> -    //  Update the device state
> -    //
> -    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -    pNicDevice->bComplete = FALSE;
> -    pNicDevice->bLinkUp = FALSE;
> -
> -    pMode = pSimpleNetwork->Mode;
> -    pMode->MediaPresent = FALSE;
> -
> -    //
> -    //  Discard any received packets
> -    //
> -    while ( NULL != pNicDevice->pRxHead ) {
> -      //
> -      //  Remove the packet from the received packet list
> -      //
> -      pRxPacket = pNicDevice->pRxHead;
> -      pNicDevice->pRxHead = pRxPacket->pNext;
> -
> -      //
> -      //  Queue the packet to the free list
> -      //
> -      pRxPacket->pNext = pNicDevice->pRxFree;
> -      pNicDevice->pRxFree = pRxPacket;
> -    }
> -    pNicDevice->pRxTail = NULL;
> -
> -    //
> -    //  Reset the device
> -    //
> -    Status = Ax88772Reset ( pNicDevice );
> -    if ( !EFI_ERROR ( Status )) {
> -      //
> -      //  Update the receive filters in the adapter
> -      //
> -      Status = ReceiveFilterUpdate ( pSimpleNetwork );
> -
> -      //
> -      //  Try to get a connection to the network
> -      //
> -      if ( !EFI_ERROR ( Status )) {
> -        //
> -        //  Start the autonegotiation
> -        //
> -        Status = Ax88772NegotiateLinkStart ( pNicDevice );
> -      }
> -    }
> -
> -    //
> -    //  Release the synchronization with Ax88772Timer
> -    //
> -    gBS->RestoreTPL ( TplPrevious );
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Initialize the simple network protocol.
> -
> -  This routine calls ::Ax88772MacAddressGet to obtain the
> -  MAC address.
> -
> -  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
> -
> -  @retval EFI_SUCCESS     Setup was successful
> -
> -**/
> -EFI_STATUS
> -SN_Setup (
> -  IN NIC_DEVICE * pNicDevice
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Initialize the simple network protocol
> -  //
> -  pSimpleNetwork = &pNicDevice->SimpleNetwork;
> -  pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
> -  pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
> -  pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
> -  pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
> -  pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
> -  pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
> -  pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
> -  pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
> -  pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
> -  pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
> -  pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
> -  pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
> -  pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
> -  pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
> -  pSimpleNetwork->WaitForPacket = NULL;
> -  pMode = &pNicDevice->SimpleNetworkData;
> -  pSimpleNetwork->Mode = pMode;
> -
> -  pMode->State = EfiSimpleNetworkStopped;
> -  pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> -  pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
> -  pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> -  pMode->NvRamSize = 0;
> -  pMode->NvRamAccessSize = 0;
> -  pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> -                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> -                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> -                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> -                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> -  pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> -                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
> -  pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
> -  pMode->MCastFilterCount = 0;
> -  SetMem ( &pMode->BroadcastAddress,
> -           PXE_HWADDR_LEN_ETHER,
> -           0xff );
> -  pMode->IfType = EfiNetworkInterfaceUndi;
> -  pMode->MacAddressChangeable = TRUE;
> -  pMode->MultipleTxSupported = TRUE;
> -  pMode->MediaPresentSupported = TRUE;
> -  pMode->MediaPresent = FALSE;
> -
> -  //
> -  //  Read the MAC address
> -  //
> -  pNicDevice->PhyId = PHY_ID_INTERNAL;
> -  pNicDevice->b100Mbps = TRUE;
> -  pNicDevice->bFullDuplex = TRUE;
> -
> -  Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> -                               MAX_BULKIN_SIZE,
> -                               (VOID **) &pNicDevice->pBulkInBuff);
> -  if ( EFI_ERROR(Status)) {
> -    DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
> -    return Status;
> -  }
> -
> -  Status = Ax88772MacAddressGet (
> -                pNicDevice,
> -                &pMode->PermanentAddress.Addr[0]);
> -  if ( !EFI_ERROR ( Status )) {
> -    //
> -    //  Display the MAC address
> -    //
> -    DEBUG (( DEBUG_MAC_ADDRESS | DEBUG_INFO,
> -              "MAC: %02x-%02x-%02x-%02x-%02x-%02x\n",
> -              pMode->PermanentAddress.Addr[0],
> -              pMode->PermanentAddress.Addr[1],
> -              pMode->PermanentAddress.Addr[2],
> -              pMode->PermanentAddress.Addr[3],
> -              pMode->PermanentAddress.Addr[4],
> -              pMode->PermanentAddress.Addr[5]));
> -
> -    //
> -    //  Use the hardware address as the current address
> -    //
> -    CopyMem ( &pMode->CurrentAddress,
> -              &pMode->PermanentAddress,
> -              PXE_HWADDR_LEN_ETHER );
> -  }
> -
> -  //
> -  //  Return the setup status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  This routine starts the network interface.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_ALREADY_STARTED   The network interface was already started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Start (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  )
> -{
> -  NIC_DEVICE * pNicDevice;
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Verify the parameters
> -  //
> -  Status = EFI_INVALID_PARAMETER;
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkStopped == pMode->State ) {
> -      //
> -      // Initialize the mode structure
> -      // NVRAM access is not supported
> -      //
> -      ZeroMem ( pMode, sizeof ( *pMode ));
> -
> -      pMode->State = EfiSimpleNetworkStarted;
> -      pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> -      pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
> -      pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> -      pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> -                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> -                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> -                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> -                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> -      pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
> -      pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
> -      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -      Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
> -      CopyMem ( &pMode->CurrentAddress,
> -                &pMode->PermanentAddress,
> -                sizeof ( pMode->CurrentAddress ));
> -      pMode->BroadcastAddress.Addr[0] = 0xff;
> -      pMode->BroadcastAddress.Addr[1] = 0xff;
> -      pMode->BroadcastAddress.Addr[2] = 0xff;
> -      pMode->BroadcastAddress.Addr[3] = 0xff;
> -      pMode->BroadcastAddress.Addr[4] = 0xff;
> -      pMode->BroadcastAddress.Addr[5] = 0xff;
> -      pMode->IfType = 1;
> -      pMode->MacAddressChangeable = TRUE;
> -      pMode->MultipleTxSupported = TRUE;
> -      pMode->MediaPresentSupported = TRUE;
> -      pMode->MediaPresent = FALSE;
> -    }
> -    else {
> -      Status = EFI_ALREADY_STARTED;
> -    }
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Set the MAC address.
> -
> -  This function modifies or resets the current station address of a
> -  network interface.  If Reset is TRUE, then the current station address
> -  is set ot the network interface's permanent address.  If Reset if FALSE
> -  then the current station address is changed to the address specified by
> -  pNew.
> -
> -  This routine calls ::Ax88772MacAddressSet to update the MAC address
> -  in the network adapter.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bReset            Flag used to reset the station address to the
> -                                network interface's permanent address.
> -  @param [in] pNew              New station address to be used for the network
> -                                interface.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_StationAddress (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bReset,
> -  IN EFI_MAC_ADDRESS * pNew
> -  )
> -{
> -  NIC_DEVICE * pNicDevice;
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork )
> -    && ( NULL != pSimpleNetwork->Mode )
> -    && (( !bReset ) || ( bReset && ( NULL != pNew )))) {
> -    //
> -    // Verify that the adapter is already started
> -    //
> -    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkStarted == pMode->State ) {
> -      //
> -      // Determine the adapter MAC address
> -      //
> -      if ( bReset ) {
> -        //
> -        // Use the permanent address
> -        //
> -        CopyMem ( &pMode->CurrentAddress,
> -                  &pMode->PermanentAddress,
> -                  sizeof ( pMode->CurrentAddress ));
> -      }
> -      else {
> -        //
> -        // Use the specified address
> -        //
> -        CopyMem ( &pMode->CurrentAddress,
> -                  pNew,
> -                  sizeof ( pMode->CurrentAddress ));
> -      }
> -
> -      //
> -      // Update the address on the adapter
> -      //
> -      Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
> -    }
> -    else {
> -      Status = EFI_NOT_STARTED;
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  This function resets or collects the statistics on a network interface.
> -  If the size of the statistics table specified by StatisticsSize is not
> -  big enough for all of the statistics that are collected by the network
> -  interface, then a partial buffer of statistics is returned in
> -  StatisticsTable.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
> -  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
> -                                the size, in bytes, of the resulting table of statistics.
> -  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
> -                                conains the statistics.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Statistics (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bReset,
> -  IN OUT UINTN * pStatisticsSize,
> -  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
> -  )
> -{
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // This is not currently supported
> -  //
> -  Status = EFI_UNSUPPORTED;
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  This function stops a network interface.  This call is only valid
> -  if the network interface is in the started state.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Stop (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    // Determine if the interface is started
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkStopped != pMode->State ) {
> -      if ( EfiSimpleNetworkStarted == pMode->State ) {
> -        //
> -        //  Release the resources acquired in SN_Start
> -        //
> -
> -        //
> -        //  Mark the adapter as stopped
> -        //
> -        pMode->State = EfiSimpleNetworkStopped;
> -        Status = EFI_SUCCESS;
> -      }
> -      else {
> -        Status = EFI_UNSUPPORTED;
> -      }
> -    }
> -    else {
> -      Status = EFI_NOT_STARTED;
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  This function releases the memory buffers assigned in the Initialize() call.
> -  Pending transmits and receives are lost, and interrupts are cleared and disabled.
> -  After this call, only Initialize() and Stop() calls may be used.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Shutdown (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  UINT32 RxFilter;
> -  EFI_STATUS Status;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    // Determine if the interface is already started
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> -      //
> -      // Stop the adapter
> -      //
> -      RxFilter = pMode->ReceiveFilterSetting;
> -      pMode->ReceiveFilterSetting = 0;
> -      Status = SN_Reset ( pSimpleNetwork, FALSE );
> -      pMode->ReceiveFilterSetting = RxFilter;
> -      if ( !EFI_ERROR ( Status )) {
> -        //
> -        // Release the resources acquired by SN_Initialize
> -        //
> -
> -        //
> -        // Update the network state
> -        //
> -        pMode->State = EfiSimpleNetworkStarted;
> -      }
> -    }
> -    else {
> -      Status = EFI_NOT_STARTED;
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> -
> -
> -/**
> -  Send a packet over the network.
> -
> -  This function places the packet specified by Header and Buffer on
> -  the transmit queue.  This function performs a non-blocking transmit
> -  operation.  When the transmit is complete, the buffer is returned
> -  via the GetStatus() call.
> -
> -  This routine calls ::Ax88772Rx to empty the network adapter of
> -  receive packets.  The routine then passes the transmit packet
> -  to the network adapter.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
> -                                the Transmit() function.  If HeaderSize is non-zero, then
> -                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
> -                                and DestAddr and Protocol parameters must not be NULL.
> -  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
> -                                data) to be transmitted through the network interface.
> -  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
> -                                to be transmitted.  This parameter can not be NULL.  If
> -                                HeaderSize is zero, then the media header is Buffer must
> -                                already be filled in by the caller.  If HeaderSize is nonzero,
> -                                then the media header will be filled in by the Transmit()
> -                                function.
> -  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
> -                                this parameter is ignored.  If HeaderSize is nonzero and
> -                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> -                                is used for the source HW MAC address.
> -  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
> -                                this parameter is ignored.
> -  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
> -                                this parameter is ignored.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
> -  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Transmit (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN UINTN HeaderSize,
> -  IN UINTN BufferSize,
> -  IN VOID * pBuffer,
> -  IN EFI_MAC_ADDRESS * pSrcAddr,
> -  IN EFI_MAC_ADDRESS * pDestAddr,
> -  IN UINT16 * pProtocol
> -  )
> -{
> -  RX_TX_PACKET Packet;
> -  ETHERNET_HEADER * pHeader;
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  NIC_DEVICE * pNicDevice;
> -  EFI_USB_IO_PROTOCOL * pUsbIo;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -  UINTN TransferLength;
> -  UINT32 TransferStatus;
> -  UINT16 Type;
> -
> -  DBG_ENTER ( );
> -
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    // The interface must be running
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> -      //
> -      //  Synchronize with Ax88772Timer
> -      //
> -      VERIFY_TPL ( TPL_AX88772 );
> -      TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
> -
> -      //
> -      // Update the link status
> -      //
> -      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -
> -      //
> -      //No need to call receive to receive packet
> -      //
> -      //Ax88772Rx ( pNicDevice, FALSE );
> -      pMode->MediaPresent = pNicDevice->bLinkUp;
> -
> -      //
> -      //  Release the synchronization with Ax88772Timer
> -      //
> -      gBS->RestoreTPL ( TplPrevious );
> -      if ( pMode->MediaPresent ) {
> -        //
> -        //  Copy the packet into the USB buffer
> -        //
> -        CopyMem ( &Packet.Data[0], pBuffer, BufferSize );
> -        Packet.Length = (UINT16) BufferSize;
> -
> -        //
> -        //  Transmit the packet
> -        //
> -        pHeader = (ETHERNET_HEADER *) &Packet.Data[0];
> -        if ( 0 != HeaderSize ) {
> -          if ( NULL != pDestAddr ) {
> -            CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
> -          }
> -          if ( NULL != pSrcAddr ) {
> -            CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
> -          }
> -          else {
> -            CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
> -          }
> -          if ( NULL != pProtocol ) {
> -            Type = *pProtocol;
> -          }
> -          else {
> -            Type = Packet.Length;
> -          }
> -          Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
> -          pHeader->type = Type;
> -        }
> -        if ( Packet.Length < MIN_ETHERNET_PKT_SIZE ) {
> -          Packet.Length = MIN_ETHERNET_PKT_SIZE;
> -          ZeroMem ( &Packet.Data[ BufferSize ],
> -                    Packet.Length - BufferSize );
> -        }
> -        DEBUG (( DEBUG_TX | DEBUG_INFO,
> -                  "TX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
> -                  Packet.Data[0],
> -                  Packet.Data[1],
> -                  Packet.Data[2],
> -                  Packet.Data[3],
> -                  Packet.Data[4],
> -                  Packet.Data[5],
> -                  Packet.Data[6],
> -                  Packet.Data[7],
> -                  Packet.Data[8],
> -                  Packet.Data[9],
> -                  Packet.Data[10],
> -                  Packet.Data[11],
> -                  Packet.Data[12],
> -                  Packet.Data[13],
> -                  Packet.Length ));
> -        Packet.LengthBar = ~Packet.Length;
> -        TransferLength = sizeof ( Packet.Length )
> -                       + sizeof ( Packet.LengthBar )
> -                       + Packet.Length;
> -
> -        //
> -        //  Work around USB bus driver bug where a timeout set by receive
> -        //  succeeds but the timeout expires immediately after, causing the
> -        //  transmit operation to timeout.
> -        //
> -        pUsbIo = pNicDevice->pUsbIo;
> -        Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
> -                                           BULK_OUT_ENDPOINT,
> -                                           &Packet.Length,
> -                                           &TransferLength,
> -                                           0xfffffffe,
> -                                           &TransferStatus );
> -        if ( !EFI_ERROR ( Status )) {
> -          Status = TransferStatus;
> -        }
> -        if (( !EFI_ERROR ( Status ))
> -          && ( TransferLength != (UINTN)( Packet.Length + 4 ))) {
> -          Status = EFI_WARN_WRITE_FAILURE;
> -        }
> -        if ( EFI_SUCCESS == Status ) {
> -          pNicDevice->pTxBuffer = pBuffer;
> -        }
> -        else {
> -          DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> -                    "Ax88772 USB transmit error, TransferLength: %d, Status: %r\r\n",
> -                    sizeof ( Packet.Length ) + Packet.Length,
> -                    Status ));
> -          //
> -          //  Reset the controller to fix the error
> -          //
> -          if ( EFI_DEVICE_ERROR == Status ) {
> -            SN_Reset ( pSimpleNetwork, FALSE );
> -          }
> -        }
> -      }
> -      else {
> -        //
> -        // No packets available.
> -        //
> -        Status = EFI_NOT_READY;
> -      }
> -    }
> -    else {
> -      Status = EFI_NOT_STARTED;
> -    }
> -  }
> -  else {
> -    DEBUG (( DEBUG_ERROR | DEBUG_INFO,
> -              "Ax88772 invalid transmit parameter\r\n"
> -              "  0x%08x: HeaderSize\r\n"
> -              "  0x%08x: BufferSize\r\n"
> -              "  0x%08x: Buffer\r\n"
> -              "  0x%08x: SrcAddr\r\n"
> -              "  0x%08x: DestAddr\r\n"
> -              "  0x%04x:     Protocol\r\n",
> -              HeaderSize,
> -              BufferSize,
> -              pBuffer,
> -              pSrcAddr,
> -              pDestAddr,
> -              pProtocol ));
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // Return the operation status
> -  //
> -  DBG_EXIT_STATUS ( Status );
> -  return Status;
> -}
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
> deleted file mode 100644
> index 12684a6bd16b..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
> +++ /dev/null
> @@ -1,875 +0,0 @@
> -/** @file
> -  Implement the interface to the AX88772 Ethernet controller.
> -
> -  This module implements the interface to the ASIX AX88772
> -  USB to Ethernet MAC with integrated 10/100 PHY.  Note that this implementation
> -  only supports the integrated PHY since no other test cases were available.
> -
> -  Copyright (c) 2011, Intel Corporation. All rights reserved.
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include "Ax88772.h"
> -
> -
> -/**
> -  Compute the CRC
> -
> -  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
> -
> -  @returns The CRC-32 value associated with this MAC address
> -
> -**/
> -UINT32
> -Ax88772Crc (
> -  IN UINT8 * pMacAddress
> -  )
> -{
> -  UINT32 BitNumber;
> -  INT32 Carry;
> -  INT32 Crc;
> -  UINT32 Data;
> -  UINT8 * pEnd;
> -
> -  //
> -  //  Walk the MAC address
> -  //
> -  Crc = -1;
> -  pEnd = &pMacAddress[ PXE_HWADDR_LEN_ETHER ];
> -  while ( pEnd > pMacAddress ) {
> -    Data = *pMacAddress++;
> -    //
> -    //  CRC32: x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
> -    //
> -    //          1 0000 0100 1100 0001 0001 1101 1011 0111
> -    //
> -    for ( BitNumber = 0; 8 > BitNumber; BitNumber++ ) {
> -      Carry = (( Crc >> 31 ) & 1 ) ^ ( Data & 1 );
> -      Crc <<= 1;
> -      if ( 0 != Carry ) {
> -        Crc ^= 0x04c11db7;
> -      }
> -      Data >>= 1;
> -    }
> -  }
> -  //
> -  //  Return the CRC value
> -  //
> -  return (UINT32) Crc;
> -}
> -
> -
> -/**
> -  Get the MAC address
> -
> -  This routine calls ::Ax88772UsbCommand to request the MAC
> -  address from the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [out] pMacAddress      Address of a six byte buffer to receive the MAC address.
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772MacAddressGet (
> -  IN NIC_DEVICE * pNicDevice,
> -  OUT UINT8 * pMacAddress
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  //
> -  //  Set the register address.
> -  //
> -  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> -                       | USB_REQ_TYPE_VENDOR
> -                       | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_MAC_ADDRESS_READ;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
> -
> -  //
> -  //  Read the PHY register
> -  //
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                               &SetupMsg,
> -                               pMacAddress );
> -  return Status;
> -}
> -
> -
> -/**
> -  Set the MAC address
> -
> -  This routine calls ::Ax88772UsbCommand to set the MAC address
> -  in the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pMacAddress      Address of a six byte buffer to containing the new MAC address.
> -
> -  @retval EFI_SUCCESS          The MAC address was set.
> -  @retval other                The MAC address was not set.
> -
> -**/
> -EFI_STATUS
> -Ax88772MacAddressSet (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 * pMacAddress
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  //
> -  //  Set the register address.
> -  //
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                       | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
> -
> -  //
> -  //  Read the PHY register
> -  //
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                               &SetupMsg,
> -                               pMacAddress );
> -  return Status;
> -}
> -
> -/**
> -  Clear the multicast hash table
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -**/
> -VOID
> -Ax88772MulticastClear (
> -  IN NIC_DEVICE * pNicDevice
> -  )
> -{
> -  int i = 0;
> -  //
> -  // Clear the multicast hash table
> -  //
> -  for ( i = 0 ; i < 8 ; i ++ )
> -     pNicDevice->MulticastHash[0] = 0;
> -}
> -
> -/**
> -  Enable a multicast address in the multicast hash table
> -
> -  This routine calls ::Ax88772Crc to compute the hash bit for
> -  this MAC address.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
> -
> -**/
> -VOID
> -Ax88772MulticastSet (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 * pMacAddress
> -  )
> -{
> -  UINT32 Crc;
> -
> -  //
> -  //  Compute the CRC on the destination address
> -  //
> -  Crc = Ax88772Crc ( pMacAddress ) >> 26;
> -
> -  //
> -  //  Set the bit corresponding to the destination address
> -  //
> -   pNicDevice->MulticastHash [ Crc >> 3 ] |= ( 1<< (Crc& 7));
> -}
> -
> -/**
> -  Start the link negotiation
> -
> -  This routine calls ::Ax88772PhyWrite to start the PHY's link
> -  negotiation.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -  @retval EFI_SUCCESS          The link negotiation was started.
> -  @retval other                Failed to start the link negotiation.
> -
> -**/
> -EFI_STATUS
> -Ax88772NegotiateLinkStart (
> -  IN NIC_DEVICE * pNicDevice
> -  )
> -{
> -  UINT16 Control;
> -  EFI_STATUS Status;
> -  int i;
> -  //
> -  // Set the supported capabilities.
> -  //
> -  Status = Ax88772PhyWrite ( pNicDevice,
> -                             PHY_ANAR,
> -                             AN_CSMA_CD
> -                             | AN_TX_FDX | AN_TX_HDX
> -                             | AN_10_FDX | AN_10_HDX );
> -  if ( !EFI_ERROR ( Status )) {
> -    //
> -    // Set the link speed and duplex
> -    //
> -    Control = BMCR_AUTONEGOTIATION_ENABLE
> -            | BMCR_RESTART_AUTONEGOTIATION;
> -    if ( pNicDevice->b100Mbps ) {
> -      Control |= BMCR_100MBPS;
> -    }
> -    if ( pNicDevice->bFullDuplex ) {
> -      Control |= BMCR_FULL_DUPLEX;
> -    }
> -    Status = Ax88772PhyWrite ( pNicDevice, PHY_BMCR, Control );
> -  }
> -
> -  if (!EFI_ERROR(Status)) {
> -    i = 0;
> -    do {
> -
> -        if (pNicDevice->bComplete && pNicDevice->bLinkUp) {
> -            pNicDevice->SimpleNetwork.Mode->MediaPresent
> -               = pNicDevice->bLinkUp & pNicDevice->bComplete;
> -           break;
> -       }
> -       else {
> -            gBS->Stall(AUTONEG_DELAY);
> -            Status = Ax88772NegotiateLinkComplete ( pNicDevice,
> -                                            &pNicDevice->PollCount,
> -                                            &pNicDevice->bComplete,
> -                                            &pNicDevice->bLinkUp,
> -                                            &pNicDevice->b100Mbps,
> -                                            &pNicDevice->bFullDuplex );
> -            i++;
> -        }
> -    }while(!pNicDevice->bLinkUp && i < AUTONEG_POLLCNT);
> -  }
> -  return Status;
> -}
> -
> -
> -/**
> -  Complete the negotiation of the PHY link
> -
> -  This routine calls ::Ax88772PhyRead to determine if the
> -  link negotiation is complete.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in, out] pPollCount  Address of number of times this routine was polled
> -  @param [out] pbComplete      Address of boolean to receive complate status.
> -  @param [out] pbLinkUp        Address of boolean to receive link status, TRUE=up.
> -  @param [out] pbHiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
> -  @param [out] pbFullDuplex    Address of boolean to receive link duplex, TRUE=full.
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772NegotiateLinkComplete (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN OUT UINTN * pPollCount,
> -  OUT BOOLEAN * pbComplete,
> -  OUT BOOLEAN * pbLinkUp,
> -  OUT BOOLEAN * pbHiSpeed,
> -  OUT BOOLEAN * pbFullDuplex
> -  )
> -{
> -  UINT16 Mask;
> -  UINT16 PhyData;
> -  EFI_STATUS  Status;
> -
> -  //
> -  //  Determine if the link is up.
> -  //
> -  *pbComplete = FALSE;
> -
> -  //
> -  //  Get the link status
> -  //
> -  Status = Ax88772PhyRead ( pNicDevice,
> -                            PHY_BMSR,
> -                            &PhyData );
> -
> -  if ( !EFI_ERROR ( Status )) {
> -      *pbLinkUp = (BOOLEAN)( 0 != ( PhyData & BMSR_LINKST ));
> -      if ( 0 == *pbLinkUp ) {
> -        DEBUG (( EFI_D_INFO, "Link Down\n" ));
> -      }
> -      else {
> -         *pbComplete = (BOOLEAN)( 0 != ( PhyData & 0x20 ));
> -         if ( 0 == *pbComplete ) {
> -              DEBUG (( EFI_D_INFO, "Autoneg is not yet Complete\n" ));
> -        }
> -        else {
> -          Status = Ax88772PhyRead ( pNicDevice,
> -                                PHY_ANLPAR,
> -                                &PhyData );
> -          if ( !EFI_ERROR ( Status )) {
> -            //
> -            //  Autonegotiation is complete
> -            //  Determine the link speed.
> -            //
> -            *pbHiSpeed = (BOOLEAN)( 0 != ( PhyData & ( AN_TX_FDX | AN_TX_HDX )));
> -
> -            //
> -            //  Determine the link duplex.
> -            //
> -            Mask = ( *pbHiSpeed ) ? AN_TX_FDX : AN_10_FDX;
> -            *pbFullDuplex = (BOOLEAN)( 0 != ( PhyData & Mask ));
> -          }
> -        }
> -      }
> -  }
> -  else {
> -      DEBUG (( EFI_D_ERROR, "Failed to read BMCR\n" ));
> -  }
> -  return Status;
> -}
> -
> -
> -/**
> -  Read a register from the PHY
> -
> -  This routine calls ::Ax88772UsbCommand to read a PHY register.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RegisterAddress  Number of the register to read.
> -  @param [in, out] pPhyData    Address of a buffer to receive the PHY register value
> -
> -  @retval EFI_SUCCESS          The PHY data is available.
> -  @retval other                The PHY data is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772PhyRead (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 RegisterAddress,
> -  IN OUT UINT16 * pPhyData
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  //
> -  //  Request access to the PHY
> -  //
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                       | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                               &SetupMsg,
> -                               NULL );
> -  if ( !EFI_ERROR ( Status )) {
> -    //
> -    //  Read the PHY register address.
> -    //
> -    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> -                         | USB_REQ_TYPE_VENDOR
> -                         | USB_TARGET_DEVICE;
> -    SetupMsg.Request = CMD_PHY_REG_READ;
> -    SetupMsg.Value = pNicDevice->PhyId;
> -    SetupMsg.Index = RegisterAddress;
> -    SetupMsg.Length = sizeof ( *pPhyData );
> -    Status = Ax88772UsbCommand ( pNicDevice,
> -                                 &SetupMsg,
> -                                 pPhyData );
> -    if ( !EFI_ERROR ( Status )) {
> -
> -      //
> -      //  Release the PHY to the hardware
> -      //
> -      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                           | USB_TARGET_DEVICE;
> -      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> -      SetupMsg.Value = 0;
> -      SetupMsg.Index = 0;
> -      SetupMsg.Length = 0;
> -      Status = Ax88772UsbCommand ( pNicDevice,
> -                                   &SetupMsg,
> -                                   NULL );
> -    }
> -  }
> -  return Status;
> -}
> -
> -
> -/**
> -  Write to a PHY register
> -
> -  This routine calls ::Ax88772UsbCommand to write a PHY register.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RegisterAddress  Number of the register to read.
> -  @param [in] PhyData          Address of a buffer to receive the PHY register value
> -
> -  @retval EFI_SUCCESS          The PHY data was written.
> -  @retval other                Failed to wwrite the PHY register.
> -
> -**/
> -EFI_STATUS
> -Ax88772PhyWrite (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT8 RegisterAddress,
> -  IN UINT16 PhyData
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  //
> -  //  Request access to the PHY
> -  //
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                       | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                               &SetupMsg,
> -                               NULL );
> -  if ( !EFI_ERROR ( Status )) {
> -    //
> -    //  Write the PHY register
> -    //
> -    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                         | USB_TARGET_DEVICE;
> -    SetupMsg.Request = CMD_PHY_REG_WRITE;
> -    SetupMsg.Value = pNicDevice->PhyId;
> -    SetupMsg.Index = RegisterAddress;
> -    SetupMsg.Length = sizeof ( PhyData );
> -    Status = Ax88772UsbCommand ( pNicDevice,
> -                                 &SetupMsg,
> -                                 &PhyData );
> -    if ( !EFI_ERROR ( Status )) {
> -
> -      //
> -      //  Release the PHY to the hardware
> -      //
> -      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                           | USB_TARGET_DEVICE;
> -      SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> -      SetupMsg.Value = 0;
> -      SetupMsg.Index = 0;
> -      SetupMsg.Length = 0;
> -      Status = Ax88772UsbCommand ( pNicDevice,
> -                                   &SetupMsg,
> -                                   NULL );
> -    }
> -  }
> -
> -  return Status;
> -}
> -
> -
> -/**
> -  Reset the AX88772
> -
> -  This routine uses ::Ax88772UsbCommand to reset the network
> -  adapter.  This routine also uses ::Ax88772PhyWrite to reset
> -  the PHY.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -
> -  @retval EFI_SUCCESS          The MAC address is available.
> -  @retval other                The MAC address is not valid.
> -
> -**/
> -EFI_STATUS
> -Ax88772Reset (
> -  IN NIC_DEVICE * pNicDevice
> -  )
> -{
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -
> -  EFI_USB_IO_PROTOCOL *pUsbIo;
> -  EFI_USB_DEVICE_DESCRIPTOR Device;
> -
> -  pUsbIo = pNicDevice->pUsbIo;
> -  Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
> -
> -	if (EFI_ERROR(Status)) goto err;
> -
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                           | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                                &SetupMsg,
> -                                NULL );
> -
> -  if (EFI_ERROR(Status)) goto err;
> -
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                          | USB_TARGET_DEVICE;
> -      SetupMsg.Request = CMD_PHY_SELECT;
> -      SetupMsg.Value = SPHY_PSEL;
> -      SetupMsg.Index = 0;
> -      SetupMsg.Length = 0;
> -      Status = Ax88772UsbCommand ( pNicDevice,
> -                                    &SetupMsg,
> -                                    NULL );
> -
> -  if (EFI_ERROR(Status)) goto err;
> -
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                          | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_RESET;
> -      SetupMsg.Value = SRR_IPRL ;
> -      SetupMsg.Index = 0;
> -      SetupMsg.Length = 0;
> -      Status = Ax88772UsbCommand ( pNicDevice,
> -                                   &SetupMsg,
> -                                   NULL );
> -
> -  if (EFI_ERROR(Status)) goto err;
> -
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                          | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_RESET;
> -        SetupMsg.Value = SRR_IPPD | SRR_IPRL ;
> -        SetupMsg.Index = 0;
> -        SetupMsg.Length = 0;
> -        Status = Ax88772UsbCommand ( pNicDevice,
> -                                    &SetupMsg,
> -                                    NULL );
> -
> -  gBS->Stall ( 200000 );
> -
> -  if (EFI_ERROR(Status)) goto err;
> -
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                          | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_RESET;
> -  SetupMsg.Value =  SRR_IPRL  ;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                                &SetupMsg,
> -                                NULL );
> -
> -  gBS->Stall ( 200000 );
> -
> -  if (EFI_ERROR(Status)) goto err;
> -
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                          | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_RESET;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                                    &SetupMsg,
> -                                    NULL );
> -
> -  if (EFI_ERROR(Status)) goto err;
> -
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                          | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_PHY_SELECT;
> -  SetupMsg.Value = SPHY_PSEL;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                                    &SetupMsg,
> -                                    NULL );
> -
> -  if (EFI_ERROR(Status)) goto err;
> -
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                          | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_RESET;
> -  SetupMsg.Value =  SRR_IPRL | SRR_BZ | SRR_BZTYPE;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                                    &SetupMsg,
> -                                    NULL );
> -
> -  if (EFI_ERROR(Status)) goto err;
> -
> -  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                        | USB_TARGET_DEVICE;
> -  SetupMsg.Request = CMD_RX_CONTROL_WRITE;
> -  SetupMsg.Value = 0;
> -  SetupMsg.Index = 0;
> -  SetupMsg.Length = 0;
> -  Status = Ax88772UsbCommand ( pNicDevice,
> -                                  &SetupMsg,
> -                                  NULL );
> -
> -  if (EFI_ERROR(Status)) goto err;
> -
> -  if (pNicDevice->Flags != FLAG_TYPE_AX88772) {
> -        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                        | USB_TARGET_DEVICE;
> -        SetupMsg.Request = CMD_RXQTC;
> -        SetupMsg.Value = 0x8000;
> -        SetupMsg.Index = 0x8001;
> -        SetupMsg.Length = 0;
> -        Status = Ax88772UsbCommand ( pNicDevice,
> -                                  &SetupMsg,
> -                                  NULL );
> -  }
> -
> -err:
> -  return Status;
> -}
> -
> -/**
> -  Enable or disable the receiver
> -
> -  This routine calls ::Ax88772UsbCommand to update the
> -  receiver state.  This routine also calls ::Ax88772MacAddressSet
> -  to establish the MAC address for the network adapter.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] RxFilter         Simple network RX filter mask value
> -
> -  @retval EFI_SUCCESS          The MAC address was set.
> -  @retval other                The MAC address was not set.
> -
> -**/
> -EFI_STATUS
> -Ax88772RxControl (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT32 RxFilter
> -  )
> -{
> -  UINT16 MediumStatus;
> -  UINT16 RxControl;
> -  USB_DEVICE_REQUEST SetupMsg;
> -  EFI_STATUS Status;
> -  EFI_USB_IO_PROTOCOL *pUsbIo;
> -  EFI_USB_DEVICE_DESCRIPTOR Device;
> -
> -  pUsbIo = pNicDevice->pUsbIo;
> -  Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
> -
> -  if (EFI_ERROR(Status)) {
> -    DEBUG (( EFI_D_ERROR, "Failed to get device descriptor\n" ));
> -    return Status;
> -  }
> -
> -  //
> -  // Enable the receiver if something is to be received
> -  //
> -
> -  if ( 0 != RxFilter ) {
> -    //
> -    //  Enable the receiver
> -    //
> -    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> -                         | USB_REQ_TYPE_VENDOR
> -                         | USB_TARGET_DEVICE;
> -    SetupMsg.Request = CMD_MEDIUM_STATUS_READ;
> -    SetupMsg.Value = 0;
> -    SetupMsg.Index = 0;
> -    SetupMsg.Length = sizeof ( MediumStatus );
> -    Status = Ax88772UsbCommand ( pNicDevice,
> -                                 &SetupMsg,
> -                                 &MediumStatus );
> -    if ( !EFI_ERROR ( Status )) {
> -      if ( 0 == ( MediumStatus & MS_RE )) {
> -        MediumStatus |= MS_RE | MS_ONE;
> -
> -        if ( pNicDevice->bFullDuplex )
> -          MediumStatus |= MS_TFC | MS_RFC | MS_FD;
> -        else
> -          MediumStatus &= ~(MS_TFC | MS_RFC | MS_FD);
> -
> -        if ( pNicDevice->b100Mbps )
> -          MediumStatus |= MS_PS;
> -        else
> -          MediumStatus &= ~MS_PS;
> -
> -        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                             | USB_TARGET_DEVICE;
> -        SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
> -        SetupMsg.Value = MediumStatus;
> -        SetupMsg.Index = 0;
> -        SetupMsg.Length = 0;
> -        Status = Ax88772UsbCommand ( pNicDevice,
> -                                     &SetupMsg,
> -                                     NULL );
> -        if ( EFI_ERROR ( Status )) {
> -            DEBUG (( EFI_D_ERROR, "Failed to enable receiver, Status: %r\r\n",
> -              Status ));
> -        }
> -      }
> -    }
> -    else {
> -        DEBUG (( EFI_D_ERROR, "Failed to read receiver status, Status: %r\r\n",
> -              Status ));
> -    }
> -  }
> -
> -  RxControl = RXC_SO | RXC_RH1M;
> -  //
> -  //  Enable multicast if requested
> -  //
> -  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
> -      RxControl |= RXC_AM;
> -      //
> -      //  Update the multicast hash table
> -      //
> -      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                           | USB_TARGET_DEVICE;
> -      SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
> -      SetupMsg.Value = 0;
> -      SetupMsg.Index = 0;
> -      SetupMsg.Length = sizeof ( pNicDevice ->MulticastHash );
> -      Status = Ax88772UsbCommand ( pNicDevice,
> -                                   &SetupMsg,
> -                                   &pNicDevice->MulticastHash );
> -  }
> -  //
> -  //  Enable all multicast if requested
> -  //
> -  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST )) {
> -      RxControl |= RXC_AMALL;
> -  }
> -
> -  //
> -  //  Enable broadcast if requested
> -  //
> -  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST )) {
> -      RxControl |= RXC_AB;
> -  }
> -
> -  //
> -  //  Enable promiscuous mode if requested
> -  //
> -  if ( 0 != ( RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS )) {
> -      RxControl |= RXC_PRO;
> -  }
> -
> -  //
> -  //  Update the receiver control
> -  //
> -  if (pNicDevice->CurRxControl != RxControl) {
> -    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> -                         | USB_TARGET_DEVICE;
> -    SetupMsg.Request = CMD_RX_CONTROL_WRITE;
> -    SetupMsg.Value = RxControl;
> -    SetupMsg.Index = 0;
> -    SetupMsg.Length = 0;
> -    Status = Ax88772UsbCommand ( pNicDevice,
> -                                 &SetupMsg,
> -                                 NULL );
> -    if ( !EFI_ERROR ( Status )) {
> -      pNicDevice->CurRxControl = RxControl;
> -
> -    }
> -    else {
> -        DEBUG (( EFI_D_ERROR, "ERROR - Failed to set receiver control, Status: %r\r\n",
> -            Status ));
> -    }
> -  }
> -  return Status;
> -}
> -
> -
> -/**
> -  Read an SROM location
> -
> -  This routine calls ::Ax88772UsbCommand to read data from the
> -  SROM.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] Address          SROM address
> -  @param [out] pData           Buffer to receive the data
> -
> -  @retval EFI_SUCCESS          The read was successful
> -  @retval other                The read failed
> -
> -**/
> -EFI_STATUS
> -Ax88772SromRead (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN UINT32 Address,
> -  OUT UINT16 * pData
> -  )
> -{
> -  return EFI_UNSUPPORTED;
> -}
> -
> -/**
> -  Send a command to the USB device.
> -
> -  @param [in] pNicDevice       Pointer to the NIC_DEVICE structure
> -  @param [in] pRequest         Pointer to the request structure
> -  @param [in, out] pBuffer     Data buffer address
> -
> -  @retval EFI_SUCCESS          The USB transfer was successful
> -  @retval other                The USB transfer failed
> -
> -**/
> -EFI_STATUS
> -Ax88772UsbCommand (
> -  IN NIC_DEVICE * pNicDevice,
> -  IN USB_DEVICE_REQUEST * pRequest,
> -  IN OUT VOID * pBuffer
> -  )
> -{
> -  UINT32 CmdStatus;
> -  EFI_USB_DATA_DIRECTION Direction;
> -  EFI_USB_IO_PROTOCOL * pUsbIo;
> -  EFI_STATUS Status;
> -
> -  //
> -  // Determine the transfer direction
> -  //
> -  Direction = EfiUsbNoData;
> -  if ( 0 != pRequest->Length ) {
> -    Direction = ( 0 != ( pRequest->RequestType & USB_ENDPOINT_DIR_IN ))
> -              ? EfiUsbDataIn : EfiUsbDataOut;
> -  }
> -
> -  //
> -  // Issue the command
> -  //
> -  pUsbIo = pNicDevice->pUsbIo;
> -  Status = pUsbIo->UsbControlTransfer ( pUsbIo,
> -                                        pRequest,
> -                                        Direction,
> -                                        USB_BUS_TIMEOUT,
> -                                        pBuffer,
> -                                        pRequest->Length,
> -                                        &CmdStatus );
> -  //
> -  // Determine the operation status
> -  //
> -  if ( !EFI_ERROR ( Status )) {
> -    Status = CmdStatus;
> -  }
> -  else {
> -    //
> -    // Only use status values associated with the Simple Network protocol
> -    //
> -    if ( EFI_TIMEOUT == Status ) {
> -      Status = EFI_DEVICE_ERROR;
> -    }
> -  }
> -  return Status;
> -}
> -
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c
> deleted file mode 100644
> index 76a732a7b007..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/ComponentName.c
> +++ /dev/null
> @@ -1,175 +0,0 @@
> -/** @file
> -  UEFI Component Name(2) protocol implementation.
> -
> -  Copyright (c) 2011, Intel Corporation. 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  gComponentName = {
> -  GetDriverName,
> -  GetControllerName,
> -  "eng"
> -};
> -
> -/**
> -  EFI Component Name 2 Protocol declaration
> -**/
> -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
> -  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
> -  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
> -  "en"
> -};
> -
> -
> -/**
> -  Driver name table declaration
> -**/
> -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> -mDriverNameTable[] = {
> -  {"eng;en", L"ASIX AX88772B Ethernet Driver 1.0"},
> -  {NULL,  NULL}
> -};
> -
> -/**
> -  Retrieves a Unicode string that is the user readable name of the driver.
> -
> -  This function retrieves the user readable name of a driver in the form of a
> -  Unicode string. If the driver specified by This has a user readable name in
> -  the language specified by Language, then a pointer to the driver name is
> -  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> -  by This does not support the language specified by Language,
> -  then EFI_UNSUPPORTED is returned.
> -
> -  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> -                                EFI_COMPONENT_NAME_PROTOCOL instance.
> -  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> -                                array indicating the language. This is the
> -                                language of the driver name that the caller is
> -                                requesting, and it must match one of the
> -                                languages specified in SupportedLanguages. The
> -                                number of languages supported by a driver is up
> -                                to the driver writer. Language is specified
> -                                in RFC 3066 or ISO 639-2 language code format.
> -  @param [out] ppDriverName     A pointer to the Unicode string to return.
> -                                This Unicode string is the name of the
> -                                driver specified by This in the language
> -                                specified by Language.
> -
> -  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> -                                This and the language specified by Language was
> -                                returned in DriverName.
> -  @retval EFI_INVALID_PARAMETER Language is NULL.
> -  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> -  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> -                                the language specified by Language.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -GetDriverName (
> -  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> -  IN  CHAR8 * pLanguage,
> -  OUT CHAR16 ** ppDriverName
> -  )
> -{
> -  EFI_STATUS Status;
> -
> -  Status = LookupUnicodeString2 (
> -             pLanguage,
> -             pThis->SupportedLanguages,
> -             mDriverNameTable,
> -             ppDriverName,
> -             (BOOLEAN)(pThis == &gComponentName)
> -             );
> -
> -  return Status;
> -}
> -
> -/**
> -  Retrieves a Unicode string that is the user readable name of the controller
> -  that is being managed by a driver.
> -
> -  This function retrieves the user readable name of the controller specified by
> -  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> -  driver specified by This has a user readable name in the language specified by
> -  Language, then a pointer to the controller name is returned in ControllerName,
> -  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> -  managing the controller specified by ControllerHandle and ChildHandle,
> -  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> -  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> -
> -  @param [in] pThis             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> -                                EFI_COMPONENT_NAME_PROTOCOL instance.
> -  @param [in] ControllerHandle  The handle of a controller that the driver
> -                                specified by This is managing.  This handle
> -                                specifies the controller whose name is to be
> -                                returned.
> -  @param [in] ChildHandle       The handle of the child controller to retrieve
> -                                the name of.  This is an optional parameter that
> -                                may be NULL.  It will be NULL for device
> -                                drivers.  It will also be NULL for a bus drivers
> -                                that wish to retrieve the name of the bus
> -                                controller.  It will not be NULL for a bus
> -                                driver that wishes to retrieve the name of a
> -                                child controller.
> -  @param [in] pLanguage         A pointer to a Null-terminated ASCII string
> -                                array indicating the language.  This is the
> -                                language of the driver name that the caller is
> -                                requesting, and it must match one of the
> -                                languages specified in SupportedLanguages. The
> -                                number of languages supported by a driver is up
> -                                to the driver writer. Language is specified in
> -                                RFC 3066 or ISO 639-2 language code format.
> -  @param [out] ppControllerName A pointer to the Unicode string to return.
> -                                This Unicode string is the name of the
> -                                controller specified by ControllerHandle and
> -                                ChildHandle in the language specified by
> -                                Language from the point of view of the driver
> -                                specified by This.
> -
> -  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> -                                the language specified by Language for the
> -                                driver specified by This was returned in
> -                                DriverName.
> -  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
> -  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> -                                EFI_HANDLE.
> -  @retval EFI_INVALID_PARAMETER Language is NULL.
> -  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> -  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> -                                managing the controller specified by
> -                                ControllerHandle and ChildHandle.
> -  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> -                                the language specified by Language.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -GetControllerName (
> -  IN  EFI_COMPONENT_NAME_PROTOCOL * pThis,
> -  IN  EFI_HANDLE ControllerHandle,
> -  IN OPTIONAL EFI_HANDLE ChildHandle,
> -  IN  CHAR8 * pLanguage,
> -  OUT CHAR16 ** ppControllerName
> -  )
> -{
> -  EFI_STATUS Status;
> -
> -  //
> -  // Set the controller name
> -  //
> -  *ppControllerName = L"ASIX AX88772B USB Fast Ethernet Controller";
> -  Status = EFI_SUCCESS;
> -
> -  //
> -  // Return the operation status
> -  //
> -
> -  return Status;
> -}
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
> deleted file mode 100644
> index 2bec94414000..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
> +++ /dev/null
> @@ -1,696 +0,0 @@
> -/** @file
> -  Implement the driver binding protocol for Asix AX88772 Ethernet driver.
> -
> -  Copyright (c) 2011-2013, Intel Corporation. All rights reserved.
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include "Ax88772.h"
> -
> -ASIX_DONGLE ASIX_DONGLES[] = {
> -  { 0x05AC, 0x1402, FLAG_TYPE_AX88772 }, // Apple USB Ethernet Adapter
> -  // ASIX 88772B
> -  { 0x0B95, 0x772B, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
> -  { 0x0000, 0x0000, FLAG_NONE }   // END - Do not remove
> -};
> -
> -/**
> -  Verify the controller type
> -
> -  @param [in] pThis                Protocol instance pointer.
> -  @param [in] Controller           Handle of device to test.
> -  @param [in] pRemainingDevicePath Not used.
> -
> -  @retval EFI_SUCCESS          This driver supports this device.
> -  @retval other                This driver does not support this device.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -DriverSupported (
> -  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
> -  IN EFI_HANDLE Controller,
> -  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
> -  )
> -{
> -  EFI_USB_DEVICE_DESCRIPTOR Device;
> -  EFI_USB_IO_PROTOCOL * pUsbIo;
> -  EFI_STATUS Status;
> -  UINT32 Index;
> -
> -  //
> -  //  Connect to the USB stack
> -  //
> -  Status = gBS->OpenProtocol (
> -                  Controller,
> -                  &gEfiUsbIoProtocolGuid,
> -                  (VOID **) &pUsbIo,
> -                  pThis->DriverBindingHandle,
> -                  Controller,
> -                  EFI_OPEN_PROTOCOL_BY_DRIVER
> -                  );
> -  if (!EFI_ERROR ( Status )) {
> -
> -    //
> -    //  Get the interface descriptor to check the USB class and find a transport
> -    //  protocol handler.
> -    //
> -    Status = pUsbIo->UsbGetDeviceDescriptor ( pUsbIo, &Device );
> -    if (EFI_ERROR ( Status )) {
> -    	Status = EFI_UNSUPPORTED;
> -    }
> -    else {
> -      //
> -      //  Validate the adapter
> -      //
> -      for (Index = 0; ASIX_DONGLES[Index].VendorId != 0; Index++) {
> -        if (ASIX_DONGLES[Index].VendorId == Device.IdVendor &&
> -            ASIX_DONGLES[Index].ProductId == Device.IdProduct) {
> -              DEBUG ((EFI_D_INFO, "Found the AX88772B\r\n"));
> -              break;
> -        }
> -      }
> -
> -      if (ASIX_DONGLES[Index].VendorId == 0)
> -         Status = EFI_UNSUPPORTED;
> -    }
> -
> -    //
> -    //  Done with the USB stack
> -    //
> -    gBS->CloseProtocol (
> -           Controller,
> -           &gEfiUsbIoProtocolGuid,
> -           pThis->DriverBindingHandle,
> -           Controller
> -           );
> -  }
> -  return Status;
> -}
> -
> -
> -/**
> -  Start this driver on Controller by opening UsbIo and DevicePath protocols.
> -  Initialize PXE structures, create a copy of the Controller Device Path with the
> -  NIC's MAC address appended to it, install the NetworkInterfaceIdentifier protocol
> -  on the newly created Device Path.
> -
> -  @param [in] pThis                Protocol instance pointer.
> -  @param [in] Controller           Handle of device to work with.
> -  @param [in] pRemainingDevicePath Not used, always produce all possible children.
> -
> -  @retval EFI_SUCCESS          This driver is added to Controller.
> -  @retval other                This driver does not support this device.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -DriverStart (
> -  IN EFI_DRIVER_BINDING_PROTOCOL * pThis,
> -  IN EFI_HANDLE Controller,
> -  IN EFI_DEVICE_PATH_PROTOCOL * pRemainingDevicePath
> -  )
> -{
> -
> -	EFI_STATUS						Status;
> -	NIC_DEVICE						*pNicDevice;
> -	UINTN							LengthInBytes;
> -	EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath = NULL;
> -	MAC_ADDR_DEVICE_PATH            MacDeviceNode;
> -        EFI_USB_DEVICE_DESCRIPTOR       Device;
> -        UINT32                          Index;
> -
> -  //
> -	//  Allocate the device structure
> -	//
> -	LengthInBytes = sizeof ( *pNicDevice );
> -	Status = gBS->AllocatePool (
> -                  EfiRuntimeServicesData,
> -                  LengthInBytes,
> -                  (VOID **) &pNicDevice
> -                  );
> -
> -	if (EFI_ERROR (Status)) {
> -		DEBUG ((EFI_D_ERROR, "gBS->AllocatePool:pNicDevice ERROR Status = %r\n", Status));
> -		goto EXIT;
> -	}
> -
> -	//
> -  //  Set the structure signature
> -  //
> -  ZeroMem ( pNicDevice, LengthInBytes );
> -  pNicDevice->Signature = DEV_SIGNATURE;
> -
> -	Status = gBS->OpenProtocol (
> -                    Controller,
> -                    &gEfiUsbIoProtocolGuid,
> -                    (VOID **) &pNicDevice->pUsbIo,
> -                    pThis->DriverBindingHandle,
> -                    Controller,
> -                    EFI_OPEN_PROTOCOL_BY_DRIVER
> -                    );
> -
> -	if (EFI_ERROR (Status)) {
> -		DEBUG ((EFI_D_ERROR, "gBS->OpenProtocol:EFI_USB_IO_PROTOCOL ERROR Status = %r\n", Status));
> -		gBS->FreePool ( pNicDevice );
> -		goto EXIT;
> -	}
> -
> -	//
> -  //  Initialize the simple network protocol
> -  //
> -	Status = SN_Setup ( pNicDevice );
> -
> -	if (EFI_ERROR(Status)){
> -	   DEBUG ((EFI_D_ERROR, "SN_Setup ERROR Status = %r\n", Status));
> -	   gBS->CloseProtocol (
> -					Controller,
> -					&gEfiUsbIoProtocolGuid,
> -					pThis->DriverBindingHandle,
> -					Controller
> -					);
> -		  gBS->FreePool ( pNicDevice );
> -		  goto EXIT;
> -  }
> -
> -  Status = pNicDevice->pUsbIo->UsbGetDeviceDescriptor ( pNicDevice->pUsbIo, &Device );
> -  if (EFI_ERROR ( Status )) {
> -     gBS->CloseProtocol (
> -               Controller,
> -               &gEfiUsbIoProtocolGuid,
> -               pThis->DriverBindingHandle,
> -               Controller
> -               );
> -     gBS->FreePool ( pNicDevice );
> -              goto EXIT;
> -  } else {
> -      //
> -      //  Validate the adapter
> -      //
> -      for (Index = 0; ASIX_DONGLES[Index].VendorId != 0; Index++) {
> -          if (ASIX_DONGLES[Index].VendorId == Device.IdVendor &&
> -              ASIX_DONGLES[Index].ProductId == Device.IdProduct) {
> -                break;
> -          }
> -      }
> -
> -      if (ASIX_DONGLES[Index].VendorId == 0) {
> -         gBS->CloseProtocol (
> -                   Controller,
> -                   &gEfiUsbIoProtocolGuid,
> -                   pThis->DriverBindingHandle,
> -                   Controller
> -                   );
> -          gBS->FreePool ( pNicDevice );
> -                   goto EXIT;
> -      }
> -
> -      pNicDevice->Flags = ASIX_DONGLES[Index].Flags;
> -  }
> -
> -	//
> -  // Set Device Path
> -  //
> -  Status = gBS->OpenProtocol (
> -                  Controller,
> -                  &gEfiDevicePathProtocolGuid,
> -                  (VOID **) &ParentDevicePath,
> -				          pThis->DriverBindingHandle,
> -                  Controller,
> -                  EFI_OPEN_PROTOCOL_BY_DRIVER
> -                  );
> -	if (EFI_ERROR(Status)) {
> -        DEBUG ((EFI_D_ERROR, "gBS->OpenProtocol:EFI_DEVICE_PATH_PROTOCOL error. Status = %r\n",
> -            Status));
> -		    gBS->CloseProtocol (
> -					Controller,
> -					&gEfiUsbIoProtocolGuid,
> -					pThis->DriverBindingHandle,
> -					Controller
> -					);
> -		  gBS->FreePool ( pNicDevice );
> -		  goto EXIT;
> -	}
> -
> -  ZeroMem (&MacDeviceNode, sizeof (MAC_ADDR_DEVICE_PATH));
> -  MacDeviceNode.Header.Type = MESSAGING_DEVICE_PATH;
> -  MacDeviceNode.Header.SubType = MSG_MAC_ADDR_DP;
> -
> -  SetDevicePathNodeLength (&MacDeviceNode.Header, sizeof (MAC_ADDR_DEVICE_PATH));
> -
> -  CopyMem (&MacDeviceNode.MacAddress,
> -      								&pNicDevice->SimpleNetworkData.CurrentAddress,
> -      								PXE_HWADDR_LEN_ETHER);
> -
> -  MacDeviceNode.IfType = pNicDevice->SimpleNetworkData.IfType;
> -
> -  pNicDevice->MyDevPath = AppendDevicePathNode (
> -                                          ParentDevicePath,
> -                                          (EFI_DEVICE_PATH_PROTOCOL *) &MacDeviceNode
> -                                          );
> -
> -	pNicDevice->Controller = NULL;
> -
> -	//
> -  //  Install both the simple network and device path protocols.
> -  //
> -  Status = gBS->InstallMultipleProtocolInterfaces (
> -                          &pNicDevice->Controller,
> -                          &gEfiCallerIdGuid,
> -                          pNicDevice,
> -                          &gEfiSimpleNetworkProtocolGuid,
> -                          &pNicDevice->SimpleNetwork,
> -						              &gEfiDevicePathProtocolGuid,
> -						              pNicDevice->MyDevPath,
> -                          NULL
> -                          );
> -
> -	if (EFI_ERROR(Status)){
> -		DEBUG ((EFI_D_ERROR, "gBS->InstallMultipleProtocolInterfaces error. Status = %r\n",
> -            Status));
> -		gBS->CloseProtocol (
> -					               Controller,
> -					               &gEfiDevicePathProtocolGuid,
> -					               pThis->DriverBindingHandle,
> -					               Controller);
> -	   gBS->CloseProtocol (
> -					Controller,
> -					&gEfiUsbIoProtocolGuid,
> -					pThis->DriverBindingHandle,
> -					Controller
> -					);
> -		  gBS->FreePool ( pNicDevice );
> -		  goto EXIT;
> -	}
> -
> -	//
> -	// Open For Child Device
> -	//
> -	Status = gBS->OpenProtocol (
> -                  Controller,
> -                  &gEfiUsbIoProtocolGuid,
> -                  (VOID **) &pNicDevice->pUsbIo,
> -                  pThis->DriverBindingHandle,
> -                  pNicDevice->Controller,
> -                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
> -                  );
> -
> -	if (EFI_ERROR(Status)){
> -	   gBS->UninstallMultipleProtocolInterfaces (
> -              &pNicDevice->Controller,
> -                          &gEfiCallerIdGuid,
> -                          pNicDevice,
> -                          &gEfiSimpleNetworkProtocolGuid,
> -                          &pNicDevice->SimpleNetwork,
> -						              &gEfiDevicePathProtocolGuid,
> -						              pNicDevice->MyDevPath,
> -                          NULL
> -                          );
> -		gBS->CloseProtocol (
> -					               Controller,
> -					               &gEfiDevicePathProtocolGuid,
> -					               pThis->DriverBindingHandle,
> -					               Controller);
> -	   gBS->CloseProtocol (
> -					Controller,
> -					&gEfiUsbIoProtocolGuid,
> -					pThis->DriverBindingHandle,
> -					Controller
> -					);
> -		  gBS->FreePool ( pNicDevice );
> -	}
> -
> -EXIT:
> -	return Status;
> -
> -}
> -
> -/**
> -  Stop this driver on Controller by removing NetworkInterfaceIdentifier protocol and
> -  closing the DevicePath and PciIo protocols on Controller.
> -
> -  @param [in] pThis                Protocol instance pointer.
> -  @param [in] Controller           Handle of device to stop driver on.
> -  @param [in] NumberOfChildren     How many children need to be stopped.
> -  @param [in] pChildHandleBuffer   Not used.
> -
> -  @retval EFI_SUCCESS          This driver is removed Controller.
> -  @retval EFI_DEVICE_ERROR     The device could not be stopped due to a device error.
> -  @retval other                This driver was not removed from this device.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -DriverStop (
> -  IN  EFI_DRIVER_BINDING_PROTOCOL * pThis,
> -  IN  EFI_HANDLE Controller,
> -  IN  UINTN NumberOfChildren,
> -  IN  EFI_HANDLE * ChildHandleBuffer
> -  )
> -{
> -		BOOLEAN                                   AllChildrenStopped;
> -		UINTN                                     Index;
> -		EFI_SIMPLE_NETWORK_PROTOCOL				  *SimpleNetwork;
> -		EFI_STATUS                                Status = EFI_SUCCESS;
> -		NIC_DEVICE								  *pNicDevice;
> -
> -		//
> -		// Complete all outstanding transactions to Controller.
> -		// Don't allow any new transaction to Controller to be started.
> -		//
> -		if (NumberOfChildren == 0) {
> -
> -		  Status = gBS->OpenProtocol (
> -				                Controller,
> -				                &gEfiSimpleNetworkProtocolGuid,
> -				                (VOID **) &SimpleNetwork,
> -				                pThis->DriverBindingHandle,
> -				                Controller,
> -				                EFI_OPEN_PROTOCOL_GET_PROTOCOL
> -				                );
> -
> -			if (EFI_ERROR(Status)) {
> -        //
> -        // This is a 2nd type handle(multi-lun root), it needs to close devicepath
> -        // and usbio protocol.
> -        //
> -        gBS->CloseProtocol (
> -            Controller,
> -            &gEfiDevicePathProtocolGuid,
> -            pThis->DriverBindingHandle,
> -            Controller
> -            );
> -        gBS->CloseProtocol (
> -            Controller,
> -            &gEfiUsbIoProtocolGuid,
> -            pThis->DriverBindingHandle,
> -            Controller
> -            );
> -        return EFI_SUCCESS;
> -      }
> -
> -      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork );
> -
> -      Status = gBS->UninstallMultipleProtocolInterfaces (
> -				                  Controller,
> -				                  &gEfiCallerIdGuid,
> -                          pNicDevice,
> -                          &gEfiSimpleNetworkProtocolGuid,
> -                          &pNicDevice->SimpleNetwork,
> -						              &gEfiDevicePathProtocolGuid,
> -						              pNicDevice->MyDevPath,
> -                          NULL
> -                          );
> -
> -      if (EFI_ERROR (Status)) {
> -        return Status;
> -      }
> -		  //
> -		  // Close the bus driver
> -		  //
> -		  Status = gBS->CloseProtocol (
> -		                  Controller,
> -		                  &gEfiDevicePathProtocolGuid,
> -		                  pThis->DriverBindingHandle,
> -		                  Controller
> -		                  );
> -
> -		  if (EFI_ERROR(Status)){
> -          DEBUG ((EFI_D_ERROR, "driver stop: gBS->CloseProtocol:EfiDevicePathProtocol error. Status %r\n", Status));
> -		  }
> -
> -		  Status = gBS->CloseProtocol (
> -		                  Controller,
> -		                  &gEfiUsbIoProtocolGuid,
> -		                  pThis->DriverBindingHandle,
> -		                  Controller
> -		                  );
> -
> -		  if (EFI_ERROR(Status)){
> -          DEBUG ((EFI_D_ERROR, "driver stop: gBS->CloseProtocol:EfiUsbIoProtocol error. Status %r\n", Status));
> -		  }
> -      return EFI_SUCCESS;
> -		}
> -		AllChildrenStopped = TRUE;
> -
> -		for (Index = 0; Index < NumberOfChildren; Index++) {
> -
> -				Status = gBS->OpenProtocol (
> -				                ChildHandleBuffer[Index],
> -				                &gEfiSimpleNetworkProtocolGuid,
> -				                (VOID **) &SimpleNetwork,
> -				                pThis->DriverBindingHandle,
> -				                Controller,
> -				                EFI_OPEN_PROTOCOL_GET_PROTOCOL
> -				                );
> -
> -				if (EFI_ERROR (Status)) {
> -          AllChildrenStopped = FALSE;
> -          DEBUG ((EFI_D_ERROR, "Fail to stop No.%d multi-lun child handle when opening SimpleNetwork\n", (UINT32)Index));
> -          continue;
> -        }
> -
> -        pNicDevice = DEV_FROM_SIMPLE_NETWORK ( SimpleNetwork );
> -
> -        gBS->CloseProtocol (
> -				                    Controller,
> -				                    &gEfiUsbIoProtocolGuid,
> -				                    pThis->DriverBindingHandle,
> -				                    ChildHandleBuffer[Index]
> -				                    );
> -
> -				Status = gBS->UninstallMultipleProtocolInterfaces (
> -				                  ChildHandleBuffer[Index],
> -				                  &gEfiCallerIdGuid,
> -                          pNicDevice,
> -                          &gEfiSimpleNetworkProtocolGuid,
> -                          &pNicDevice->SimpleNetwork,
> -						              &gEfiDevicePathProtocolGuid,
> -						              pNicDevice->MyDevPath,
> -                          NULL
> -                          );
> -
> -        if (EFI_ERROR (Status)) {
> -            Status = gBS->OpenProtocol (
> -                  Controller,
> -                  &gEfiUsbIoProtocolGuid,
> -                  (VOID **) &pNicDevice->pUsbIo,
> -                  pThis->DriverBindingHandle,
> -                  ChildHandleBuffer[Index],
> -                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
> -                  );
> -        }
> -        else {
> -            int i;
> -            RX_PKT * pCurr = pNicDevice->QueueHead;
> -            RX_PKT * pFree;
> -
> -            for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
> -                 if ( NULL != pCurr ) {
> -                    pFree = pCurr;
> -                    pCurr = pCurr->pNext;
> -                    gBS->FreePool (pFree);
> -                 }
> -            }
> -
> -            if ( NULL != pNicDevice->pRxTest)
> -						    gBS->FreePool (pNicDevice->pRxTest);
> -
> -					 if ( NULL != pNicDevice->pTxTest)
> -						    gBS->FreePool (pNicDevice->pTxTest);
> -
> -           if ( NULL != pNicDevice->MyDevPath)
> -					       gBS->FreePool (pNicDevice->MyDevPath);
> -
> -				    if ( NULL != pNicDevice)
> -                  gBS->FreePool (pNicDevice);
> -        }
> -    }
> -
> -        if (!AllChildrenStopped) {
> -                return EFI_DEVICE_ERROR;
> -        }
> -        return EFI_SUCCESS;
> -}
> -
> -
> -/**
> -  Driver binding protocol declaration
> -**/
> -EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
> -  DriverSupported,
> -  DriverStart,
> -  DriverStop,
> -  0xa,
> -  NULL,
> -  NULL
> -};
> -
> -
> -/**
> -  Ax88772 driver unload routine.
> -
> -  @param [in] ImageHandle       Handle for the image.
> -
> -  @retval EFI_SUCCESS           Image may be unloaded
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -DriverUnload (
> -  IN EFI_HANDLE ImageHandle
> -  )
> -{
> -  UINTN BufferSize;
> -  UINTN Index;
> -  UINTN Max;
> -  EFI_HANDLE * pHandle;
> -  EFI_STATUS Status;
> -
> -  //
> -  //  Determine which devices are using this driver
> -  //
> -  BufferSize = 0;
> -  pHandle = NULL;
> -  Status = gBS->LocateHandle (
> -                  ByProtocol,
> -                  &gEfiCallerIdGuid,
> -                  NULL,
> -                  &BufferSize,
> -                  NULL );
> -  if ( EFI_BUFFER_TOO_SMALL == Status ) {
> -    for ( ; ; ) {
> -      //
> -      //  One or more block IO devices are present
> -      //
> -      Status = gBS->AllocatePool (
> -                      EfiRuntimeServicesData,
> -                      BufferSize,
> -                      (VOID **) &pHandle
> -                      );
> -      if ( EFI_ERROR ( Status )) {
> -        DEBUG ((EFI_D_ERROR, "Insufficient memory, failed handle buffer allocation\r\n"));
> -        break;
> -      }
> -
> -      //
> -      //  Locate the block IO devices
> -      //
> -      Status = gBS->LocateHandle (
> -                      ByProtocol,
> -                      &gEfiCallerIdGuid,
> -                      NULL,
> -                      &BufferSize,
> -                      pHandle );
> -      if ( EFI_ERROR ( Status )) {
> -        //
> -        //  Error getting handles
> -        //
> -        break;
> -      }
> -
> -      //
> -      //  Remove any use of the driver
> -      //
> -      Max = BufferSize / sizeof ( pHandle[ 0 ]);
> -      for ( Index = 0; Max > Index; Index++ ) {
> -        Status = DriverStop ( &gDriverBinding,
> -                              pHandle[ Index ],
> -                              0,
> -                              NULL );
> -        if ( EFI_ERROR ( Status )) {
> -          DEBUG ((EFI_D_ERROR, "WARNING - Failed to shutdown the driver on handle %08x\r\n", pHandle[ Index ]));
> -          break;
> -        }
> -      }
> -      break;
> -    }
> -  }
> -  else {
> -    if ( EFI_NOT_FOUND == Status ) {
> -      //
> -      //  No devices were found
> -      //
> -      Status = EFI_SUCCESS;
> -    }
> -  }
> -
> -  //
> -  //  Free the handle array
> -  //
> -  if ( NULL != pHandle ) {
> -    gBS->FreePool ( pHandle );
> -  }
> -
> -  //
> -  //  Remove the protocols installed by the EntryPoint routine.
> -  //
> -  if ( !EFI_ERROR ( Status )) {
> -    gBS->UninstallMultipleProtocolInterfaces (
> -            ImageHandle,
> -            &gEfiDriverBindingProtocolGuid,
> -            &gDriverBinding,
> -            &gEfiComponentNameProtocolGuid,
> -            &gComponentName,
> -            &gEfiComponentName2ProtocolGuid,
> -            &gComponentName2,
> -            NULL
> -            );
> -
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -            "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
> -            ImageHandle ));
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -              "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
> -              ImageHandle ));
> -    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_INFO,
> -              "Removed:   gEfiDriverBindingProtocolGuid from 0x%08x\r\n",
> -              ImageHandle ));
> -
> -  }
> -
> -  return Status;
> -}
> -
> -
> -/**
> -Ax88772 driver entry point.
> -
> -@param [in] ImageHandle       Handle for the image.
> -@param [in] pSystemTable      Address of the system table.
> -
> -@retval EFI_SUCCESS           Image successfully loaded.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -EntryPoint (
> -  IN EFI_HANDLE ImageHandle,
> -  IN EFI_SYSTEM_TABLE * pSystemTable
> -  )
> -{
> -  EFI_STATUS    Status;
> -
> -  //
> -  //  Add the driver to the list of drivers
> -  //
> -  Status = EfiLibInstallDriverBindingComponentName2 (
> -             ImageHandle,
> -             pSystemTable,
> -             &gDriverBinding,
> -             ImageHandle,
> -             &gComponentName,
> -             &gComponentName2
> -             );
> -  if ( !EFI_ERROR ( Status )) {
> -    DEBUG ((EFI_D_INFO, "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",
> -              ImageHandle));
> -    DEBUG ((EFI_D_INFO, "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",
> -              ImageHandle));
> -    DEBUG ((EFI_D_INFO,"Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",
> -              ImageHandle ));
> -
> -  }
> -  return Status;
> -}
> diff --git a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
> b/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
> deleted file mode 100644
> index 76babedb2001..000000000000
> --- a/Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
> +++ /dev/null
> @@ -1,1657 +0,0 @@
> -/** @file
> -  Provides the Simple Network functions.
> -
> -  Copyright (c) 2011 - 2016, Intel Corporation. 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] pSimpleNetwork    Simple network mode pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -ReceiveFilterUpdate (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  NIC_DEVICE * pNicDevice;
> -  EFI_STATUS Status;
> -  UINT32 Index;
> -
> -  //
> -  // Set the MAC address
> -  //
> -  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -  pMode = pSimpleNetwork->Mode;
> -
> -  //
> -  // Clear the multicast hash table
> -  //
> -  Ax88772MulticastClear ( pNicDevice );
> -
> -  //
> -  // Load the multicast hash table
> -  //
> -  if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) {
> -      for ( Index = 0; Index < pMode->MCastFilterCount; Index++ ) {
> -        //
> -        // Enable the next multicast address
> -        //
> -        Ax88772MulticastSet ( pNicDevice,
> -                              &pMode->MCastFilter[ Index ].Addr[0]);
> -      }
> -  }
> -
> -  Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting );
> -
> -  return Status;
> -}
> -
> -
> -/**
> -  This function updates the SNP driver status.
> -
> -  This function gets the current interrupt and recycled transmit
> -  buffer status from the network interface.  The interrupt status
> -  and the media status are returned as a bit mask in InterruptStatus.
> -  If InterruptStatus is NULL, the interrupt status will not be read.
> -  Upon successful return of the media status, the MediaPresent field
> -  of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change
> -  of media status.  If TxBuf is not NULL, a recycled transmit buffer
> -  address will be retrived.  If a recycled transmit buffer address
> -  is returned in TxBuf, then the buffer has been successfully
> -  transmitted, and the status for that buffer is cleared.
> -
> -  This function calls ::Ax88772Rx to update the media status and
> -  queue any receive packets.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] pInterruptStatus  A pointer to the bit mask of the current active interrupts.
> -                                If this is NULL, the interrupt status will not be read from
> -                                the device.  If this is not NULL, the interrupt status will
> -                                be read from teh device.  When the interrupt status is read,
> -                                it will also be cleared.  Clearing the transmit interrupt
> -                                does not empty the recycled transmit buffer array.
> -  @param [out] ppTxBuf          Recycled transmit buffer address.  The network interface will
> -                                not transmit if its internal recycled transmit buffer array is
> -                                full.  Reading the transmit buffer does not clear the transmit
> -                                interrupt.  If this is NULL, then the transmit buffer status
> -                                will not be read.  If there are not transmit buffers to recycle
> -                                and TxBuf is not NULL, *TxBuf will be set to NULL.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_GetStatus (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  OUT UINT32 * pInterruptStatus,
> -  OUT VOID ** ppTxBuf
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  NIC_DEVICE * pNicDevice;
> -  EFI_STATUS Status;
> -  BOOLEAN bFullDuplex;
> -  BOOLEAN bLinkUp;
> -  BOOLEAN bSpeed100;
> -  EFI_TPL TplPrevious;
> -
> -  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    // Return the transmit buffer
> -    //
> -
> -    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -    if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) {
> -     		 *ppTxBuf = pNicDevice->pTxBuffer;
> -     		 pNicDevice->pTxBuffer = NULL;
> -   	}
> -
> -    //
> -    // Determine if interface is running
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> -
> -      if ( pNicDevice->LinkIdleCnt > MAX_LINKIDLE_THRESHOLD) {
> -
> -          bLinkUp = pNicDevice->bLinkUp;
> -          bSpeed100 = pNicDevice->b100Mbps;
> -          bFullDuplex = pNicDevice->bFullDuplex;
> -          Status = Ax88772NegotiateLinkComplete ( pNicDevice,
> -                                            &pNicDevice->PollCount,
> -                                            &pNicDevice->bComplete,
> -                                            &pNicDevice->bLinkUp,
> -                                            &pNicDevice->b100Mbps,
> -                                            &pNicDevice->bFullDuplex );
> -
> -          //
> -          // Determine if the autonegotiation is complete
> -          //
> -          if ( pNicDevice->bComplete ) {
> -              if ( pNicDevice->bLinkUp ) {
> -                  if (( bSpeed100 && ( !pNicDevice->b100Mbps ))
> -                      || (( !bSpeed100 ) && pNicDevice->b100Mbps )
> -                      || ( bFullDuplex && ( !pNicDevice->bFullDuplex ))
> -                      || (( !bFullDuplex ) && pNicDevice->bFullDuplex )) {
> -                          pNicDevice->PollCount = 0;
> -                          DEBUG (( EFI_D_INFO , "Reset to establish proper link setup: %d Mbps, %a duplex\r\n",
> -                                    pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));
> -                          Status = SN_Reset ( &pNicDevice->SimpleNetwork, FALSE );
> -                  }
> -                  if (( !bLinkUp ) && pNicDevice->bLinkUp ) {
> -                      //
> -                      // Display the autonegotiation status
> -                      //
> -                      DEBUG (( EFI_D_INFO , "Link: Up, %d Mbps, %a duplex\r\n",
> -                                pNicDevice->b100Mbps ? 100 : 10, pNicDevice->bFullDuplex ? "Full" : "Half"));
> -
> -                  }
> -                  pNicDevice->LinkIdleCnt = 0;
> -            }
> -        }
> -        //
> -        //  Update the link status
> -        //
> -        if ( bLinkUp && ( !pNicDevice->bLinkUp )) {
> -            DEBUG (( EFI_D_INFO , "Link: Down\r\n"));
> -        }
> -      }
> -
> -      pMode->MediaPresent = pNicDevice->bLinkUp;
> -      //
> -      // Return the interrupt status
> -      //
> -      if ( NULL != pInterruptStatus ) {
> -        *pInterruptStatus = 0;
> -      }
> -      Status = EFI_SUCCESS;
> -    }
> -    else {
> -      if ( EfiSimpleNetworkStarted == pMode->State ) {
> -        Status = EFI_DEVICE_ERROR;
> -      }
> -      else {
> -        Status = EFI_NOT_STARTED;
> -      }
> -    }
> -
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -  gBS->RestoreTPL(TplPrevious) ;
> -
> -  return Status;
> -}
> -
> -
> -/**
> -  Resets the network adapter and allocates the transmit and receive buffers
> -  required by the network interface; optionally, also requests allocation of
> -  additional transmit and receive buffers.  This routine must be called before
> -  any other routine in the Simple Network protocol is called.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
> -  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and receive buffers
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Initialize (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN UINTN ExtraRxBufferSize,
> -  IN UINTN ExtraTxBufferSize
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_STATUS Status;
> -  UINT32  TmpState;
> -   EFI_TPL TplPrevious;
> -
> -   TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    // Determine if the interface is already started
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkStarted == pMode->State ) {
> -      if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) {
> -        //
> -        // Start the adapter
> -        //
> -        TmpState = pMode->State;
> -        pMode->State = EfiSimpleNetworkInitialized;
> -        Status = SN_Reset ( pSimpleNetwork, FALSE );
> -        if ( EFI_ERROR ( Status )) {
> -          //
> -          // Update the network state
> -          //
> -          pMode->State = TmpState;
> -          DEBUG (( EFI_D_ERROR , "SN_reset failed\n"));
> -        }
> -      }
> -      else {
> -        DEBUG (( EFI_D_ERROR , "Increase ExtraRxBufferSize = %d ExtraTxBufferSize=%d\n",
> -              ExtraRxBufferSize, ExtraTxBufferSize));
> -        Status = EFI_UNSUPPORTED;
> -      }
> -    }
> -    else {
> -      Status = EFI_NOT_STARTED;
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -  gBS->RestoreTPL (TplPrevious);
> -
> -  return Status;
> -}
> -
> -
> -/**
> -  This function converts a multicast IP address to a multicast HW MAC address
> -  for all packet transactions.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bIPv6             Set to TRUE if the multicast IP address is IPv6 [RFC2460].
> -                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
> -  @param [in] pIP               The multicast IP address that is to be converted to a
> -                                multicast HW MAC address.
> -  @param [in] pMAC              The multicast HW MAC address that is to be generated from IP.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_MCastIPtoMAC (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bIPv6,
> -  IN EFI_IP_ADDRESS * pIP,
> -  OUT EFI_MAC_ADDRESS * pMAC
> -  )
> -{
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -
> -  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> -  //
> -  // Get pointer to SNP driver instance for *this.
> -  //
> -  if (pSimpleNetwork == NULL) {
> -    gBS->RestoreTPL(TplPrevious);
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  if (pIP == NULL || pMAC == NULL) {
> -    gBS->RestoreTPL(TplPrevious);
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  if (bIPv6){
> -    Status = EFI_UNSUPPORTED;
> -  }
> -  else {
> -      //
> -      // check if the ip given is a mcast IP
> -      //
> -      if ((pIP->v4.Addr[0] & 0xF0) != 0xE0) {
> -        gBS->RestoreTPL(TplPrevious);
> -        return EFI_INVALID_PARAMETER;
> -      }
> -      else {
> -        if (pSimpleNetwork->Mode->State == EfiSimpleNetworkInitialized)
> -        {
> -          pMAC->Addr[0] = 0x01;
> -          pMAC->Addr[1] = 0x00;
> -          pMAC->Addr[2] = 0x5e;
> -          pMAC->Addr[3] = (UINT8) (pIP->v4.Addr[1] & 0x7f);
> -          pMAC->Addr[4] = (UINT8) pIP->v4.Addr[2];
> -          pMAC->Addr[5] = (UINT8) pIP->v4.Addr[3];
> -          Status = EFI_SUCCESS;
> -        }
> -        else if (pSimpleNetwork->Mode->State == EfiSimpleNetworkStarted) {
> -          Status = EFI_DEVICE_ERROR;
> -        }
> -        else {
> -          Status = EFI_NOT_STARTED;
> -        }
> -        gBS->RestoreTPL(TplPrevious);
> -      }
> -  }
> -  return Status;
> -}
> -
> -
> -/**
> -  This function performs read and write operations on the NVRAM device
> -  attached to a network interface.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] ReadWrite         TRUE for read operations, FALSE for write operations.
> -  @param [in] Offset            Byte offset in the NVRAM device at which to start the
> -                                read or write operation.  This must be a multiple of
> -                                NvRamAccessSize and less than NvRamSize.
> -  @param [in] BufferSize        The number of bytes to read or write from the NVRAM device.
> -                                This must also be a multiple of NvramAccessSize.
> -  @param [in, out] pBuffer      A pointer to the data buffer.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_NvData (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN ReadWrite,
> -  IN UINTN Offset,
> -  IN UINTN BufferSize,
> -  IN OUT VOID * pBuffer
> -  )
> -{
> -  EFI_STATUS Status;
> -  //
> -  // This is not currently supported
> -  //
> -  Status = EFI_UNSUPPORTED;
> -  return Status;
> -}
> -
> -VOID
> -FillPkt2Queue (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN UINTN BufLength)
> -{
> -
> -  UINT16 * pLength;
> -  UINT16 * pLengthBar;
> -  UINT8* pData;
> -  UINT32 offset;
> -  NIC_DEVICE * pNicDevice;
> -
> -  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork);
> -  for ( offset = 0; offset < BufLength; ){
> -      pLength = (UINT16*) (pNicDevice->pBulkInBuff + offset);
> -      pLengthBar = (UINT16*) (pNicDevice->pBulkInBuff + offset +2);
> -
> -      *pLength &= 0x7ff;
> -      *pLengthBar &= 0x7ff;
> -      *pLengthBar |= 0xf800;
> -
> -      if ((*pLength ^ *pLengthBar ) != 0xFFFF) {
> -          DEBUG (( EFI_D_ERROR , "Pkt length error. BufLength = %d\n", BufLength));
> -          return;
> -      }
> -
> -      if (TRUE == pNicDevice->pNextFill->f_Used) {
> -        return;
> -      }
> -      else {
> -          pData = pNicDevice->pBulkInBuff + offset + 4;
> -          pNicDevice->pNextFill->f_Used = TRUE;
> -          pNicDevice->pNextFill->Length = *pLength;
> -          CopyMem (&pNicDevice->pNextFill->Data[0], pData, *pLength);
> -
> -          pNicDevice->pNextFill = pNicDevice->pNextFill->pNext;
> -          offset += ((*pLength + HW_HDR_LENGTH - 1) &~3) + 1;
> -          pNicDevice->PktCntInQueue++;
> -      }
> -
> -  }
> -}
> -
> -EFI_STATUS
> -EFIAPI
> -SN_Receive (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  OUT UINTN                      * pHeaderSize,
> -  OUT UINTN                      * pBufferSize,
> -  OUT VOID                       * pBuffer,
> -  OUT EFI_MAC_ADDRESS            * pSrcAddr,
> -  OUT EFI_MAC_ADDRESS            * pDestAddr,
> -  OUT UINT16                     * pProtocol
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  NIC_DEVICE * pNicDevice;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -  UINT16 Type;
> -  EFI_USB_IO_PROTOCOL *pUsbIo;
> -  UINTN LengthInBytes;
> -  UINT32 TransferStatus;
> -  RX_PKT * pFirstFill;
> -  TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
> -
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) &&
> -    ( NULL != pSimpleNetwork->Mode ) &&
> -    (NULL != pBufferSize) &&
> -    (NULL != pBuffer)) {
> -    //
> -    // The interface must be running
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> -      //
> -      // Update the link status
> -      //
> -      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -      pNicDevice->LinkIdleCnt++;
> -      pMode->MediaPresent = pNicDevice->bLinkUp;
> -
> -      if ( pMode->MediaPresent && pNicDevice->bComplete) {
> -
> -
> -        if (pNicDevice->PktCntInQueue != 0 ) {
> -            DEBUG (( EFI_D_INFO, "pNicDevice->PktCntInQueue = %d\n",
> -                pNicDevice->PktCntInQueue));
> -        }
> -
> -        LengthInBytes = MAX_BULKIN_SIZE;
> -        if (pNicDevice->PktCntInQueue == 0 ){
> -            //
> -            // Attempt to do bulk in
> -            //
> -            SetMem (&pNicDevice->pBulkInBuff[0], 4, 0);
> -            pUsbIo = pNicDevice->pUsbIo;
> -            Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
> -                                       USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
> -                                       &pNicDevice->pBulkInBuff[0],
> -                                       &LengthInBytes,
> -                                       BULKIN_TIMEOUT,
> -                                       &TransferStatus );
> -
> -            if (LengthInBytes != 0 && !EFI_ERROR(Status) && !EFI_ERROR(TransferStatus) ){
> -                FillPkt2Queue(pSimpleNetwork, LengthInBytes);
> -            }
> -        }
> -
> -        pFirstFill = pNicDevice->pFirstFill;
> -
> -        if (TRUE == pFirstFill->f_Used) {
> -            ETHERNET_HEADER * pHeader;
> -            pNicDevice->LinkIdleCnt = 0;
> -            CopyMem (pBuffer,  &pFirstFill->Data[0], pFirstFill->Length);
> -            pHeader = (ETHERNET_HEADER *) &pFirstFill->Data[0];
> -
> -            DEBUG (( EFI_D_INFO, "RX: %02x-%02x-%02x-%02x-%02x-%02x "
> -                      "%02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x  %d bytes\r\n",
> -                      pFirstFill->Data[0],
> -                      pFirstFill->Data[1],
> -                      pFirstFill->Data[2],
> -                      pFirstFill->Data[3],
> -                      pFirstFill->Data[4],
> -                      pFirstFill->Data[5],
> -                      pFirstFill->Data[6],
> -                      pFirstFill->Data[7],
> -                      pFirstFill->Data[8],
> -                      pFirstFill->Data[9],
> -                      pFirstFill->Data[10],
> -                      pFirstFill->Data[11],
> -                      pFirstFill->Data[12],
> -                      pFirstFill->Data[13],
> -                      pFirstFill->Length));
> -
> -            if ( NULL != pHeaderSize ) {
> -              *pHeaderSize = sizeof ( *pHeader );
> -            }
> -            if ( NULL != pDestAddr ) {
> -               CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER );
> -            }
> -            if ( NULL != pSrcAddr ) {
> -             CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER );
> -            }
> -            if ( NULL != pProtocol ) {
> -              Type = pHeader->type;
> -              Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
> -              *pProtocol = Type;
> -            }
> -            Status = EFI_SUCCESS;
> -            if (*pBufferSize < pFirstFill->Length) {
> -                  DEBUG (( EFI_D_ERROR, "RX: Buffer was too small"));
> -                  Status = EFI_BUFFER_TOO_SMALL;
> -            }
> -            *pBufferSize =  pFirstFill->Length;
> -            pFirstFill->f_Used = FALSE;
> -            pNicDevice->pFirstFill = pFirstFill->pNext;
> -            pNicDevice->PktCntInQueue--;
> -        }
> -        else {
> -            pNicDevice->LinkIdleCnt++;
> -            Status = EFI_NOT_READY;
> -        }
> -      }
> -      else {
> -        //
> -        //  Link no up
> -        //
> -        pNicDevice->LinkIdleCnt++;
> -        Status = EFI_NOT_READY;
> -      }
> -
> -    }
> -    else {
> -      if (EfiSimpleNetworkStarted == pMode->State) {
> -        Status = EFI_DEVICE_ERROR;
> -      }
> -      else {
> -        Status = EFI_NOT_STARTED;
> -      }
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -  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 hardware
> -        a more liberal setting is selected.
> -
> -  If the same bits are set in the Enable and Disable parameters, then the bits
> -  in the Disable parameter takes precedence.
> -
> -  If the ResetMCastFilter parameter is TRUE, then the multicast address list
> -  filter is disabled (irregardless of what other multicast bits are set in
> -  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount field
> -  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
> -
> -  After enableing or disabling receive filter settings, software should
> -  verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
> -  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
> -
> -  Note: Some network drivers and/or devices will automatically promote
> -  receive filter settings if the requested setting can not be honored.
> -  For example, if a request for four multicast addresses is made and
> -  the underlying hardware only supports two multicast addresses the
> -  driver might set the promiscuous or promiscuous multicast receive filters
> -  instead.  The receiving software is responsible for discarding any extra
> -  packets that get through the hardware receive filters.
> -
> -  If ResetMCastFilter is TRUE, then the multicast receive filter list
> -  on the network interface will be reset to the default multicast receive
> -  filter list.  If ResetMCastFilter is FALSE, and this network interface
> -  allows the multicast receive filter list to be modified, then the
> -  MCastFilterCnt and MCastFilter are used to update the current multicast
> -  receive filter list.  The modified receive filter list settings can be
> -  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
> -
> -  This routine calls ::ReceiveFilterUpdate to update the receive
> -  state in the network adapter.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] Enable            A bit mask of receive filters to enable on the network interface.
> -  @param [in] Disable           A bit mask of receive filters to disable on the network interface.
> -                                For backward compatibility with EFI 1.1 platforms, the
> -                                EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set
> -                                when the ResetMCastFilter parameter is TRUE.
> -  @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive
> -                                filters on the network interface to their default values.
> -  @param [in] MCastFilterCnt    Number of multicast HW MAC address in the new MCastFilter list.
> -                                This value must be less than or equal to the MaxMCastFilterCnt
> -                                field of EFI_SIMPLE_NETWORK_MODE.  This field is optional if
> -                                ResetMCastFilter is TRUE.
> -  @param [in] pMCastFilter      A pointer to a list of new multicast receive filter HW MAC
> -                                addresses.  This list will replace any existing multicast
> -                                HW MAC address list.  This field is optional if ResetMCastFilter
> -                                is TRUE.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_ReceiveFilters (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN UINT32 Enable,
> -  IN UINT32 Disable,
> -/*
> -#define EFI_SIMPLE_NETWORK_RECEIVE_UNICAST               0x01
> -#define EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST             0x02
> -#define EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST             0x04
> -#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS           0x08
> -#define EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST 0x10
> -*/
> -  IN BOOLEAN bResetMCastFilter,
> -  IN UINTN MCastFilterCnt,
> -  IN EFI_MAC_ADDRESS * pMCastFilter
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_STATUS Status = EFI_SUCCESS;
> -  EFI_TPL TplPrevious;
> -
> -  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> -  pMode = pSimpleNetwork->Mode;
> -
> -  if (pSimpleNetwork == NULL) {
> -    gBS->RestoreTPL(TplPrevious);
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  switch (pMode->State) {
> -    case EfiSimpleNetworkInitialized:
> -      break;
> -    case EfiSimpleNetworkStopped:
> -      Status = EFI_NOT_STARTED;
> -      gBS->RestoreTPL(TplPrevious);
> -      return Status;
> -    default:
> -      Status = EFI_DEVICE_ERROR;
> -      gBS->RestoreTPL(TplPrevious);
> -      return Status;
> -  }
> -
> -  //
> -  // check if we are asked to enable or disable something that the UNDI
> -  // does not even support!
> -  //
> -  if (((Enable &~pMode->ReceiveFilterMask) != 0) ||
> -    ((Disable &~pMode->ReceiveFilterMask) != 0)) {
> -    Status = EFI_INVALID_PARAMETER;
> -    gBS->RestoreTPL(TplPrevious);
> -    return Status;
> -  }
> -
> -  if (bResetMCastFilter) {
> -    Disable |= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & pMode->ReceiveFilterMask);
> -      pMode->MCastFilterCount = 0;
> -      if ( (0 == (pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST))
> -            && Enable == 0 && Disable == 2) {
> -            gBS->RestoreTPL(TplPrevious);
> -            return EFI_SUCCESS;
> -      }
> -  }
> -  else {
> -    if (MCastFilterCnt != 0) {
> -      UINTN i;
> -      EFI_MAC_ADDRESS * pMulticastAddress;
> -      pMulticastAddress =  pMCastFilter;
> -
> -      if ((MCastFilterCnt > pMode->MaxMCastFilterCount) ||
> -          (pMCastFilter == NULL)) {
> -        Status = EFI_INVALID_PARAMETER;
> -        gBS->RestoreTPL(TplPrevious);
> -        return Status;
> -      }
> -
> -      for ( i = 0 ; i < MCastFilterCnt ; i++ ) {
> -          UINT8  tmp;
> -          tmp = pMulticastAddress->Addr[0];
> -          if ( (tmp & 0x01) != 0x01 ) {
> -            gBS->RestoreTPL(TplPrevious);
> -            return EFI_INVALID_PARAMETER;
> -          }
> -          pMulticastAddress++;
> -      }
> -
> -      pMode->MCastFilterCount = (UINT32)MCastFilterCnt;
> -      CopyMem (&pMode->MCastFilter[0],
> -                     pMCastFilter,
> -                     MCastFilterCnt * sizeof ( EFI_MAC_ADDRESS));
> -    }
> -  }
> -
> -  if (Enable == 0 && Disable == 0 && !bResetMCastFilter && MCastFilterCnt == 0) {
> -    Status = EFI_SUCCESS;
> -    gBS->RestoreTPL(TplPrevious);
> -    return Status;
> -  }
> -
> -  if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
> -    Status = EFI_INVALID_PARAMETER;
> -    gBS->RestoreTPL(TplPrevious);
> -    return Status;
> -  }
> -
> -  pMode->ReceiveFilterSetting |= Enable;
> -  pMode->ReceiveFilterSetting &= ~Disable;
> -  Status = ReceiveFilterUpdate (pSimpleNetwork);
> -
> -  if (EFI_DEVICE_ERROR == Status || EFI_INVALID_PARAMETER == Status)
> -      Status = 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] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bExtendedVerification  Indicates that the driver may perform a more
> -                                exhaustive verification operation of the device
> -                                during reset.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Reset (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bExtendedVerification
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  NIC_DEVICE * pNicDevice;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -
> -  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> -  //
> -  //  Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -		pMode = pSimpleNetwork->Mode;
> -		if ( EfiSimpleNetworkInitialized == pMode->State ) {
> -    	//
> -    	//  Update the device state
> -    	//
> -    	pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -    	pNicDevice->bComplete = FALSE;
> -    	pNicDevice->bLinkUp = FALSE;
> -    	pNicDevice->bHavePkt = FALSE;
> -    	pMode = pSimpleNetwork->Mode;
> -    	pMode->MediaPresent = FALSE;
> -
> -    	//
> -   		//  Reset the device
> -    	//
> -    	Status = Ax88772Reset ( pNicDevice );
> -    	if ( !EFI_ERROR ( Status )) {
> -     	 	//
> -     	 	//  Update the receive filters in the adapter
> -     	 	//
> -     	 	Status = ReceiveFilterUpdate ( pSimpleNetwork );
> -
> -     	 	//
> -     		 //  Try to get a connection to the network
> -     	 	//
> -     	 	if ( !EFI_ERROR ( Status )) {
> -        	//
> -        	//  Start the autonegotiation
> -       		//
> -        	Status = Ax88772NegotiateLinkStart ( pNicDevice );
> -     		}
> -   	 	}
> -   	}
> -   	else {
> -      if (EfiSimpleNetworkStarted == pMode->State) {
> -        Status = EFI_DEVICE_ERROR;
> -      }
> -      else {
> -        Status = EFI_NOT_STARTED;
> -      }
> -   	}
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -  gBS->RestoreTPL ( TplPrevious );
> -  return Status;
> -}
> -
> -/**
> -  Initialize the simple network protocol.
> -
> -  This routine calls ::Ax88772MacAddressGet to obtain the
> -  MAC address.
> -
> -  @param [in] pNicDevice       NIC_DEVICE_INSTANCE pointer
> -
> -  @retval EFI_SUCCESS     Setup was successful
> -
> -**/
> -EFI_STATUS
> -SN_Setup (
> -  IN NIC_DEVICE * pNicDevice
> -  )
> -{
> -
> -
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork;
> -  EFI_STATUS Status;
> -  RX_PKT * pCurr = NULL;
> -  RX_PKT * pPrev = NULL;
> -
> -	pSimpleNetwork = &pNicDevice->SimpleNetwork;
> -  pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
> -  pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start;
> -  pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop;
> -  pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize;
> -  pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset;
> -  pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown;
> -  pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters;
> -  pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress;
> -  pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics;
> -  pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC;
> -  pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData;
> -  pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus;
> -  pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit;
> -  pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive;
> -  pSimpleNetwork->WaitForPacket = NULL;
> -  pMode = &pNicDevice->SimpleNetworkData;
> -  pSimpleNetwork->Mode = pMode;
> -  pMode->State = EfiSimpleNetworkStopped;
> -  pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> -  pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
> -  pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> -  pMode->NvRamSize = 0;
> -  pMode->NvRamAccessSize = 0;
> -  pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> -                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> -                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> -                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> -                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> -  pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> -                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
> -  pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
> -  pMode->MCastFilterCount = 0;
> -  SetMem ( &pMode->BroadcastAddress,
> -           PXE_HWADDR_LEN_ETHER,
> -           0xff );
> -  pMode->IfType = EfiNetworkInterfaceUndi;
> -  pMode->MacAddressChangeable = TRUE;
> -  pMode->MultipleTxSupported = FALSE;
> -  pMode->MediaPresentSupported = TRUE;
> -  pMode->MediaPresent = FALSE;
> -  pNicDevice->LinkIdleCnt = 0;
> -  //
> -  //  Read the MAC address
> -  //
> -  pNicDevice->PhyId = PHY_ID_INTERNAL;
> -  pNicDevice->b100Mbps = TRUE;
> -  pNicDevice->bFullDuplex = TRUE;
> -
> -  Status = Ax88772MacAddressGet (
> -                pNicDevice,
> -                &pMode->PermanentAddress.Addr[0]);
> -
> -  if ( !EFI_ERROR ( Status )) {
> -    int i;
> -    //
> -    //  Use the hardware address as the current address
> -    //
> -
> -    CopyMem ( &pMode->CurrentAddress,
> -              &pMode->PermanentAddress,
> -              PXE_HWADDR_LEN_ETHER );
> -
> -    CopyMem ( &pNicDevice->MAC,
> -              &pMode->PermanentAddress,
> -              PXE_HWADDR_LEN_ETHER );
> -
> -    pNicDevice->PktCntInQueue = 0;
> -
> -    for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
> -        Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> -                                      sizeof (RX_PKT),
> -                                      (VOID **) &pCurr);
> -        if ( EFI_ERROR(Status)) {
> -            DEBUG (( EFI_D_ERROR, "Memory are not enough\n"));
> -            return Status;
> -        }
> -        pCurr->f_Used = FALSE;
> -
> -        if ( i ) {
> -            pPrev->pNext = pCurr;
> -        }
> -        else {
> -            pNicDevice->QueueHead = pCurr;
> -        }
> -
> -        if (MAX_QUEUE_SIZE - 1 == i) {
> -            pCurr->pNext = pNicDevice->QueueHead;
> -        }
> -
> -        pPrev = pCurr;
> -    }
> -
> -    pNicDevice->pNextFill = pNicDevice->QueueHead;
> -    pNicDevice->pFirstFill = pNicDevice->QueueHead;
> -
> -    Status = gBS->AllocatePool (EfiRuntimeServicesData,
> -                                MAX_BULKIN_SIZE,
> -                                (VOID **) &pNicDevice->pBulkInBuff);
> -
> -    if (EFI_ERROR(Status)) {
> -        DEBUG (( EFI_D_ERROR, "gBS->AllocatePool for pBulkInBuff error. Status = %r\n",
> -              Status));
> -        return Status;
> -    }
> -  }
> -  else {
> -    DEBUG (( EFI_D_ERROR, "Ax88772MacAddressGet error. Status = %r\n", Status));
> -		return Status;
> -  }
> -
> -  Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> -                                   sizeof ( RX_TX_PACKET ),
> -                                   (VOID **) &pNicDevice->pRxTest );
> -
> -  if (EFI_ERROR (Status)) {
> -    DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pRxTest error. Status = %r\n",
> -              Status));
> -	  return Status;
> -  }
> -
> -  Status = gBS->AllocatePool ( EfiRuntimeServicesData,
> -                                   sizeof ( RX_TX_PACKET ),
> -                                   (VOID **) &pNicDevice->pTxTest );
> -
> -  if (EFI_ERROR (Status)) {
> -    DEBUG (( EFI_D_ERROR, "gBS->AllocatePool:pNicDevice->pTxTest error. Status = %r\n",
> -              Status));
> -	  gBS->FreePool (pNicDevice->pRxTest);
> -  }
> -
> -  return Status;
> -}
> -
> -
> -/**
> -  This routine starts the network interface.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_ALREADY_STARTED   The network interface was already started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Start (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  )
> -{
> -  NIC_DEVICE * pNicDevice;
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -  int i = 0;
> -  RX_PKT * pCurr = NULL;
> -
> -  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> -  //
> -  // Verify the parameters
> -  //
> -  Status = EFI_INVALID_PARAMETER;
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkStopped == pMode->State ) {
> -      //
> -      // Initialize the mode structuref
> -      // NVRAM access is not supported
> -      //
> -      ZeroMem ( pMode, sizeof ( *pMode ));
> -
> -      pMode->State = EfiSimpleNetworkStarted;
> -      pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> -      pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER );
> -      pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> -      pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> -                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> -                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> -                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> -                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> -      pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
> -      pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
> -      pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -      Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]);
> -      CopyMem ( &pMode->CurrentAddress,
> -                &pMode->PermanentAddress,
> -                sizeof ( pMode->CurrentAddress ));
> -      SetMem(&pMode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
> -      pMode->IfType = EfiNetworkInterfaceUndi;
> -      pMode->MacAddressChangeable = TRUE;
> -      pMode->MultipleTxSupported = FALSE;
> -      pMode->MediaPresentSupported = TRUE;
> -      pMode->MediaPresent = FALSE;
> -      pNicDevice->PktCntInQueue = 0;
> -      pNicDevice->pNextFill = pNicDevice->QueueHead;
> -      pNicDevice->pFirstFill = pNicDevice->QueueHead;
> -      pCurr = pNicDevice->QueueHead;
> -
> -      for ( i = 0 ; i < MAX_QUEUE_SIZE ; i++) {
> -        pCurr->f_Used = FALSE;
> -        pCurr = pCurr->pNext;
> -      }
> -
> -    }
> -    else {
> -      Status = EFI_ALREADY_STARTED;
> -    }
> -  }
> -  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 FALSE
> -  then the current station address is changed to the address specified by
> -  pNew.
> -
> -  This routine calls ::Ax88772MacAddressSet to update the MAC address
> -  in the network adapter.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bReset            Flag used to reset the station address to the
> -                                network interface's permanent address.
> -  @param [in] pNew              New station address to be used for the network
> -                                interface.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_StationAddress (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bReset,
> -  IN EFI_MAC_ADDRESS * pNew
> -  )
> -{
> -  NIC_DEVICE * pNicDevice;
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -
> -  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork )
> -    && ( NULL != pSimpleNetwork->Mode )
> -    && (( bReset ) || ( ( !bReset) && ( NULL != pNew )))) {
> -    //
> -    // Verify that the adapter is already started
> -    //
> -    pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> -      //
> -      // Determine the adapter MAC address
> -      //
> -      if ( bReset ) {
> -        //
> -        // Use the permanent address
> -        //
> -        CopyMem ( &pMode->CurrentAddress,
> -                  &pMode->PermanentAddress,
> -                  sizeof ( pMode->CurrentAddress ));
> -      }
> -      else {
> -        //
> -        // Use the specified address
> -        //
> -        CopyMem ( &pMode->CurrentAddress,
> -                  pNew,
> -                  sizeof ( pMode->CurrentAddress ));
> -      }
> -
> -      //
> -      // Update the address on the adapter
> -      //
> -      Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]);
> -    }
> -    else {
> -      if (EfiSimpleNetworkStarted == pMode->State) {
> -        Status = EFI_DEVICE_ERROR;
> -      }
> -      else {
> -        Status = EFI_NOT_STARTED;
> -      }
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -  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] pSimpleNetwork    Protocol instance pointer
> -  @param [in] bReset            Set to TRUE to reset the statistics for the network interface.
> -  @param [in, out] pStatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
> -                                the size, in bytes, of the resulting table of statistics.
> -  @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
> -                                conains the statistics.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_BUFFER_TOO_SMALL  The pStatisticsTable is NULL or the buffer is too small.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -  typedef struct {
> -  UINT64 RxTotalFrames;
> -  UINT64 RxGoodFrames;
> -  UINT64 RxUndersizeFrames;
> -  UINT64 RxOversizeFrames;
> -  UINT64 RxDroppedFrames;
> -  UINT64 RxUnicastFrames;
> -  UINT64 RxBroadcastFrames;
> -  UINT64 RxMulticastFrames;
> -  UINT64 RxCrcErrorFrames;
> -  UINT64 RxTotalBytes;
> -  UINT64 TxTotalFrames;
> -  UINT64 TxGoodFrames;
> -  UINT64 TxUndersizeFrames;
> -  UINT64 TxOversizeFrames;
> -  UINT64 TxDroppedFrames;
> -  UINT64 TxUnicastFrames;
> -  UINT64 TxBroadcastFrames;
> -  UINT64 TxMulticastFrames;
> -  UINT64 TxCrcErrorFrames;
> -  UINT64 TxTotalBytes;
> -  UINT64 Collisions;
> -  UINT64 UnsupportedProtocol;
> -  } EFI_NETWORK_STATISTICS;
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Statistics (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN BOOLEAN bReset,
> -  IN OUT UINTN * pStatisticsSize,
> -  OUT EFI_NETWORK_STATISTICS * pStatisticsTable
> -  )
> -{
> -  EFI_STATUS Status;
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  //
> -  // Verify the prarameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    pMode = pSimpleNetwork->Mode;
> -    //
> -    // Determine if the interface is started
> -    //
> -    if (EfiSimpleNetworkInitialized == pMode->State){
> -      //
> -      // Determine if the StatisticsSize is big enough
> -      //
> -      if (sizeof (EFI_NETWORK_STATISTICS) <= *pStatisticsSize){
> -        if (bReset) {
> -          Status = EFI_SUCCESS;
> -        }
> -        else {
> -          Status = EFI_UNSUPPORTED;
> -        }
> -      }
> -      else {
> -        Status = EFI_BUFFER_TOO_SMALL;
> -      }
> -    }
> -    else{
> -      if (EfiSimpleNetworkStarted == pMode->State) {
> -        Status = EFI_DEVICE_ERROR;
> -      }
> -      else {
> -        Status = EFI_NOT_STARTED;
> -      }
> -    }
> -  }
> -  else {
> -  	Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  return Status;
> -}
> -
> -
> -/**
> -  This function stops a network interface.  This call is only valid
> -  if the network interface is in the started state.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Stop (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -
> -  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    // Determine if the interface is started
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkStarted == pMode->State ) {
> -        pMode->State = EfiSimpleNetworkStopped;
> -        Status = EFI_SUCCESS;
> -    }
> -    else {
> -        Status = EFI_NOT_STARTED;
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  gBS->RestoreTPL ( TplPrevious );
> -  return Status;
> -}
> -
> -
> -/**
> -  This function releases the memory buffers assigned in the Initialize() call.
> -  Pending transmits and receives are lost, and interrupts are cleared and disabled.
> -  After this call, only Initialize() and Stop() calls may be used.
> -
> -  @param [in] pSimpleNetwork    Protocol instance pointer
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Shutdown (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
> -  )
> -{
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  UINT32 RxFilter;
> -  EFI_STATUS Status;
> -  EFI_TPL TplPrevious;
> -
> -  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> -  //
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) {
> -    //
> -    // Determine if the interface is already started
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    if ( EfiSimpleNetworkInitialized == pMode->State ) {
> -      //
> -      // Stop the adapter
> -      //
> -      RxFilter = pMode->ReceiveFilterSetting;
> -      pMode->ReceiveFilterSetting = 0;
> -      Status = SN_Reset ( pSimpleNetwork, FALSE );
> -      pMode->ReceiveFilterSetting = RxFilter;
> -      if ( !EFI_ERROR ( Status )) {
> -
> -        //
> -        // Update the network state
> -        //
> -        pMode->State = EfiSimpleNetworkStarted;
> -      }
> -      else if ( EFI_DEVICE_ERROR == Status ) {
> -      	pMode->State = EfiSimpleNetworkStopped;
> -      }
> -    }
> -    else {
> -      Status = EFI_NOT_STARTED;
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -  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] pSimpleNetwork    Protocol instance pointer
> -  @param [in] HeaderSize        The size, in bytes, of the media header to be filled in by
> -                                the Transmit() function.  If HeaderSize is non-zero, then
> -                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
> -                                and DestAddr and Protocol parameters must not be NULL.
> -  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
> -                                data) to be transmitted through the network interface.
> -  @param [in] pBuffer           A pointer to the packet (media header followed by data) to
> -                                to be transmitted.  This parameter can not be NULL.  If
> -                                HeaderSize is zero, then the media header is Buffer must
> -                                already be filled in by the caller.  If HeaderSize is nonzero,
> -                                then the media header will be filled in by the Transmit()
> -                                function.
> -  @param [in] pSrcAddr          The source HW MAC address.  If HeaderSize is zero, then
> -                                this parameter is ignored.  If HeaderSize is nonzero and
> -                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> -                                is used for the source HW MAC address.
> -  @param [in] pDestAddr         The destination HW MAC address.  If HeaderSize is zero, then
> -                                this parameter is ignored.
> -  @param [in] pProtocol         The type of header to build.  If HeaderSize is zero, then
> -                                this parameter is ignored.
> -
> -  @retval EFI_SUCCESS           This operation was successful.
> -  @retval EFI_NOT_STARTED       The network interface was not started.
> -  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
> -  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> -  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
> -                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
> -  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -SN_Transmit (
> -  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork,
> -  IN UINTN HeaderSize,
> -  IN UINTN BufferSize,
> -  IN VOID * pBuffer,
> -  IN EFI_MAC_ADDRESS * pSrcAddr,
> -  IN EFI_MAC_ADDRESS * pDestAddr,
> -  IN UINT16 * pProtocol
> -  )
> -{
> -  ETHERNET_HEADER * pHeader;
> -  EFI_SIMPLE_NETWORK_MODE * pMode;
> -  NIC_DEVICE * pNicDevice;
> -  EFI_USB_IO_PROTOCOL * pUsbIo;
> -  EFI_STATUS Status;
> -  UINTN TransferLength;
> -  UINT32 TransferStatus;
> -  UINT16 Type;
> -  EFI_TPL TplPrevious;
> -
> -  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> -
> -  // Verify the parameters
> -  //
> -  if (( NULL != pSimpleNetwork ) &&
> -      ( NULL != pSimpleNetwork->Mode ) &&
> -      ( NULL != pBuffer) &&
> -      ( (HeaderSize == 0) || ( (NULL != pDestAddr) && (NULL != pProtocol) ))) {
> -    //
> -    // The interface must be running
> -    //
> -    pMode = pSimpleNetwork->Mode;
> -    //
> -    // Verify parameter of HeaderSize
> -    //
> -    if ((HeaderSize == 0) || (HeaderSize == pMode->MediaHeaderSize)){
> -      //
> -      // Determine if BufferSize is big enough
> -      //
> -      if (BufferSize >= pMode->MediaHeaderSize){
> -        if ( EfiSimpleNetworkInitialized == pMode->State ) {
> -          //
> -          // Update the link status
> -          //
> -          pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
> -          pMode->MediaPresent = pNicDevice->bLinkUp;
> -
> -          //
> -          //  Release the synchronization with Ax88772Timer
> -          //
> -          if ( pMode->MediaPresent && pNicDevice->bComplete) {
> -            //
> -            //  Copy the packet into the USB buffer
> -            //
> -
> -            CopyMem ( &pNicDevice->pTxTest->Data[0], pBuffer, BufferSize );
> -            pNicDevice->pTxTest->Length = (UINT16) BufferSize;
> -
> -            //
> -            //  Transmit the packet
> -            //
> -            pHeader = (ETHERNET_HEADER *) &pNicDevice->pTxTest->Data[0];
> -            if ( 0 != HeaderSize ) {
> -              if ( NULL != pDestAddr ) {
> -                CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER );
> -              }
> -              if ( NULL != pSrcAddr ) {
> -                CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER );
> -              }
> -              else {
> -                CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER );
> -              }
> -              if ( NULL != pProtocol ) {
> -                Type = *pProtocol;
> -              }
> -              else {
> -                Type = pNicDevice->pTxTest->Length;
> -              }
> -              Type = (UINT16)(( Type >> 8 ) | ( Type << 8 ));
> -              pHeader->type = Type;
> -            }
> -            if ( pNicDevice->pTxTest->Length < MIN_ETHERNET_PKT_SIZE ) {
> -              pNicDevice->pTxTest->Length = MIN_ETHERNET_PKT_SIZE;
> -              ZeroMem ( &pNicDevice->pTxTest->Data[ BufferSize ],
> -                        pNicDevice->pTxTest->Length - BufferSize );
> -            }
> -
> -            DEBUG ((EFI_D_INFO, "TX: %02x-%02x-%02x-%02x-%02x-%02x  %02x-%02x-%02x-%02x-%02x-%02x"
> -                      "  %02x-%02x  %d bytes\r\n",
> -                      pNicDevice->pTxTest->Data[0],
> -                      pNicDevice->pTxTest->Data[1],
> -                      pNicDevice->pTxTest->Data[2],
> -                      pNicDevice->pTxTest->Data[3],
> -                      pNicDevice->pTxTest->Data[4],
> -                      pNicDevice->pTxTest->Data[5],
> -                      pNicDevice->pTxTest->Data[6],
> -                      pNicDevice->pTxTest->Data[7],
> -                      pNicDevice->pTxTest->Data[8],
> -                      pNicDevice->pTxTest->Data[9],
> -                      pNicDevice->pTxTest->Data[10],
> -                      pNicDevice->pTxTest->Data[11],
> -                      pNicDevice->pTxTest->Data[12],
> -                      pNicDevice->pTxTest->Data[13],
> -                      pNicDevice->pTxTest->Length ));
> -
> -            pNicDevice->pTxTest->LengthBar = ~(pNicDevice->pTxTest->Length);
> -            TransferLength = sizeof ( pNicDevice->pTxTest->Length )
> -                           + sizeof ( pNicDevice->pTxTest->LengthBar )
> -                           + pNicDevice->pTxTest->Length;
> -
> -            if (TransferLength % 512 == 0 || TransferLength % 1024 == 0)
> -                TransferLength +=4;
> -
> -            //
> -            //  Work around USB bus driver bug where a timeout set by receive
> -            //  succeeds but the timeout expires immediately after, causing the
> -            //  transmit operation to timeout.
> -            //
> -            pUsbIo = pNicDevice->pUsbIo;
> -            Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
> -                                               BULK_OUT_ENDPOINT,
> -                                               &pNicDevice->pTxTest->Length,
> -                                               &TransferLength,
> -                                               0xfffffffe,
> -                                               &TransferStatus );
> -            if ( !EFI_ERROR ( Status )) {
> -              Status = TransferStatus;
> -            }
> -
> -            if ( !EFI_ERROR ( Status )) {
> -              pNicDevice->pTxBuffer = pBuffer;
> -            }
> -            else {
> -              if ((TransferLength != (UINTN)( pNicDevice->pTxTest->Length + 4 )) &&
> -                   (TransferLength != (UINTN)(( pNicDevice->pTxTest->Length + 4 ) + 4))) {
> -                DEBUG ((EFI_D_INFO, "TransferLength didn't match Packet Length\n"));
> -              }
> -              //
> -              //  Reset the controller to fix the error
> -              //
> -              if ( EFI_DEVICE_ERROR == Status ) {
> -                SN_Reset ( pSimpleNetwork, FALSE );
> -              }
> -              Status = EFI_NOT_READY;
> -            }
> -          }
> -          else {
> -            //
> -            // No packets available.
> -            //
> -            Status = EFI_NOT_READY;
> -          }
> -
> -        }
> -        else {
> -          if (EfiSimpleNetworkStarted == pMode->State) {
> -            Status = EFI_DEVICE_ERROR;
> -          }
> -          else {
> -            Status = EFI_NOT_STARTED ;
> -          }
> -        }
> -      }
> -      else {
> -        Status = EFI_BUFFER_TOO_SMALL;
> -      }
> -    }
> -    else {
> -      Status = EFI_INVALID_PARAMETER;
> -    }
> -  }
> -  else {
> -    Status = EFI_INVALID_PARAMETER;
> -  }
> -
> -  gBS->RestoreTPL (TplPrevious);
> -
> -  return Status;
> -}
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [edk2-platform][PATCH v3 1/6] Drivers/ASIX: Create ASIX package
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 1/6] Drivers/ASIX: Create ASIX package Samer El-Haj-Mahmoud
@ 2020-06-09  0:37   ` Ni, Ray
  0 siblings, 0 replies; 14+ messages in thread
From: Ni, Ray @ 2020-06-09  0:37 UTC (permalink / raw)
  To: Samer El-Haj-Mahmoud, devel@edk2.groups.io
  Cc: Leif Lindholm, Ard Biesheuvel, Kinney, Michael D

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>
> Sent: Monday, June 8, 2020 9:38 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Leif Lindholm <leif@nuviainc.com>; Ard Biesheuvel <ard.biesheuvel@arm.com>; Kinney,
> Michael D <michael.d.kinney@intel.com>
> Subject: [edk2-platform][PATCH v3 1/6] Drivers/ASIX: Create ASIX package
> 
> Create a new ASIX package for build verification of ASIX USB drivers.
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> 
> Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
> ---
>  Drivers/ASIX/Asix.dec | 30 +++++++++
>  Drivers/ASIX/Asix.dsc | 67 ++++++++++++++++++++
>  2 files changed, 97 insertions(+)
> 
> diff --git a/Drivers/ASIX/Asix.dec b/Drivers/ASIX/Asix.dec
> new file mode 100644
> index 000000000000..5639f2096751
> --- /dev/null
> +++ b/Drivers/ASIX/Asix.dec
> @@ -0,0 +1,30 @@
> +## @file
> +# Package for ASIX drivers build validation file for All Architectures.
> +#
> +# Copyright (c) 2020, ARM Limited. All rights reserved.
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +
> +[Defines]
> +  DEC_SPECIFICATION              = 0x00010005
> +  PACKAGE_NAME                   = Asix
> +  PACKAGE_GUID                   = 687fc389-78e4-4a28-90c1-3b22c949da80
> +  PACKAGE_VERSION                = 0.1
> +
> +[Includes]
> +  Include
> +
> +[LibraryClasses]
> +
> +[Guids]
> +  gAsixTokenSpaceGuid = {0x7a7a1758, 0x5234, 0x4b3f, {0x8a, 0x5c, 0x1c, 0x35, 0x6d, 0x2d, 0xbd, 0x37}}
> +
> +
> +[PcdsFeatureFlag]
> +
> +[PcdsFixedAtBuild, PcdsPatchableInModule]
> +
> +
> diff --git a/Drivers/ASIX/Asix.dsc b/Drivers/ASIX/Asix.dsc
> new file mode 100644
> index 000000000000..d65857bb1cd4
> --- /dev/null
> +++ b/Drivers/ASIX/Asix.dsc
> @@ -0,0 +1,67 @@
> +## @file
> +# Package for ASIX drivers build validation file for All Architectures.
> +#
> +# Copyright (c) 2020, ARM Limited. All rights reserved.
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +################################################################################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +################################################################################
> +[Defines]
> +  PLATFORM_NAME                  = Asix
> +  PLATFORM_GUID                  = 11c6ff4c-5931-464b-8a2f-1716d57fb134
> +  PLATFORM_VERSION               = 0.1
> +  DSC_SPECIFICATION              = 0x00010005
> +  OUTPUT_DIRECTORY               = Build/$(PLATFORM_NAME)
> +  SUPPORTED_ARCHITECTURES        = IA32|X64|EBC|ARM|AARCH64
> +  BUILD_TARGETS                  = DEBUG|RELEASE
> +
> +################################################################################
> +#
> +# Library Class section - list of all Library Classes needed by this Platform.
> +#
> +################################################################################
> +[LibraryClasses]
> +  DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
> +  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
> +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> +  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
> +  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
> +  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
> +  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
> +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> +  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
> +  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
> +
> +[LibraryClasses.AARCH64, LibraryClasses.ARM]
> +  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
> +
> +[LibraryClasses.ARM]
> +  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
> +
> +################################################################################
> +#
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform
> +#
> +################################################################################
> +[PcdsFeatureFlag]
> +
> +[PcdsFixedAtBuild]
> +
> +################################################################################
> +#
> +# Components Section - list of all EDK II Modules needed by this Platform
> +#
> +################################################################################
> +[Components]
> +
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [edk2-platform][PATCH v3 3/6] Drivers/ASIX: Add ASIX Ax88772c driver
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 3/6] Drivers/ASIX: Add ASIX Ax88772c driver Samer El-Haj-Mahmoud
@ 2020-06-09  0:37   ` Ni, Ray
  0 siblings, 0 replies; 14+ messages in thread
From: Ni, Ray @ 2020-06-09  0:37 UTC (permalink / raw)
  To: Samer El-Haj-Mahmoud, devel@edk2.groups.io
  Cc: Leif Lindholm, Ard Biesheuvel, Kinney, Michael D

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>
> Sent: Monday, June 8, 2020 9:38 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Leif Lindholm <leif@nuviainc.com>; Ard Biesheuvel <ard.biesheuvel@arm.com>; Kinney,
> Michael D <michael.d.kinney@intel.com>
> Subject: [edk2-platform][PATCH v3 3/6] Drivers/ASIX: Add ASIX Ax88772c driver
> 
> 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=driverdetail&PItemID=136
> 
> 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
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> 
> Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
> ---
>  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(+)
> 
> 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.<BR>
> +# Copyright (c) 2020, ARM Limited. All rights reserved.
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010018
> +  BASE_NAME                      = Ax88772c
> +  FILE_GUID                      = B15239D6-6A01-4808-A0F7-B7F20F073555
> +  MODULE_TYPE                    = UEFI_DRIVER
> +  VERSION_STRING                 = 1.0
> +
> +  ENTRY_POINT                    = 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 <Uefi.h>
> +
> +#include <Guid/EventGroup.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/NetLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/LoadedImage.h>
> +#include <Protocol/NetworkInterfaceIdentifier.h>
> +#include <Protocol/SimpleNetwork.h>
> +#include <Protocol/UsbIo.h>
> +
> +#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) != 0)  ///<  Return TRUE/FALSE for IN direction
> +#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7) == 0)  ///<  Return TRUE/FALSE for OUT
> direction
> +#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_BULK)      ///<  Return
> TRUE/FALSE for BULK type
> +#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 | BIT1)) == 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 messages
> +#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast messages
> +#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast messages
> +#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 values
> +#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 bytes 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 packet 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 the 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 >= 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 = 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 <= 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')  ///<  Signature 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 AX88772 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 address hash table
> +#define RXC_AP            0x0020  ///<  Accept physical address from Multicast 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=100, 0=10 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=Auto select, 0=Manual select
> +
> +//
> +//  Software Reset register
> +//
> +
> +#define SRR_RR            0x01    ///<  Clear receive frame length error
> +#define SRR_RT            0x02    ///<  Clear transmit frame length error
> +#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 register, Value: New value
> +#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value: 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 table
> +#define CMD_MULTICAST_HASH_WRITE  0x16  ///<  Write the multicast hash table, Data: New 8 byte value
> +#define CMD_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status register, Data: Register value
> +#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status register, 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 advertisement register
> +#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter ability register
> +#define PHY_ANER                        6       ///<  Autonegotiation expansion register
> +
> +//  BMCR - Register 0
> +
> +#define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears after reset
> +#define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
> +#define BMCR_100MBPS                    0x2000  ///<  100 Mbits/Sec
> +#define BMCR_10MBPS                     0       ///<  10 Mbits/Sec
> +#define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable autonegotiation
> +#define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
> +#define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
> +#define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart autonegotiation
> +#define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
> +#define BMCR_HALF_DUPLEX                0       ///<  Half duplex operation
> +#define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test enabled
> +
> +//  BSMR - Register 1
> +
> +#define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
> +#define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full duplex
> +#define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half duplex
> +#define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
> +#define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half duplex
> +#define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with preamble suppressed
> +#define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation complete
> +#define BMSR_RF                         0x0010  ///<  1 = Remote fault
> +#define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform autonegotiation
> +#define BMSR_LINKST                     0x0004  ///<  1 = Link up
> +#define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition detected
> +#define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended register capable
> +
> +//  ANAR and ANLPAR Registers 4, 5
> +
> +#define AN_NP                           0x8000  ///<  1 = Next page available
> +#define AN_ACK                          0x4000  ///<  1 = Link partner acknowledged
> +#define AN_RF                           0x2000  ///<  1 = Remote fault indicated by link partner
> +#define AN_FCS                          0x0400  ///<  1 = Flow control ability
> +#define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
> +#define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
> +#define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
> +#define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
> +#define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
> +#define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/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 identification
> +
> +  //
> +  //  USB data
> +  //
> +  EFI_HANDLE                Controller;        ///<  Controller handle
> +  EFI_USB_IO_PROTOCOL       *UsbIo;            ///<  USB driver interface
> +
> +  //
> +  //  Simple network protocol data
> +  //
> +  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;     ///<  Driver's network stack interface
> +  EFI_SIMPLE_NETWORK_MODE     SimpleNetworkData; ///<  Data for simple network
> +
> +  //
> +  // Ethernet controller data
> +  //
> +  BOOLEAN                   Initialized;       ///<  Controller initialized
> +  UINT16                    PhyId;             ///<  PHY ID
> +
> +  //
> +  //  Link state
> +  //
> +  BOOLEAN                   LinkSpeed100Mbps;   ///<  Current link speed, FALSE = 10 Mbps
> +  BOOLEAN                   Complete;           ///<  Current state of auto-negotiation
> +  BOOLEAN                   FullDuplex;         ///<  Current duplex
> +  BOOLEAN                   LinkUp;             ///<  Current link state
> +  UINTN                     PollCount;          ///<  Number of times the 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, DEV_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 perform a more
> +                                exhaustive verification operation of the device
> +                                during reset.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 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 network 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 FALSE
> +  then the current station address is changed to the address specified by
> +  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 network
> +                                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 network 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 the network interface.
> +  @param [in, out] StatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
> +                                the size, in bytes, of the resulting table of statistics.
> +  @param [out] StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
> +                                conains the statistics.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_BUFFER_TOO_SMALL  The StatisticsTable is NULL or the buffer 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 network 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 network 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 network 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 must not be NULL.
> +  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
> +                                data) to be transmitted through the network interface.
> +  @param [in] Buffer           A pointer to the packet (media header followed by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [in] SrcAddr          The source HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [in] DestAddr         The destination HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [in] Protocol         The type of header to build.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
> +  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 the MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772MacAddressGet (
> +  IN NIC_DEVICE *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 was polled
> +  @param [out] Complete      Address of boolean to receive complate status.
> +  @param [out] LinkUp        Address of boolean to receive link status, TRUE=up.
> +  @param [out] HiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
> +  @param [out] FullDuplex    Address of boolean to receive link duplex, TRUE=full.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772NegotiateLinkComplete (
> +  IN     NIC_DEVICE *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 register 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 register 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 packet
> +  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 = 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 name protocol declaration
> +extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<  Component name 2 protocol declaration
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] Language         A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 3066 or ISO 639-2 language code format.
> +  @param [out] 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 specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
> +  IN  CHAR8                       *Language,
> +  OUT CHAR16                      **DriverName
> +  );
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified by
> +  Language, then a pointer to the controller name is returned in ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> +  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] ControllerHandle  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +  @param [in] ChildHandle       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +  @param [in] Language         A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 3066 or ISO 639-2 language code format.
> +  @param [out] 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 driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> +                                EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL *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 implementation
> +  only supports the integrated PHY since no other test cases were available.
> +
> +  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 = -1;
> +  End = &MacAddress[PXE_HWADDR_LEN_ETHER];
> +  while (End > MacAddress) {
> +    Data = *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 = 0; 8 > BitNumber; BitNumber++) {
> +      Carry = ((Crc >> 31) & 1) ^ (Data & 1);
> +      Crc <<= 1;
> +      if (Carry != 0) {
> +        Crc ^= 0x04c11db7;
> +      }
> +      Data >>= 1;
> +    }
> +  }
> +
> +  //
> +  //  Return the CRC value
> +  //
> +  return (UINT32) Crc;
> +}
> +
> +/**
> +  Get the MAC address
> +
> +  This routine calls ::Ax88772UsbCommand to request the MAC
> +  address from the network adapter.
> +
> +  @param [in] NicDevice       Pointer to the NIC_DEVICE structure
> +  @param [out] MacAddress      Address of a six byte buffer to receive the MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772MacAddressGet (
> +  IN  NIC_DEVICE *NicDevice,
> +  OUT UINT8      *MacAddress
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS Status;
> +
> +  //
> +  //  Set the register address.
> +  //
> +  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                       | USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_MAC_ADDRESS_READ;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
> +
> +  //
> +  //  Read the PHY register
> +  //
> +  Status = Ax88772UsbCommand (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 = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_MAC_ADDRESS_WRITE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = PXE_HWADDR_LEN_ETHER;
> +
> +  //
> +  //  Read the PHY register
> +  //
> +  Status = Ax88772UsbCommand (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 = 0;
> +  //
> +  // Clear the multicast hash table
> +  //
> +  for (Index = 0 ; Index < 8 ; Index ++)
> +    NicDevice->MulticastHash[Index] = 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 = Ax88772Crc (MacAddress) >> 26;
> +
> +  //
> +  //  Set the bit corresponding to the destination address
> +  //
> +  NicDevice->MulticastHash [Crc >> 3] |= (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 = 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 = BMCR_AUTONEGOTIATION_ENABLE
> +            | BMCR_RESTART_AUTONEGOTIATION;
> +    if (NicDevice->LinkSpeed100Mbps) {
> +      Control |= BMCR_100MBPS;
> +    }
> +    if (NicDevice->FullDuplex) {
> +      Control |= BMCR_FULL_DUPLEX;
> +    }
> +    Status = 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 was polled
> +  @param [out] Complete       Address of boolean to receive complate status.
> +  @param [out] LinkUp         Address of boolean to receive link status, TRUE=up.
> +  @param [out] HiSpeed        Address of boolean to receive link speed, TRUE=100Mbps.
> +  @param [out] FullDuplex     Address of boolean to receive link duplex, TRUE=full.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88772NegotiateLinkComplete (
> +  IN     NIC_DEVICE *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 = FALSE;
> +
> +  //
> +  //  Get the link status
> +  //
> +  Status = Ax88772PhyRead (NicDevice,
> +                            PHY_BMSR,
> +                            &PhyData);
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  *LinkUp = ((PhyData & BMSR_LINKST) != 0);
> +  if (0 == *LinkUp) {
> +  } else {
> +    *Complete = ((PhyData & 0x20) != 0);
> +    if (0 == *Complete) {
> +    } else {
> +      Status = Ax88772PhyRead (NicDevice,
> +                                PHY_ANLPAR,
> +                                &PhyData);
> +
> +      if (!EFI_ERROR (Status)) {
> +        //
> +        //  Autonegotiation is complete
> +        //  Determine the link speed.
> +        //
> +        *HiSpeed = ((PhyData & (AN_TX_FDX | AN_TX_HDX))!= 0);
> +         //
> +        //  Determine the link duplex.
> +        //
> +        Mask = (*HiSpeed) ? AN_TX_FDX : AN_10_FDX;
> +        *FullDuplex = (BOOLEAN)((PhyData & Mask) != 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 register 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 = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  //  Read the PHY register address.
> +  //
> +  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                       | USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_REG_READ;
> +  SetupMsg.Value = NicDevice->PhyId;
> +  SetupMsg.Index = RegisterAddress;
> +  SetupMsg.Length = sizeof(*PhyData);
> +  Status = Ax88772UsbCommand(NicDevice,
> +                             &SetupMsg,
> +                             PhyData);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  //  Release the PHY to the hardware
> +  //
> +    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand(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 register 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 = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_ACCESS_SOFTWARE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  //  Write the PHY register
> +  //
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_REG_WRITE;
> +  SetupMsg.Value = NicDevice->PhyId;
> +  SetupMsg.Index = RegisterAddress;
> +  SetupMsg.Length = sizeof (PhyData);
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               &PhyData);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  //  Release the PHY to the hardware
> +  //
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (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 = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_ACCESS_HARDWARE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                          | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_SELECT;
> +  SetupMsg.Value = SPHY_PSEL;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RESET;
> +  SetupMsg.Value = SRR_IPRL ;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RESET;
> +  SetupMsg.Value = SRR_IPPD | SRR_IPRL ;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  gBS->Stall (200000);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RESET;
> +  SetupMsg.Value =  SRR_IPRL  ;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  gBS->Stall (200000);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RESET;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_PHY_SELECT;
> +  SetupMsg.Value = SPHY_PSEL;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RESET;
> +  SetupMsg.Value =  SRR_IPRL | SRR_BZ | SRR_BZTYPE;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_RX_CONTROL_WRITE;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  if (!NicDevice->Flag772A) {
> +    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_RXQTC;
> +#if RXTHOU
> +    /*size cannot exceed 3K*/
> +    //SetupMsg.Value = 0x0;
> +    //SetupMsg.Index = 0x8001;
> +    /*size cannot exceed 16K*/
> +    SetupMsg.Value = 0x8300;
> +    SetupMsg.Index = 0x8500;
> +    /*size cannot exceed 32K*/
> +    //SetupMsg.Value = 0x8784;
> +    //SetupMsg.Index = 0x8A00;
> +    SetupMsg.Length = 0;
> +#else
> +    SetupMsg.Value = 0x8000;
> +    SetupMsg.Index = 0x8001;
> +#endif
> +    Status = 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 = EFI_SUCCESS;
> +
> +  //
> +  // Enable the receiver if something is to be received
> +  //
> +  if (RxFilter != 0) {
> +    //
> +    //  Enable the receiver
> +    //
> +    SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                         | USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_MEDIUM_STATUS_READ;
> +    SetupMsg.Value = 0;
> +    SetupMsg.Index = 0;
> +    SetupMsg.Length = sizeof (MediumStatus);
> +    Status = Ax88772UsbCommand (NicDevice,
> +                                 &SetupMsg,
> +                                 &MediumStatus);
> +    if (!EFI_ERROR (Status)) {
> +      if (0 == (MediumStatus & MS_RE)) {
> +        MediumStatus |= MS_RE | MS_ONE;
> +
> +        if (NicDevice->FullDuplex)
> +          MediumStatus |= MS_TFC | MS_RFC | MS_FD;
> +        else
> +          MediumStatus &= ~(MS_TFC | MS_RFC | MS_FD);
> +
> +        if (NicDevice->LinkSpeed100Mbps)
> +          MediumStatus |= MS_PS;
> +        else
> +          MediumStatus &= ~MS_PS;
> +
> +        SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                             | USB_TARGET_DEVICE;
> +        SetupMsg.Request = CMD_MEDIUM_STATUS_WRITE;
> +        SetupMsg.Value = MediumStatus;
> +        SetupMsg.Index = 0;
> +        SetupMsg.Length = 0;
> +        Status = Ax88772UsbCommand (NicDevice,
> +                                     &SetupMsg,
> +                                     NULL);
> +
> +        if (EFI_ERROR(Status))
> +              goto EXIT;
> +      }
> +    } else {
> +        goto EXIT;
> +    }
> +  }
> +  RxControl = RXC_SO;
> +  if (!NicDevice->Flag772A)
> +    RxControl |= RXC_RH1M;
> +
> +  //
> +  //  Enable multicast if requested
> +  //
> +  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
> +      RxControl |= RXC_AM;
> +      //
> +      //  Update the multicast hash table
> +      //
> +      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +      SetupMsg.Request = CMD_MULTICAST_HASH_WRITE;
> +      SetupMsg.Value = 0;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = sizeof (NicDevice ->MulticastHash);
> +      Status = Ax88772UsbCommand (NicDevice,
> +                                   &SetupMsg,
> +                                   &NicDevice->MulticastHash);
> +
> +      if (EFI_ERROR(Status))
> +              goto EXIT;
> +  }
> +
> +  //
> +  //  Enable all multicast if requested
> +  //
> +  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
> +      RxControl |= RXC_AMALL;
> +  }
> +
> +  //
> +  //  Enable broadcast if requested
> +  //
> +  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
> +      RxControl |= RXC_AB;
> +  }
> +
> +  //
> +  //  Enable promiscuous mode if requested
> +  //
> +  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
> +      RxControl |= RXC_PRO;
> +  }
> +
> +  //
> +  //  Update the receiver control
> +  //
> +  if (NicDevice->CurRxControl != RxControl) {
> +    SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                         | USB_TARGET_DEVICE;
> +    SetupMsg.Request = CMD_RX_CONTROL_WRITE;
> +#if RXTHOU
> +    if (NicDevice->Flag772A)
> +      RxControl |= 0x0300;
> +#endif
> +    if (NicDevice->Flag772A)
> +      RxControl &= ~(RXC_MFB);
> +    SetupMsg.Value = RxControl;
> +    SetupMsg.Index = 0;
> +    SetupMsg.Length = 0;
> +    Status = Ax88772UsbCommand (NicDevice,
> +                                 &SetupMsg,
> +                                 NULL);
> +    if (!EFI_ERROR (Status))
> +      NicDevice->CurRxControl = 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 = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +
> +  SetupMsg.Request = CMD_WRITE_GPIOS;
> +  SetupMsg.Value = 0x80;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0 ;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  if (EFI_SUCCESS == 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 = USB_ENDPOINT_DIR_IN
> +                       | USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = CMD_SROM_READ;
> +  SetupMsg.Value = (UINT16) Address;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = sizeof (*Data);
> +  Status = 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 = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +
> +  SetupMsg.Request = CMD_SROM_WRITE_EN;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0 ;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  if (EFI_SUCCESS == 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 = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +
> +  SetupMsg.Request = CMD_SROM_WRITE_DIS;
> +  SetupMsg.Value = 0;
> +  SetupMsg.Index = 0;
> +  SetupMsg.Length = 0;
> +  Status = Ax88772UsbCommand (NicDevice,
> +                      &SetupMsg,
> +                      NULL);
> +
> +  if (EFI_SUCCESS == 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 = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +
> +  SetupMsg.Request = CMD_SROM_WRITE;
> +  SetupMsg.Value = (UINT16) Address;
> +  SetupMsg.Index = (UINT16) (*Data);
> +  SetupMsg.Length = 0;
> +
> +  Status = 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 = EfiUsbNoData;
> +  if (Request->Length != 0) {
> +    Direction = ((Request->RequestType & USB_ENDPOINT_DIR_IN) != 0)
> +              ? EfiUsbDataIn : EfiUsbDataOut;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  UsbIo = NicDevice->UsbIo;
> +  Status = UsbIo->UsbControlTransfer (UsbIo,
> +                                        Request,
> +                                        Direction,
> +                                        USB_BUS_TIMEOUT,
> +                                        Buffer,
> +                                        Request->Length,
> +                                        &CmdStatus);
> +
> +  //
> +  // Determine the operation status
> +  //
> +  if (!EFI_ERROR (Status)) {
> +    Status = CmdStatus;
> +  } else {
> +    //
> +    // Only use status values associated with the Simple Network protocol
> +    //
> +    if (EFI_TIMEOUT == Status) {
> +      Status = EFI_DEVICE_ERROR;
> +    }
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  return Status;
> +}
> +
> +BOOLEAN
> +Ax88772GetLinkStatus (
> +  IN NIC_DEVICE *NicDevice
> +)
> +{
> +  UINT32              CmdStatus;
> +  EFI_USB_IO_PROTOCOL *UsbIo;
> +  UINT64              IntData = 0;
> +  UINTN               IntDataLeng = 8;
> +  EFI_STATUS          Status;
> +
> +  //
> +  // Issue the command
> +  //
> +  UsbIo = NicDevice->UsbIo;
> +  Status = UsbIo->UsbSyncInterruptTransfer(UsbIo,
> +                                        USB_ENDPOINT_DIR_IN | INTERRUPT_ENDPOINT,
> +                                        &IntData,
> +                                        &IntDataLeng,
> +                                        USB_BUS_TIMEOUT,
> +                                        &CmdStatus);
> +
> +  if (EFI_ERROR(Status) || EFI_ERROR(CmdStatus) || 0 == IntDataLeng) {
> +      return FALSE;
> +  }
> +  return (IntData & 0x800000)? FALSE : TRUE;
> +
> +}
> +
> +#if RXTHOU
> +EFI_STATUS
> +Ax88772BulkIn(
> +  IN NIC_DEVICE * NicDevice
> +)
> +{
> +  UINTN               Index;
> +  UINTN               LengthInBytes = 0;
> +  UINTN               TmpLen = AX88772_MAX_BULKIN_SIZE;
> +  UINTN               OrigTmpLen = 0;
> +  UINT16              TmpLen2;
> +  UINT16              TmpLenBar;
> +  UINT16              TmpTotalLen = 0;
> +  UINTN               TotalLen = LengthInBytes;
> +  EFI_STATUS          Status = EFI_DEVICE_ERROR;
> +  EFI_USB_IO_PROTOCOL *UsbIo;
> +  UINT32              TransferStatus = 0;
> +  UINT16              TmpPktCnt = 0;
> +  UINT16              *TmpHdr = (UINT16 *)NicDevice->BulkInbuf;
> +  USB_DEVICE_REQUEST  SetupMsg;
> +
> +  UsbIo = NicDevice->UsbIo;
> +  for (Index = 0 ; Index < (AX88772_MAX_BULKIN_SIZE / 512) && UsbIo != NULL; Index++) {
> +    VOID* TmpAddr = 0;
> +
> +    TmpPktCnt = 0;
> +    TmpAddr = (VOID*) &NicDevice->BulkInbuf[LengthInBytes];
> +    OrigTmpLen = TmpLen;
> +    Status = UsbIo->UsbBulkTransfer (UsbIo,
> +                          USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
> +                          TmpAddr,
> +                          &TmpLen,
> +                          BULKIN_TIMEOUT,
> +                          &TransferStatus);
> +
> +    if (OrigTmpLen == TmpLen) {
> +      Status = EFI_NOT_READY;
> +      goto no_pkt;
> +    }
> +
> +    if ((!EFI_ERROR (Status)) &&
> +        (!EFI_ERROR (TransferStatus)) &&
> +        TmpLen != 0) {
> +      LengthInBytes += TmpLen;
> +      if ((TmpLen % 512) != 0) {
> +        goto done;
> +      }
> +    } else if ((!EFI_ERROR (Status)) &&
> +               (!EFI_ERROR (TransferStatus)) &&
> +               (TmpLen == 0)) {
> +      Status = EFI_NOT_READY;
> +      goto done;
> +    } else if (EFI_TIMEOUT == Status && EFI_USB_ERR_TIMEOUT == TransferStatus) {
> +      SetupMsg.RequestType = USB_REQ_TYPE_STANDARD | 0x02;
> +      SetupMsg.Request = 0x01;
> +      SetupMsg.Value =  0;
> +      SetupMsg.Index = 0x82;
> +      SetupMsg.Length = 0;
> +      Status = Ax88772UsbCommand (NicDevice,
> +                                   &SetupMsg,
> +                                   NULL);
> +      Status = EFI_NOT_READY;
> +      goto done;
> +    } else {
> +      Status = EFI_DEVICE_ERROR;
> +      goto done;
> +    }
> +  }
> +done:
> +  if (LengthInBytes != 0) {
> +
> +    do {
> +      TmpLen2 = (*TmpHdr) & 0x7FF;
> +      TmpLenBar = *(TmpHdr + 1);
> +      TmpTotalLen = ((TmpLen + 4 + 1) & 0xfffe);
> +
> +      if ((TmpLen2 & 0x7FF) + (TmpLenBar & 0x7FF) == 0x7FF) {
> +        TmpPktCnt++;
> +      } else {
> +        if (TmpPktCnt != 0) {
> +          break;
> +        }
> +        Status = EFI_NOT_READY;
> +        goto no_pkt;
> +      }
> +      TmpHdr += (TmpTotalLen / 2);
> +      TotalLen -= TmpTotalLen;
> +    } while (TotalLen > 0);
> +
> +  if (LengthInBytes >= 1000 && TmpPktCnt != 0) {
> +    if ((NicDevice->RxBurst) == 1) {
> +      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +      SetupMsg.Request = CMD_RESET;
> +      SetupMsg.Value =  SRR_IPRL;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = 0;
> +      Ax88772UsbCommand (NicDevice,
> +                          &SetupMsg,
> +                          NULL);
> +    }
> +
> +    if (NicDevice->RxBurst < 2)
> +    NicDevice->RxBurst++;
> +
> +  } else {
> +    if (NicDevice->RxBurst >= 2) {
> +      SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                           | USB_TARGET_DEVICE;
> +      SetupMsg.Request = CMD_RESET;
> +      SetupMsg.Value =  SRR_IPRL| SRR_BZ | SRR_BZTYPE;
> +      SetupMsg.Index = 0;
> +      SetupMsg.Length = 0;
> +      Ax88772UsbCommand (NicDevice,
> +                          &SetupMsg,
> +                          NULL);
> +      }
> +      NicDevice->RxBurst = 0;
> +    }
> +  }
> +
> +  if (TmpPktCnt != 0) {
> +    NicDevice->PktCnt = TmpPktCnt;
> +    NicDevice->CurPktHdrOff = NicDevice->BulkInbuf;
> +    NicDevice->CurPktOff = NicDevice->BulkInbuf + 4;
> +    Status = EFI_SUCCESS;
> +  }
> +
> +no_pkt:
> +  return Status;
> +}
> +#else
> +EFI_STATUS
> +Ax88772BulkIn(
> +  IN NIC_DEVICE *NicDevice
> +)
> +{
> +  UINTN               Index;
> +  UINTN               LengthInBytes = 0;
> +  UINTN               TmpLen = AX88772_MAX_BULKIN_SIZE;
> +  UINTN               OrigTmpLen = 0;
> +  UINT16              TmpLen2;
> +  UINT16              TmpLenBar;
> +  UINT16              TmpTotalLen = 0;
> +  UINTN               CURBufSize = AX88772_MAX_BULKIN_SIZE;
> +  EFI_STATUS          Status = EFI_DEVICE_ERROR;
> +  EFI_USB_IO_PROTOCOL *UsbIo;
> +  UINT32              TransferStatus = 0;
> +  UINT16              TmpPktCnt = 0;
> +  UINT16              *TmpHdr = (UINT16 *)NicDevice->BulkInbuf;
> +
> +  UsbIo = NicDevice->UsbIo;
> +  for (Index = 0 ; Index < (AX88772_MAX_BULKIN_SIZE / 512) && UsbIo != NULL; Index++) {
> +    VOID *TmpAddr = 0;
> +
> +    TmpPktCnt = 0;
> +    TmpAddr = (VOID*) &NicDevice->BulkInbuf[LengthInBytes];
> +    OrigTmpLen = TmpLen;
> +    Status = UsbIo->UsbBulkTransfer (UsbIo,
> +                          USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
> +                          TmpAddr,
> +                          &TmpLen,
> +                          BULKIN_TIMEOUT,
> +                          &TransferStatus);
> +
> +    if (OrigTmpLen == TmpLen) {
> +      Status = EFI_NOT_READY;
> +      goto no_pkt;
> +    }
> +
> +    if ((!EFI_ERROR (Status)) &&
> +        (!EFI_ERROR (TransferStatus)) &&
> +        TmpLen != 0) {
> +
> +      LengthInBytes += TmpLen;
> +      CURBufSize = CURBufSize - TmpLen;
> +      TmpLen = CURBufSize;
> +      do {
> +        TmpLen2 = *TmpHdr;
> +        TmpLenBar = *(TmpHdr + 1);
> +        TmpTotalLen += ((TmpLen2 + 4 + 1) & 0xfffe);
> +
> +        if (((TmpLen2 ^ TmpLenBar) == 0xffff))  {
> +          if (TmpTotalLen == LengthInBytes) {
> +            TmpPktCnt++;
> +            Status = EFI_SUCCESS;
> +            goto done;
> +          } else if (TmpTotalLen > LengthInBytes) {
> +            break;
> +          }
> +        } else if (((TmpLen2 ^ TmpLenBar) != 0xffff)) {
> +          if (TmpPktCnt != 0) {
> +            Status = EFI_SUCCESS;
> +            goto done;
> +          }
> +          Status = EFI_NOT_READY;
> +          goto no_pkt;
> +        }
> +        TmpHdr += (TmpTotalLen / 2);
> +        TmpPktCnt++;
> +      } while (TmpTotalLen < LengthInBytes);
> +    } else if ((!EFI_ERROR (Status)) &&
> +               (!EFI_ERROR (TransferStatus)) &&
> +               (TmpLen == 0)) {
> +      if (TmpPktCnt != 0) {
> +        Status = EFI_SUCCESS;
> +        goto done;
> +      }
> +      Status = EFI_NOT_READY;
> +      goto no_pkt;
> +    } else if (EFI_TIMEOUT == Status && EFI_USB_ERR_TIMEOUT == TransferStatus) {
> +      if (TmpPktCnt != 0) {
> +        Status = EFI_SUCCESS;
> +        goto done;
> +      }
> +      Status = EFI_NOT_READY;
> +      goto no_pkt;
> +    } else {
> +      if (TmpPktCnt != 0) {
> +        Status = EFI_SUCCESS;
> +        goto done;
> +      }
> +      Status = EFI_DEVICE_ERROR;
> +      goto no_pkt;
> +    }
> +  }
> +done:
> +  NicDevice->PktCnt = TmpPktCnt;
> +  NicDevice->CurPktHdrOff = NicDevice->BulkInbuf;
> +  NicDevice->CurPktOff = 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  gComponentName = {
> +  GetDriverName,
> +  GetControllerName,
> +  "eng"
> +};
> +
> +/**
> +  EFI Component Name 2 Protocol declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
> +  "en"
> +};
> +
> +
> +/**
> +  Driver name table declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> +mDriverNameTable[] = {
> +  {"eng;en", L"ASIX AX88772B Ethernet Driver 2.8.0"},
> +  {NULL,  NULL}
> +};
> +
> +/**
> +  Controller name table declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> +mControllerNameTable[] = {
> +  {"eng;en", L"ASIX AX88772B USB Fast Ethernet Controller"},
> +  {NULL,  NULL}
> +};
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] Language         A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 3066 or ISO 639-2 language code format.
> +  @param [out] 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 specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
> +  IN  CHAR8                       *Language,
> +  OUT CHAR16                      **DriverName
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +
> +  Status = LookupUnicodeString2 (
> +             Language,
> +             This->SupportedLanguages,
> +             mDriverNameTable,
> +             DriverName,
> +             (BOOLEAN)(This == &gComponentName)
> +             );
> +
> +  return Status;
> +}
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified by
> +  Language, then a pointer to the controller name is returned in ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> +  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] ControllerHandle  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +  @param [in] ChildHandle       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +  @param [in] Language         A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 3066 or ISO 639-2 language code format.
> +  @param [out] 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 driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> +                                EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +
> +
> +
> +EFI_STATUS
> +EFIAPI
> +GetControllerName (
> +  IN          EFI_COMPONENT_NAME_PROTOCOL *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 != NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Check Controller's handle
> +  //
> +  Status = 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 != EFI_ALREADY_STARTED) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Status =  LookupUnicodeString2 (
> +           Language,
> +            This->SupportedLanguages,
> +           mControllerNameTable,
> +           ControllerName,
> +           (BOOLEAN)(This == &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 = 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 transport
> +    //  protocol handler.
> +    //
> +    Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &Device);
> +    if (EFI_ERROR(Status)) {
> +      Status = EFI_UNSUPPORTED;
> +    } else {
> +      //
> +      //  Validate the adapter
> +      //
> +      if (VENDOR_ID == Device.IdVendor) {
> +        if (PRODUCT_AX88772B_ID != Device.IdProduct) {
> +        } else if (PRODUCT_AX88772B_ASUS_ID == Device.IdProduct) {
> +        } else if (PRODUCT_AX88772A_ID == Device.IdProduct) {
> +        } else if (PRODUCT_ID == Device.IdProduct) {
> +        } else {
> +          Status = EFI_UNSUPPORTED;
> +        }
> +      } else if (VENDOR_AX88772B_LENOVO_ID == Device.IdVendor) {
> +        if (PRODUCT_AX88772B_LENOVO_ID != Device.IdProduct) {
> +          Status = EFI_UNSUPPORTED;
> +        }
> +      } else {
> +        Status = 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 protocols.
> +  Initialize PXE structures, create a copy of the Controller Device Path with the
> +  NIC's MAC address apEnded to it, install the NetworkInterfaceIdentifier 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 = NULL;
> +  MAC_ADDR_DEVICE_PATH      MacDeviceNode;
> +  EFI_USB_DEVICE_DESCRIPTOR Device;
> +
> +  //
> +  //  Allocate the device structure
> +  //
> +  LengthInBytes = sizeof (*NicDevice);
> +  Status = gBS->AllocatePool (
> +                  EfiBootServicesData,
> +                  LengthInBytes,
> +                  (VOID **) &NicDevice
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto ERR;
> +  }
> +
> +  //
> +  //  Set the structure signature
> +  //
> +  ZeroMem (NicDevice, LengthInBytes);
> +  NicDevice->Signature = DEV_SIGNATURE;
> +
> +  Status = gBS->OpenProtocol (
> +                    Controller,
> +                    &gEfiUsbIoProtocolGuid,
> +                    (VOID **) &NicDevice->UsbIo,
> +                    This->DriverBindingHandle,
> +                    Controller,
> +                    EFI_OPEN_PROTOCOL_BY_DRIVER
> +                    );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto ERR;
> +  }
> +
> +  NicDevice->Flag772A = FALSE;
> +  NicDevice->UsbIo->UsbGetDeviceDescriptor (NicDevice->UsbIo, &Device);
> +  if ((PRODUCT_AX88772A_ID == Device.IdProduct) ||
> +      (PRODUCT_ID == Device.IdProduct))
> +    NicDevice->Flag772A = TRUE;
> +  //
> +  //  Initialize the simple network protocol
> +  //
> +  Status = SN_Setup (NicDevice);
> +
> +  if (EFI_ERROR(Status)){
> +    gBS->CloseProtocol (
> +              Controller,
> +              &gEfiUsbIoProtocolGuid,
> +              This->DriverBindingHandle,
> +              Controller
> +              );
> +    goto ERR;
> +  }
> +
> +  //
> +  // Set Device Path
> +  //
> +  Status = 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 = MESSAGING_DEVICE_PATH;
> +  MacDeviceNode.Header.SubType = MSG_MAC_ADDR_DP;
> +
> +  SetDevicePathNodeLength (&MacDeviceNode.Header, sizeof (MAC_ADDR_DEVICE_PATH));
> +
> +  CopyMem (&MacDeviceNode.MacAddress,
> +           &NicDevice->SimpleNetworkData.CurrentAddress,
> +           PXE_HWADDR_LEN_ETHER);
> +
> +  MacDeviceNode.IfType = NicDevice->SimpleNetworkData.IfType;
> +
> +  NicDevice->MyDevPath = AppendDevicePathNode (
> +                                          ParentDevicePath,
> +                                          (EFI_DEVICE_PATH_PROTOCOL *) &MacDeviceNode
> +                                          );
> +
> +  NicDevice->Controller = NULL;
> +
> +  //
> +  //  Install both the simple network and device path protocols.
> +  //
> +  Status = 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 = 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 != NULL) {
> +    gBS->FreePool (NicDevice->BulkInbuf);
> +  }
> +
> +  if (NicDevice->TxTest != NULL) {
> +    gBS->FreePool (NicDevice->TxTest);
> +  }
> +
> +  if (NicDevice->MyDevPath != NULL) {
> +    gBS->FreePool (NicDevice->MyDevPath);
> +  }
> +
> +  if (NicDevice != 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 device.
> +
> +**/
> +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 = 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 == 0) {
> +    Status = 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 devicepath
> +      // and usbio protocol.
> +      //
> +      gBS->CloseProtocol (
> +                Controller,
> +                &gEfiDevicePathProtocolGuid,
> +                This->DriverBindingHandle,
> +                Controller
> +                );
> +      gBS->CloseProtocol (
> +                Controller,
> +                &gEfiUsbIoProtocolGuid,
> +                This->DriverBindingHandle,
> +                Controller
> +                );
> +      return EFI_SUCCESS;
> +    }
> +
> +    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +    Status = gBS->UninstallMultipleProtocolInterfaces (
> +                          Controller,
> +                          &gEfiCallerIdGuid,
> +                          NicDevice,
> +                          &gEfiSimpleNetworkProtocolGuid,
> +                          &NicDevice->SimpleNetwork,
> +                          &gEfiDevicePathProtocolGuid,
> +                          NicDevice->MyDevPath,
> +                          NULL
> +                          );
> +
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    //
> +    // Close the bus driver
> +    //
> +    Status = gBS->CloseProtocol (
> +                       Controller,
> +                       &gEfiDevicePathProtocolGuid,
> +                       This->DriverBindingHandle,
> +                       Controller
> +                       );
> +
> +    Status = gBS->CloseProtocol (
> +                       Controller,
> +                       &gEfiUsbIoProtocolGuid,
> +                       This->DriverBindingHandle,
> +                       Controller
> +                       );
> +
> +    return EFI_SUCCESS;
> +  }
> +
> +  AllChildrenStopped = TRUE;
> +
> +  for (Index = 0; Index < NumberOfChildren; Index++) {
> +    Status = gBS->OpenProtocol (
> +                      ChildHandleBuffer[Index],
> +                      &gEfiSimpleNetworkProtocolGuid,
> +                      (VOID **) &SimpleNetwork,
> +                      This->DriverBindingHandle,
> +                      Controller,
> +                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                      );
> +
> +    if (EFI_ERROR (Status)) {
> +      AllChildrenStopped = FALSE;
> +      continue;
> +    }
> +
> +    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +    gBS->CloseProtocol (
> +              Controller,
> +              &gEfiUsbIoProtocolGuid,
> +              This->DriverBindingHandle,
> +              ChildHandleBuffer[Index]
> +              );
> +
> +    Status = gBS->UninstallMultipleProtocolInterfaces (
> +                          ChildHandleBuffer[Index],
> +                          &gEfiCallerIdGuid,
> +                          NicDevice,
> +                          &gEfiSimpleNetworkProtocolGuid,
> +                          &NicDevice->SimpleNetwork,
> +                          &gEfiDevicePathProtocolGuid,
> +                          NicDevice->MyDevPath,
> +                          NULL
> +                          );
> +
> +    if (EFI_ERROR (Status)) {
> +      Status = gBS->OpenProtocol (
> +                        Controller,
> +                        &gEfiUsbIoProtocolGuid,
> +                        (VOID **) &NicDevice->UsbIo,
> +                        This->DriverBindingHandle,
> +                        ChildHandleBuffer[Index],
> +                        EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
> +                        );
> +    } else {
> +      if (NicDevice->BulkInbuf != NULL) {
> +        gBS->FreePool (NicDevice->BulkInbuf);
> +      }
> +
> +      if (NicDevice->TxTest != NULL) {
> +        gBS->FreePool (NicDevice->TxTest);
> +      }
> +
> +      if (NicDevice->MyDevPath != NULL) {
> +        gBS->FreePool (NicDevice->MyDevPath);
> +      }
> +
> +      if (NicDevice != NULL) {
> +        gBS->FreePool (NicDevice);
> +      }
> +    }
> +  }
> +
> +  if (!AllChildrenStopped) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Driver binding protocol declaration
> +**/
> +EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
> +  DriverSupported,
> +  DriverStart,
> +  DriverStop,
> +  0xa,
> +  NULL,
> +  NULL
> +};
> +
> +
> +/**
> +  Ax88772 driver unload routine.
> +
> +  @param [in] ImageHandle       Handle for the image.
> +
> +  @retval EFI_SUCCESS           Image may be unloaded
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverUnload (
> +  IN EFI_HANDLE ImageHandle
> +  )
> +{
> +  UINTN       BufferSize;
> +  UINTN       Index;
> +  UINTN       Max;
> +  EFI_HANDLE  *Handle;
> +  EFI_STATUS  Status;
> +
> +  //
> +  //  Determine which devices are using this driver
> +  //
> +  BufferSize = 0;
> +  Handle = NULL;
> +  Status = gBS->LocateHandle (
> +                  ByProtocol,
> +                  &gEfiCallerIdGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  NULL);
> +  if (EFI_BUFFER_TOO_SMALL == Status) {
> +    for (; ;) {
> +      //
> +      //  One or more block IO devices are present
> +      //
> +      Status = gBS->AllocatePool (
> +                      EfiBootServicesData,
> +                      BufferSize,
> +                      (VOID **) &Handle
> +                      );
> +      if (EFI_ERROR (Status)) {
> +        break;
> +      }
> +
> +      //
> +      //  Locate the block IO devices
> +      //
> +      Status = gBS->LocateHandle (
> +                      ByProtocol,
> +                      &gEfiCallerIdGuid,
> +                      NULL,
> +                      &BufferSize,
> +                      Handle);
> +      if (EFI_ERROR (Status)) {
> +        //
> +        //  Error getting handles
> +        //
> +
> +        break;
> +      }
> +
> +      //
> +      //  Remove any use of the driver
> +      //
> +      Max = BufferSize / sizeof (Handle[0]);
> +      for (Index = 0; Max > Index; Index++) {
> +        Status = DriverStop (&gDriverBinding,
> +                              Handle[Index],
> +                              0,
> +                              NULL);
> +        if (EFI_ERROR (Status)) {
> +          break;
> +        }
> +      }
> +      break;
> +    }
> +  } else {
> +    if (EFI_NOT_FOUND == Status) {
> +      //
> +      //  No devices were found
> +      //
> +      Status = EFI_SUCCESS;
> +    }
> +  }
> +
> +  //
> +  //  Free the handle array
> +  //
> +  if (Handle != 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 = gBS->HandleProtocol (
> +                  gImageHandle,
> +                  &gEfiLoadedImageProtocolGuid,
> +                  (VOID **)&LoadedImage
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +    LoadedImage->Unload = DriverUnload;
> +  }
> +
> +  //
> +  //  Add the driver to the list of drivers
> +  //
> +  Status = 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 network 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 = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +  Mode = SimpleNetwork->Mode;
> +  //
> +  // Clear the multicast hash table
> +  //
> +  Ax88772MulticastClear (NicDevice);
> +
> +  //
> +  // Load the multicast hash table
> +  //
> +  if ((Mode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
> +    for (Index = 0; Index < Mode->MCastFilterCount; Index++) {
> +      //
> +      // Enable the next multicast address
> +      //
> +      Ax88772MulticastSet (NicDevice,
> +                            &Mode->MCastFilter[Index].Addr[0]);
> +    }
> +  }
> +
> +    Status = 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 will not be read from
> +                                the device.  If this is not NULL, the interrupt status will
> +                                be read from teh device.  When the interrupt status is read,
> +                                it will also be cleared.  Clearing the transmit interrupt
> +                                does not empty the recycled transmit buffer array.
> +  @param [out] TxBuf          Recycled transmit buffer address.  The network interface will
> +                                not transmit if its internal recycled transmit buffer array is
> +                                full.  Reading the transmit buffer does not clear the transmit
> +                                interrupt.  If this is NULL, then the transmit buffer status
> +                                will not be read.  If there are not transmit buffers to recycle
> +                                and TxBuf is not NULL, *TxBuf will be set to NULL.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = NULL;
> +  EFI_STATUS              Status = EFI_SUCCESS;
> +  EFI_TPL                 TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // Return the transmit buffer
> +    //
> +    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +    if ((TxBuf != NULL) && (NicDevice->TxBuffer != NULL)) {
> +      *TxBuf = NicDevice->TxBuffer;
> +      NicDevice->TxBuffer = NULL;
> +    }
> +
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      if ((TxBuf == NULL) && (InterruptStatus == NULL)) {
> +        Status = EFI_INVALID_PARAMETER;
> +        goto EXIT;
> +      }
> +
> +#if REPORTLINK
> +#else
> +      if (!NicDevice->LinkUp || !NicDevice->Complete) {
> +#endif
> +        Status = Ax88772NegotiateLinkComplete (NicDevice,
> +                                                &NicDevice->PollCount,
> +                                                &NicDevice->Complete,
> +                                                &NicDevice->LinkUp,
> +                                                &NicDevice->LinkSpeed100Mbps,
> +                                                &NicDevice->FullDuplex);
> +
> +        if (EFI_ERROR(Status))
> +          goto EXIT;
> +#if REPORTLINK
> +        if (NicDevice->LinkUp && NicDevice->Complete) {
> +          Mode->MediaPresent = TRUE;
> +          Status = ReceiveFilterUpdate (SimpleNetwork);
> +        } else {
> +          Mode->MediaPresent = FALSE;
> +        }
> +#else
> +        if (NicDevice->LinkUp && NicDevice->Complete) {
> +          Mode->MediaPresent = TRUE;
> +          Mode->MediaPresentSupported = FALSE;
> +          Status = ReceiveFilterUpdate (SimpleNetwork);
> +        }
> +      }
> +#endif
> +    } else {
> +      if (EfiSimpleNetworkStarted == Mode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      } else {
> +        Status = EFI_NOT_STARTED ;
> +      }
> +    }
> +  } else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +  if (InterruptStatus != NULL) {
> +    *InterruptStatus = 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 write operations.
> +  @param [in] Offset            Byte offset in the NVRAM device at which to start the
> +                                read or write operation.  This must be a multiple of
> +                                NvRamAccessSize and less than NvRamSize.
> +  @param [in] BufferSize        The number of bytes to read or write from the NVRAM device.
> +                                This must also be a multiple of NvramAccessSize.
> +  @param [in, out] 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 network 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 = EFI_INVALID_PARAMETER;
> +  EFI_TPL                 TplPrevious;
> +  EFI_SIMPLE_NETWORK_MODE *Mode;
> +  NIC_DEVICE              *NicDevice;
> +  UINTN                   Index;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  if ((SimpleNetwork == NULL) || (SimpleNetwork->Mode == NULL)) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto  EXIT;
> +  }
> +
> +  NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +  Mode = SimpleNetwork->Mode;
> +
> +  if (EfiSimpleNetworkInitialized != Mode->State) {
> +    Status = EFI_NOT_STARTED;
> +    goto  EXIT;
> +  }
> +
> +  if (Offset != 0) {
> +    if (((Offset % Mode->NvRamAccessSize) != 0) ||
> +        (Offset >= Mode->NvRamSize)) {
> +      Status = EFI_INVALID_PARAMETER;
> +      goto  EXIT;
> +    }
> +  }
> +  //
> +  // Offset must be a multiple of NvRamAccessSize and less than NvRamSize.
> +  //
> +  if ((BufferSize % Mode->NvRamAccessSize) != 0) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto  EXIT;
> +  }
> +
> +  if (BufferSize + Offset > Mode->NvRamSize) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto  EXIT;
> +  }
> +
> +  if (Buffer == NULL) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto  EXIT;
> +  }
> +
> +  //
> +  // ReadWrite: TRUE FOR READ FALSE FOR WRITE
> +  //
> +  if (ReadWrite) {
> +    for (Index = 0; Index < BufferSize / 2; Index++) {
> +      Status = Ax88772SromRead (NicDevice,
> +                                 (UINT32)(Offset/2 + Index),
> +                                 (((UINT16*)Buffer) + Index));
> +    }
> +  } else {
> +    Status = Ax88772EnableSromWrite(NicDevice);
> +    if (EFI_ERROR(Status))
> +      goto EXIT;
> +
> +    for (Index = 0; Index < BufferSize / 2; Index++) {
> +      Status = Ax88772SromWrite (NicDevice,
> +                                  (UINT32)(Offset/2 + Index),
> +                                  (((UINT16*)Buffer) + Index));
> +    }
> +
> +    Status = Ax88772DisableSromWrite(NicDevice);
> +
> +    if (BufferSize == 272)
> +      Status = Ax88772ReloadSrom(NicDevice);
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +EXIT:
> +  gBS->RestoreTPL (TplPrevious);
> +  return Status;
> +}
> +
> +/**
> +  Resets the network adapter and allocates the transmit and receive buffers
> +  required by the network interface; optionally, also requests allocation of
> +  additional transmit and receive buffers.  This routine must be called before
> +  any other routine in the Simple Network protocol is called.
> +
> +  @param [in] SimpleNetwork    Protocol instance pointer
> +  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
> +  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and receive buffers
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // Determine if the interface is already started
> +    //
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkStarted == Mode->State) {
> +      if ((0 == ExtraRxBufferSize) && (0 == ExtraTxBufferSize)) {
> +        //
> +        // Start the adapter
> +        //
> +        TmpState = Mode->State;
> +        Mode->State = EfiSimpleNetworkInitialized;
> +        Status = SN_Reset (SimpleNetwork, FALSE);
> +        if (EFI_ERROR (Status)) {
> +          //
> +          // Update the network state
> +          //
> +          Mode->State = TmpState; // EfiSimpleNetworkInitialized;
> +        } else {
> +          Mode->MediaPresentSupported = TRUE;
> +          NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +          Mode->MediaPresent = Ax88772GetLinkStatus (NicDevice);
> +        }
> +      } else {
> +        Status = EFI_UNSUPPORTED;
> +      }
> +    } else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  } else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  gBS->RestoreTPL (TplPrevious);
> +  return Status;
> +}
> +
> +
> +/**
> +  This function converts a multicast IP address to a multicast HW MAC address
> +  for all packet transactions.
> +
> +  @param [in] SimpleNetwork    Protocol instance pointer
> +  @param [in] IPv6             Set to TRUE if the multicast IP address is IPv6 [RFC2460].
> +                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
> +  @param [in] IP               The multicast IP address that is to be converted to a
> +                                multicast HW MAC address.
> +  @param [in] MAC              The multicast HW MAC address that is to be generated from IP.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // The interface must be running
> +    //
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      if (IP == NULL || MAC == NULL) {
> +        Status = EFI_INVALID_PARAMETER;
> +        goto EXIT;
> +      }
> +      if (IPv6) {
> +        Status = EFI_UNSUPPORTED;
> +        goto EXIT;
> +      } else {
> +        //
> +        // check if the ip given is a mcast IP
> +        //
> +        if ((IP->v4.Addr[0] & 0xF0) != 0xE0) {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        } else {
> +          MAC->Addr[0] = 0x01;
> +          MAC->Addr[1] = 0x00;
> +          MAC->Addr[2] = 0x5e;
> +          MAC->Addr[3] = (UINT8) (IP->v4.Addr[1] & 0x7f);
> +          MAC->Addr[4] = (UINT8) IP->v4.Addr[2];
> +          MAC->Addr[5] = (UINT8) IP->v4.Addr[3];
> +          Status = EFI_SUCCESS;
> +        }
> +      }
> +    } else {
> +      if (EfiSimpleNetworkStarted == Mode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      } else {
> +        Status = EFI_NOT_STARTED ;
> +      }
> +    }
> +  } else {
> +    Status = 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 network
> +  interface.  If there are no packets on the receive queue, then EFI_NOT_READY
> +  will be returned.  If there is a packet on the receive queue, and the size
> +  of the packet is smaller than BufferSize, then the contents of the packet
> +  will be placed in Buffer, and BufferSize will be udpated with the actual
> +  size of the packet.  In addition, if SrcAddr, DestAddr, and Protocol are
> +  not NULL, then these values will be extracted from the media header and
> +  returned.  If BufferSize is smaller than the received packet, then the
> +  size of the receive packet will be placed in BufferSize and
> +  EFI_BUFFER_TOO_SMALL will be returned.
> +
> +  This routine calls ::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 to be filled in by
> +                                the Transmit() function.  If HeaderSize is non-zero, then
> +                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
> +                                and DestAddr and Protocol parameters must not be NULL.
> +  @param [out] BufferSize      The size, in bytes, of the entire packet (media header and
> +                                data) to be transmitted through the network interface.
> +  @param [out] Buffer          A pointer to the packet (media header followed by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [out] SrcAddr         The source HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [out] DestAddr        The destination HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [out] Protocol        The type of header to build.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         No packets have been received on the network interface.
> +  @retval EFI_BUFFER_TOO_SMALL  The packet is larger than BufferSize bytes.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = NULL;
> +  EFI_STATUS              Status;
> +  EFI_TPL                 TplPrevious;
> +  UINT16                  Type;
> +  UINT16                  CurrentPktLen;
> +
> +
> +  TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // The interface must be running
> +    //
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      if ((BufferSize == NULL) || (Buffer == NULL)) {
> +        Status = EFI_INVALID_PARAMETER;
> +        gBS->RestoreTPL (TplPrevious);
> +        return Status;
> +      }
> +
> +      //
> +      // Update the link status
> +      //
> +      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +      if (NicDevice->LinkUp && NicDevice->Complete) {
> +        if ((HeaderSize != NULL) && (*HeaderSize == 7720)) {
> +          NicDevice->Grub_f = TRUE;
> +        }
> +
> +        if ((NicDevice->Grub_f) && (*HeaderSize != 7720)) {
> +          gBS->RestoreTPL (TplPrevious);
> +          return EFI_NOT_READY;
> +        }
> +
> +        //
> +        //  Attempt to receive a packet
> +        //
> +        if (0 == NicDevice->PktCnt) {
> +          Status = Ax88772BulkIn(NicDevice);
> +          if (EFI_ERROR(Status)) {
> +            goto  no_pkt;
> +          }
> +        }
> +
> +        CurrentPktLen = *((UINT16*) (NicDevice->CurPktHdrOff));
> +        CurrentPktLen &=  0x7ff;
> +
> +        if ((60 <= CurrentPktLen) &&
> +            (CurrentPktLen - 14 <= MAX_ETHERNET_PKT_SIZE)) {
> +            if (*BufferSize < (UINTN)CurrentPktLen) {
> +              gBS->RestoreTPL (TplPrevious);
> +              return EFI_BUFFER_TOO_SMALL;
> +            }
> +
> +            *BufferSize = CurrentPktLen;
> +            CopyMem (Buffer, NicDevice->CurPktOff, CurrentPktLen);
> +            Header = (ETHERNET_HEADER *) NicDevice->CurPktOff;
> +
> +            if ((HeaderSize != NULL)  && (*HeaderSize != 7720)) {
> +              *HeaderSize = sizeof (*Header);
> +            }
> +            if (DestAddr != NULL) {
> +              CopyMem (DestAddr, &Header->DestAddr, PXE_HWADDR_LEN_ETHER);
> +            }
> +            if (SrcAddr != NULL) {
> +              CopyMem (SrcAddr, &Header->SrcAddr, PXE_HWADDR_LEN_ETHER);
> +            }
> +            if (Protocol != NULL) {
> +              Type = Header->Type;
> +              Type = (UINT16)((Type >> 8) | (Type << 8));
> +              *Protocol = Type;
> +            }
> +            NicDevice->PktCnt--;
> +            NicDevice->CurPktHdrOff += (CurrentPktLen + 4 + 1) & 0xfffe;
> +            NicDevice->CurPktOff = NicDevice->CurPktHdrOff + 4;
> +            Status = EFI_SUCCESS;
> +        } else {
> +          NicDevice->PktCnt = 0;
> +          Status = EFI_DEVICE_ERROR;
> +        }
> +      } else {
> +        //
> +        //  Link no up
> +        //
> +        Status = EFI_NOT_READY;
> +      }
> +    } else {
> +      if (EfiSimpleNetworkStarted == Mode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      } else {
> +        Status = EFI_NOT_STARTED;
> +      }
> +    }
> +  } else {
> +    Status = 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 hardware
> +        a more liberal setting is selected.
> +
> +  If the same bits are set in the Enable and Disable parameters, then the bits
> +  in the Disable parameter takes precedence.
> +
> +  If the ResetMCastFilter parameter is TRUE, then the multicast address list
> +  filter is disabled (irregardless of what other multicast bits are set in
> +  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount field
> +  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
> +
> +  After enableing or disabling receive filter settings, software should
> +  verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
> +  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
> +
> +  Note: Some network drivers and/or devices will automatically promote
> +  receive filter settings if the requested setting can not be honored.
> +  For example, if a request for four multicast addresses is made and
> +  the underlying hardware only supports two multicast addresses the
> +  driver might set the promiscuous or promiscuous multicast receive filters
> +  instead.  The receiving software is responsible for discarding any extra
> +  packets that get through the hardware receive filters.
> +
> +  If ResetMCastFilter is TRUE, then the multicast receive filter list
> +  on the network interface will be reset to the default multicast receive
> +  filter list.  If ResetMCastFilter is FALSE, and this network interface
> +  allows the multicast receive filter list to be modified, then the
> +  MCastFilterCnt and MCastFilter are used to update the current multicast
> +  receive filter list.  The modified receive filter list settings can be
> +  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
> +
> +  This routine calls ::ReceiveFilterUpdate to update the receive
> +  state in the network adapter.
> +
> +  @param [in] 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 TRUE.
> +  @param [in] ResetMCastFilter Set to TRUE to reset the contents of the multicast receive
> +                                filters on the network interface to their default values.
> +  @param [in] MCastFilterCnt    Number of multicast HW MAC address in the new MCastFilter list.
> +                                This value must be less than or equal to the MaxMCastFilterCnt
> +                                field of EFI_SIMPLE_NETWORK_MODE.  This field is optional if
> +                                ResetMCastFilter is TRUE.
> +  @param [in] MCastFilter      A pointer to a list of new multicast receive filter HW MAC
> +                                addresses.  This list will replace any existing multicast
> +                                HW MAC address list.  This field is optional if ResetMCastFilter
> +                                is TRUE.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = EFI_SUCCESS;
> +  EFI_TPL                 TplPrevious;
> +  UINTN                   Index;
> +  UINT8                   Temp;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  Mode = SimpleNetwork->Mode;
> +
> +  if (SimpleNetwork == NULL) {
> +    gBS->RestoreTPL(TplPrevious);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  switch (Mode->State) {
> +  case EfiSimpleNetworkInitialized:
> +    break;
> +
> +  case EfiSimpleNetworkStopped:
> +    Status = EFI_NOT_STARTED;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +
> +  default:
> +    Status = 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) != 0) ||
> +      ((Disable &~Mode->ReceiveFilterMask) != 0)) {
> +    Status = EFI_INVALID_PARAMETER;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +  }
> +
> +  if (ResetMCastFilter) {
> +    if ((0 == (Mode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST)) &&
> +          Enable == 0 &&
> +          Disable == 2) {
> +      gBS->RestoreTPL(TplPrevious);
> +      return EFI_SUCCESS;
> +    }
> +    Mode->MCastFilterCount = 0;
> +    SetMem (&Mode->MCastFilter[0],
> +             sizeof(EFI_MAC_ADDRESS) * MAX_MCAST_FILTER_CNT,
> +             0);
> +  } else {
> +    if (MCastFilterCnt != 0) {
> +      EFI_MAC_ADDRESS * MulticastAddress;
> +      MulticastAddress =  MCastFilter;
> +
> +      if ((MCastFilterCnt > Mode->MaxMCastFilterCount) ||
> +          (MCastFilter == NULL)) {
> +        Status = EFI_INVALID_PARAMETER;
> +        gBS->RestoreTPL(TplPrevious);
> +        return Status;
> +      }
> +
> +      for (Index = 0 ; Index < MCastFilterCnt ; Index++) {
> +          Temp = MulticastAddress->Addr[0];
> +          if ((Temp & 0x01) != 0x01) {
> +            gBS->RestoreTPL(TplPrevious);
> +            return EFI_INVALID_PARAMETER;
> +          }
> +          MulticastAddress++;
> +      }
> +
> +      Mode->MCastFilterCount = (UINT32)MCastFilterCnt;
> +      CopyMem (&Mode->MCastFilter[0],
> +               MCastFilter,
> +               MCastFilterCnt * sizeof (EFI_MAC_ADDRESS));
> +    }
> +  }
> +
> +  if (Enable == 0 && Disable == 0 && !ResetMCastFilter && MCastFilterCnt == 0) {
> +    Status = EFI_SUCCESS;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +  }
> +
> +  if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
> +    Status = EFI_INVALID_PARAMETER;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +  }
> +
> +  Mode->ReceiveFilterSetting |= Enable;
> +  Mode->ReceiveFilterSetting &= ~Disable;
> +
> +  Status = ReceiveFilterUpdate (SimpleNetwork);
> +
> +  if (EFI_DEVICE_ERROR == Status || EFI_INVALID_PARAMETER == Status)
> +    Status = 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 perform a more
> +                                exhaustive verification operation of the device
> +                                during reset.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  //  Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      //
> +      //  Update the device state
> +      //
> +      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +      //
> +      //  Reset the device
> +      //
> +      if (!NicDevice->FirstRst) {
> +        Status = EFI_SUCCESS;
> +      } else {
> +        Status = Ax88772Reset (NicDevice);
> +        if (!EFI_ERROR (Status)) {
> +          Status = ReceiveFilterUpdate (SimpleNetwork);
> +          if (!EFI_ERROR (Status) && !NicDevice->LinkUp && NicDevice->FirstRst) {
> +            Status = Ax88772NegotiateLinkStart (NicDevice);
> +            NicDevice->FirstRst = FALSE;
> +          }
> +        }
> +      }
> +    } else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  } else {
> +    Status = 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 = &NicDevice->SimpleNetwork;
> +  SimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
> +  SimpleNetwork->Start = SN_Start;
> +  SimpleNetwork->Stop = SN_Stop;
> +  SimpleNetwork->Initialize = SN_Initialize;
> +  SimpleNetwork->Reset = SN_Reset;
> +  SimpleNetwork->Shutdown = SN_Shutdown;
> +  SimpleNetwork->ReceiveFilters = SN_ReceiveFilters;
> +  SimpleNetwork->StationAddress = SN_StationAddress;
> +  SimpleNetwork->Statistics = SN_Statistics;
> +  SimpleNetwork->MCastIpToMac = SN_MCastIPtoMAC;
> +  SimpleNetwork->NvData = SN_NvData;
> +  SimpleNetwork->GetStatus = SN_GetStatus;
> +  SimpleNetwork->Transmit = SN_Transmit;
> +  SimpleNetwork->Receive = SN_Receive;
> +  SimpleNetwork->WaitForPacket = NULL;
> +  Mode = &NicDevice->SimpleNetworkData;
> +  SimpleNetwork->Mode = Mode;
> +  Mode->State = EfiSimpleNetworkStopped;
> +  Mode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> +  Mode->MediaHeaderSize = sizeof (ETHERNET_HEADER);
> +  Mode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> +  Mode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> +  Mode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
> +  Mode->MaxMCastFilterCount = ASIX_MCAST_FILTER_CNT;
> +  Mode->MCastFilterCount = 0;
> +  Mode->NvRamSize = 512;
> +  Mode->NvRamAccessSize = 2;
> +  SetMem (&Mode->BroadcastAddress,
> +           PXE_HWADDR_LEN_ETHER,
> +           0xff);
> +
> +  SetMem (&Mode->MCastFilter[0],
> +           sizeof(EFI_MAC_ADDRESS) * MAX_MCAST_FILTER_CNT,
> +           0);
> +
> +  Mode->IfType = NET_IFTYPE_ETHERNET;
> +  Mode->MacAddressChangeable = TRUE;
> +  Mode->MultipleTxSupported = FALSE;
> +  Mode->MediaPresentSupported = TRUE;
> +  Mode->MediaPresent = FALSE;
> +
> +  //
> +  //  Read the MAC address
> +  //
> +  NicDevice->PhyId = PHY_ID_INTERNAL;
> +  NicDevice->LinkSpeed100Mbps = TRUE;
> +  NicDevice->FullDuplex = TRUE;
> +  NicDevice->Complete = FALSE;
> +  NicDevice->LinkUp = FALSE;
> +  NicDevice->Grub_f = FALSE;
> +  NicDevice->FirstRst = TRUE;
> +  NicDevice->PktCnt = 0;
> +
> +  Status = 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 = gBS->AllocatePool (EfiBootServicesData,
> +                                   AX88772_MAX_BULKIN_SIZE,
> +                                   (VOID **) &NicDevice->BulkInbuf);
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = 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 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  Status = EFI_INVALID_PARAMETER;
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkStopped == Mode->State) {
> +      //
> +      // Initialize the mode structure
> +      // NVRAM access is not supported
> +      //
> +      ZeroMem (Mode, sizeof (*Mode));
> +
> +      Mode->State = EfiSimpleNetworkStarted;
> +      Mode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> +      Mode->MediaHeaderSize = sizeof (ETHERNET_HEADER);
> +      Mode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> +      Mode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> +      Mode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
> +      Mode->MaxMCastFilterCount = ASIX_MCAST_FILTER_CNT;
> +      Mode->MCastFilterCount = 0;
> +
> +      SetMem (&Mode->MCastFilter[0],
> +               sizeof(EFI_MAC_ADDRESS) * MAX_MCAST_FILTER_CNT,
> +               0);
> +
> +      Mode->NvRamSize = 512;
> +      Mode->NvRamAccessSize = 2;
> +      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +      Status = Ax88772MacAddressGet (NicDevice, &Mode->PermanentAddress.Addr[0]);
> +      CopyMem (&Mode->CurrentAddress,
> +                &Mode->PermanentAddress,
> +                sizeof (Mode->CurrentAddress));
> +      SetMem(&Mode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
> +      Mode->IfType = NET_IFTYPE_ETHERNET;
> +      Mode->MacAddressChangeable = TRUE;
> +      Mode->MultipleTxSupported = FALSE;
> +      Mode->MediaPresentSupported = TRUE;
> +      Mode->MediaPresent = FALSE;
> +
> +    } else {
> +      Status = 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 FALSE
> +  then the current station address is changed to the address specified by
> +  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 network
> +                                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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) &&
> +      (SimpleNetwork->Mode != NULL) &&
> +      ((!Reset) || (Reset && (New != NULL)))) {
> +    //
> +    // Verify that the adapter is already started
> +    //
> +    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == 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 = Ax88772MacAddressSet (NicDevice, &Mode->CurrentAddress.Addr[0]);
> +    } else {
> +      if (EfiSimpleNetworkStarted == Mode->State) {
> +        Status = EFI_DEVICE_ERROR; ;
> +      } else {
> +        Status = EFI_NOT_STARTED ;
> +      }
> +    }
> +  } else {
> +    Status = 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 the network interface.
> +  @param [in, out] StatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
> +                                the size, in bytes, of the resulting table of statistics.
> +  @param [out] StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
> +                                conains the statistics.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_BUFFER_TOO_SMALL  The StatisticsTable is NULL or the buffer 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  Mode = SimpleNetwork->Mode;
> +
> +  if (EfiSimpleNetworkInitialized == Mode->State) {
> +    if ((StatisticsSize != NULL) && (*StatisticsSize == 0)) {
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto EXIT;
> +    }
> +
> +    if(Reset) {
> +      Status = EFI_SUCCESS;
> +    } else {
> +      Status = EFI_SUCCESS;
> +    }
> +  } else {
> +    if (EfiSimpleNetworkStarted == Mode->State) {
> +      Status = EFI_DEVICE_ERROR; ;
> +    } else {
> +      Status = 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // Determine if the interface is started
> +    //
> +    Mode = SimpleNetwork->Mode;
> +
> +    if (EfiSimpleNetworkStarted == Mode->State) {
> +        Mode->State = EfiSimpleNetworkStopped;
> +        Status = EFI_SUCCESS;
> +    } else {
> +        Status = EFI_NOT_STARTED;
> +    }
> +  } else {
> +    Status = 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // Determine if the interface is already started
> +    //
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      //
> +      // Stop the adapter
> +      //
> +      RxFilter = Mode->ReceiveFilterSetting;
> +      Mode->ReceiveFilterSetting = 0;
> +      Status = SN_Reset (SimpleNetwork, FALSE);
> +      Mode->ReceiveFilterSetting = RxFilter;
> +      if (!EFI_ERROR (Status)) {
> +        //
> +        // Update the network state
> +        //
> +        Mode->State = EfiSimpleNetworkStarted;
> +      } else if (EFI_DEVICE_ERROR == Status) {
> +        Mode->State = EfiSimpleNetworkStopped;
> +      }
> +
> +    } else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  } else {
> +    Status = 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 must not be NULL.
> +  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
> +                                data) to be transmitted through the network interface.
> +  @param [in] Buffer           A pointer to the packet (media header followed by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [in] SrcAddr          The source HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [in] DestAddr         The destination HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [in] Protocol         The type of header to build.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
> +  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // The interface must be running
> +    //
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      //
> +      // Update the link status
> +      //
> +      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +      //
> +      //  Release the synchronization with Ax88772Timer
> +      //
> +      if (NicDevice->LinkUp && NicDevice->Complete) {
> +        //
> +        //  Copy the packet into the USB buffer
> +        //
> +
> +        if ((HeaderSize != 0) && (Mode->MediaHeaderSize != HeaderSize))  {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        }
> +        if (BufferSize <  Mode->MediaHeaderSize) {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        }
> +        if (Buffer == NULL) {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        }
> +        if ((HeaderSize != 0) && (DestAddr == NULL)) {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        }
> +        if ((HeaderSize != 0) && (Protocol == NULL)) {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        }
> +
> +        CopyMem (&NicDevice->TxTest->Data[0], Buffer, BufferSize);
> +        NicDevice->TxTest->Length = (UINT16) BufferSize;
> +
> +        //
> +        //  Transmit the packet
> +        //
> +        Header = (ETHERNET_HEADER *) &NicDevice->TxTest->Data[0];
> +        if (HeaderSize != 0) {
> +          if (DestAddr != NULL) {
> +            CopyMem (&Header->DestAddr, DestAddr, PXE_HWADDR_LEN_ETHER);
> +          }
> +          if (SrcAddr != NULL) {
> +            CopyMem (&Header->SrcAddr, SrcAddr, PXE_HWADDR_LEN_ETHER);
> +          } else {
> +            CopyMem (&Header->SrcAddr, &Mode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER);
> +          }
> +          if (Protocol != NULL) {
> +            Type = *Protocol;
> +          } else {
> +            Type = NicDevice->TxTest->Length;
> +          }
> +          Type = (UINT16)((Type >> 8) | (Type << 8));
> +          Header->Type = Type;
> +        }
> +
> +
> +        if (NicDevice->TxTest->Length < MIN_ETHERNET_PKT_SIZE) {
> +          NicDevice->TxTest->Length = MIN_ETHERNET_PKT_SIZE;
> +          ZeroMem (&NicDevice->TxTest->Data[BufferSize],
> +                    NicDevice->TxTest->Length - BufferSize);
> +        }
> +
> +        NicDevice->TxTest->LengthBar = ~(NicDevice->TxTest->Length);
> +        TransferLength = sizeof (NicDevice->TxTest->Length)
> +                       + sizeof (NicDevice->TxTest->LengthBar)
> +                       + NicDevice->TxTest->Length;
> +
> +        if (TransferLength % 512 == 0 || TransferLength % 1024 == 0)
> +          TransferLength +=4;
> +#if RXTHOU
> +        if (NicDevice->RxBurst == 1)
> +          NicDevice->RxBurst--;
> +#endif
> +        //
> +        //  Work around USB bus driver bug where a timeout set by receive
> +        //  succeeds but the timeout expires immediately after, causing the
> +        //  transmit operation to timeout.
> +        //
> +        UsbIo = NicDevice->UsbIo;
> +        Status = UsbIo->UsbBulkTransfer (UsbIo,
> +                                           BULK_OUT_ENDPOINT,
> +                                           &NicDevice->TxTest->Length,
> +                                           &TransferLength,
> +                                           0xfffffffe,
> +                                           &TransferStatus);
> +        if (EFI_SUCCESS == Status) {
> +          Status = TransferStatus;
> +        }
> +        if (EFI_SUCCESS == Status && EFI_SUCCESS == TransferStatus) {
> +          NicDevice->TxBuffer = Buffer;
> +        } else {
> +          if (EFI_DEVICE_ERROR == Status) {
> +            SN_Reset (SimpleNetwork, FALSE);
> +          }
> +          Status = EFI_NOT_READY;
> +        }
> +      } else {
> +        //
> +        // No packets available.
> +        //
> +        Status = EFI_NOT_READY;
> +      }
> +    } else {
> +      if (EfiSimpleNetworkStarted == Mode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      } else {
> +        Status = EFI_NOT_STARTED;
> +      }
> +    }
> +  } else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +EXIT:
> +  gBS->RestoreTPL (TplPrevious);
> +  return Status;
> +}
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [edk2-platform][PATCH v3 2/6] Drivers/ASIX: Add ASIX Ax88179 driver
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 2/6] Drivers/ASIX: Add ASIX Ax88179 driver Samer El-Haj-Mahmoud
@ 2020-06-09  0:37   ` Ni, Ray
  0 siblings, 0 replies; 14+ messages in thread
From: Ni, Ray @ 2020-06-09  0:37 UTC (permalink / raw)
  To: Samer El-Haj-Mahmoud, devel@edk2.groups.io
  Cc: Leif Lindholm, Ard Biesheuvel, Kinney, Michael D

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>
> Sent: Monday, June 8, 2020 9:38 PM
> To: devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>; Leif Lindholm <leif@nuviainc.com>; Ard Biesheuvel <ard.biesheuvel@arm.com>; Kinney,
> Michael D <michael.d.kinney@intel.com>
> Subject: [edk2-platform][PATCH v3 2/6] Drivers/ASIX: Add ASIX Ax88179 driver
> 
> This is the initial revision of ASIX USB networking UEFI driver
> version 2.9.0 for Ax88179 and Ax88178a
> https://www.asix.com.tw/products.php?op=pItemdetail&PItemID=131;71;112
> 
> Original source code provided by ASIX is at:
> https://github.com/samerhaj/uefi_drivers/blob/master/UsbNetworking/Asix/
> zip/source/AX88179_178a_UEFI_v2.9.0_Source.zip
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> 
> Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
> ---
>  Drivers/ASIX/Asix.dsc                                      |    2 +-
>  Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf     |   45 +
>  Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.h       | 1053 +++++++++++++
>  Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.c       | 1042 +++++++++++++
>  Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/ComponentName.c |  223 +++
>  Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/DriverBinding.c |  639 ++++++++
>  Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/SimpleNetwork.c | 1548 ++++++++++++++++++++
>  7 files changed, 4551 insertions(+), 1 deletion(-)
> 
> diff --git a/Drivers/ASIX/Asix.dsc b/Drivers/ASIX/Asix.dsc
> index d65857bb1cd4..73b5cbd5a18f 100644
> --- a/Drivers/ASIX/Asix.dsc
> +++ b/Drivers/ASIX/Asix.dsc
> @@ -64,4 +64,4 @@ [PcdsFixedAtBuild]
>  #
>  ################################################################################
>  [Components]
> -
> +Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf
> diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf
> b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf
> new file mode 100644
> index 000000000000..317ec538fa60
> --- /dev/null
> +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.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, Intel Corporation
> +# Copyright (c) 2020, ARM Limited. All rights reserved.
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010018
> +  BASE_NAME                      = Ax88179
> +  FILE_GUID                      = 27E5D3B6-7839-47C2-8618-5D2190729BC7
> +  MODULE_TYPE                    = UEFI_DRIVER
> +  VERSION_STRING                 = 1.0
> +
> +  ENTRY_POINT                    = EntryPoint
> +
> +[Sources.common]
> +  Ax88179.h
> +  Ax88179.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/Ax88179/Ax88179.h
> b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.h
> new file mode 100644
> index 000000000000..498212ec149b
> --- /dev/null
> +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.h
> @@ -0,0 +1,1053 @@
> +/** @file
> +  Definitions for ASIX AX88179 Ethernet adapter.
> +
> +  Copyright (c) 2011, Intel Corporation
> +  Copyright (c) 2020, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef AX88179_H_
> +#define AX88179_H_
> +
> +#include <Uefi.h>
> +
> +#include <Guid/EventGroup.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/NetLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/LoadedImage.h>
> +#include <Protocol/NetworkInterfaceIdentifier.h>
> +#include <Protocol/SimpleNetwork.h>
> +#include <Protocol/UsbIo.h>
> +
> +
> +#define FORCE_100Mbps 0
> +#define REPORTLINK    1
> +
> +
> +//------------------------------------------------------------------------------
> +//  Macros
> +//------------------------------------------------------------------------------
> +
> +#define USB_IS_IN_ENDPOINT(EndPointAddr)      (((EndPointAddr) & BIT7) != 0)  ///<  Return TRUE/FALSE for IN direction
> +#define USB_IS_OUT_ENDPOINT(EndPointAddr)     (((EndPointAddr) & BIT7) == 0)  ///<  Return TRUE/FALSE for OUT
> direction
> +#define USB_IS_BULK_ENDPOINT(Attribute)       (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_BULK)      ///<  Return
> TRUE/FALSE for BULK type
> +#define USB_IS_INTERRUPT_ENDPOINT(Attribute)  (((Attribute) & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) ///<
> Return TRUE/FALSE for INTERRUPT type
> +
> +//------------------------------------------------------------------------------
> +//  Constants
> +//------------------------------------------------------------------------------
> +
> +#define DEBUG_RX_BROADCAST  0x40000000  ///<  Display RX broadcast messages
> +#define DEBUG_RX_MULTICAST  0x20000000  ///<  Display RX multicast messages
> +#define DEBUG_RX_UNICAST    0x10000000  ///<  Display RX unicast messages
> +#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 values
> +#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
> +
> +
> +#define ETHERNET_HEADER_SIZE  sizeof (ETHERNET_HEADER)  ///<  Size in bytes of the Ethernet header
> +#define MIN_ETHERNET_PKT_SIZE 60    ///<  Minimum packet size including Ethernet header
> +#define MAX_ETHERNET_PKT_SIZE 1500
> +
> +#define USB_NETWORK_CLASS   0x09    ///<  USB Network class code
> +#define USB_BUS_TIMEOUT     1000    ///<  USB timeout in milliseconds
> +
> +#define AX88179_BULKIN_SIZE_INK     2
> +#define AX88179_MAX_BULKIN_SIZE    (1024 * AX88179_BULKIN_SIZE_INK)
> +#define AX88179_MAX_PKT_SIZE  2048
> +
> +#define HC_DEBUG        0
> +#define ADD_MACPATHNOD  1
> +#define BULKIN_TIMEOUT  3 //5000
> +#define TX_RETRY        0
> +#define AUTONEG_DELAY   1000000
> +
> +/**
> +  Verify new TPL value
> +
> +  This macro which is enabled when debug is enabled verifies that
> +  the new TPL value is >= 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 = 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 <= tpl);                \
> +  }                                             \
> +}
> +
> +#else   //  MDEPKG_NDEBUG
> +
> +#define VERIFY_TPL(tpl)
> +
> +#endif  //  MDEPKG_NDEBUG
> +
> +//------------------------------------------------------------------------------
> +//  Hardware Definition
> +//------------------------------------------------------------------------------
> +
> +#define DEV_SIGNATURE     SIGNATURE_32 ('A','X','8','8')  ///<  Signature of data structures in memory
> +
> +#define VENDOR_ID         0x0B95  ///<  Vendor ID for Asix
> +#define PRODUCT_ID        0x1790  ///<  Product ID for the AX88179 USB 10/100 Ethernet controller
> +#define PRODUCT_ID_178A   0x178A
> +
> +#define RESET_MSEC        1000    ///<  Reset duration
> +#define PHY_RESET_MSEC    100     ///<  PHY reset duration
> +
> +//
> +//  RX Control register
> +//
> +
> +
> +//
> +//  Medium Status register
> +//
> +
> +
> +
> +//
> +//  Software PHY Select register
> +//
> +
> +#define SPHY_PSEL         0x01    ///<  Select internal PHY
> +#define SPHY_ASEL         0x02    ///<  1=Auto select, 0=Manual select
> +
> +//
> +//  Software Reset register
> +//
> +
> +#define SRR_RR            0x01    ///<  Clear receive frame length error
> +#define SRR_RT            0x02    ///<  Clear transmit frame length error
> +#define SRR_PRTE          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   0x0003  ///<  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_RX_CONTROL_WRITE      0x10  ///<  Set the RX control register, Value: New value
> +#define CMD_GAPS_WRITE            0x12  ///<  Write the gaps register, Value: New value
> +#define CMD_MAC_ADDRESS_READ      0x11  ///<  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_MEDIUM_STATUS_READ    0x1a  ///<  Read medium status register, Data: Register value
> +#define CMD_MEDIUM_STATUS_WRITE   0x1b  ///<  Write medium status register, Value: New value
> +#define CMD_RESET                 0x20  ///<  Reset register, Value: New value
> +#define CMD_PHY_SELECT            0x22  ///<  PHY select register, Value: New value
> +
> +//------------------------------
> +//  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_ANER                        6       ///<  Autonegotiation expansion register
> +//  BSMR - Register 1
> +//  ANAR and ANLPAR Registers 4, 5
> +#define RXHDR_DROP 0x8000
> +#define RXHDR_CRCERR 0x2000
> +
> +
> +//------------------------------------------------------------------------------
> +//  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 _TX_PACKET {
> +  UINT32  TxHdr1;
> +  UINT32  TxHdr2;
> +  UINT8   Data[AX88179_MAX_PKT_SIZE]; ///<  Received packet data
> +} TX_PACKET;
> +#pragma pack()
> +
> +#pragma pack(1)
> +typedef struct _RX_PACKET {
> +  struct _RX_PACKET *Next;
> +  UINT16            Length;
> +  UINT16            EEEE;
> +  UINT8             Data[AX88179_MAX_PKT_SIZE];
> +} RX_PACKET;
> +#pragma pack()
> +
> +/**
> +  AX88179 control structure
> +
> +  The driver uses this structure to manage the Asix AX88179 10/100
> +  Ethernet controller.
> +**/
> +typedef struct {
> +  UINTN                     Signature;         ///<  Structure identification
> +
> +  //
> +  //  USB data
> +  //
> +  EFI_HANDLE                Controller;        ///<  Controller handle
> +  EFI_USB_IO_PROTOCOL       *UsbIo;            ///<  USB driver interface
> +
> +  //
> +  //  Simple network protocol data
> +  //
> +  EFI_SIMPLE_NETWORK_PROTOCOL SimpleNetwork;     ///<  Driver's network stack interface
> +  EFI_SIMPLE_NETWORK_MODE     SimpleNetworkData; ///<  Data for simple network
> +
> +  //
> +  // Ethernet controller data
> +  //
> +  BOOLEAN                   Initialized;       ///<  Controller initialized
> +  UINT16                    PhyId;             ///<  PHY ID
> +
> +  //
> +  //  Link state
> +  //
> +  BOOLEAN                   LinkSpeed100Mbps;   ///<  Current link speed, FALSE = 10 Mbps
> +  BOOLEAN                   LinkSpeed1000Mbps;  ///<  Current link speed, FALSE = 100/10 bps
> +  BOOLEAN                   Complete;           ///<  Current state of auto-negotiation
> +  BOOLEAN                   FullDuplex;         ///<  Current duplex
> +  BOOLEAN                   LinkUp;             ///<  Current link state
> +  BOOLEAN                   LinkIdle;           ///<  TRUE = No received traffic
> +  EFI_EVENT                 Timer;              ///<  Timer to monitor link state and receive packets
> +  UINTN                     PollCount;          ///<  Number of times the autonegotiation status was polled
> +  UINTN                     SkipRXCnt;
> +
> +  UINT8                     *BulkInbuf;
> +  UINT16                    PktCnt;
> +  UINT8                     *CurPktHdrOff;
> +  UINT8                     *CurPktOff;
> +
> +  TX_PACKET                 *TxTest;
> +
> +  INT8                      MulticastHash[8];
> +  EFI_MAC_ADDRESS           MAC;
> +
> +  UINT16                    CurMediumStatus;
> +  UINT16                    CurRxControl;
> +  VOID *                    TxBuffer;
> +
> +  EFI_DEVICE_PATH_PROTOCOL  *MyDevPath;
> +  BOOLEAN                   Grub_f;
> +  BOOLEAN                   FirstRst;
> +  BOOLEAN                   SetZeroLen;
> +  UINT8                     RxBurst;
> +  UINTN                     UsbMaxPktSize;
> +} NIC_DEVICE;
> +
> +#define DEV_FROM_SIMPLE_NETWORK(a)  CR (a, NIC_DEVICE, SimpleNetwork, DEV_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 ::Ax88179Reset to perform the adapter specific
> +  reset operation.  This routine also starts the link negotiation
> +  by calling ::Ax88179NegotiateLinkStart.
> +
> +  @param [in] SimpleNetwork    Protocol instance pointer
> +  @param [in] ExtendedVerification  Indicates that the driver may perform a more
> +                                exhaustive verification operation of the device
> +                                during reset.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 ::Ax88179MacAddressGet 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 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 network 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 FALSE
> +  then the current station address is changed to the address specified by
> +  New.
> +
> +  This routine calls ::Ax88179MacAddressSet 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 network
> +                                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 network 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 the network interface.
> +  @param [in, out] StatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
> +                                the size, in bytes, of the resulting table of statistics.
> +  @param [out] StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
> +                                conains the statistics.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_BUFFER_TOO_SMALL  The StatisticsTable is NULL or the buffer 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 network 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 network 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 network 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 ::Ax88179Rx 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 must not be NULL.
> +  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
> +                                data) to be transmitted through the network interface.
> +  @param [in] Buffer           A pointer to the packet (media header followed by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [in] SrcAddr          The source HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [in] DestAddr         The destination HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [in] Protocol         The type of header to build.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
> +  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 ::Ax88179UsbCommand 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 the MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88179MacAddressGet (
> +  IN NIC_DEVICE *NicDevice,
> +  OUT UINT8     *MacAddress
> +  );
> +
> +
> +/**
> +  Clear the multicast hash table
> +
> +  @param [in] NicDevice       Pointer to the NIC_DEVICE structure
> +
> +**/
> +VOID
> +Ax88179MulticastClear (
> +  IN NIC_DEVICE *NicDevice
> +  );
> +
> +/**
> +  Enable a multicast address in the multicast hash table
> +
> +  This routine calls ::Ax88179Crc 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
> +Ax88179MulticastSet (
> +  IN NIC_DEVICE *NicDevice,
> +  IN UINT8      *MacAddress
> +  );
> +
> +/**
> +  Start the link negotiation
> +
> +  This routine calls ::Ax88179PhyWrite 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
> +Ax88179NegotiateLinkStart (
> +  IN NIC_DEVICE *NicDevice
> +  );
> +
> +/**
> +  Complete the negotiation of the PHY link
> +
> +  This routine calls ::Ax88179PhyRead 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 was polled
> +  @param [out] Complete      Address of boolean to receive complate status.
> +  @param [out] LinkUp        Address of boolean to receive link status, TRUE=up.
> +  @param [out] HiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
> +  @param [out] FullDuplex    Address of boolean to receive link duplex, TRUE=full.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88179NegotiateLinkComplete (
> +  IN     NIC_DEVICE *NicDevice,
> +  IN OUT UINTN      *PollCount,
> +  OUT    BOOLEAN    *Complete,
> +  OUT    BOOLEAN    *LinkUp,
> +  OUT    BOOLEAN    *HiSpeed,
> +  OUT    BOOLEAN    *GigaSpeed,
> +  OUT    BOOLEAN    *FullDuplex
> +  );
> +
> +/**
> +  Read a register from the PHY
> +
> +  This routine calls ::Ax88179UsbCommand 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 register value
> +
> +  @retval EFI_SUCCESS          The PHY data is available.
> +  @retval other                The PHY data is not valid.
> +
> +**/
> +
> +
> +/**
> +  Reset the AX88179
> +
> +  This routine uses ::Ax88179UsbCommand to reset the network
> +  adapter.  This routine also uses ::Ax88179PhyWrite 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
> +Ax88179Reset (
> +  IN NIC_DEVICE *NicDevice
> +  );
> +
> +/**
> +  Enable or disable the receiver
> +
> +  This routine calls ::Ax88179UsbCommand to update the
> +  receiver state.  This routine also calls ::Ax88179MacAddressSet
> +  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
> +Ax88179RxControl (
> +  IN NIC_DEVICE *NicDevice,
> +  IN UINT32     RxFilter
> +  );
> +
> +  EFI_STATUS
> +Ax88179ReloadSrom  (
> +  IN NIC_DEVICE *NicDevice
> +  );
> +
> +/**
> +  Read an SROM location
> +
> +  This routine calls ::Ax88179UsbCommand 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
> +Ax88179SromRead (
> +  IN  NIC_DEVICE *NicDevice,
> +  IN  UINT32     Address,
> +  OUT UINT16     *Data
> +  );
> +
> +
> +EFI_STATUS
> +Ax88179EnableSromWrite  (
> +  IN NIC_DEVICE *NicDevice
> +  );
> +
> +
> +EFI_STATUS
> +Ax88179DisableSromWrite  (
> +  IN NIC_DEVICE *NicDevice
> +  );
> +
> +EFI_STATUS
> +Ax88179SromWrite (
> +  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
> +Ax88179UsbCommand (
> +  IN NIC_DEVICE         *NicDevice,
> +  IN USB_DEVICE_REQUEST *Request,
> +  IN OUT VOID           *Buffer
> +  );
> +
> +//------------------------------------------------------------------------------
> +// EFI Component Name Protocol Support
> +//------------------------------------------------------------------------------
> +extern EFI_DRIVER_BINDING_PROTOCOL   gDriverBinding;
> +extern EFI_COMPONENT_NAME_PROTOCOL   gComponentName;  ///<  Component name protocol declaration
> +extern EFI_COMPONENT_NAME2_PROTOCOL  gComponentName2; ///<  Component name 2 protocol declaration
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] Language         A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 3066 or ISO 639-2 language code format.
> +  @param [out] 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 specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
> +  IN  CHAR8                       *Language,
> +  OUT CHAR16                      **DriverName
> +  );
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified by
> +  Language, then a pointer to the controller name is returned in ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> +  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] ControllerHandle  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +  @param [in] ChildHandle       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +  @param [in] Language         A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 3066 or ISO 639-2 language code format.
> +  @param [out] 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 driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> +                                EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
> +  IN  EFI_HANDLE                  ControllerHandle,
> +  IN OPTIONAL EFI_HANDLE          ChildHandle,
> +  IN  CHAR8                       *Language,
> +  OUT CHAR16                      **ControllerName
> +  );
> +
> +EFI_STATUS
> +Ax88179SetMedium (
> +  IN NIC_DEVICE * NicDevice
> +  );
> +
> +//-----------------------------------------------------------------------------
> +
> +
> +#define ACCESS_MAC  0x01
> +#define ACCESS_PHY  0x02
> +
> +#define PLSR                0x02
> +  #define PLSR_USB_FS  0x01
> +  #define PLSR_USB_HS  0x02
> +  #define PLSR_USB_SS  0x04
> +
> +#define NODE_ID               0x10
> +
> +#define RXCTL                 0x0b
> +  #define RXCTL_PRO         0x0001  ///<  Receive all packets
> +  #define RXCTL_AMALL       0x0002  ///<  Receive all multicast packets
> +  #define RXCTL_SEP         0x0004  ///<  Save error packets
> +  #define RXCTL_AB          0x0008  ///<  Receive broadcast packets
> +  #define RXCTL_AM          0x0010  ///<  Use multicast destination address hash table
> +  #define RXCTL_AP          0x0020  ///<  Accept physical address from Multicast Filter
> +  #define RXCTL_ARP         0x0040  ///<  Accept runt packet
> +  #define RXCTL_SO          0x0080  ///<  Start operation
> +  #define RXCTL_DROPCRCERR  0x0100  ///<  RX header 1 formate selection
> +  #define RXCTL_IPE         0x0200  ///<  RX header 2 formate selection
> +  #define RXCTL_TXPADCRC    0x0400  ///<  RX header 3 formate selection
> +  #define RXCTL_LPBK        0x1000  ///<  MAC loop back for diagnostic
> +
> +#define MULCATFLTARRY       0x16  ///<  Write the multicast hash table, Data: New 8 byte value
> +
> +#define MEDIUMSTSMOD          0x22
> +  #define MEDIUMSTSMOD_GM   0x0001  ///<  Gigabit Mode
> +  #define MEDIUMSTSMOD_FD   0x0002  ///<  Full duplex
> +  #define MEDIUMSTSMOD_ONE  0x0004  ///<  Must be one
> +  #define MEDIUMSTSMOD_ENCK 0x0008  ///<  Add in 04h
> +  #define MEDIUMSTSMOD_RFC  0x0010  ///<  RX flow control enable
> +  #define MEDIUMSTSMOD_TFC  0x0020  ///<  TX flow control enable
> +  #define MEDIUMSTSMOD_JFE  0x0040  ///<  Pause frame enable
> +  #define MEDIUMSTSMOD_PF   0x0080  ///<  Pause frame enable
> +  #define MEDIUMSTSMOD_RE   0x0100  ///<  Receive enable
> +  #define MEDIUMSTSMOD_PS   0x0200  ///<  Port speed 1=100, 0=10 Mbps
> +  #define MEDIUMSTSMOD_SBP  0x0800  ///<  Stop back pressure
> +  #define MEDIUMSTSMOD_SM   0x1000  ///<  Super MAC support
> +
> +#define MONITORSTAUS          0x24
> +  #define  MONITORSTAUS_PMETYPE   0x40
> +  #define  MONITORSTAUS_PMEPOL    0x20
> +
> +#define PHYPWRRSTCTL          0x26
> +  #define PHYPWRRSTCTL_IPRL     0x20
> +  #define PHYPWRRSTCTL_OSCDSSEL 0x80
> +  #define PHYPWRRSTCTL_BZTYPE   0x4
> +  #define PHYPWRRSTCTL_BZ      0x10
> +
> +#define SISSR                 0x28
> +  #define SISSR_PSEL        0x01
> +  #define SISSR_ASEL        0x02
> +
> +#define RXBINQCTRL            0x2e
> +  #define RXBINQCTRL_TIMEN  0x01
> +  #define RXBINQCTRL_IFGEN  0x02
> +  #define RXBINQCTRL_SIZEN  0x04
> +
> +#define RXBINQTIMERL          0x2f
> +#define RXBINQTIMERH          0x30
> +#define RXBINQSIZE            0x31
> +#define RXBINQIFG             0x32
> +
> +#define CLKSELECT             0x33
> +  #define CLKSELECT_ACS       0x02
> +  #define CLKSELECT_BCS       0x01
> +
> +#define PAUSE_WATERLVL_HIGH   0x54
> +#define PAUSE_WATERLVL_LOW    0x55
> +
> +#define RXFREEBUF             0x57
> +  #define MAX_RXBUF_PAGE    0x067F
> +
> +#define PHY_BMCR                        0       ///<  Control register
> +  #define BMCR_RESET                      0x8000  ///<  1 = Reset the PHY, bit clears after reset
> +  #define BMCR_LOOPBACK                   0x4000  ///<  1 = Loopback enabled
> +  #define BMCR_AUTONEGOTIATION_ENABLE     0x1000  ///<  1 = Enable autonegotiation
> +  #define BMCR_POWER_DOWN                 0x0800  ///<  1 = Power down
> +  #define BMCR_ISOLATE                    0x0400  ///<  0 = Isolate PHY
> +  #define BMCR_RESTART_AUTONEGOTIATION    0x0200  ///<  1 = Restart autonegotiation
> +  #define BMCR_FULL_DUPLEX                0x0100  ///<  Full duplex operation
> +  #define BMCR_COLLISION_TEST             0x0080  ///<  1 = Collision test enabled
> +  #define BMCR_1000MBPS                   0x40  ///<  Forced mode in 1000Mbps
> +  #define BMCR_100MBPS                    0x2000    ///<  Forced mode in 10Mbps
> +
> +#define PHY_BMSR                        1       ///<  Status register
> +  #define BMSR_100BASET4                  0x8000  ///<  1 = 100BASE-T4 mode
> +  #define BMSR_100BASETX_FDX              0x4000  ///<  1 = 100BASE-TX full duplex
> +  #define BMSR_100BASETX_HDX              0x2000  ///<  1 = 100BASE-TX half duplex
> +  #define BMSR_10BASET_FDX                0x1000  ///<  1 = 10BASE-T full duplex
> +  #define BMSR_10BASET_HDX                0x0800  ///<  1 = 10BASE-T half duplex
> +  #define BMSR_MF                         0x0040  ///<  1 = PHY accepts frames with preamble suppressed
> +  #define BMSR_AUTONEG_CMPLT              0x0020  ///<  1 = Autonegotiation complete
> +  #define BMSR_RF                         0x0010  ///<  1 = Remote fault
> +  #define BMSR_AUTONEG                    0x0008  ///<  1 = Able to perform autonegotiation
> +  #define BMSR_LINKST                     0x0004  ///<  1 = Link up
> +  #define BMSR_JABBER_DETECT              0x0002  ///<  1 = jabber condition detected
> +  #define BMSR_EXTENDED_CAPABILITY        0x0001  ///<  1 = Extended register capable
> +
> +#define PHY_ANAR                        4       ///<  Autonegotiation advertisement register
> +  #define AN_NP                           0x8000  ///<  1 = Next page available
> +  #define AN_RF                           0x2000  ///<  1 = Remote fault indicated by link partner
> +  #define AN_FCS                          0x0400  ///<  1 = Flow control ability
> +  #define AN_T4                           0x0200  ///<  1 = 100BASE-T4 support
> +  #define AN_TX_FDX                       0x0100  ///<  1 = 100BASE-TX Full duplex
> +  #define AN_TX_HDX                       0x0080  ///<  1 = 100BASE-TX support
> +  #define AN_10_FDX                       0x0040  ///<  1 = 10BASE-T Full duplex
> +  #define AN_10_HDX                       0x0020  ///<  1 = 10BASE-T support
> +  #define AN_CSMA_CD                      0x0001  ///<  1 = IEEE 802.3 CSMA/CD support
> +
> +#define PHY_ANLPAR                      5       ///<  Autonegotiation link parter ability register
> +
> +#define PHY_PHYSR                       0x11
> +  #define PHYSR_SPEED_MASK                0xC000
> +  #define PHYSR_1000                      0x8000
> +  #define PHYSR_100                       0x4000
> +  #define PHYSR_FULLDUP                   0x2000
> +  #define PHYSR_LINK                      0x400
> +
> +EFI_STATUS
> +Ax88179PhyRead (
> +  IN     NIC_DEVICE *NicDevice,
> +  IN     UINT8      RegisterAddress,
> +  IN OUT UINT16     *PhyData
> +  );
> +
> +EFI_STATUS
> +Ax88179PhyWrite (
> +  IN NIC_DEVICE *NicDevice,
> +  IN UINT8      RegisterAddress,
> +  IN UINT16     PhyData
> +  );
> +
> +EFI_STATUS
> +Ax88179MacRead (
> +  IN            UINT8 Offset,
> +  IN            UINT8 Length,
> +  IN            NIC_DEVICE * NicDevice,
> +  IN  OUT  VOID *Data
> +  );
> +
> +EFI_STATUS
> +Ax88179SetIInInterval (
> +  IN  NIC_DEVICE *NicDevice,
> +  IN  UINT8      Offset
> +  );
> +
> +EFI_STATUS
> +Ax88179MacWrite (
> +  IN      UINT8      Offset,
> +  IN      UINT8      Length,
> +  IN      NIC_DEVICE *NicDevice,
> +  IN  OUT VOID       *Data
> +  );
> +
> +EFI_STATUS
> +Ax88179MacAddressGet (
> +  IN  NIC_DEVICE *NicDevice,
> +  OUT UINT8      *MacAddress
> +  );
> +
> +EFI_STATUS
> +Ax88179MacAddressSet (
> +  IN  NIC_DEVICE *NicDevice,
> +  OUT UINT8      *MacAddress
> +  );
> +
> +BOOLEAN
> +Ax88179GetLinkStatus (
> +  IN NIC_DEVICE *NicDevice
> +);
> +
> +EFI_STATUS
> +Ax88179BulkIn(
> +  IN NIC_DEVICE *NicDevice
> +);
> +
> +
> +#endif  //  AX88179_H_
> diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.c
> b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.c
> new file mode 100644
> index 000000000000..a2af3c5618d1
> --- /dev/null
> +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.c
> @@ -0,0 +1,1042 @@
> + /** @file
> +  Implement the interface to the AX88179 Ethernet controller.
> +
> +  This module implements the interface to the ASIX AX88179
> +  USB to Ethernet MAC with integrated 10/100 PHY.  Note that this implementation
> +  only supports the integrated PHY since no other test cases were available.
> +
> +  Copyright (c) 2011, Intel Corporation
> +  Copyright (c) 2020, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88179.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
> +Ax88179Crc (
> +  IN UINT8 *MacAddress
> +  )
> +{
> +  UINT32 BitNumber;
> +  INT32  Carry;
> +  INT32  Crc;
> +  UINT32 Data;
> +  UINT8  *End;
> +
> +  //
> +  //  Walk the MAC address
> +  //
> +  Crc = -1;
> +  End = &MacAddress[PXE_HWADDR_LEN_ETHER];
> +  while (End > MacAddress) {
> +    Data = *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 = 0; 8 > BitNumber; BitNumber++) {
> +      Carry = ((Crc >> 31) & 1) ^ (Data & 1);
> +      Crc <<= 1;
> +      if (Carry != 0) {
> +        Crc ^= 0x04c11db7;
> +      }
> +      Data >>= 1;
> +    }
> +  }
> +
> +  //
> +  //  Return the CRC value
> +  //
> +  return (UINT32) Crc;
> +}
> +
> +/**
> +  Get the MAC address
> +
> +  This routine calls ::Ax88179UsbCommand 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 the MAC address.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88179MacAddressGet (
> +  IN  NIC_DEVICE *NicDevice,
> +  OUT UINT8      *MacAddress
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status  = Ax88179MacRead (NODE_ID,
> +                            PXE_HWADDR_LEN_ETHER,
> +                            NicDevice,
> +                            MacAddress);
> +
> +  return Status;
> +}
> +
> +/**
> +  Set the MAC address
> +
> +  This routine calls ::Ax88179UsbCommand 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
> +Ax88179MacAddressSet (
> +  IN  NIC_DEVICE *NicDevice,
> +  OUT UINT8      *MacAddress
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status  = Ax88179MacWrite (NODE_ID,
> +                             PXE_HWADDR_LEN_ETHER,
> +                             NicDevice,
> +                             MacAddress);
> +
> +  return Status;
> +}
> +
> +/**
> +  Clear the multicast hash table
> +
> +  @param [in] NicDevice       Pointer to the NIC_DEVICE structure
> +
> +**/
> +VOID
> +Ax88179MulticastClear (
> +  IN NIC_DEVICE *NicDevice
> +  )
> +{
> +  int Index = 0;
> +  //
> +  // Clear the multicast hash table
> +  //
> +  for (Index = 0 ; Index < 8 ; Index ++)
> +    NicDevice->MulticastHash[Index] = 0;
> +}
> +
> +/**
> +  Enable a multicast address in the multicast hash table
> +
> +  This routine calls ::Ax88179Crc 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
> +Ax88179MulticastSet (
> +  IN NIC_DEVICE *NicDevice,
> +  IN UINT8      *MacAddress
> +  )
> +{
> +  UINT32 Crc;
> +
> +  //
> +  // Compute the CRC on the destination address
> +  //
> +  Crc = Ax88179Crc (MacAddress) >> 26;
> +
> +  //
> +  //  Set the bit corresponding to the destination address
> +  //
> +  NicDevice->MulticastHash [Crc >> 3] |= (1 << (Crc & 7));
> +
> +}
> +
> +/**
> +  Start the link negotiation
> +
> +  This routine calls ::Ax88179PhyWrite 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
> +Ax88179NegotiateLinkStart (
> +  IN NIC_DEVICE *NicDevice
> +  )
> +{
> +  UINT16     Control = 0;
> +  EFI_STATUS Status;
> +
> +#if FORCE_100Mbps
> +  Ax88179PhyRead (NicDevice,
> +                   0x09,
> +                   &Control);
> +  Control &= 0xFCFF;
> +  Ax88179PhyWrite (NicDevice, 0x09, Control);
> +#endif
> +
> +  //
> +  // Set the link speed and duplex
> +  //
> +  Control = BMCR_AUTONEGOTIATION_ENABLE
> +          | BMCR_RESTART_AUTONEGOTIATION;
> +  if (NicDevice->LinkSpeed1000Mbps) {
> +    Control |= BMCR_1000MBPS;
> +  } else if (NicDevice->LinkSpeed100Mbps) {
> +    Control |= BMCR_100MBPS;
> +  }
> +
> +  if (NicDevice->FullDuplex) {
> +    Control |= BMCR_FULL_DUPLEX;
> +  }
> +  Status = Ax88179PhyWrite (NicDevice, PHY_BMCR, Control);
> +  if (!EFI_ERROR(Status))
> +    gBS->Stall(3000000);
> +  //
> +  // Return the operation status
> +  //
> +  return Status;
> +}
> +
> +
> +
> +/**
> +  Complete the negotiation of the PHY link
> +
> +  This routine calls ::Ax88179PhyRead 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 was polled
> +  @param [out] Complete      Address of boolean to receive complate status.
> +  @param [out] LinkUp        Address of boolean to receive link status, TRUE=up.
> +  @param [out] HiSpeed       Address of boolean to receive link speed, TRUE=100Mbps.
> +  @param [out] FullDuplex    Address of boolean to receive link duplex, TRUE=full.
> +
> +  @retval EFI_SUCCESS          The MAC address is available.
> +  @retval other                The MAC address is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88179NegotiateLinkComplete (
> +  IN     NIC_DEVICE *NicDevice,
> +  IN OUT UINTN      *PollCount,
> +  OUT    BOOLEAN    *Complete,
> +  OUT    BOOLEAN    *LinkUp,
> +  OUT    BOOLEAN    *HiSpeed,
> +  OUT    BOOLEAN    *GigaSpeed,
> +  OUT    BOOLEAN    *FullDuplex
> +  )
> +{
> +  UINT16      PhyData;
> +  EFI_STATUS  Status;
> +
> +  //
> +  //  Determine if the link is up.
> +  //
> +  *Complete = FALSE;
> +
> +  //
> +  //  Get the link status
> +  //
> +  Status = Ax88179PhyRead (NicDevice,
> +                            PHY_PHYSR,
> +                            &PhyData);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  *LinkUp = ((PhyData & PHYSR_LINK) != 0);
> +  if (*LinkUp) {
> +    //
> +    //  Determine if the autonegotiation is complete.
> +    //
> +    Status = Ax88179PhyRead (NicDevice,
> +                          PHY_BMSR,
> +                          &PhyData);
> +    if (EFI_ERROR(Status)) {
> +      return Status;
> +    }
> +
> +    *Complete = ((PhyData & BMSR_AUTONEG_CMPLT) != 0);
> +
> +    if (*Complete != 0) {
> +      //
> +      //  Get the partners capabilities.
> +      //
> +      Status = Ax88179PhyRead (NicDevice,
> +                                PHY_PHYSR,
> +                                &PhyData);
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +
> +      //
> +      //  Autonegotiation is complete
> +      //  Determine the link speed.
> +      //
> +      *GigaSpeed = ((PhyData & PHYSR_SPEED_MASK) == PHYSR_1000);
> +      *HiSpeed = ((PhyData & PHYSR_SPEED_MASK) == PHYSR_100);
> +
> +      //
> +      //  Determine the link duplex.
> +      //
> +      *FullDuplex = ((PhyData & PHYSR_FULLDUP) == PHYSR_FULLDUP);
> +    }
> +  }
> +
> +
> +  //
> +  // Return the operation status
> +  //
> +  return Status;
> +}
> +
> +
> +/**
> +  Read a register from the PHY
> +
> +  This routine calls ::Ax88179UsbCommand 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 register value
> +
> +  @retval EFI_SUCCESS          The PHY data is available.
> +  @retval other                The PHY data is not valid.
> +
> +**/
> +EFI_STATUS
> +Ax88179PhyRead (
> +  IN     NIC_DEVICE *NicDevice,
> +  IN     UINT8      RegisterAddress,
> +  IN OUT UINT16     *PhyData
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS         Status;
> +
> +  //
> +  //  Read the PHY register address.
> +  //
> +  SetupMsg.RequestType = USB_ENDPOINT_DIR_IN
> +                       | USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = ACCESS_PHY;
> +  SetupMsg.Value = NicDevice->PhyId;
> +  SetupMsg.Index = RegisterAddress;
> +  SetupMsg.Length = sizeof (*PhyData);
> +  Status = Ax88179UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               PhyData);
> +
> +  //
> +  //  Return the operation status.
> +  //
> +  return Status;
> +}
> +
> +
> +/**
> +  Write to a PHY register
> +
> +  This routine calls ::Ax88179UsbCommand 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 register value
> +
> +  @retval EFI_SUCCESS          The PHY data was written.
> +  @retval other                Failed to wwrite the PHY register.
> +
> +**/
> +EFI_STATUS
> +Ax88179PhyWrite (
> +  IN NIC_DEVICE *NicDevice,
> +  IN UINT8      RegisterAddress,
> +  IN UINT16     PhyData
> +  )
> +{
> +  USB_DEVICE_REQUEST SetupMsg;
> +  EFI_STATUS         Status;
> +
> +  //
> +  //  Write the PHY register
> +  //
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +  SetupMsg.Request = ACCESS_PHY;
> +  SetupMsg.Value = NicDevice->PhyId;
> +  SetupMsg.Index = RegisterAddress;
> +  SetupMsg.Length = sizeof (PhyData);
> +  Status = Ax88179UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               &PhyData);
> +  //
> +  //  Return the operation status.
> +  //
> +  return Status;
> +}
> +
> +
> +/**
> +  Reset the AX88179
> +
> +  This routine uses ::Ax88179UsbCommand to reset the network
> +  adapter.  This routine also uses ::Ax88179PhyWrite 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
> +Ax88179Reset (
> +  IN NIC_DEVICE *NicDevice
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT16     Val;
> +  UINT8      Val8;
> +
> +  Status = Ax88179SetIInInterval(NicDevice, 0xff);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  Val8 = 0;
> +  Status  = Ax88179MacRead (PLSR,
> +                            sizeof(Val8),
> +                            NicDevice,
> +                            &Val8);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  if (Val8 & PLSR_USB_SS)
> +    NicDevice->UsbMaxPktSize = 1024;
> +  else
> +    NicDevice->UsbMaxPktSize = 512;
> +
> +  Val = 0;
> +  Status = Ax88179MacWrite (PHYPWRRSTCTL,
> +                             sizeof (Val),
> +                             NicDevice,
> +                             &Val);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  gBS->Stall (10000);
> +
> +  Val =  PHYPWRRSTCTL_IPRL;
> +  Status = Ax88179MacWrite (PHYPWRRSTCTL,
> +                             sizeof (Val),
> +                             NicDevice,
> +                             &Val);
> +
> +  if (EFI_ERROR(Status)){
> +    goto err;
> +  }
> +
> +  gBS->Stall (200000);
> +
> +  Val = CLKSELECT_BCS | CLKSELECT_ACS;
> +  Status = Ax88179MacWrite (CLKSELECT,
> +                             1,
> +                             NicDevice,
> +                             &Val);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  gBS->Stall (100000);
> +
> +  Val = 0x52;
> +  Status = Ax88179MacWrite (PAUSE_WATERLVL_HIGH,
> +                             1,
> +                             NicDevice,
> +                             &Val);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  Val = 0x34;
> +  Status = Ax88179MacWrite (PAUSE_WATERLVL_LOW,
> +                             1,
> +                             NicDevice,
> +                             &Val);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  Val = RXBINQCTRL_TIMEN | RXBINQCTRL_IFGEN | RXBINQCTRL_SIZEN;
> +
> +  Status =  Ax88179MacWrite (RXBINQCTRL,
> +                              0x01,
> +                              NicDevice,
> +                              &Val);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  Val = 0;
> +  Status =  Ax88179MacWrite (RXBINQTIMERL,
> +                              0x01,
> +                              NicDevice,
> +                              &Val);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  Val = 0;
> +  Status =  Ax88179MacWrite (RXBINQTIMERH,
> +                              0x01,
> +                              NicDevice,
> +                              &Val);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  Val = 12; //AX88179_BULKIN_SIZE_INK - 1;
> +  Status =  Ax88179MacWrite (RXBINQSIZE,
> +                              0x01,
> +                              NicDevice,
> +                              &Val);
> +
> +  if (EFI_ERROR(Status)) goto err;
> +
> +  Val = 0x0F;
> +  Status =  Ax88179MacWrite (RXBINQIFG,
> +                              0x01,
> +                              NicDevice,
> +                              &Val);
> +
> +err:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +Ax88179RxControl (
> +  IN NIC_DEVICE *NicDevice,
> +  IN UINT32     RxFilter
> +  )
> +{
> +  UINT16     MediumStatus;
> +  UINT16     RxControl = 0;
> +  EFI_STATUS Status = EFI_SUCCESS;
> +
> +  //
> +  // Enable the receiver if something is to be received
> +  //
> +  if (RxFilter != 0) {
> +    //
> +    //  Enable the receiver
> +    //
> +    Status  = Ax88179MacRead (MEDIUMSTSMOD,
> +                              sizeof (MediumStatus),
> +                              NicDevice,
> +                              &MediumStatus);
> +
> +    if (!EFI_ERROR (Status) && NicDevice->CurMediumStatus != MediumStatus) {
> +        MediumStatus = MEDIUMSTSMOD_RE | MEDIUMSTSMOD_ONE;
> +        if (NicDevice->FullDuplex) {
> +          MediumStatus |= MEDIUMSTSMOD_TFC | MEDIUMSTSMOD_RFC | MEDIUMSTSMOD_FD;
> +        } else {
> +          MediumStatus &= ~(MEDIUMSTSMOD_TFC | MEDIUMSTSMOD_RFC | MEDIUMSTSMOD_FD);
> +        }
> +        if (NicDevice->LinkSpeed1000Mbps) {
> +          MediumStatus |= MEDIUMSTSMOD_GM;
> +          MediumStatus |= MEDIUMSTSMOD_ENCK;
> +          MediumStatus &= ~MEDIUMSTSMOD_PS;
> +        } else {
> +          MediumStatus &= ~MEDIUMSTSMOD_GM;
> +          MediumStatus &= ~MEDIUMSTSMOD_ENCK;
> +          if (NicDevice->LinkSpeed100Mbps) {
> +            MediumStatus |= MEDIUMSTSMOD_PS;
> +          }  else {
> +            MediumStatus &= ~MEDIUMSTSMOD_PS;
> +          }
> +        }
> +        Status  = Ax88179MacWrite (MEDIUMSTSMOD,
> +                                   sizeof (MediumStatus),
> +                                   NicDevice,
> +                                   &MediumStatus);
> +        if (!EFI_ERROR (Status)) {
> +          NicDevice->CurMediumStatus = MediumStatus;
> +        }
> +    }
> +  }
> +
> +  RxControl = RXCTL_SO | RXCTL_IPE;
> +
> +  //
> +  //  Enable multicast if requested
> +  //
> +  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
> +    RxControl |= RXCTL_AM;
> +    //
> +    //  Update the multicast hash table
> +    //
> +    Status  = Ax88179MacWrite (MULCATFLTARRY,
> +                               8,
> +                               NicDevice,
> +                               &NicDevice->MulticastHash);
> +  }
> +
> +  //
> +  //  Enable all multicast if requested
> +  //
> +  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
> +    RxControl |= RXCTL_AMALL;
> +  }
> +  //
> +  //  Enable broadcast if requested
> +  //
> +  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
> +    RxControl |= RXCTL_AB;
> +  }
> +
> +  //
> +  //  Enable promiscuous mode if requested
> +  //
> +  if ((RxFilter & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
> +    RxControl |= RXCTL_PRO;
> +  }
> +
> +  //
> +  //  Update the receiver control
> +  //
> +  if (NicDevice->CurRxControl != RxControl) {
> +    Status  = Ax88179MacWrite (RXCTL,
> +                               0x02,
> +                               NicDevice,
> +                               &RxControl);
> +    if (!EFI_ERROR (Status))
> +      NicDevice->CurRxControl = RxControl;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  return Status;
> +}
> +
> +EFI_STATUS
> +Ax88179ReloadSrom  (
> +  IN NIC_DEVICE *NicDevice
> + )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = EFI_UNSUPPORTED;
> +  return Status;
> +
> +}
> +
> +/**
> +  Read an SROM location
> +
> +  This routine calls ::Ax88179UsbCommand 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
> +Ax88179SromRead (
> +  IN  NIC_DEVICE *NicDevice,
> +  IN  UINT32     Address,
> +  OUT UINT16     *Data
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = EFI_UNSUPPORTED;
> +  return Status;
> +}
> +
> +EFI_STATUS
> +Ax88179EnableSromWrite  (
> +  IN NIC_DEVICE *NicDevice
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = EFI_UNSUPPORTED;
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +Ax88179DisableSromWrite  (
> +  IN NIC_DEVICE *NicDevice
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = EFI_UNSUPPORTED;
> +  return Status;
> +}
> +
> +/**
> +  Write an SROM location
> +
> +  This routine calls ::Ax88179UsbCommand 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
> +Ax88179SromWrite (
> +  IN NIC_DEVICE *NicDevice,
> +  IN UINT32     Address,
> +  IN UINT16     *Data
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = EFI_UNSUPPORTED;
> +  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
> +Ax88179UsbCommand (
> +  IN     NIC_DEVICE         *NicDevice,
> +  IN     USB_DEVICE_REQUEST *Request,
> +  IN OUT VOID               *Buffer
> +  )
> +{
> +  EFI_USB_DATA_DIRECTION Direction;
> +  EFI_USB_IO_PROTOCOL    *UsbIo;
> +  EFI_STATUS             Status = EFI_TIMEOUT;
> +  UINT32                 CmdStatus = EFI_USB_NOERROR;
> +  int                    i;
> +  //
> +  // Determine the transfer direction
> +  //
> +  Direction = EfiUsbNoData;
> +  if (Request->Length != 0) {
> +    Direction = ((Request->RequestType & USB_ENDPOINT_DIR_IN) != 0)
> +                        ? EfiUsbDataIn : EfiUsbDataOut;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  UsbIo = NicDevice->UsbIo;
> +
> +  for (i = 0 ; i < 3 && EFI_TIMEOUT == Status; i++) {
> +    Status = UsbIo->UsbControlTransfer (UsbIo,
> +                                        Request,
> +                                        Direction,
> +                                        USB_BUS_TIMEOUT,
> +                                        Buffer,
> +                                        Request->Length,
> +                                        &CmdStatus);
> +  }
> +  //
> +  // Determine the operation status
> +  //
> +  if (EFI_ERROR(Status) || EFI_ERROR(CmdStatus))
> +    Status = EFI_DEVICE_ERROR;
> +  //
> +  // Return the operation status
> +  //
> +  return Status;
> +}
> +
> +EFI_STATUS
> +Ax88179MacRead (
> +  IN       UINT8      Offset,
> +  IN       UINT8      Length,
> +  IN       NIC_DEVICE *NicDevice,
> +  IN  OUT  VOID       *Data
> +  )
> +{
> +
> +  EFI_STATUS         Status;
> +  USB_DEVICE_REQUEST SetupMsg;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE
> +                       | USB_ENDPOINT_DIR_IN;
> +
> +  SetupMsg.Request = ACCESS_MAC;
> +  SetupMsg.Value  = Offset;
> +  SetupMsg.Index  = Length;
> +  SetupMsg.Length = SetupMsg.Index;
> +
> +  Status = Ax88179UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               Data);
> +
> +  return Status;
> +
> +}
> +
> +EFI_STATUS
> +Ax88179MacWrite (
> +  IN       UINT8      Offset,
> +  IN       UINT8      Length,
> +  IN       NIC_DEVICE *NicDevice,
> +  IN  OUT  VOID       *Data
> + )
> +{
> +
> +  EFI_STATUS         Status;
> +  USB_DEVICE_REQUEST SetupMsg;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +
> +  SetupMsg.Request = ACCESS_MAC;
> +  SetupMsg.Value  = Offset;
> +  SetupMsg.Index  = Length;
> +  SetupMsg.Length = SetupMsg.Index;
> +
> +  Status = Ax88179UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               Data);
> +
> +  return Status;
> +
> +}
> +
> +EFI_STATUS
> +Ax88179SetIInInterval (
> +  IN  NIC_DEVICE *NicDevice,
> +  IN  UINT8      Interval
> + )
> +{
> +
> +  EFI_STATUS         Status;
> +  USB_DEVICE_REQUEST SetupMsg;
> +
> +  SetupMsg.RequestType = USB_REQ_TYPE_VENDOR
> +                       | USB_TARGET_DEVICE;
> +
> +  SetupMsg.Request = 0x91;
> +  SetupMsg.Value  = Interval;
> +  SetupMsg.Index  = 0;
> +  SetupMsg.Length = 0;
> +
> +  Status = Ax88179UsbCommand (NicDevice,
> +                               &SetupMsg,
> +                               NULL);
> +
> +  return Status;
> +
> +}
> +
> +EFI_STATUS
> +Ax88179SetMedium (
> +  IN NIC_DEVICE *NicDevice
> + )
> +{
> +  UINT16     MediumStatus;
> +  EFI_STATUS Status;
> +
> +  MediumStatus = MEDIUMSTSMOD_RE | MEDIUMSTSMOD_ONE;
> +  if (NicDevice->FullDuplex) {
> +    MediumStatus |= MEDIUMSTSMOD_TFC | MEDIUMSTSMOD_RFC | MEDIUMSTSMOD_FD;
> +  } else {
> +    MediumStatus &= ~(MEDIUMSTSMOD_TFC | MEDIUMSTSMOD_RFC | MEDIUMSTSMOD_FD);
> +  }
> +  if (NicDevice->LinkSpeed1000Mbps) {
> +    MediumStatus |= MEDIUMSTSMOD_GM;
> +    MediumStatus &= ~MEDIUMSTSMOD_PS;
> +  } else {
> +    MediumStatus &= ~MEDIUMSTSMOD_GM;
> +    if (NicDevice->LinkSpeed100Mbps) {
> +      MediumStatus |= MEDIUMSTSMOD_PS;
> +    } else {
> +      MediumStatus &= ~MEDIUMSTSMOD_PS;
> +    }
> +  }
> +  Status  = Ax88179MacWrite (MEDIUMSTSMOD,
> +                             sizeof (MediumStatus),
> +                             NicDevice,
> +                             &MediumStatus);
> +  if (!EFI_ERROR (Status)) {
> +    NicDevice->CurMediumStatus = MediumStatus;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +BOOLEAN
> +Ax88179GetLinkStatus (
> +  IN NIC_DEVICE *NicDevice
> +)
> +{
> +  UINT32              CmdStatus;
> +  EFI_USB_IO_PROTOCOL *UsbIo;
> +  UINT64              IntData = 0;
> +  UINTN               IntDataLeng = 8;
> +  EFI_STATUS          Status;
> +
> +  //
> +  // Issue the command
> +  //
> +  UsbIo = NicDevice->UsbIo;
> +  Status = UsbIo->UsbSyncInterruptTransfer(UsbIo,
> +                                        USB_ENDPOINT_DIR_IN | INTERRUPT_ENDPOINT,
> +                                        &IntData,
> +                                        &IntDataLeng,
> +                                        USB_BUS_TIMEOUT,
> +                                        &CmdStatus);
> +
> +  if (EFI_ERROR(Status) || EFI_ERROR(CmdStatus) || 0 == IntDataLeng)
> +    return FALSE;
> +
> +  return (IntData & 0x10000)? TRUE : FALSE;
> +
> +}
> +
> +EFI_STATUS
> +Ax88179BulkIn(
> +  IN NIC_DEVICE *NicDevice
> +)
> +{
> +  int i;
> +  UINT16  Val;
> +  UINTN               LengthInBytes = 0;
> +  UINTN               TmpLen = AX88179_MAX_BULKIN_SIZE;
> +  UINTN               CURBufSize = AX88179_MAX_BULKIN_SIZE;
> +  UINTN               PREBufSize = 0;
> +  EFI_STATUS          Status = EFI_NOT_READY;
> +  EFI_USB_IO_PROTOCOL *UsbIo;
> +  UINT32 TransferStatus;
> +
> +  NicDevice->SkipRXCnt = 0;
> +
> +  UsbIo = NicDevice->UsbIo;
> +  for (i = 0 ; i < (AX88179_MAX_BULKIN_SIZE / 512) && UsbIo != NULL; i++) {
> +    VOID* TmpAddr = 0;
> +
> +    if (NicDevice->SetZeroLen) {
> +      Val =  PHYPWRRSTCTL_IPRL | PHYPWRRSTCTL_BZ;
> +      Status = Ax88179MacWrite (PHYPWRRSTCTL,
> +                                 sizeof (Val),
> +                                 NicDevice,
> +                                 &Val);
> +      if (EFI_ERROR(Status)) {
> +        LengthInBytes = 0;
> +        Status = EFI_NOT_READY;
> +        goto no_pkt;
> +      }
> +      NicDevice->SetZeroLen = FALSE;
> +    }
> +    TmpAddr = (VOID*) &NicDevice->BulkInbuf[LengthInBytes];
> +
> +    Status =  EFI_NOT_READY;
> +    Status = UsbIo->UsbBulkTransfer (UsbIo,
> +                          USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
> +                          TmpAddr,
> +                          &TmpLen,
> +                          BULKIN_TIMEOUT,
> +                          &TransferStatus);
> +
> +    if ((!EFI_ERROR (Status)) && (!EFI_ERROR (TransferStatus)) && TmpLen != 0) {
> +      LengthInBytes += TmpLen;
> +      if ((TmpLen % NicDevice->UsbMaxPktSize) != 0) {
> +        goto done;
> +      }
> +      CURBufSize = CURBufSize - TmpLen;
> +      TmpLen = CURBufSize;
> +      NicDevice->SetZeroLen = TRUE;
> +    } else if ((!EFI_ERROR (Status)) &&
> +               (!EFI_ERROR (TransferStatus)) &&
> +               (TmpLen == 0) &&
> +               LengthInBytes) {
> +      if (PREBufSize == CURBufSize) {
> +        goto done;
> +      }
> +      TmpLen = CURBufSize;
> +      PREBufSize = CURBufSize;
> +      NicDevice->SetZeroLen = TRUE;
> +    } else if ((!EFI_ERROR (Status)) &&
> +               (!EFI_ERROR (TransferStatus)) &&
> +               (TmpLen == 0)) {
> +      NicDevice->SetZeroLen = TRUE;
> +      LengthInBytes = 0;
> +      Status = EFI_NOT_READY;
> +      goto done;
> +    } else if (EFI_TIMEOUT == Status && EFI_USB_ERR_TIMEOUT == TransferStatus) {
> +      NicDevice->SetZeroLen = TRUE;
> +      LengthInBytes = 0;
> +      Status = EFI_NOT_READY;
> +      goto done;
> +    } else {
> +      NicDevice->SetZeroLen = TRUE;
> +      LengthInBytes = 0;
> +      Status = EFI_NOT_READY;
> +      goto done;
> +    }
> +  }
> +
> +done:
> +  if (LengthInBytes != 0) {
> +    UINT16 tmplen = 0;
> +    UINT16 TmpPktCnt = 0;
> +
> +    TmpPktCnt = *((UINT16 *) (NicDevice->BulkInbuf + LengthInBytes - 4));
> +    tmplen =  *((UINT16*) (NicDevice->BulkInbuf + LengthInBytes - 2));
> +
> +    if (((UINTN)(((TmpPktCnt * 4 + 4 + 7) & 0xfff8) + tmplen)) == LengthInBytes) {
> +      NicDevice->PktCnt = TmpPktCnt;
> +      NicDevice->CurPktHdrOff = NicDevice->BulkInbuf + tmplen;
> +      NicDevice->CurPktOff = NicDevice->BulkInbuf;
> +      *((UINT16 *) (NicDevice->BulkInbuf + LengthInBytes - 4)) = 0;
> +      *((UINT16*) (NicDevice->BulkInbuf + LengthInBytes - 2)) = 0;
> +      Status = EFI_SUCCESS;
> +    } else {
> +      Status = EFI_NOT_READY;
> +    }
> +  } else {
> +    Status = EFI_NOT_READY;
> +  }
> +no_pkt:
> +   return Status;
> +}
> diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/ComponentName.c
> b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/ComponentName.c
> new file mode 100644
> index 000000000000..daf917ce5b7d
> --- /dev/null
> +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/ComponentName.c
> @@ -0,0 +1,223 @@
> +/** @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 "Ax88179.h"
> +
> +/**
> +  EFI Component Name Protocol declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gComponentName = {
> +  GetDriverName,
> +  GetControllerName,
> +  "eng"
> +};
> +
> +/**
> +  EFI Component Name 2 Protocol declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GetControllerName,
> +  "en"
> +};
> +
> +
> +/**
> +  Driver name table declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> +mDriverNameTable[] = {
> +  {"eng;en", L"ASIX AX88179 Ethernet Driver 2.9.0"},
> +  {NULL,  NULL}
> +};
> +
> +/**
> +  Controller name table declaration
> +**/
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> +mControllerNameTable[] = {
> +  {"eng;en", L"AX88179 USB3.0 Gigabit Ethernet Controller"},
> +  {NULL,  NULL}
> +};
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] Language         A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 3066 or ISO 639-2 language code format.
> +  @param [out] 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 specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
> +  IN  CHAR8                       *Language,
> +  OUT CHAR16                      **DriverName
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +
> +  Status = LookupUnicodeString2 (
> +             Language,
> +             This->SupportedLanguages,
> +             mDriverNameTable,
> +             DriverName,
> +             (BOOLEAN)(This == &gComponentName)
> +             );
> +
> +  return Status;
> +}
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified by
> +  Language, then a pointer to the controller name is returned in ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> +  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> +  @param [in] This             A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +  @param [in] ControllerHandle  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +  @param [in] ChildHandle       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +  @param [in] Language         A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 3066 or ISO 639-2 language code format.
> +  @param [out] 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 driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> +                                EFI_HANDLE.
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +
> +
> +
> +EFI_STATUS
> +EFIAPI
> +GetControllerName (
> +  IN          EFI_COMPONENT_NAME_PROTOCOL *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 != NULL) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Check Controller's handle
> +  //
> +  Status = 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 != EFI_ALREADY_STARTED) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Status =  LookupUnicodeString2 (
> +           Language,
> +            This->SupportedLanguages,
> +           mControllerNameTable,
> +           ControllerName,
> +           (BOOLEAN)(This == &gComponentName)
> +           );
> +
> +  return  Status;
> +}
> +
> diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/DriverBinding.c
> b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/DriverBinding.c
> new file mode 100644
> index 000000000000..7a287cfbfb5d
> --- /dev/null
> +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/DriverBinding.c
> @@ -0,0 +1,639 @@
> +/** @file
> +  Implement the driver binding protocol for Asix AX88179 Ethernet driver.
> +
> +  Copyright (c) 2011, Intel Corporation
> +  Copyright (c) 2020, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88179.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 = 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 transport
> +    //  protocol handler.
> +    //
> +    Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &Device);
> +    if (EFI_ERROR(Status)) {
> +      Status = EFI_UNSUPPORTED;
> +    } else {
> +      //
> +      //  Validate the adapter
> +      //
> +      if ((VENDOR_ID == Device.IdVendor) &&
> +          (PRODUCT_ID == Device.IdProduct)) {
> +        Status = EFI_SUCCESS;
> +      } else if ((VENDOR_ID == Device.IdVendor) &&
> +                 (PRODUCT_ID_178A == Device.IdProduct)) {
> +        Status = EFI_SUCCESS;
> +      } else {
> +        Status = 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 protocols.
> +  Initialize PXE structures, create a copy of the Controller Device Path with the
> +  NIC's MAC address apEnded to it, install the NetworkInterfaceIdentifier 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 = NULL;
> +  MAC_ADDR_DEVICE_PATH      MacDeviceNode;
> +
> +  //
> +  //  Allocate the device structure
> +  //
> +  LengthInBytes = sizeof (*NicDevice);
> +  Status = gBS->AllocatePool (
> +                  EfiBootServicesData,
> +                  LengthInBytes,
> +                  (VOID **) &NicDevice
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto ERR;
> +  }
> +
> +  //
> +  //  Set the structure signature
> +  //
> +  ZeroMem (NicDevice, LengthInBytes);
> +  NicDevice->Signature = DEV_SIGNATURE;
> +
> +  Status = gBS->OpenProtocol (
> +                    Controller,
> +                    &gEfiUsbIoProtocolGuid,
> +                    (VOID **) &NicDevice->UsbIo,
> +                    This->DriverBindingHandle,
> +                    Controller,
> +                    EFI_OPEN_PROTOCOL_BY_DRIVER
> +                    );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto ERR;
> +  }
> +
> +  //
> +  //  Initialize the simple network protocol
> +  //
> +  Status = SN_Setup (NicDevice);
> +
> +  if (EFI_ERROR(Status)){
> +    gBS->CloseProtocol (
> +              Controller,
> +              &gEfiUsbIoProtocolGuid,
> +              This->DriverBindingHandle,
> +              Controller
> +              );
> +    goto ERR;
> +  }
> +
> +  //
> +  // Set Device Path
> +  //
> +  Status = 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 = MESSAGING_DEVICE_PATH;
> +  MacDeviceNode.Header.SubType = MSG_MAC_ADDR_DP;
> +
> +  SetDevicePathNodeLength (&MacDeviceNode.Header, sizeof (MAC_ADDR_DEVICE_PATH));
> +
> +  CopyMem (&MacDeviceNode.MacAddress,
> +           &NicDevice->SimpleNetworkData.CurrentAddress,
> +           PXE_HWADDR_LEN_ETHER);
> +
> +  MacDeviceNode.IfType = NicDevice->SimpleNetworkData.IfType;
> +
> +  NicDevice->MyDevPath = AppendDevicePathNode (
> +                                          ParentDevicePath,
> +                                          (EFI_DEVICE_PATH_PROTOCOL *) &MacDeviceNode
> +                                          );
> +
> +  NicDevice->Controller = NULL;
> +
> +  //
> +  //  Install both the simple network and device path protocols.
> +  //
> +  Status = 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 = 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 != NULL) {
> +    gBS->FreePool (NicDevice->BulkInbuf);
> +  }
> +
> +  if (NicDevice->TxTest != NULL) {
> +    gBS->FreePool (NicDevice->TxTest);
> +  }
> +
> +  if (NicDevice->MyDevPath != NULL) {
> +    gBS->FreePool (NicDevice->MyDevPath);
> +  }
> +
> +  if (NicDevice != 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 device.
> +
> +**/
> +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 = 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 == 0) {
> +    Status = 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 devicepath
> +      // and usbio protocol.
> +      //
> +      gBS->CloseProtocol (
> +                Controller,
> +                &gEfiDevicePathProtocolGuid,
> +                This->DriverBindingHandle,
> +                Controller
> +                );
> +      gBS->CloseProtocol (
> +                Controller,
> +                &gEfiUsbIoProtocolGuid,
> +                This->DriverBindingHandle,
> +                Controller
> +                );
> +      return EFI_SUCCESS;
> +    }
> +
> +    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +    Status = gBS->UninstallMultipleProtocolInterfaces (
> +                          Controller,
> +                          &gEfiCallerIdGuid,
> +                          NicDevice,
> +                          &gEfiSimpleNetworkProtocolGuid,
> +                          &NicDevice->SimpleNetwork,
> +                          &gEfiDevicePathProtocolGuid,
> +                          NicDevice->MyDevPath,
> +                          NULL
> +                          );
> +
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +    //
> +    // Close the bus driver
> +    //
> +    Status = gBS->CloseProtocol (
> +                        Controller,
> +                        &gEfiDevicePathProtocolGuid,
> +                        This->DriverBindingHandle,
> +                        Controller
> +                        );
> +
> +    Status = gBS->CloseProtocol (
> +                        Controller,
> +                        &gEfiUsbIoProtocolGuid,
> +                        This->DriverBindingHandle,
> +                        Controller
> +                        );
> +    return EFI_SUCCESS;
> +  }
> +
> +  AllChildrenStopped = TRUE;
> +
> +  for (Index = 0; Index < NumberOfChildren; Index++) {
> +    Status = gBS->OpenProtocol (
> +                      ChildHandleBuffer[Index],
> +                      &gEfiSimpleNetworkProtocolGuid,
> +                      (VOID **) &SimpleNetwork,
> +                      This->DriverBindingHandle,
> +                      Controller,
> +                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                      );
> +
> +    if (EFI_ERROR (Status)) {
> +      AllChildrenStopped = FALSE;
> +      continue;
> +    }
> +
> +    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +    gBS->CloseProtocol (
> +              Controller,
> +              &gEfiUsbIoProtocolGuid,
> +              This->DriverBindingHandle,
> +              ChildHandleBuffer[Index]
> +              );
> +
> +    Status = gBS->UninstallMultipleProtocolInterfaces (
> +                          ChildHandleBuffer[Index],
> +                          &gEfiCallerIdGuid,
> +                          NicDevice,
> +                          &gEfiSimpleNetworkProtocolGuid,
> +                          &NicDevice->SimpleNetwork,
> +                          &gEfiDevicePathProtocolGuid,
> +                          NicDevice->MyDevPath,
> +                          NULL
> +                          );
> +
> +    if (EFI_ERROR (Status)) {
> +      Status = gBS->OpenProtocol (
> +                        Controller,
> +                        &gEfiUsbIoProtocolGuid,
> +                        (VOID **) &NicDevice->UsbIo,
> +                        This->DriverBindingHandle,
> +                        ChildHandleBuffer[Index],
> +                        EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
> +                        );
> +    } else {
> +      if (NicDevice->BulkInbuf != NULL) {
> +        gBS->FreePool (NicDevice->BulkInbuf);
> +      }
> +
> +      if (NicDevice->TxTest != NULL) {
> +        gBS->FreePool (NicDevice->TxTest);
> +      }
> +
> +      if (NicDevice->MyDevPath != NULL) {
> +        gBS->FreePool (NicDevice->MyDevPath);
> +      }
> +
> +      if (NicDevice != NULL) {
> +        gBS->FreePool (NicDevice);
> +      }
> +    }
> +  }
> +
> +  if (!AllChildrenStopped) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Driver binding protocol declaration
> +**/
> +EFI_DRIVER_BINDING_PROTOCOL  gDriverBinding = {
> +  DriverSupported,
> +  DriverStart,
> +  DriverStop,
> +  0xa,
> +  NULL,
> +  NULL
> +};
> +
> +
> +/**
> +  Ax88179 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 = 0;
> +  Handle = NULL;
> +  Status = gBS->LocateHandle (
> +                  ByProtocol,
> +                  &gEfiCallerIdGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  NULL);
> +  if (EFI_BUFFER_TOO_SMALL == Status) {
> +    for (; ;) {
> +      //
> +      //  One or more block IO devices are present
> +      //
> +      Status = gBS->AllocatePool (
> +                      EfiBootServicesData,
> +                      BufferSize,
> +                      (VOID **) &Handle
> +                      );
> +      if (EFI_ERROR (Status)) {
> +        break;
> +      }
> +
> +      //
> +      //  Locate the block IO devices
> +      //
> +      Status = gBS->LocateHandle (
> +                      ByProtocol,
> +                      &gEfiCallerIdGuid,
> +                      NULL,
> +                      &BufferSize,
> +                      Handle);
> +      if (EFI_ERROR (Status)) {
> +        //
> +        //  Error getting handles
> +        //
> +
> +        break;
> +      }
> +
> +      //
> +      //  Remove any use of the driver
> +      //
> +      Max = BufferSize / sizeof (Handle[0]);
> +      for (Index = 0; Max > Index; Index++) {
> +        Status = DriverStop (&gDriverBinding,
> +                              Handle[Index],
> +                              0,
> +                              NULL);
> +        if (EFI_ERROR (Status)) {
> +          break;
> +        }
> +      }
> +      break;
> +    }
> +  } else {
> +    if (EFI_NOT_FOUND == Status) {
> +      //
> +      //  No devices were found
> +      //
> +      Status = EFI_SUCCESS;
> +    }
> +  }
> +
> +  //
> +  //  Free the handle array
> +  //
> +  if (Handle != 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;
> +}
> +
> +
> +/**
> +Ax88179 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 = gBS->HandleProtocol (
> +                  gImageHandle,
> +                  &gEfiLoadedImageProtocolGuid,
> +                  (VOID **)&LoadedImage
> +                  );
> +  if (!EFI_ERROR (Status)) {
> +    LoadedImage->Unload = DriverUnload;
> +  }
> +
> +  //
> +  //  Add the driver to the list of drivers
> +  //
> +  Status = EfiLibInstallDriverBindingComponentName2 (
> +             ImageHandle,
> +             SystemTable,
> +             &gDriverBinding,
> +             ImageHandle,
> +             &gComponentName,
> +             &gComponentName2
> +             );
> +
> +  return Status;
> +}
> diff --git a/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/SimpleNetwork.c
> b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/SimpleNetwork.c
> new file mode 100644
> index 000000000000..948b73031463
> --- /dev/null
> +++ b/Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/SimpleNetwork.c
> @@ -0,0 +1,1548 @@
> +/** @file
> +  Provides the Simple Network functions.
> +
> +  Copyright (c) 2011, Intel Corporation
> +  Copyright (c) 2020, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "Ax88179.h"
> +
> +/**
> +  This function updates the filtering on the receiver.
> +
> +  This support routine calls ::Ax88179MacAddressSet to update
> +  the MAC address.  This routine then rebuilds the multicast
> +  hash by calling ::Ax88179MulticastClear and ::Ax88179MulticastSet.
> +  Finally this routine enables the receiver by calling
> +  ::Ax88179RxControl.
> +
> +  @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 network 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 = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +  Mode = SimpleNetwork->Mode;
> +  //
> +  // Clear the multicast hash table
> +  //
> +  Ax88179MulticastClear (NicDevice);
> +
> +  //
> +  // Load the multicast hash table
> +  //
> +  if ((Mode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
> +    for (Index = 0; Index < Mode->MCastFilterCount; Index++) {
> +      //
> +      // Enable the next multicast address
> +      //
> +      Ax88179MulticastSet (NicDevice,
> +                            &Mode->MCastFilter[Index].Addr[0]);
> +    }
> +  }
> +
> +  //
> +  // Enable the receiver
> +  //
> +  Status = Ax88179RxControl (NicDevice, Mode->ReceiveFilterSetting);
> +
> +  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 ::Ax88179Rx 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 will not be read from
> +                                the device.  If this is not NULL, the interrupt status will
> +                                be read from teh device.  When the interrupt status is read,
> +                                it will also be cleared.  Clearing the transmit interrupt
> +                                does not empty the recycled transmit buffer array.
> +  @param [out] TxBuf          Recycled transmit buffer address.  The network interface will
> +                                not transmit if its internal recycled transmit buffer array is
> +                                full.  Reading the transmit buffer does not clear the transmit
> +                                interrupt.  If this is NULL, then the transmit buffer status
> +                                will not be read.  If there are not transmit buffers to recycle
> +                                and TxBuf is not NULL, *TxBuf will be set to NULL.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER 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 network 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;
> +  EFI_STATUS              Status = EFI_SUCCESS;
> +  EFI_TPL                 TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // Return the transmit buffer
> +    //
> +    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +    if ((TxBuf != NULL) && (NicDevice->TxBuffer != NULL)) {
> +      *TxBuf = NicDevice->TxBuffer;
> +      NicDevice->TxBuffer = NULL;
> +    }
> +
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      if ((TxBuf == NULL) && (InterruptStatus == NULL)) {
> +        Status = EFI_INVALID_PARAMETER;
> +        goto EXIT;
> +      }
> +
> +#if REPORTLINK
> +#else
> +      if (!NicDevice->LinkUp || !NicDevice->Complete) {
> +#endif
> +        Status = Ax88179NegotiateLinkComplete (NicDevice,
> +                                                &NicDevice->PollCount,
> +                                                &NicDevice->Complete,
> +                                                &NicDevice->LinkUp,
> +                                                &NicDevice->LinkSpeed100Mbps,
> +                                                &NicDevice->LinkSpeed1000Mbps,
> +                                                &NicDevice->FullDuplex);
> +
> +        if (EFI_ERROR(Status))
> +          goto EXIT;
> +#if REPORTLINK
> +        if (NicDevice->LinkUp && NicDevice->Complete) {
> +          Mode->MediaPresent = TRUE;
> +          Status = Ax88179SetMedium (NicDevice);
> +        } else {
> +          Mode->MediaPresent = FALSE;
> +        }
> +#else
> +        if (NicDevice->LinkUp && NicDevice->Complete) {
> +          Mode->MediaPresent = TRUE;
> +          Mode->MediaPresentSupported = FALSE;
> +          Status = Ax88179SetMedium (NicDevice);
> +
> +        }
> +      }
> +#endif
> +    } else {
> +      if (EfiSimpleNetworkStarted == Mode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      } else {
> +        Status = EFI_NOT_STARTED ;
> +      }
> +    }
> +  } else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +  if (InterruptStatus != NULL) {
> +    *InterruptStatus = 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 write operations.
> +  @param [in] Offset            Byte offset in the NVRAM device at which to start the
> +                                read or write operation.  This must be a multiple of
> +                                NvRamAccessSize and less than NvRamSize.
> +  @param [in] BufferSize        The number of bytes to read or write from the NVRAM device.
> +                                This must also be a multiple of NvramAccessSize.
> +  @param [in, out] 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 network 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 = EFI_INVALID_PARAMETER;
> +  EFI_TPL                 TplPrevious;
> +  EFI_SIMPLE_NETWORK_MODE *Mode;
> +  NIC_DEVICE              *NicDevice;
> +  UINTN                   Index;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  if ((SimpleNetwork == NULL) || (SimpleNetwork->Mode == NULL)) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto  EXIT;
> +  }
> +
> +  NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +  Mode = SimpleNetwork->Mode;
> +
> +  if (EfiSimpleNetworkInitialized != Mode->State) {
> +    Status = EFI_NOT_STARTED;
> +    goto  EXIT;
> +  }
> +
> +  if (Offset != 0) {
> +    if (((Offset % Mode->NvRamAccessSize) != 0) || (Offset >= Mode->NvRamSize)) {
> +      Status = EFI_INVALID_PARAMETER;
> +      goto  EXIT;
> +    }
> +  }
> +  //
> +  // Offset must be a multiple of NvRamAccessSize and less than NvRamSize.
> +  //
> +  if ((BufferSize % Mode->NvRamAccessSize) != 0) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto  EXIT;
> +  }
> +
> +  if (BufferSize + Offset > Mode->NvRamSize) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto  EXIT;
> +  }
> +
> +  if (Buffer == NULL) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto  EXIT;
> +  }
> +
> +  //
> +  // ReadWrite: TRUE FOR READ FALSE FOR WRITE
> +  //
> +  if (ReadWrite) {
> +    for (Index = 0; Index < BufferSize / 2; Index++) {
> +      Status = Ax88179SromRead (NicDevice,
> +                                 (UINT32)(Offset/2 + Index),
> +                                 (((UINT16*)Buffer) + Index));
> +    }
> +  } else {
> +    Status = Ax88179EnableSromWrite(NicDevice);
> +    if (EFI_ERROR(Status))
> +      goto EXIT;
> +
> +    for (Index = 0; Index < BufferSize / 2; Index++) {
> +      Status = Ax88179SromWrite (NicDevice,
> +                                  (UINT32)(Offset/2 + Index),
> +                                  (((UINT16*)Buffer) + Index));
> +    }
> +
> +    Status = Ax88179DisableSromWrite(NicDevice);
> +
> +    if (BufferSize == 272)
> +      Status = Ax88179ReloadSrom(NicDevice);
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +EXIT:
> +  gBS->RestoreTPL (TplPrevious);
> +  return Status;
> +}
> +
> +/**
> +  Resets the network adapter and allocates the transmit and receive buffers
> +  required by the network interface; optionally, also requests allocation of
> +  additional transmit and receive buffers.  This routine must be called before
> +  any other routine in the Simple Network protocol is called.
> +
> +  @param [in] SimpleNetwork    Protocol instance pointer
> +  @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation
> +  @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_OUT_OF_RESOURCES  There was not enough memory for the transmit and receive buffers
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL (TPL_CALLBACK);
> +
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // Determine if the interface is already started
> +    //
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkStarted == Mode->State) {
> +      if ((0 == ExtraRxBufferSize) && (0 == ExtraTxBufferSize)) {
> +        //
> +        // Start the adapter
> +        //
> +        TmpState = Mode->State;
> +        Mode->State = EfiSimpleNetworkInitialized;
> +        Status = SN_Reset (SimpleNetwork, FALSE);
> +        if (EFI_ERROR (Status)) {
> +          //
> +          // Update the network state
> +          //
> +          Mode->State = TmpState;
> +        } else {
> +          Mode->MediaPresentSupported = TRUE;
> +          NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +          Mode->MediaPresent = Ax88179GetLinkStatus (NicDevice);
> +        }
> +      } else {
> +        Status = EFI_UNSUPPORTED;
> +      }
> +    } else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  } else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Return the operation status
> +  //
> +  gBS->RestoreTPL (TplPrevious);
> +  return Status;
> +}
> +
> +
> +/**
> +  This function converts a multicast IP address to a multicast HW MAC address
> +  for all packet transactions.
> +
> +  @param [in] SimpleNetwork    Protocol instance pointer
> +  @param [in] IPv6             Set to TRUE if the multicast IP address is IPv6 [RFC2460].
> +                                Set to FALSE if the multicast IP address is IPv4 [RFC 791].
> +  @param [in] IP               The multicast IP address that is to be converted to a
> +                                multicast HW MAC address.
> +  @param [in] MAC              The multicast HW MAC address that is to be generated from IP.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // The interface must be running
> +    //
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      if (IP == NULL || MAC == NULL) {
> +        Status = EFI_INVALID_PARAMETER;
> +        goto EXIT;
> +      }
> +      if (IPv6) {
> +        Status = EFI_UNSUPPORTED;
> +        goto EXIT;
> +      } else {
> +        //
> +        // check if the ip given is a mcast IP
> +        //
> +        if ((IP->v4.Addr[0] & 0xF0) != 0xE0) {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        } else {
> +          MAC->Addr[0] = 0x01;
> +          MAC->Addr[1] = 0x00;
> +          MAC->Addr[2] = 0x5e;
> +          MAC->Addr[3] = (UINT8) (IP->v4.Addr[1] & 0x7f);
> +          MAC->Addr[4] = (UINT8) IP->v4.Addr[2];
> +          MAC->Addr[5] = (UINT8) IP->v4.Addr[3];
> +          Status = EFI_SUCCESS;
> +        }
> +      }
> +    } else {
> +      if (EfiSimpleNetworkStarted == Mode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      } else {
> +        Status = EFI_NOT_STARTED ;
> +      }
> +    }
> +  } else {
> +    Status = 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 network
> +  interface.  If there are no packets on the receive queue, then EFI_NOT_READY
> +  will be returned.  If there is a packet on the receive queue, and the size
> +  of the packet is smaller than BufferSize, then the contents of the packet
> +  will be placed in Buffer, and BufferSize will be udpated with the actual
> +  size of the packet.  In addition, if SrcAddr, DestAddr, and Protocol are
> +  not NULL, then these values will be extracted from the media header and
> +  returned.  If BufferSize is smaller than the received packet, then the
> +  size of the receive packet will be placed in BufferSize and
> +  EFI_BUFFER_TOO_SMALL will be returned.
> +
> +  This routine calls ::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 to be filled in by
> +                                the Transmit() function.  If HeaderSize is non-zero, then
> +                                it must be equal to SimpleNetwork->Mode->MediaHeaderSize
> +                                and DestAddr and Protocol parameters must not be NULL.
> +  @param [out] BufferSize      The size, in bytes, of the entire packet (media header and
> +                                data) to be transmitted through the network interface.
> +  @param [out] Buffer          A pointer to the packet (media header followed by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [out] SrcAddr         The source HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [out] DestAddr        The destination HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [out] Protocol        The type of header to build.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         No packets have been received on the network interface.
> +  @retval EFI_BUFFER_TOO_SMALL  The packet is larger than BufferSize bytes.
> +  @retval EFI_INVALID_PARAMETER 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 network 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;
> +  EFI_STATUS              Status;
> +  UINT16                  Type = 0;
> +  UINT16                  CurrentPktLen;
> +  BOOLEAN                 Valid = TRUE;
> +  EFI_TPL                 TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL (TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // The interface must be running
> +    //
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      if ((BufferSize == NULL) || (Buffer == NULL)) {
> +        Status = EFI_INVALID_PARAMETER;
> +        gBS->RestoreTPL (TplPrevious);
> +        return Status;
> +      }
> +
> +      //
> +      // Update the link status
> +      //
> +      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +      if (NicDevice->LinkUp && NicDevice->Complete) {
> +        if ((HeaderSize != NULL) && (*HeaderSize == 7720)) {
> +          NicDevice->Grub_f = TRUE;
> +        }
> +
> +        if ((NicDevice->Grub_f) && (*HeaderSize != 7720)) {
> +          gBS->RestoreTPL (TplPrevious);
> +          return EFI_NOT_READY;
> +        }
> +
> +        //
> +        //  Attempt to do bulk in
> +        //
> +        if (NicDevice->PktCnt == 0) {
> +          Status = Ax88179BulkIn(NicDevice);
> +          if (EFI_ERROR(Status))
> +            goto  no_pkt;
> +        }
> +        CurrentPktLen = *((UINT16*) (NicDevice->CurPktHdrOff + 2));
> +        if (CurrentPktLen & (RXHDR_DROP | RXHDR_CRCERR))
> +          Valid = FALSE;
> +        CurrentPktLen &=  0x1fff;
> +        CurrentPktLen -= 2; /*EEEE*/
> +
> +        if (Valid && (60 <= CurrentPktLen) &&
> +        ((CurrentPktLen - 14) <= MAX_ETHERNET_PKT_SIZE) &&
> +            (*((UINT16*)NicDevice->CurPktOff)) == 0xEEEE) {
> +          if (*BufferSize < (UINTN)CurrentPktLen) {
> +            gBS->RestoreTPL (TplPrevious);
> +            return EFI_BUFFER_TOO_SMALL;
> +          }
> +          *BufferSize = CurrentPktLen;
> +          CopyMem (Buffer, NicDevice->CurPktOff + 2, CurrentPktLen);
> +
> +          Header = (ETHERNET_HEADER *) NicDevice->CurPktOff + 2;
> +
> +          if ((HeaderSize != NULL)  && ((*HeaderSize != 7720))) {
> +            *HeaderSize = sizeof (*Header);
> +          }
> +
> +          if (DestAddr != NULL) {
> +            CopyMem (DestAddr, &Header->DestAddr, PXE_HWADDR_LEN_ETHER);
> +          }
> +          if (SrcAddr != NULL) {
> +            CopyMem (SrcAddr, &Header->SrcAddr, PXE_HWADDR_LEN_ETHER);
> +          }
> +          if (Protocol != NULL) {
> +            Type = Header->Type;
> +            Type = (UINT16)((Type >> 8) | (Type << 8));
> +            *Protocol = Type;
> +          }
> +          NicDevice->PktCnt--;
> +          NicDevice->CurPktHdrOff += 4;
> +          NicDevice->CurPktOff += (CurrentPktLen + 2 + 7) & 0xfff8;
> +          Status = EFI_SUCCESS;
> +        } else {
> +          NicDevice->PktCnt = 0;
> +          Status = EFI_NOT_READY;
> +        }
> +      } else {
> +        Status = EFI_NOT_READY;
> +      }
> +    } else {
> +      if (EfiSimpleNetworkStarted == Mode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      } else {
> +        Status = EFI_NOT_STARTED;
> +      }
> +    }
> +  } else {
> +    Status = 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 hardware
> +        a more liberal setting is selected.
> +
> +  If the same bits are set in the Enable and Disable parameters, then the bits
> +  in the Disable parameter takes precedence.
> +
> +  If the ResetMCastFilter parameter is TRUE, then the multicast address list
> +  filter is disabled (irregardless of what other multicast bits are set in
> +  the enable and Disable parameters).  The SNP->Mode->MCastFilterCount field
> +  is set to zero.  The SNP->Mode->MCastFilter contents are undefined.
> +
> +  After enableing or disabling receive filter settings, software should
> +  verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings,
> +  SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields.
> +
> +  Note: Some network drivers and/or devices will automatically promote
> +  receive filter settings if the requested setting can not be honored.
> +  For example, if a request for four multicast addresses is made and
> +  the underlying hardware only supports two multicast addresses the
> +  driver might set the promiscuous or promiscuous multicast receive filters
> +  instead.  The receiving software is responsible for discarding any extra
> +  packets that get through the hardware receive filters.
> +
> +  If ResetMCastFilter is TRUE, then the multicast receive filter list
> +  on the network interface will be reset to the default multicast receive
> +  filter list.  If ResetMCastFilter is FALSE, and this network interface
> +  allows the multicast receive filter list to be modified, then the
> +  MCastFilterCnt and MCastFilter are used to update the current multicast
> +  receive filter list.  The modified receive filter list settings can be
> +  found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE.
> +
> +  This routine calls ::ReceiveFilterUpdate to update the receive
> +  state in the network adapter.
> +
> +  @param [in] 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 TRUE.
> +  @param [in] ResetMCastFilter Set to TRUE to reset the contents of the multicast receive
> +                                filters on the network interface to their default values.
> +  @param [in] MCastFilterCnt    Number of multicast HW MAC address in the new MCastFilter list.
> +                                This value must be less than or equal to the MaxMCastFilterCnt
> +                                field of EFI_SIMPLE_NETWORK_MODE.  This field is optional if
> +                                ResetMCastFilter is TRUE.
> +  @param [in] MCastFilter      A pointer to a list of new multicast receive filter HW MAC
> +                                addresses.  This list will replace any existing multicast
> +                                HW MAC address list.  This field is optional if ResetMCastFilter
> +                                is TRUE.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = EFI_SUCCESS;
> +  EFI_TPL                 TplPrevious;
> +  UINTN                   Index;
> +  UINT8                   Temp;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  Mode = SimpleNetwork->Mode;
> +
> +  if (SimpleNetwork == NULL) {
> +    gBS->RestoreTPL(TplPrevious);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  switch (Mode->State) {
> +  case EfiSimpleNetworkInitialized:
> +    break;
> +
> +  case EfiSimpleNetworkStopped:
> +    Status = EFI_NOT_STARTED;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +
> +  default:
> +    Status = 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) != 0) ||
> +      ((Disable &~Mode->ReceiveFilterMask) != 0)) {
> +    Status = EFI_INVALID_PARAMETER;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +  }
> +
> +  if (ResetMCastFilter) {
> +    Disable |= (EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & Mode->ReceiveFilterMask);
> +    MCastFilterCnt = 0;
> +    Mode->MCastFilterCount = 0;
> +    if ((0 == (Mode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST)) &&
> +   Enable == 0 && Disable == 2) {
> +      gBS->RestoreTPL(TplPrevious);
> +      return EFI_SUCCESS;
> +    }
> +  } else {
> +    if (MCastFilterCnt != 0) {
> +      EFI_MAC_ADDRESS * MulticastAddress;
> +      MulticastAddress =  MCastFilter;
> +
> +      if ((MCastFilterCnt > Mode->MaxMCastFilterCount) ||
> +          (MCastFilter == NULL)) {
> +        Status = EFI_INVALID_PARAMETER;
> +        gBS->RestoreTPL(TplPrevious);
> +        return Status;
> +      }
> +
> +      for (Index = 0 ; Index < MCastFilterCnt ; Index++) {
> +          Temp = MulticastAddress->Addr[0];
> +          if ((Temp & 0x01) != 0x01) {
> +            gBS->RestoreTPL(TplPrevious);
> +            return EFI_INVALID_PARAMETER;
> +          }
> +          MulticastAddress++;
> +      }
> +
> +      Mode->MCastFilterCount = (UINT32)MCastFilterCnt;
> +      CopyMem (&Mode->MCastFilter[0],
> +               MCastFilter,
> +               MCastFilterCnt * sizeof (EFI_MAC_ADDRESS/**MCastFilter*/));
> +    }
> +  }
> +
> +  if (Enable == 0 && Disable == 0 && !ResetMCastFilter && MCastFilterCnt == 0) {
> +    Status = EFI_SUCCESS;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +  }
> +
> +  if ((Enable & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastFilterCnt == 0) {
> +    Status = EFI_INVALID_PARAMETER;
> +    gBS->RestoreTPL(TplPrevious);
> +    return Status;
> +  }
> +
> +  Mode->ReceiveFilterSetting |= Enable;
> +  Mode->ReceiveFilterSetting &= ~Disable;
> +
> +  Status = ReceiveFilterUpdate (SimpleNetwork);
> +
> +  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 ::Ax88179Reset to perform the adapter specific
> +  reset operation.  This routine also starts the link negotiation
> +  by calling ::Ax88179NegotiateLinkStart.
> +
> +  @param [in] SimpleNetwork    Protocol instance pointer
> +  @param [in] ExtendedVerification  Indicates that the driver may perform a more
> +                                exhaustive verification operation of the device
> +                                during reset.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  //  Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      //
> +      //  Update the device state
> +      //
> +      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +      //
> +      //  Reset the device
> +      //
> +      if (!NicDevice->FirstRst) {
> +        Status = EFI_SUCCESS;
> +      } else {
> +        Status = Ax88179Reset (NicDevice);
> +        if (!EFI_ERROR (Status)) {
> +          Status = ReceiveFilterUpdate (SimpleNetwork);
> +          if (!EFI_ERROR (Status) && !NicDevice->LinkUp && NicDevice->FirstRst) {
> +            Status = Ax88179NegotiateLinkStart (NicDevice);
> +            NicDevice->FirstRst = FALSE;
> +          }
> +        }
> +      }
> +    } else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  } else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +  //
> +  // Return the operation status
> +  //
> +  gBS->RestoreTPL(TplPrevious);
> +  return Status;
> +}
> +
> +/**
> +  Initialize the simple network protocol.
> +
> +  This routine calls ::Ax88179MacAddressGet 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 = &NicDevice->SimpleNetwork;
> +  SimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
> +  SimpleNetwork->Start = SN_Start;
> +  SimpleNetwork->Stop = SN_Stop;
> +  SimpleNetwork->Initialize = SN_Initialize;
> +  SimpleNetwork->Reset = SN_Reset;
> +  SimpleNetwork->Shutdown = SN_Shutdown;
> +  SimpleNetwork->ReceiveFilters = SN_ReceiveFilters;
> +  SimpleNetwork->StationAddress = SN_StationAddress;
> +  SimpleNetwork->Statistics = SN_Statistics;
> +  SimpleNetwork->MCastIpToMac = SN_MCastIPtoMAC;
> +  SimpleNetwork->NvData = SN_NvData;
> +  SimpleNetwork->GetStatus = SN_GetStatus;
> +  SimpleNetwork->Transmit = SN_Transmit;
> +  SimpleNetwork->Receive = SN_Receive;
> +  SimpleNetwork->WaitForPacket = NULL;
> +  Mode = &NicDevice->SimpleNetworkData;
> +  SimpleNetwork->Mode = Mode;
> +  Mode->State = EfiSimpleNetworkStopped;
> +  Mode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> +  Mode->MediaHeaderSize = sizeof (ETHERNET_HEADER);
> +  Mode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> +  Mode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> +                           | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> +  Mode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                              | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
> +  Mode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
> +  Mode->MCastFilterCount = 0;
> +  Mode->NvRamSize = 512;
> +  Mode->NvRamAccessSize = 2;
> +  SetMem (&Mode->BroadcastAddress,
> +           PXE_HWADDR_LEN_ETHER,
> +           0xff);
> +  Mode->IfType = NET_IFTYPE_ETHERNET;
> +  Mode->MacAddressChangeable = TRUE;
> +  Mode->MultipleTxSupported = FALSE;
> +  Mode->MediaPresentSupported = TRUE;
> +  Mode->MediaPresent = FALSE;
> +  //
> +  //  Read the MAC address
> +  //
> +  NicDevice->PhyId = PHY_ID_INTERNAL;
> +  NicDevice->LinkSpeed100Mbps = FALSE;
> +  NicDevice->LinkSpeed1000Mbps = TRUE;
> +  NicDevice->FullDuplex = TRUE;
> +  NicDevice->Complete = FALSE;
> +  NicDevice->LinkUp = FALSE;
> +  NicDevice->Grub_f = FALSE;
> +  NicDevice->FirstRst = TRUE;
> +  NicDevice->PktCnt = 0;
> +  NicDevice->SkipRXCnt = 0;
> +  NicDevice->UsbMaxPktSize = 512;
> +  NicDevice->SetZeroLen = TRUE;
> +
> +  Status = Ax88179MacAddressGet (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 = gBS->AllocatePool (EfiBootServicesData,
> +                               AX88179_MAX_BULKIN_SIZE,
> +                               (VOID **) &NicDevice->BulkInbuf);
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = gBS->AllocatePool (EfiBootServicesData,
> +                               sizeof (TX_PACKET),
> +                               (VOID **) &NicDevice->TxTest);
> +  if (EFI_ERROR (Status)) {
> +    gBS->FreePool (NicDevice->BulkInbuf);
> +  }
> +
> +  //
> +  //  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 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  Status = EFI_INVALID_PARAMETER;
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkStopped == Mode->State) {
> +      //
> +      // Initialize the mode structure
> +      // NVRAM access is not supported
> +      //
> +      ZeroMem (Mode, sizeof (*Mode));
> +
> +      Mode->State = EfiSimpleNetworkStarted;
> +      Mode->HwAddressSize = PXE_HWADDR_LEN_ETHER;
> +      Mode->MediaHeaderSize = sizeof (ETHERNET_HEADER);
> +      Mode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE;
> +      Mode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS
> +                               | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
> +      Mode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
> +      Mode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
> +      Mode->MCastFilterCount = 0;
> +      Mode->NvRamSize = 512;
> +      Mode->NvRamAccessSize = 2;
> +      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +      Status = Ax88179MacAddressGet (NicDevice, &Mode->PermanentAddress.Addr[0]);
> +      CopyMem (&Mode->CurrentAddress,
> +                &Mode->PermanentAddress,
> +                sizeof (Mode->CurrentAddress));
> +      SetMem(&Mode->BroadcastAddress, PXE_HWADDR_LEN_ETHER, 0xff);
> +      Mode->IfType = NET_IFTYPE_ETHERNET;
> +      Mode->MacAddressChangeable = TRUE;
> +      Mode->MultipleTxSupported = FALSE;
> +      Mode->MediaPresentSupported = TRUE;
> +      Mode->MediaPresent = FALSE;
> +
> +    } else {
> +      Status = 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 FALSE
> +  then the current station address is changed to the address specified by
> +  New.
> +
> +  This routine calls ::Ax88179MacAddressSet 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 network
> +                                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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) &&
> +      (SimpleNetwork->Mode != NULL) &&
> +      ((!Reset) || (Reset && (New != NULL)))) {
> +    //
> +    // Verify that the adapter is already started
> +    //
> +    NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == 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 = Ax88179MacAddressSet (NicDevice, &Mode->CurrentAddress.Addr[0]);
> +    } else {
> +      if (EfiSimpleNetworkStarted == Mode->State) {
> +        Status = EFI_DEVICE_ERROR; ;
> +      } else {
> +        Status = EFI_NOT_STARTED ;
> +      }
> +    }
> +  } else {
> +    Status = 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 the network interface.
> +  @param [in, out] StatisticsSize  On input the size, in bytes, of StatisticsTable.  On output
> +                                the size, in bytes, of the resulting table of statistics.
> +  @param [out] StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
> +                                conains the statistics.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_BUFFER_TOO_SMALL  The StatisticsTable is NULL or the buffer 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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  Mode = SimpleNetwork->Mode;
> +
> +  if (EfiSimpleNetworkInitialized == Mode->State) {
> +    if ((StatisticsSize != NULL) && (*StatisticsSize == 0)) {
> +      Status = EFI_BUFFER_TOO_SMALL;
> +      goto EXIT;
> +    }
> +
> +    if(Reset) {
> +      Status = EFI_SUCCESS;
> +    } else {
> +      Status = EFI_SUCCESS;
> +    }
> +  } else {
> +    if (EfiSimpleNetworkStarted == Mode->State) {
> +      Status = EFI_DEVICE_ERROR; ;
> +    } else {
> +      Status = EFI_NOT_STARTED ;
> +    }
> +  }
> +
> +  Status = EFI_UNSUPPORTED;
> +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 network 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 = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // Determine if the interface is started
> +    //
> +    Mode = SimpleNetwork->Mode;
> +
> +    if (EfiSimpleNetworkStarted == Mode->State) {
> +        Mode->State = EfiSimpleNetworkStopped;
> +        Status = EFI_SUCCESS;
> +    } else {
> +        Status = EFI_NOT_STARTED;
> +    }
> +  } else {
> +    Status = 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 network 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;
> +  EFI_STATUS              Status;
> +  NIC_DEVICE              *NicDevice;
> +  EFI_TPL                 TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // Determine if the interface is already started
> +    //
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      //
> +      // Stop the adapter
> +      //
> +      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +      Status = Ax88179MacAddressGet (NicDevice, &Mode->PermanentAddress.Addr[0]);
> +      if (!EFI_ERROR (Status)) {
> +        //
> +        // Update the network state
> +        //
> +        Mode->State = EfiSimpleNetworkStarted;
> +      } else if (EFI_DEVICE_ERROR == Status) {
> +        Mode->State = EfiSimpleNetworkStopped;
> +      }
> +
> +    } else {
> +      Status = EFI_NOT_STARTED;
> +    }
> +  } else {
> +    Status = 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 ::Ax88179Rx 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 must not be NULL.
> +  @param [in] BufferSize        The size, in bytes, of the entire packet (media header and
> +                                data) to be transmitted through the network interface.
> +  @param [in] Buffer           A pointer to the packet (media header followed by data) to
> +                                to be transmitted.  This parameter can not be NULL.  If
> +                                HeaderSize is zero, then the media header is Buffer must
> +                                already be filled in by the caller.  If HeaderSize is nonzero,
> +                                then the media header will be filled in by the Transmit()
> +                                function.
> +  @param [in] SrcAddr          The source HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.  If HeaderSize is nonzero and
> +                                SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress
> +                                is used for the source HW MAC address.
> +  @param [in] DestAddr         The destination HW MAC address.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +  @param [in] Protocol         The type of header to build.  If HeaderSize is zero, then
> +                                this parameter is ignored.
> +
> +  @retval EFI_SUCCESS           This operation was successful.
> +  @retval EFI_NOT_STARTED       The network interface was not started.
> +  @retval EFI_NOT_READY         The network interface is too busy to accept this transmit request.
> +  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
> +  @retval EFI_INVALID_PARAMETER 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 network 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 = 0;
> +  EFI_TPL                 TplPrevious;
> +
> +  TplPrevious = gBS->RaiseTPL(TPL_CALLBACK);
> +  //
> +  // Verify the parameters
> +  //
> +  if ((SimpleNetwork != NULL) && (SimpleNetwork->Mode != NULL)) {
> +    //
> +    // The interface must be running
> +    //
> +    Mode = SimpleNetwork->Mode;
> +    if (EfiSimpleNetworkInitialized == Mode->State) {
> +      //
> +      // Update the link status
> +      //
> +      NicDevice = DEV_FROM_SIMPLE_NETWORK (SimpleNetwork);
> +
> +      if (NicDevice->LinkUp && NicDevice->Complete) {
> +        if ((HeaderSize != 0) && (Mode->MediaHeaderSize != HeaderSize))  {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        }
> +        if (BufferSize <  Mode->MediaHeaderSize) {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        }
> +        if (Buffer == NULL) {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        }
> +        if ((HeaderSize != 0) && (DestAddr == NULL)) {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        }
> +        if ((HeaderSize != 0) && (Protocol == NULL)) {
> +          Status = EFI_INVALID_PARAMETER;
> +          goto EXIT;
> +        }
> +        //
> +        //  Copy the packet into the USB buffer
> +        //
> +        // Buffer starting with 14 bytes 0
> +        CopyMem (&NicDevice->TxTest->Data[0], Buffer, BufferSize);
> +        NicDevice->TxTest->TxHdr1 = (UINT32) BufferSize;
> +        NicDevice->TxTest->TxHdr2 = 0;
> +        //
> +        //  Transmit the packet
> +        //
> +        Header = (ETHERNET_HEADER *) &NicDevice->TxTest->Data[0];
> +        if (HeaderSize != 0) {
> +          if (DestAddr != NULL) {
> +            CopyMem (&Header->DestAddr, DestAddr, PXE_HWADDR_LEN_ETHER);
> +          }
> +          if (SrcAddr != NULL) {
> +            CopyMem (&Header->SrcAddr, SrcAddr, PXE_HWADDR_LEN_ETHER);
> +          } else {
> +            CopyMem (&Header->SrcAddr, &Mode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER);
> +          }
> +          if (Protocol != NULL) {
> +            Type = *Protocol;
> +          } else {
> +              Type = (UINT16) BufferSize;
> +          }
> +          Type = (UINT16)((Type >> 8) | (Type << 8));
> +          Header->Type = Type;
> +        }
> +
> +        if (NicDevice->TxTest->TxHdr1 < MIN_ETHERNET_PKT_SIZE) {
> +          NicDevice->TxTest->TxHdr1 = MIN_ETHERNET_PKT_SIZE;
> +          ZeroMem (&NicDevice->TxTest->Data[BufferSize],
> +                    MIN_ETHERNET_PKT_SIZE - BufferSize);
> +        }
> +
> +        TransferLength = sizeof (NicDevice->TxTest->TxHdr1)
> +                       + sizeof (NicDevice->TxTest->TxHdr2)
> +                       + NicDevice->TxTest->TxHdr1;
> +        //
> +        //  Work around USB bus driver bug where a timeout set by receive
> +        //  succeeds but the timeout expires immediately after, causing the
> +        //  transmit operation to timeout.
> +        //
> +        UsbIo = NicDevice->UsbIo;
> +        Status = UsbIo->UsbBulkTransfer (UsbIo,
> +                                           BULK_OUT_ENDPOINT,
> +                                           &NicDevice->TxTest->TxHdr1,
> +                                           &TransferLength,
> +                                           0xfffffffe,
> +                                           &TransferStatus);
> +
> +        if (!EFI_ERROR(Status) && !EFI_ERROR(Status)) {
> +          NicDevice->TxBuffer = Buffer;
> +          Status = EFI_SUCCESS;
> +        } else if (EFI_TIMEOUT == Status && EFI_USB_ERR_TIMEOUT == TransferStatus) {
> +          Status = EFI_NOT_READY;
> +        } else {
> +          Status = EFI_DEVICE_ERROR;
> +        }
> +      } else {
> +        //
> +        // No packets available.
> +        //
> +        Status = EFI_NOT_READY;
> +      }
> +    } else {
> +      if (EfiSimpleNetworkStarted == Mode->State) {
> +        Status = EFI_DEVICE_ERROR;
> +      } else {
> +        Status = EFI_NOT_STARTED;
> +      }
> +    }
> +  } else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +EXIT:
> +  gBS->RestoreTPL (TplPrevious);
> +  return Status;
> +}
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [edk2-platform][PATCH v3 4/6] Platform/RaspberryPi: Switch RPi3 USB NIC driver to Ax88772c
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 4/6] Platform/RaspberryPi: Switch RPi3 USB NIC driver to Ax88772c Samer El-Haj-Mahmoud
@ 2020-07-08 14:55   ` Ard Biesheuvel
  0 siblings, 0 replies; 14+ messages in thread
From: Ard Biesheuvel @ 2020-07-08 14:55 UTC (permalink / raw)
  To: Samer El-Haj-Mahmoud, devel; +Cc: Pete Batard, Andrei Warkentin, Leif Lindholm

On 6/8/20 4:38 PM, Samer El-Haj-Mahmoud wrote:
> Switch the ASIX USB NIC driver used in the RPi3 to the new Ax88772c.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Pete Batard <pete@akeo.ie>
> Cc: Andrei Warkentin <andrey.warkentin@gmail.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> 
> Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>

Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>

> ---
>   Platform/RaspberryPi/RPi3/RPi3.dsc | 2 +-
>   Platform/RaspberryPi/RPi3/RPi3.fdf | 2 +-
>   2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/Platform/RaspberryPi/RPi3/RPi3.dsc b/Platform/RaspberryPi/RPi3/RPi3.dsc
> index 059d16a912ab..b6c568f400ef 100644
> --- a/Platform/RaspberryPi/RPi3/RPi3.dsc
> +++ b/Platform/RaspberryPi/RPi3/RPi3.dsc
> @@ -656,7 +656,7 @@ [Components.common]
>     MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
>     MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
>     MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> -  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> +  Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf
>   
>     #
>     # SD/MMC support
> diff --git a/Platform/RaspberryPi/RPi3/RPi3.fdf b/Platform/RaspberryPi/RPi3/RPi3.fdf
> index e854cd214153..3c569f57740b 100644
> --- a/Platform/RaspberryPi/RPi3/RPi3.fdf
> +++ b/Platform/RaspberryPi/RPi3/RPi3.fdf
> @@ -289,7 +289,7 @@ [FV.FvMain]
>     INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
>     INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
>     INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> -  INF Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> +  INF Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf
>   
>     #
>     # SD/MMC support
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [edk2-platform][PATCH v3 5/6] Platform/HiSilicon: Switch HiKey USB NIC driver to Ax88772c
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 5/6] Platform/HiSilicon: Switch HiKey " Samer El-Haj-Mahmoud
@ 2020-07-08 14:55   ` Ard Biesheuvel
  0 siblings, 0 replies; 14+ messages in thread
From: Ard Biesheuvel @ 2020-07-08 14:55 UTC (permalink / raw)
  To: Samer El-Haj-Mahmoud, devel; +Cc: Andrei Warkentin

On 6/8/20 4:38 PM, Samer El-Haj-Mahmoud wrote:
> Switch the ASIX USB NIC driver used in HiKey to the new Ax88772c.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Andrei Warkentin <andrey.warkentin@gmail.com>
> 
> Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>

Reviewed-by: Ard Biesheuvel <ard.biesheuvel@arm.com>

> ---
>   Platform/Hisilicon/HiKey/HiKey.dsc | 2 +-
>   Platform/Hisilicon/HiKey/HiKey.fdf | 2 +-
>   2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/Platform/Hisilicon/HiKey/HiKey.dsc b/Platform/Hisilicon/HiKey/HiKey.dsc
> index 600f19a30762..83c901cf470c 100644
> --- a/Platform/Hisilicon/HiKey/HiKey.dsc
> +++ b/Platform/Hisilicon/HiKey/HiKey.dsc
> @@ -247,7 +247,7 @@ [Components.common]
>     #
>     # AX88772 Ethernet Driver
>     #
> -  Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> +  Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf
>   
>     #
>     # FAT filesystem + GPT/MBR partitioning
> diff --git a/Platform/Hisilicon/HiKey/HiKey.fdf b/Platform/Hisilicon/HiKey/HiKey.fdf
> index 657e6c8ef2ec..d9fe481527fb 100644
> --- a/Platform/Hisilicon/HiKey/HiKey.fdf
> +++ b/Platform/Hisilicon/HiKey/HiKey.fdf
> @@ -158,7 +158,7 @@ [FV.FvMain]
>     #
>     # AX88772 Ethernet Driver for Apple Ethernet Adapter
>     #
> -  INF Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
> +  INF Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf
>   
>     #
>     # FAT filesystem + GPT/MBR partitioning
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers
  2020-06-08 13:38 [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Samer El-Haj-Mahmoud
                   ` (5 preceding siblings ...)
  2020-06-08 13:38 ` [edk2-platform][PATCH v3 6/6] Drivers/OptionRomPkg: Remove old ASIX NIC drivers Samer El-Haj-Mahmoud
@ 2020-07-08 14:56 ` Ard Biesheuvel
  6 siblings, 0 replies; 14+ messages in thread
From: Ard Biesheuvel @ 2020-07-08 14:56 UTC (permalink / raw)
  To: Samer El-Haj-Mahmoud, devel
  Cc: Ray Ni, Leif Lindholm, Michael D Kinney, Pete Batard,
	Andrei Warkentin

On 6/8/20 4:38 PM, Samer El-Haj-Mahmoud wrote:
> This series updates the ASIX USB networking drivers:
> 
>   - Create new Drivers/ASIX/ package
>   - Add new ASIX drivers Ax88179 and Ax88772c to the new ASIX package
>   - Delete old Ax88772 and Ax88772b drivers from OptionRomPkg
> 
> Code pushed to https://github.com/samerhaj/edk2-platforms/tree/asix_usb_nic_drivers_ver3

Series pushes as 9e8e784277ce..d144cf773449

Thanks all.

> 
> version 1: https://edk2.groups.io/g/devel/message/58771
> version 2: https://edk2.groups.io/g/devel/message/58986
> version 3 changes:
>   - Rename AsixPkg to ASIX [Ray]
>   - Changed SNP Mode->IfType from EfiNetworkInterfaceUndi to
>     NET_IFTYPE_ETHERNET [Ard]
>   - Dropped runtime module types and associated depex, libraries,
>     and memory allocation [Ard]
>   - Dropped "SCT_PASS" and kept the enable logic [Leif]
>   - Dropped dead / commented out code and macros
>     (including "ARM" and "AMI") [Ard, Leif]
>   - Dropped unused debug macros [Leif, Ard]
>   - Dropped "Freddy" Comments and unused macros [Leif, Ard]
>   - Dropped inorrect VALID_ARCHITECTURES from INF files [Ard]
>   - Dropped all Hungarian notation variables [Ard, Leif]
>   - Dropped 'Yoda-style' compariosns [Ard, Leif]
>   - Dropped redundant casts [Ard]
>   - Fixed spacing, indentation, and curly braces [Ard, Leif]
>   - Used CamelCase definitions per coding style [Ard]
>   - Dropped 'success handling' [Ard]
>   - Sorted LibraryClasses and include files [Ard]
>   - Aligned variables and function parameters declarations [Ard]
>   - Cleaned up include headers [Leif]
>   - Added public link to orignal ASIX provided code [Leif]
> 
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Pete Batard <pete@akeo.ie>
> Cc: Andrei Warkentin <andrey.warkentin@gmail.com>
> 
> Signed-off-by: Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>
> 
> Samer El-Haj-Mahmoud (6):
>    Drivers/ASIX: Create ASIX drivers package
>    Drivers/ASIX: Add ASIX Ax88179 driver
>    Drivers/ASIX: Add ASIX Ax88772c driver
>    Platform/RaspberryPi: Switch RPi3 USB NIC driver to Ax88772c
>    Platform/HiSilicon: Switch HiKey USB NIC driver to Ax88772c
>    Drivers/OptionRomPkg: Remove old ASIX NIC drivers
> 
>   Drivers/ASIX/Asix.dec                         |   30 +
>   Drivers/ASIX/Asix.dsc                         |   68 +
>   Drivers/OptionRomPkg/OptionRomPkg.dsc         |    3 +-
>   Platform/Hisilicon/HiKey/HiKey.dsc            |    2 +-
>   Platform/RaspberryPi/RPi3/RPi3.dsc            |    2 +-
>   Platform/Hisilicon/HiKey/HiKey.fdf            |    2 +-
>   Platform/RaspberryPi/RPi3/RPi3.fdf            |    2 +-
>   .../Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf |   45 +
>   .../Usb/UsbNetworking/Ax88772c/Ax88772c.inf}  |   28 +-
>   .../Usb/UsbNetworking/Ax88772b/Ax88772b.inf   |   61 -
>   .../Bus/Usb/UsbNetworking/Ax88179/Ax88179.h}  |  792 ++++----
>   .../Bus/Usb/UsbNetworking/Ax88772c}/Ax88772.h |  489 ++---
>   .../Bus/Usb/UsbNetworking/Ax88179/Ax88179.c   | 1042 +++++++++++
>   .../UsbNetworking/Ax88179}/ComponentName.c    |  107 +-
>   .../Usb/UsbNetworking/Ax88179/DriverBinding.c |  639 +++++++
>   .../Usb/UsbNetworking/Ax88179/SimpleNetwork.c | 1548 +++++++++++++++
>   .../Bus/Usb/UsbNetworking/Ax88772c/Ax88772.c  | 1300 +++++++++++++
>   .../UsbNetworking/Ax88772c}/ComponentName.c   |   97 +-
>   .../UsbNetworking/Ax88772c/DriverBinding.c    |  652 +++++++
>   .../UsbNetworking/Ax88772c/SimpleNetwork.c    | 1581 ++++++++++++++++
>   .../Bus/Usb/UsbNetworking/Ax88772/Ax88772.c   | 1318 -------------
>   .../Usb/UsbNetworking/Ax88772/DriverBinding.c |  507 -----
>   .../Usb/UsbNetworking/Ax88772/SimpleNetwork.c | 1503 ---------------
>   .../Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c  |  875 ---------
>   .../UsbNetworking/Ax88772b/DriverBinding.c    |  696 -------
>   .../UsbNetworking/Ax88772b/SimpleNetwork.c    | 1657 -----------------
>   26 files changed, 7754 insertions(+), 7292 deletions(-)
>   create mode 100644 Drivers/ASIX/Asix.dec
>   create mode 100644 Drivers/ASIX/Asix.dsc
>   create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.inf
>   rename Drivers/{OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.inf => ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772c.inf} (58%)
>   delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772b.inf
>   rename Drivers/{OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.h => ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.h} (52%)
>   rename Drivers/{OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b => ASIX/Bus/Usb/UsbNetworking/Ax88772c}/Ax88772.h (69%)
>   create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/Ax88179.c
>   rename Drivers/{OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772 => ASIX/Bus/Usb/UsbNetworking/Ax88179}/ComponentName.c (69%)
>   create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/DriverBinding.c
>   create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88179/SimpleNetwork.c
>   create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/Ax88772.c
>   rename Drivers/{OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b => ASIX/Bus/Usb/UsbNetworking/Ax88772c}/ComponentName.c (70%)
>   create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/DriverBinding.c
>   create mode 100644 Drivers/ASIX/Bus/Usb/UsbNetworking/Ax88772c/SimpleNetwork.c
>   delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/Ax88772.c
>   delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/DriverBinding.c
>   delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772/SimpleNetwork.c
>   delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/Ax88772.c
>   delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/DriverBinding.c
>   delete mode 100644 Drivers/OptionRomPkg/Bus/Usb/UsbNetworking/Ax88772b/SimpleNetwork.c
> 


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-07-08 14:56 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-06-08 13:38 [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Samer El-Haj-Mahmoud
2020-06-08 13:38 ` [edk2-platform][PATCH v3 1/6] Drivers/ASIX: Create ASIX package Samer El-Haj-Mahmoud
2020-06-09  0:37   ` Ni, Ray
2020-06-08 13:38 ` [edk2-platform][PATCH v3 2/6] Drivers/ASIX: Add ASIX Ax88179 driver Samer El-Haj-Mahmoud
2020-06-09  0:37   ` Ni, Ray
2020-06-08 13:38 ` [edk2-platform][PATCH v3 3/6] Drivers/ASIX: Add ASIX Ax88772c driver Samer El-Haj-Mahmoud
2020-06-09  0:37   ` Ni, Ray
2020-06-08 13:38 ` [edk2-platform][PATCH v3 4/6] Platform/RaspberryPi: Switch RPi3 USB NIC driver to Ax88772c Samer El-Haj-Mahmoud
2020-07-08 14:55   ` Ard Biesheuvel
2020-06-08 13:38 ` [edk2-platform][PATCH v3 5/6] Platform/HiSilicon: Switch HiKey " Samer El-Haj-Mahmoud
2020-07-08 14:55   ` Ard Biesheuvel
2020-06-08 13:38 ` [edk2-platform][PATCH v3 6/6] Drivers/OptionRomPkg: Remove old ASIX NIC drivers Samer El-Haj-Mahmoud
2020-06-09  0:36   ` Ni, Ray
2020-07-08 14:56 ` [edk2-platform][PATCH v3 0/6] Update ASIX USB Networking drivers Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox