From 549ff2286a4d8a24a912b3123a10d264ddafcb88 Mon Sep 17 00:00:00 2001
From: Shivamurthy Shastri <shiva.murthy@samsung.com>
Date: Tue, 19 Mar 2013 15:49:50 +0530
Subject: [PATCH] PXE for Arndale. Still work is under progress. NOT A FINAL
 PATCH.

---
 .../UncachedMemoryAllocationLib.c                  |   13 +-
 MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c                |    2 +-
 MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c           |    2 +-
 MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c           |    3 +-
 MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h    |    4 +-
 MdePkg/Library/BaseLib/String.c                    |    2 +-
 .../ArndaleBoardPkg/arndale-Exynos5250.dsc         |   21 +
 .../ArndaleBoardPkg/arndale-Exynos5250.fdf         |   16 +
 .../ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.c  | 1314 +++++++++++++++++
 .../ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.h  |  976 +++++++++++++
 .../Exynos5250/Drivers/EthDxe/Ax88772.inf          |   57 +
 .../Exynos5250/Drivers/EthDxe/ComponentName.c      |  184 +++
 .../Exynos5250/Drivers/EthDxe/DriverBinding.c      |  543 +++++++
 .../ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c   |  788 ----------
 .../ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h   |  612 --------
 .../ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf |   59 -
 .../Exynos5250/Drivers/EthDxe/SimpleNetwork.c      | 1533 ++++++++++++++++++++
 .../ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c       |    2 +-
 .../Exynos5250/Drivers/PciEmulation/Exynos5_USB.c  |   73 +-
 .../Exynos5250/Drivers/PciEmulation/PciEmulation.h |    1 +
 .../Drivers/PciEmulation/PciEmulation.inf          |    1 +
 .../Exynos5250/Include/Platform/ArmPlatform.h      |    4 +
 22 files changed, 4727 insertions(+), 1483 deletions(-)
 create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.c
 create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.h
 create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.inf
 create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/ComponentName.c
 create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/DriverBinding.c
 delete mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c
 delete mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h
 delete mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf
 create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/SimpleNetwork.c

diff --git a/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c b/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c
index 4db93db..9afd2ff 100644
--- a/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c
+++ b/ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.c
@@ -95,7 +95,7 @@ RemovePagesFromList (
       *Pages = OldNode->Pages;
       
       RemoveEntryList (&OldNode->Link);
-      FreePool (OldNode);
+      //gBS->FreePool (OldNode);
       return;
     }
   }
@@ -142,6 +142,17 @@ UncachedAllocatePages (
 
 VOID *
 EFIAPI
+UncachedAllocateAlignedPages (
+  IN UINTN  Pages,
+	IN UINTN  Alignment
+  )
+{
+  return UncachedInternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);
+}
+
+
+VOID *
+EFIAPI
 UncachedAllocateRuntimePages (
   IN UINTN  Pages
   )
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
index 59891b8..470c2f4 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
@@ -948,7 +948,7 @@ ON_EXIT:
   gBS->RestoreTPL (OldTpl);
 
   if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult));
+    //DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult));
   }
 
   return Status;
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
index 4dc8e1a..4d04c2a 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
@@ -718,7 +718,7 @@ EhcExecTransfer (
   }
 
   if (!Finished) {
-    DEBUG ((EFI_D_ERROR, "EhcExecTransfer: transfer not finished in %dms\n", (UINT32)TimeOut));
+//    DEBUG ((EFI_D_ERROR, "EhcExecTransfer: transfer not finished in %dms\n", (UINT32)TimeOut));
     EhcDumpQh (Urb->Qh, NULL, FALSE);
 
     Status = EFI_TIMEOUT;
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
index 529b136..7328c8a 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
@@ -617,7 +617,8 @@ UsbGetOneString (
   Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_STRING, Index, LangId, &Desc, 2);
 
   if (EFI_ERROR (Status)) {
-    return NULL;
+    Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_STRING, Index, LangId, &Desc, 0x4);// Need to change this code as per USB 2.0 spec. This is temp code for ASIX chip.
+    //return NULL;
   }
 
   Buf = AllocateZeroPool (Desc.Length);
diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h b/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h
index f94e208..b3d899a 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h
+++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h
@@ -20,9 +20,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
 #define NET_ETHER_FCS_SIZE            4
 
-#define MNP_SYS_POLL_INTERVAL         (10 * TICKS_PER_MS)   // 10 milliseconds
+#define MNP_SYS_POLL_INTERVAL         (800 * TICKS_PER_MS)   // 10 milliseconds
 #define MNP_TIMEOUT_CHECK_INTERVAL    (50 * TICKS_PER_MS)   // 50 milliseconds
-#define MNP_MEDIA_DETECT_INTERVAL     (500 * TICKS_PER_MS)  // 500 milliseconds
+#define MNP_MEDIA_DETECT_INTERVAL     (100000 * TICKS_PER_MS)  // 500 milliseconds
 #define MNP_TX_TIMEOUT_TIME           (500 * TICKS_PER_MS)  // 500 milliseconds
 #define MNP_INIT_NET_BUFFER_NUM       512
 #define MNP_NET_BUFFER_INCREASEMENT   64
diff --git a/MdePkg/Library/BaseLib/String.c b/MdePkg/Library/BaseLib/String.c
index 227a0dc..0294372 100644
--- a/MdePkg/Library/BaseLib/String.c
+++ b/MdePkg/Library/BaseLib/String.c
@@ -164,7 +164,7 @@ StrLen (
   UINTN                             Length;
 
   ASSERT (String != NULL);
-  ASSERT (((UINTN) String & BIT0) == 0);
+  //ASSERT (((UINTN) String & BIT0) == 0);
 
   for (Length = 0; *String != L'\0'; String++, Length++) {
     //
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc
index 941c6e5..5c75717 100755
--- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc
@@ -47,6 +47,10 @@
   ArmGicSecLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf
   ArmGicLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicLib.inf
   ArmSmcLib|ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
 
 [LibraryClasses.common.SEC]
   ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
@@ -352,6 +356,23 @@
   MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
   MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
 
+  #Network
+  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
+  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
+  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+  MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+  MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+  SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.inf
+
+
   #
   # Graphics for Exynos
   #
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf
index 8b5a5a7..d89a8ab 100755
--- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf
@@ -213,6 +213,22 @@ READ_LOCK_STATUS   = TRUE
   INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
   INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
 
+  #Network
+  INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+#  INF MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
+  INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigDxe.inf
+  INF MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+  INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+  INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+  INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.inf
+
   #
   # Graphics for Exynos
   #
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.c
new file mode 100644
index 0000000..4d7c2f3
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.c
@@ -0,0 +1,1314 @@
+/** @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>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ax88772.h"
+
+
+/**
+  Compute the CRC
+
+  @param [in] pMacAddress      Address of a six byte buffer to containing the MAC address.
+
+  @returns The CRC-32 value associated with this MAC address
+
+**/
+UINT32
+Ax88772Crc (
+  IN UINT8 * pMacAddress
+  )
+{
+  UINT32 BitNumber;
+  INT32 Carry;
+  INT32 Crc;
+  UINT32 Data;
+  UINT8 * pEnd;
+
+  DBG_ENTER ( );
+  DEBUG((DEBUG_WARN, "Ax88772Crc\n"));
+
+  //
+  //  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 ( );
+  DEBUG((DEBUG_WARN, "Ax88772MacAddressGet\n"));
+  
+  //
+  //  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 ( );
+  DEBUG((DEBUG_WARN, "Ax88772MacAddressSet\n"));
+
+
+  DEBUG (( DEBUG_ERROR, "Ax88772MacAddressSet: SET MAC Before:"));
+  DEBUG (( DEBUG_ERROR,
+              "%02x:%02x:%02x:%02x:%02x:%02x\n",
+              pMacAddress[0],
+              pMacAddress[1],
+              pMacAddress[2],
+              pMacAddress[3],
+              pMacAddress[4],
+              pMacAddress[5]));
+
+/*  pMacAddress[0] = 0x00;
+  pMacAddress[1] = 0x40;
+  pMacAddress[2] = 0x5C;
+  pMacAddress[3] = 0x26;
+  pMacAddress[4] = 0x0A;
+  pMacAddress[5] = 0x5B;
+
+  DEBUG (( DEBUG_ERROR, "Ax88772MacAddressSet: SET MAC After:"));  */
+  //
+  //  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;
+  
+
+  DEBUG (( DEBUG_ERROR,
+              "%02x:%02x:%02x:%02x:%02x:%02x\n",
+              pMacAddress[0],
+              pMacAddress[1],
+              pMacAddress[2],
+              pMacAddress[3],
+              pMacAddress[4],
+              pMacAddress[5]));
+  //
+  //  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 ( );
+  DEBUG((DEBUG_WARN, "Ax88772MulticastClear\n"));
+
+  //
+  // 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 ( );
+  DEBUG((DEBUG_WARN, "Ax88772MulticastSet\n"));
+
+  //
+  //  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_ERROR,
+            "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 ( );
+  DEBUG((DEBUG_WARN, "Ax88772NegotiateLinkStart\n"));
+
+  //
+  // 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 ( );
+  DEBUG((DEBUG_ERROR, "Ax88772NegotiateLinkComplete\n"));
+  
+  //
+  //  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.
+    //
+    DEBUG((DEBUG_ERROR, "PhyData:%x\n",PhyData));
+    *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 ( );
+  DEBUG((DEBUG_ERROR, "Ax88772PhyRead\n"));
+
+  //
+  //  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_ERROR,
+                "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 ( );
+  DEBUG((DEBUG_WARN, "Ax88772PhyWrite\n"));
+  
+  //
+  //  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_ERROR,
+                "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 ( );
+  DEBUG((DEBUG_WARN, "Ax88772Reset\n"));
+
+  //
+  //  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_ERROR,
+              "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;
+}
+
+
+/**
+  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;
+
+//  DEBUG((DEBUG_WARN, "Ax88772Rx\n"));
+  //
+  //  Synchronize with Ax88772Timer
+  //
+//  VERIFY_TPL ( TPL_AX88772 );
+//  TplPrevious = gBS->RaiseTPL ( TPL_AX88772 );
+//  DEBUG (( DEBUG_TPL | DEBUG_ERROR,
+//            "%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 );
+	//DEBUG((DEBUG_ERROR, "Status:%r,PollCount:%x,bComplete:%x,bLinkUp:%x,b100Mbps:%x,bFullDuplex:%x\n",Status,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_ERROR,
+                    "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_ERROR,
+                    "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_ERROR, "Link: Down\r\n" ));
+    }
+  }
+
+  //
+  //  Loop until all the packets are emptied from the receiver
+  //
+if (bUpdateLink == FALSE) {
+  do {
+    bRxPacket = FALSE;
+
+    //
+    //  Locate a packet for use
+    //
+    pRxPacket = pNicDevice->pRxFree;
+    LengthInBytes = sizeof ( *pRxPacket ) - sizeof ( pRxPacket->pNext );
+    if ( NULL == pRxPacket ) {
+      Status = gBS->AllocatePool ( EfiRuntimeServicesData,
+                                   LengthInBytes,
+                                   (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
+    //
+    pUsbIo = pNicDevice->pUsbIo;
+    Status = pUsbIo->UsbBulkTransfer ( pUsbIo,
+                                       USB_ENDPOINT_DIR_IN | BULK_IN_ENDPOINT,
+                                       &pRxPacket->Length,
+                                       &LengthInBytes,
+                                       1,
+                                       &TransferStatus );
+
+    if (( !EFI_ERROR ( Status ))
+      && ( 0 < pRxPacket->Length )
+      && ( pRxPacket->Length <= sizeof ( pRxPacket->Data ))) {
+
+      //
+      //  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_ERROR,
+                      "BROADRX: %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_ERROR,
+                      "MULTIRX: %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_ERROR,
+                    "UNIRX: %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 ));
+        }
+        
+        //
+        //  Remove this packet from the free packet list
+        //
+        pNicDevice->pRxFree = pRxPacket->pNext;
+        pRxPacket->pNext = NULL;
+
+        //
+        //  Append this packet to the receive list
+        //
+        if ( NULL == pNicDevice->pRxTail ) {
+          pNicDevice->pRxHead = pRxPacket;
+        }
+        else {
+          pNicDevice->pRxTail->pNext = pRxPacket;
+        }
+        pNicDevice->pRxTail = pRxPacket;
+      }
+      else {
+        //
+        //  Error, not enough buffers for this packet, discard packet
+        //
+        DEBUG (( DEBUG_ERROR | DEBUG_ERROR,
+                  "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_ERROR,
+//            "%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 ( );
+
+  DEBUG((DEBUG_WARN, "Ax88772RxControl\n"));
+  //
+  //  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_ERROR,
+                    "ERROR - Failed to enable receiver, Status: %r\r\n",
+                    Status ));
+        }
+      }
+    }
+    else {
+      DEBUG (( DEBUG_ERROR | DEBUG_ERROR,
+                "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 )) {
+    DEBUG (( DEBUG_ERROR, "Ax88772RxControl:Ax88772MacAddressSet\n"));
+    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_ERROR,
+                "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_ERROR,
+                  "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_ERROR,
+                  "ERROR - Failed to update multicast hash table, Status: %r\r\n",
+                  Status ));
+      }
+    }
+    else {
+      DEBUG (( DEBUG_ERROR | DEBUG_ERROR,
+                "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 ( );
+  DEBUG((DEBUG_WARN, "Ax88772SromRead\n"));
+
+  //
+  //  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
+  )
+{
+  DEBUG((DEBUG_WARN, "Ax88772Timer\n"));
+  //
+  //  Use explicit DEBUG messages since the output frequency is too
+  //  high for DEBUG_ERROR 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 ( );
+  DEBUG((DEBUG_ERROR, "Ax88772UsbCommand\n"));
+
+  //
+  // 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_ERROR,
+              "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/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.h
new file mode 100644
index 0000000..5eaaaa5
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.h
@@ -0,0 +1,976 @@
+/** @file
+  Definitions for ASIX AX88772 Ethernet adapter.
+
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _AX88772_H_
+#define _AX88772_H_
+
+#include <Uefi.h>
+
+#include <Guid/EventGroup.h>
+#include <Guid/NicIp4ConfigNvData.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
+//------------------------------------------------------------------------------
+#undef DEBUG_WARN
+#define DEBUG_WARN 0
+
+#undef DEBUG_ERROR
+#define DEBUG_ERROR 0
+
+#if defined(_MSC_VER)           /* Handle Microsoft VC++ compiler specifics. */
+#define DBG_ENTER()             DEBUG (( DEBUG_ERROR, "Entering " __FUNCTION__ "\n" )) ///<  Display routine entry
+#define DBG_EXIT()              DEBUG (( DEBUG_ERROR, "Exiting " __FUNCTION__ "\n" ))  ///<  Display routine exit
+#define DBG_EXIT_DEC(Status)    DEBUG (( DEBUG_ERROR, "Exiting " __FUNCTION__ ", Status: %d\n", Status ))      ///<  Display routine exit with decimal value
+#define DBG_EXIT_HEX(Status)    DEBUG (( DEBUG_ERROR, "Exiting " __FUNCTION__ ", Status: 0x%08x\n", Status ))  ///<  Display routine exit with hex value
+#define DBG_EXIT_STATUS(Status) DEBUG (( DEBUG_ERROR, "Exiting " __FUNCTION__ ", Status: %r\n", Status ))      ///<  Display routine exit with status value
+#define DBG_EXIT_TF(Status)     DEBUG (( DEBUG_ERROR, "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 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        0x772A  ///<  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
+} 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/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.inf
new file mode 100644
index 0000000..065aeeb
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/Ax88772.inf
@@ -0,0 +1,57 @@
+## @file
+# Component description file for ASIX AX88772 USB/Ethernet driver.
+#
+# This module provides support for the ASIX AX88772 USB/Ethernet adapter.
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010006
+  BASE_NAME                      = Ax88772
+  FILE_GUID                      = B15239D6-6A01-4808-A0F7-B7F20F073555
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 0.1
+  ENTRY_POINT                    = EntryPoint
+
+[Sources.common]
+  Ax88772.h
+  Ax88772.c
+  ComponentName.c
+  DriverBinding.c
+  SimpleNetwork.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+  SamsungPlatformPkg/SamsungPlatformPkg.dec
+
+[LibraryClasses]
+  UefiLib
+  UefiBootServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  UefiDriverEntryPoint
+  DevicePathLib
+  BaseLib
+  NetLib
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
+  gEfiSimpleNetworkProtocolGuid
+  gEfiUsbIoProtocolGuid                ## TO_START
+  gSamsungPlatformGpioProtocolGuid
+  gEfiPxeBaseCodeProtocolGuid
+
+[Depex]
+  TRUE
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/ComponentName.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/ComponentName.c
new file mode 100644
index 0000000..8fceb60
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/ComponentName.c
@@ -0,0 +1,184 @@
+/** @file
+  UEFI Component Name(2) protocol implementation.
+
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ax88772.h"
+
+/**
+  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/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/DriverBinding.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/DriverBinding.c
new file mode 100644
index 0000000..a88a340
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/DriverBinding.c
@@ -0,0 +1,543 @@
+/** @file
+  Implement the driver binding protocol for Asix AX88772 Ethernet driver.
+
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ax88772.h"
+#include <Platform/ArmPlatform.h>
+#include "Protocol/ExynosGpio.h"
+#include <Library/MemoryAllocationLib.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;
+  EXYNOS_GPIO *Gpio;
+  static int i = 0;
+
+  //
+  //  Connect to the USB stack
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiUsbIoProtocolGuid,
+                  (VOID **) &pUsbIo,
+                  pThis->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (i == 0) {
+     if (Status == EFI_SUCCESS) {
+        i=i+1;
+     } else {
+            gBS->LocateProtocol(&gSamsungPlatformGpioProtocolGuid, NULL, (VOID **)&Gpio);
+            Gpio->Set(Gpio, USB_2_X3, GPIO_MODE_OUTPUT_0);
+            Gpio->Set(Gpio, USB_2_X3, GPIO_MODE_OUTPUT_1);
+     }
+  }
+
+  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_ERROR,
+                  "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_ERROR,
+                      "Installed: gEfiCallerIdGuid on   0x%08x\r\n",
+                      Controller ));
+            DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_ERROR,
+                      "Installed: gEfiSimpleNetworkProtocolGuid on   0x%08x\r\n",
+                      Controller ));
+            DBG_EXIT_STATUS ( Status );
+            return Status;
+          }
+          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_ERROR,
+                    "ERROR - Failed to install gEfiSimpleNetworkProtocol on 0x%08x\r\n",
+                    Controller ));
+        }
+        else {
+          DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_ERROR,
+                    "ERROR - Failed to start the timer, Status: %r\r\n",
+                    Status ));
+        }
+      }
+      else {
+        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_ERROR,
+                  "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_ERROR,
+                "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_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
+        //
+        DEBUG (( DEBUG_ERROR | DEBUG_INIT | DEBUG_ERROR,
+                "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_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_ERROR,
+            "Removed:   gEfiComponentName2ProtocolGuid from 0x%08x\r\n",
+            ImageHandle ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_ERROR,
+              "Removed:   gEfiComponentNameProtocolGuid from 0x%08x\r\n",
+              ImageHandle ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_ERROR,
+              "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_LOADED_IMAGE_PROTOCOL * pLoadedImage;
+  EFI_STATUS    Status;
+
+  DBG_ENTER ( );
+
+  //
+  //  Enable unload support
+  //
+  Status = gBS->HandleProtocol (
+                  gImageHandle,
+                  &gEfiLoadedImageProtocolGuid,
+                  (VOID **)&pLoadedImage
+                  );
+  if (!EFI_ERROR (Status)) {
+    pLoadedImage->Unload = DriverUnload;
+  }
+
+  //
+  //  Add the driver to the list of drivers
+  //
+  Status = EfiLibInstallDriverBindingComponentName2 (
+             ImageHandle,
+             pSystemTable,
+             &gDriverBinding,
+             ImageHandle,
+             &gComponentName,
+             &gComponentName2
+             );
+  ASSERT_EFI_ERROR (Status);
+  if ( !EFI_ERROR ( Status )) {
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_ERROR,
+              "Installed: gEfiDriverBindingProtocolGuid on   0x%08x\r\n",
+              ImageHandle ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_ERROR,
+              "Installed: gEfiComponentNameProtocolGuid on   0x%08x\r\n",
+              ImageHandle ));
+    DEBUG (( DEBUG_POOL | DEBUG_INIT | DEBUG_ERROR,
+              "Installed: gEfiComponentName2ProtocolGuid on   0x%08x\r\n",
+              ImageHandle ));
+  }
+  DBG_EXIT_STATUS ( Status );
+  return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c
deleted file mode 100644
index 51a8c16..0000000
--- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c
+++ /dev/null
@@ -1,788 +0,0 @@
-/** @file
-  Template for Timer Architecture Protocol driver of the ARM flavor
-
-  Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
-
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-
-#include <PiDxe.h>
-
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-#include <Library/PcdLib.h>
-#include <Library/IoLib.h>
-#include <Library/NetLib.h>
-#include <Library/TimerLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Protocol/SimpleNetwork.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/ExynosGpio.h>
-#include <Platform/ArmPlatform.h>
-#include "EthDxe.h"
-
-
-ETH_DXE_PRIVATE_DATA gEthDxePrivateTemplate = {
-	ETH_DXE_PRIVATE_DATA_SIGNATURE,
-	{
-		EFI_SIMPLE_NETWORK_PROTOCOL_REVISION,
-		EthStart,
-		EthStop,
-		EthInitialize,
-		EthReset,
-		EthShutdown,
-		EthReceiveFilters,
-		EthStationAddress,
-		EthStatistics,
-		EthMCastIpToMac,
-		EthNvData,
-		EthGetStatus,
-		EthTransmit,
-		EthReceive,
-		NULL,
-		NULL
-	},
-	{
-		EfiSimpleNetworkStopped,	//  State
-		NET_ETHER_ADDR_LEN,		//  HwAddressSize
-    		NET_ETHER_HEADER_SIZE,	//  MediaHeaderSize
-    		1500,					//  MaxPacketSize
-    		0,						//  NvRamSize
-    		0,						//  NvRamAccessSize
-    		0,						//  ReceiveFilterMask
-    		0,						//  ReceiveFilterSetting
-    		MAX_MCAST_FILTER_CNT,	//  MaxMCastFilterCount
-    		0,						//  MCastFilterCount
-    		{
-    			0
-		},                    			//  MCastFilter
-		{
-			0
-		},			                    	//  CurrentAddress
-		{
-			0
-		},						//  BroadcastAddress
-		{
-			0
-		},						//  PermanentAddress
-		NET_IFTYPE_ETHERNET,		//  IfType
-		FALSE,                  			//  MacAddressChangeable
-		FALSE,					//  MultipleTxSupported
-		FALSE,					//  MediaPresentSupported
-		TRUE                  			//  MediaPresent
-	},
-	{
-		{
-			HARDWARE_DEVICE_PATH,
-			HW_VENDOR_DP,
-			(UINT8)(sizeof(VENDOR_DEVICE_PATH)),
-			(UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
-			EFI_SIMPLE_NETWORK_PROTOCOL_GUID
-		},
-		{
-			END_DEVICE_PATH_TYPE,
-			END_ENTIRE_DEVICE_PATH_SUBTYPE,
-			sizeof (EFI_DEVICE_PATH_PROTOCOL),
-			0
-		}
-	}
-};
-
-
-UINT32 smc911x_reg_read(UINT32 offset)
-{
-	UINT32 regBase = PcdGet32(PcdSMC911XBase);
-	UINT32 val;
-
-	val = (MmioRead16(regBase + offset) & 0xFFFF) | ((MmioRead16(regBase + offset + 2) & 0xFFFF) << 16);
-
-	return val;
-}
-
-VOID smc911x_reg_write(UINT32 offset, UINT32 val)
-{
-	UINT32 regBase = PcdGet32(PcdSMC911XBase);
-
-	MmioWrite16(regBase + offset, ((UINT16)(val & 0xFFFF)));
-	MmioWrite16(regBase + offset + 2, ((UINT16)((val & 0xFFFF0000)>>16)));
-}
-
-UINT32 smc911x_get_mac_csr(UINT8 reg)
-{
-	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
-		;	
-	smc911x_reg_write(MAC_CSR_CMD, (MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg));
-	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
-		;
-	return smc911x_reg_read(MAC_CSR_DATA);
-}
-
-VOID smc911x_set_mac_csr(UINT8 reg, UINT32 data)
-{
-	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
-		;
-	smc911x_reg_write(MAC_CSR_DATA, data);
-	smc911x_reg_write(MAC_CSR_CMD, (MAC_CSR_CMD_CSR_BUSY | reg));
-	while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
-		;
-}
-
-VOID smc911x_reset(VOID)
-{
-	INT32 timeout;
-
-	/* Take out of PM setting first */
-	if (smc911x_reg_read(PMT_CTRL) & PMT_CTRL_READY) {
-		/* Write to the bytetest will take out of powerdown */
-		smc911x_reg_write(BYTE_TEST, 0x0);
-
-		timeout = 10;
-
-		while (timeout-- && !(smc911x_reg_read(PMT_CTRL) & PMT_CTRL_READY))
-			MicroSecondDelay(10);
-		if (!timeout) {
-			DEBUG((EFI_D_ERROR, "smc911x_reset: timeout waiting for PM restore\n"));
-			return;
-		}
-	}
-
-	/* Disable interrupts */
-	smc911x_reg_write(INT_EN, 0);
-
-	smc911x_reg_write(HW_CFG, HW_CFG_SRST);
-
-	timeout = 1000;
-	while (timeout-- && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY))
-		MicroSecondDelay(10);
-
-	if (!timeout) {
-		DEBUG((EFI_D_ERROR, "smc911x_reset: reset timeout\n"));
-		return;
-	}
-
-	/* Reset the FIFO level and flow control settings */
-	smc911x_set_mac_csr(FLOW, FLOW_FCPT | FLOW_FCEN);
-	smc911x_reg_write(AFC_CFG, 0x0050287F);
-
-	/* Set to LED outputs */
-	smc911x_reg_write(GPIO_CFG, 0x70070000);
-}
-
-VOID smc911x_phy_reset(VOID)
-{
-	UINT32 reg;
-
-	reg = smc911x_reg_read(PMT_CTRL);
-	reg &= ~0xfffff030;
-	reg |= PMT_CTRL_PHY_RST;
-	smc911x_reg_write(PMT_CTRL, reg);
-
-	MicroSecondDelay(100000);
-}
-
-VOID smc911x_miiphy_read(UINT8 phy, UINT8 reg, UINT16 *val)
-{
-	while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY)
-		;
-
-	smc911x_set_mac_csr(MII_ACC, (phy << 11 | reg << 6 | MII_ACC_MII_BUSY));
-
-	while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY)
-		;
-
-	*val = smc911x_get_mac_csr(MII_DATA);
-}
-
-VOID smc911x_miiphy_write(UINT8 phy, UINT8 reg, UINT16 val)
-{
-	while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY)
-		;
-
-	smc911x_set_mac_csr(MII_DATA, val);
-	smc911x_set_mac_csr(MII_ACC, (phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE));
-
-	while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY)
-		;
-}
-
-VOID smc911x_phy_configure(VOID)
-{
-	INT32 timeout;
-	UINT16 status;
-
-	smc911x_phy_reset();
-
-	smc911x_miiphy_write(1, PHY_BMCR, PHY_BMCR_RESET);
-	MicroSecondDelay(1000);
-	smc911x_miiphy_write(1, PHY_ANAR, 0x01e1);
-	smc911x_miiphy_write(1, PHY_BMCR, (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG));
-
-	timeout = 5000;
-	do {
-		MicroSecondDelay(1000);
-		if ((timeout--) == 0)
-			goto err_out;
-
-		smc911x_miiphy_read(1, PHY_BMSR, &status);
-	} while (!(status & PHY_BMSR_LS));
-
-	DEBUG((EFI_D_ERROR, "smc911x_phy_configure: PHY initialized\n"));
-
-	return;
-
-err_out:
-	DEBUG((EFI_D_ERROR, "smc911x_phy_configure: autonegotiation timed out\n"));
-}
-
-VOID smc911x_handle_mac_address(ETH_DXE_PRIVATE_DATA	*Private)
-{
-	UINT32 addrh, addrl;
-
-	addrl = Private->Mode.CurrentAddress.Addr[0] | \
-			(Private->Mode.CurrentAddress.Addr[1] << 8) | \
-			(Private->Mode.CurrentAddress.Addr[2] << 16) | \
-			(Private->Mode.CurrentAddress.Addr[3] << 24);
-	addrh = Private->Mode.CurrentAddress.Addr[4] | \
-			(Private->Mode.CurrentAddress.Addr[5] << 8);
-	
-	smc911x_set_mac_csr(ADDRL, addrl);
-	smc911x_set_mac_csr(ADDRH, addrh);
-}
-
-VOID smc911x_enable(VOID)
-{
-	/* Enable TX */
-	smc911x_reg_write(HW_CFG, (8 << 16 | HW_CFG_SF));
-
-	smc911x_reg_write(GPT_CFG, (GPT_CFG_TIMER_EN | 10000));
-
-	smc911x_reg_write(TX_CFG, TX_CFG_TX_ON);
-
-	/* no padding to start of packets */
-	smc911x_reg_write(RX_CFG, 0);
-
-	smc911x_set_mac_csr(MAC_CR, (MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS /*| MAC_CR_PADSTR*/));
-}
-
-EFI_STATUS
-EFIAPI
-EthStart(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This
-)
-{
-	ETH_DXE_PRIVATE_DATA	*Private;
-
-	Private = ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(This);
-
-	switch ( Private->Snp.Mode->State )
-	{
-		case EfiSimpleNetworkStopped:
-			break;
-
-		case EfiSimpleNetworkStarted:
-		case EfiSimpleNetworkInitialized:
-			return( EFI_ALREADY_STARTED );
-      			break;
-
-    		default:
-      			return( EFI_DEVICE_ERROR );
-      			break;
-	}
-	
-	/* gpio configuration */
-	MmioAndThenOr32(0x11000000 + 0x120, ~((0xFF<<16)|(0xFF<<4)), ((0x22<<16)|(0x52<<4)));
-
-	/* 16 Bit bus width */
-	MmioWrite32(0x11000000 + 0x1C0, 0x22222222);
-	MmioWrite32(0x11000000 + 0x1E0, 0x22222222);
-	
-	/* SROM BANK1 */
-	MmioAndThenOr32(0x12570000, ~(0xF<<4), (((1<<0)|(0<<2)|(1<<3))<<4));
-
-	/* set timing for nCS1 suitable for ethernet chip */
-	MmioWrite32(0x12570008, ((0x1 << 0) | (0x9 << 4) | (0xC << 8) | (0x1 << 12) | \
-								(0x6 << 16) | (0x1 << 24) | (0x1 << 28)));
-
-	Private->Snp.Mode->State = EfiSimpleNetworkStarted;
-
-	return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-EthStop(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This
-)
-{
-	ETH_DXE_PRIVATE_DATA	*Private;
-
-	Private = ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(This);
-
-	switch ( Private->Snp.Mode->State )
-	{
-		case EfiSimpleNetworkStarted:
-			break;
-
-		case EfiSimpleNetworkStopped:
-			return( EFI_NOT_STARTED );
-			break;
-
-		default:
-			return( EFI_DEVICE_ERROR );
-			break;
-	}
-
-	Private->Snp.Mode->State = EfiSimpleNetworkStopped;
-
-	return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-EthInitialize(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	UINTN							ExtraRxBufferSize,
-	UINTN							ExtraTxBufferSize
-)
-{
-	UINT32 val, i, addrh, addrl;
-	ETH_DXE_PRIVATE_DATA *Private;
-
-	Private = ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(This);
-
-	switch ( Private->Snp.Mode->State )
-	{
-		case EfiSimpleNetworkStarted:
-			break;
-
-		case EfiSimpleNetworkStopped:
-			return( EFI_NOT_STARTED );
-			break;
-
-		default:
-			return( EFI_DEVICE_ERROR );
-			break;
-	}
-
-	val = smc911x_reg_read(BYTE_TEST);
-
-	if(val == 0xFFFFFFFF) {
-		return EFI_NO_MEDIA;
-	}
-	else if(val != 0x87654321) {
-		DEBUG((EFI_D_ERROR,"EthInitialize: Invalid chip endian 0x%x\n", val));
-		return EFI_NO_MEDIA;
-	}
-
-	val = smc911x_reg_read(ID_REV) >> 16;
-	for(i=0;chip_ids[i].id != 0;i++) {
-		if(chip_ids[i].id == val)
-			break;
-	}
-
-	if(!chip_ids[i].id) {
-		DEBUG((EFI_D_ERROR,"EthInitialize: Unknown chip id 0x%x\n", val));
-		return EFI_NO_MEDIA;
-	}
-	else {
-		DEBUG((EFI_D_ERROR,"EthInitialize: Chip id 0x%x\n", val));
-	}
-
-	addrh = smc911x_get_mac_csr(ADDRH);
-	addrl = smc911x_get_mac_csr(ADDRL);
-
-	if (addrl == 0xffffffff && addrh == 0x0000ffff) {
-		addrh = 0x00000040;
-		addrl = 0x5c260a5b;
-	}
-	
-	Private->Mode.CurrentAddress.Addr[0] = (addrl & 0xFF);
-	Private->Mode.CurrentAddress.Addr[1] = (addrl & 0xFF00)>>8;
-	Private->Mode.CurrentAddress.Addr[2] = (addrl & 0xFF0000)>>16;
-	Private->Mode.CurrentAddress.Addr[3] = (addrl & 0xFF000000)>>24;
-	Private->Mode.CurrentAddress.Addr[4] = (addrh & 0xFF);
-	Private->Mode.CurrentAddress.Addr[5] = (addrh & 0xFF00)>>8;
-	gBS->CopyMem((VOID *)&Private->Mode.PermanentAddress, \
-					(VOID *)&Private->Mode.CurrentAddress, \
-					sizeof(EFI_MAC_ADDRESS));
-
-	DEBUG((EFI_D_ERROR,"EthInitialize: MAC address is "));
-
-	for(i=6;i>0;i--) {
-		DEBUG((EFI_D_ERROR,"%02x", Private->Mode.CurrentAddress.Addr[i - 1]));
-		if(i > 1)
-			DEBUG((EFI_D_ERROR,":"));
-		else
-			DEBUG((EFI_D_ERROR,"\n"));
-	}
-
-	smc911x_reset();
-
-	/* Configure the PHY, initialize the link state */
-	smc911x_phy_configure();
-
-	smc911x_handle_mac_address(Private);
-
-	/* Turn on Tx + Rx */
-	smc911x_enable();
-
-	Private->Snp.Mode->State = EfiSimpleNetworkInitialized;
-
-	return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-EthReset(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	BOOLEAN							ExtendedVerification
-)
-{
-	ETH_DXE_PRIVATE_DATA	*Private;
-
-	Private = ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(This);
-
-	switch ( Private->Snp.Mode->State )
-	{
-		case EfiSimpleNetworkInitialized:
-			break;
-
-		case EfiSimpleNetworkStopped:
-			return( EFI_NOT_STARTED );
-			break;
-
-		default:
-			return( EFI_DEVICE_ERROR );
-			break;
-	}
-
-	return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-EthShutdown(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This
-)
-{
-	ETH_DXE_PRIVATE_DATA	*Private;
-
-	Private = ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(This);
-
-	switch ( Private->Snp.Mode->State )
-	{
-		case EfiSimpleNetworkInitialized:
-			break;
-
-		case EfiSimpleNetworkStopped:
-			return( EFI_NOT_STARTED );
-			break;
-
-		default:
-			return( EFI_DEVICE_ERROR );
-			break;
-	}
-
-	Private->Snp.Mode->State = EfiSimpleNetworkStarted;
-
-	return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-EthReceiveFilters(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	UINT32							Enable,
-	UINT32							Disable,
-	BOOLEAN							ResetMCastFilter,
-	UINTN							MCastFilterCnt,
-	EFI_MAC_ADDRESS				*MCastFilter
-)
-{
-	return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-EthStationAddress(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	BOOLEAN							Reset,
-	EFI_MAC_ADDRESS				*New
-)
-{
-	return EFI_UNSUPPORTED;
-}
-
-EFI_STATUS
-EFIAPI
-EthStatistics(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	BOOLEAN							Reset,
-	UINTN							*StatisticsSize,
-	EFI_NETWORK_STATISTICS              *StatisticsTable
-)
-{
-	return EFI_UNSUPPORTED;
-}
-
-EFI_STATUS
-EFIAPI
-EthMCastIpToMac(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	BOOLEAN							IPv6,
-	EFI_IP_ADDRESS					*IP,
-	EFI_MAC_ADDRESS				*MAC
-)
-{
-	return EFI_UNSUPPORTED;
-}
-
-EFI_STATUS
-EFIAPI
-EthNvData(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	BOOLEAN							ReadWrite,
-	UINTN							Offset,
-	UINTN							BufferSize,
-	VOID							*Buffer
-)
-{
-	return EFI_UNSUPPORTED;
-}
-
-EFI_STATUS
-EFIAPI
-EthGetStatus(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	UINT32							*InterruptStatus,
-	VOID							**TxBuf
-)
-{
-	if ( TxBuf != NULL ) {
-		*( ( UINT8 ** ) TxBuf ) = ( UINT8 * ) 1;
-	}
-
-	if ( InterruptStatus != NULL ) {
-		*InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
-	}
-
-	return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-EthTransmit(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	UINTN							HeaderSize,
-	UINTN							BufferSize,
-	VOID							*Buffer,
-	EFI_MAC_ADDRESS				*SrcAddr,
-	EFI_MAC_ADDRESS				*DestAddr,
-	UINT16							*Protocol
-)
-{
-	UINT32 *data = (UINT32 *)Buffer;
-	UINT32 tmpSize;
-	UINT32 status;
-	EthernetHeader *EnetHeader;
-
-	if ( This->Mode->State < EfiSimpleNetworkStarted ) {
-		return( EFI_NOT_STARTED );
-	}
-
-	if ( HeaderSize != 0 ) {
-		if ( ( DestAddr == NULL ) || ( Protocol == NULL ) || \
-			( HeaderSize != This->Mode->MediaHeaderSize ) ) {
-				return( EFI_INVALID_PARAMETER );
-		}
-
-		if ( SrcAddr == NULL ) {
-			SrcAddr = &This->Mode->CurrentAddress;
-		}
-
-		EnetHeader = (EthernetHeader *)Buffer;
-
-		CopyMem( EnetHeader->DstAddr, DestAddr, NET_ETHER_ADDR_LEN );
-		CopyMem( EnetHeader->SrcAddr, SrcAddr, NET_ETHER_ADDR_LEN );
-
-		EnetHeader->Type = HTONS( *Protocol );
-	}
-
-	smc911x_reg_write(TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | BufferSize);
-	smc911x_reg_write(TX_DATA_FIFO, BufferSize);
-
-	tmpSize = (BufferSize + 3) / 4;
-
-	while (tmpSize--)
-		smc911x_reg_write(TX_DATA_FIFO, *data++);
-
-	/* wait for transmission */
-	while (!((smc911x_reg_read(TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16))
-		;
-
-	/* get status. Ignore 'no carrier' error, it has no meaning for
-	 * full duplex operation
-	 */
-	status = smc911x_reg_read(TX_STATUS_FIFO) & \
-								(TX_STS_LOC | TX_STS_LATE_COLL | \
-								TX_STS_MANY_COLL | TX_STS_MANY_DEFER | \
-								TX_STS_UNDERRUN);
-
-	if (!status)
-		return EFI_SUCCESS;
-
-	DEBUG((EFI_D_ERROR, "EthTransmit: Failed to send packet: %s%s%s%s%s\n",
-			status & TX_STS_LOC ? "TX_STS_LOC " : "",
-			status & TX_STS_LATE_COLL ? "TX_STS_LATE_COLL " : "",
-			status & TX_STS_MANY_COLL ? "TX_STS_MANY_COLL " : "",
-			status & TX_STS_MANY_DEFER ? "TX_STS_MANY_DEFER " : "",
-			status & TX_STS_UNDERRUN ? "TX_STS_UNDERRUN" : ""));
-
-	return EFI_DEVICE_ERROR;
-}
-
-EFI_STATUS
-EFIAPI
-EthReceive(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	UINTN							*HeaderSize,
-	UINTN							*BufferSize,
-	VOID							*Buffer,
-	EFI_MAC_ADDRESS				*SrcAddr,
-	EFI_MAC_ADDRESS				*DestAddr,
-	UINT16							*Protocol  
-)
-{
-	UINT32 *data = (UINT32 *)Buffer;
-	UINT32 pktSize, tmpSize;
-	UINT32 status, i;
-	EthernetHeader *EnetHeader;
-	
-	/* workaround: delay for rx packet should be added here.
-	 * because NetLoop does not guarantee the RX packet delay.
-	 */
-	for (i=0; i<0x100000; i++) {
-		if ((smc911x_reg_read(RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16)
-			break;
-	}
-	
-	if (i == 0x100000) {
-		DEBUG((EFI_D_ERROR, "EthReceive: timeout in RX\n"));
-		return EFI_TIMEOUT;
-	}
-
-	if ((smc911x_reg_read(RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) {
-		status = smc911x_reg_read(RX_STATUS_FIFO);
-		pktSize = (status & RX_STS_PKT_LEN) >> 16;
-
-		smc911x_reg_write(RX_CFG, 0);
-
-		tmpSize = (pktSize + 3) / 4;
-		i = 0;
-		while (tmpSize--)
-			*data++ = smc911x_reg_read(RX_DATA_FIFO);
-		
-		if (status & RX_STS_ES) {
-			DEBUG((EFI_D_ERROR, "EthReceive: dropped bad packet. Status: 0x%x\n", status));
-		}
-
-		*BufferSize = pktSize -4; //discard 4 bytes of FCS
-
-	}
-
-#if 0
-	{
-		UINT8 *tmpBuffer = (UINT8 *)Buffer;
-
-		for(i=0;i<*BufferSize;i++) {
-			DEBUG((EFI_D_ERROR, "%02x", *tmpBuffer++));
-			if((i%16) < 15)
-				DEBUG((EFI_D_ERROR, " "));
-			else 
-				DEBUG((EFI_D_ERROR, "\n"));
-		}
-
-		DEBUG((EFI_D_ERROR, "\n"));
-	}
-#endif
-
-	if(HeaderSize != NULL) {
-		*HeaderSize = sizeof(EthernetHeader);
-	}
-
-	EnetHeader = (EthernetHeader *)Buffer;
-
-	if(SrcAddr != NULL) {
-		ZeroMem(SrcAddr, sizeof(EFI_MAC_ADDRESS));
-		CopyMem(SrcAddr, EnetHeader->SrcAddr, NET_ETHER_ADDR_LEN);
-	}
-
-	if(DestAddr != NULL) {
-		ZeroMem(DestAddr, sizeof(EFI_MAC_ADDRESS));
-		CopyMem(DestAddr, EnetHeader->DstAddr, NET_ETHER_ADDR_LEN);
-	}
-
-	if (Protocol != NULL) {
-		*Protocol = NTOHS(EnetHeader->Type);
-	}
-
-	return EFI_SUCCESS;
-}
-
-
-/**
-  Initialize the state information for the Display Dxe
-
-  @param  ImageHandle   of the loaded driver
-  @param  SystemTable   Pointer to the System Table
-
-  @retval EFI_SUCCESS           Protocol registered
-  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
-  @retval EFI_DEVICE_ERROR      Hardware problems
-
-**/
-EFI_STATUS
-EFIAPI
-EthDxeInitialize (
-	EFI_HANDLE			ImageHandle,
-	EFI_SYSTEM_TABLE   	*SystemTable
-)
-{
-	EFI_STATUS Status = EFI_SUCCESS;
-	EFI_GUID SimpleNetworkProtocolGuid = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
-	EFI_GUID DevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
-	ETH_DXE_PRIVATE_DATA *Private;
-
-	/* Allocate the private data */
-	Private = (ETH_DXE_PRIVATE_DATA *)AllocateCopyPool(sizeof(ETH_DXE_PRIVATE_DATA), &gEthDxePrivateTemplate );
-	if ( Private == NULL ) {
-		Status = EFI_OUT_OF_RESOURCES;
-		ASSERT_EFI_ERROR(Status);
-	}
-
-	Private->Snp.Mode = &Private->Mode;
-
-	/* Set the broadcast address */
-	SetMem( &Private->Mode.BroadcastAddress, sizeof( EFI_MAC_ADDRESS ), 0xFF );
-
-	Status = gBS->InstallMultipleProtocolInterfaces (
-											&ImageHandle,
-											&DevicePathProtocolGuid,
-											&Private->DevicePath,
-											&SimpleNetworkProtocolGuid,
-											&Private->Snp,
-											NULL);
-
-	return Status;
-}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h
deleted file mode 100644
index 3b9a790..0000000
--- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h
+++ /dev/null
@@ -1,612 +0,0 @@
-/** @file
-*
-*  Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
-*
-*  This program and the accompanying materials
-*  are licensed and made available under the terms and conditions of the BSD License
-*  which accompanies this distribution.  The full text of the license may be found at
-*  http://opensource.org/licenses/bsd-license.php
-*
-*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-*
-**/
-
-
-#ifndef _EthDxe_H__
-#define _EthDxe_H__
-
-#define NET_ETHER_HEADER_SIZE				14
-
-typedef struct
-{
-	UINT8	DstAddr[ NET_ETHER_ADDR_LEN ];
-	UINT8	SrcAddr[ NET_ETHER_ADDR_LEN ];
-	UINT16   Type;
-} EthernetHeader;
-
-/* Chip ID values */
-#define CHIP_9115							0x115
-#define CHIP_9116							0x116
-#define CHIP_9117							0x117
-#define CHIP_9118							0x118
-#define CHIP_9211							0x9211
-#define CHIP_9215							0x115a
-#define CHIP_9216							0x116a
-#define CHIP_9217							0x117a
-#define CHIP_9218							0x118a
-#define CHIP_9220							0x9220
-#define CHIP_9221							0x9221
-
-struct chip_id {
-	UINT16 id;
-	CHAR8 *name;
-};
-
-static const struct chip_id chip_ids[] = {
-	{ CHIP_9115, "LAN9115" },
-	{ CHIP_9116, "LAN9116" },
-	{ CHIP_9117, "LAN9117" },
-	{ CHIP_9118, "LAN9118" },
-	{ CHIP_9211, "LAN9211" },
-	{ CHIP_9215, "LAN9215" },
-	{ CHIP_9216, "LAN9216" },
-	{ CHIP_9217, "LAN9217" },
-	{ CHIP_9218, "LAN9218" },
-	{ CHIP_9220, "LAN9220" },
-	{ CHIP_9221, "LAN9221" },
-	{ 0, NULL },
-};
-	
-
-/* Below are the register offsets and bit definitions
- * of the Lan911x memory space
- */
-#define 	RX_DATA_FIFO		 				0x00
-
-#define 	TX_DATA_FIFO		 				0x20
-#define	TX_CMD_A_INT_ON_COMP			0x80000000
-#define	TX_CMD_A_INT_BUF_END_ALGN		0x03000000
-#define	TX_CMD_A_INT_4_BYTE_ALGN		0x00000000
-#define	TX_CMD_A_INT_16_BYTE_ALGN		0x01000000
-#define	TX_CMD_A_INT_32_BYTE_ALGN		0x02000000
-#define	TX_CMD_A_INT_DATA_OFFSET		0x001F0000
-#define	TX_CMD_A_INT_FIRST_SEG			0x00002000
-#define	TX_CMD_A_INT_LAST_SEG			0x00001000
-#define	TX_CMD_A_BUF_SIZE					0x000007FF
-#define	TX_CMD_B_PKT_TAG					0xFFFF0000
-#define	TX_CMD_B_ADD_CRC_DISABLE		0x00002000
-#define	TX_CMD_B_DISABLE_PADDING		0x00001000
-#define	TX_CMD_B_PKT_BYTE_LENGTH		0x000007FF
-
-#define 	RX_STATUS_FIFO					0x40
-#define	RX_STS_PKT_LEN					0x3FFF0000
-#define	RX_STS_ES							0x00008000
-#define	RX_STS_BCST						0x00002000
-#define	RX_STS_LEN_ERR					0x00001000
-#define	RX_STS_RUNT_ERR					0x00000800
-#define	RX_STS_MCAST						0x00000400
-#define	RX_STS_TOO_LONG					0x00000080
-#define	RX_STS_COLL						0x00000040
-#define	RX_STS_ETH_TYPE					0x00000020
-#define	RX_STS_WDOG_TMT					0x00000010
-#define	RX_STS_MII_ERR						0x00000008
-#define	RX_STS_DRIBBLING					0x00000004
-#define	RX_STS_CRC_ERR					0x00000002
-#define 	RX_STATUS_FIFO_PEEK				0x44
-#define 	TX_STATUS_FIFO					0x48
-#define	TX_STS_TAG							0xFFFF0000
-#define	TX_STS_ES							0x00008000
-#define	TX_STS_LOC							0x00000800
-#define	TX_STS_NO_CARR					0x00000400
-#define	TX_STS_LATE_COLL					0x00000200
-#define	TX_STS_MANY_COLL					0x00000100
-#define	TX_STS_COLL_CNT					0x00000078
-#define	TX_STS_MANY_DEFER				0x00000004
-#define	TX_STS_UNDERRUN					0x00000002
-#define	TX_STS_DEFERRED					0x00000001
-#define 	TX_STATUS_FIFO_PEEK				0x4C
-#define 	ID_REV								0x50
-#define	ID_REV_CHIP_ID						0xFFFF0000  /* RO */
-#define	ID_REV_REV_ID						0x0000FFFF  /* RO */
-
-#define 	INT_CFG							0x54
-#define	INT_CFG_INT_DEAS					0xFF000000  /* R/W */
-#define	INT_CFG_INT_DEAS_CLR				0x00004000
-#define	INT_CFG_INT_DEAS_STS				0x00002000
-#define	INT_CFG_IRQ_INT					0x00001000  /* RO */
-#define	INT_CFG_IRQ_EN					0x00000100  /* R/W */
-					/* R/W Not Affected by SW Reset */
-#define	INT_CFG_IRQ_POL					0x00000010
-					/* R/W Not Affected by SW Reset */
-#define	INT_CFG_IRQ_TYPE					0x00000001
-
-#define 	INT_STS								0x58
-#define	INT_STS_SW_INT					0x80000000  /* R/WC */
-#define	INT_STS_TXSTOP_INT				0x02000000  /* R/WC */
-#define	INT_STS_RXSTOP_INT				0x01000000  /* R/WC */
-#define	INT_STS_RXDFH_INT					0x00800000  /* R/WC */
-#define	INT_STS_RXDF_INT					0x00400000  /* R/WC */
-#define	INT_STS_TX_IOC						0x00200000  /* R/WC */
-#define	INT_STS_RXD_INT					0x00100000  /* R/WC */
-#define	INT_STS_GPT_INT					0x00080000  /* R/WC */
-#define	INT_STS_PHY_INT					0x00040000  /* RO */
-#define	INT_STS_PME_INT					0x00020000  /* R/WC */
-#define	INT_STS_TXSO						0x00010000  /* R/WC */
-#define	INT_STS_RWT						0x00008000  /* R/WC */
-#define	INT_STS_RXE						0x00004000  /* R/WC */
-#define	INT_STS_TXE						0x00002000  /* R/WC */
-/*#define	INT_STS_ERX						0x00001000*/  /* R/WC */
-#define	INT_STS_TDFU						0x00000800  /* R/WC */
-#define	INT_STS_TDFO						0x00000400  /* R/WC */
-#define	INT_STS_TDFA						0x00000200  /* R/WC */
-#define	INT_STS_TSFF						0x00000100  /* R/WC */
-#define	INT_STS_TSFL						0x00000080  /* R/WC */
-/*#define	INT_STS_RXDF					0x00000040*/  /* R/WC */
-#define	INT_STS_RDFO						0x00000040  /* R/WC */
-#define	INT_STS_RDFL						0x00000020  /* R/WC */
-#define	INT_STS_RSFF						0x00000010  /* R/WC */
-#define	INT_STS_RSFL						0x00000008  /* R/WC */
-#define	INT_STS_GPIO2_INT					0x00000004  /* R/WC */
-#define	INT_STS_GPIO1_INT					0x00000002  /* R/WC */
-#define	INT_STS_GPIO0_INT					0x00000001  /* R/WC */
-#define INT_EN					0x5C
-#define	INT_EN_SW_INT_EN			0x80000000  /* R/W */
-#define	INT_EN_TXSTOP_INT_EN			0x02000000  /* R/W */
-#define	INT_EN_RXSTOP_INT_EN			0x01000000  /* R/W */
-#define	INT_EN_RXDFH_INT_EN			0x00800000  /* R/W */
-/*#define	INT_EN_RXDF_INT_EN		0x00400000*/  /* R/W */
-#define	INT_EN_TIOC_INT_EN			0x00200000  /* R/W */
-#define	INT_EN_RXD_INT_EN			0x00100000  /* R/W */
-#define	INT_EN_GPT_INT_EN			0x00080000  /* R/W */
-#define	INT_EN_PHY_INT_EN			0x00040000  /* R/W */
-#define	INT_EN_PME_INT_EN			0x00020000  /* R/W */
-#define	INT_EN_TXSO_EN				0x00010000  /* R/W */
-#define	INT_EN_RWT_EN				0x00008000  /* R/W */
-#define	INT_EN_RXE_EN				0x00004000  /* R/W */
-#define	INT_EN_TXE_EN				0x00002000  /* R/W */
-/*#define	INT_EN_ERX_EN			0x00001000*/  /* R/W */
-#define	INT_EN_TDFU_EN				0x00000800  /* R/W */
-#define	INT_EN_TDFO_EN				0x00000400  /* R/W */
-#define	INT_EN_TDFA_EN				0x00000200  /* R/W */
-#define	INT_EN_TSFF_EN				0x00000100  /* R/W */
-#define	INT_EN_TSFL_EN				0x00000080  /* R/W */
-/*#define	INT_EN_RXDF_EN			0x00000040*/  /* R/W */
-#define	INT_EN_RDFO_EN				0x00000040  /* R/W */
-#define	INT_EN_RDFL_EN				0x00000020  /* R/W */
-#define	INT_EN_RSFF_EN				0x00000010  /* R/W */
-#define	INT_EN_RSFL_EN				0x00000008  /* R/W */
-#define	INT_EN_GPIO2_INT			0x00000004  /* R/W */
-#define	INT_EN_GPIO1_INT			0x00000002  /* R/W */
-#define	INT_EN_GPIO0_INT			0x00000001  /* R/W */
-
-#define BYTE_TEST				0x64
-#define FIFO_INT				0x68
-#define	FIFO_INT_TX_AVAIL_LEVEL			0xFF000000  /* R/W */
-#define	FIFO_INT_TX_STS_LEVEL			0x00FF0000  /* R/W */
-#define	FIFO_INT_RX_AVAIL_LEVEL			0x0000FF00  /* R/W */
-#define	FIFO_INT_RX_STS_LEVEL			0x000000FF  /* R/W */
-
-#define RX_CFG					0x6C
-#define	RX_CFG_RX_END_ALGN			0xC0000000  /* R/W */
-#define		RX_CFG_RX_END_ALGN4		0x00000000  /* R/W */
-#define		RX_CFG_RX_END_ALGN16		0x40000000  /* R/W */
-#define		RX_CFG_RX_END_ALGN32		0x80000000  /* R/W */
-#define	RX_CFG_RX_DMA_CNT			0x0FFF0000  /* R/W */
-#define	RX_CFG_RX_DUMP				0x00008000  /* R/W */
-#define	RX_CFG_RXDOFF				0x00001F00  /* R/W */
-/*#define	RX_CFG_RXBAD			0x00000001*/  /* R/W */
-
-#define TX_CFG					0x70
-/*#define	TX_CFG_TX_DMA_LVL		0xE0000000*/	 /* R/W */
-						 /* R/W Self Clearing */
-/*#define	TX_CFG_TX_DMA_CNT		0x0FFF0000*/
-#define	TX_CFG_TXS_DUMP				0x00008000  /* Self Clearing */
-#define	TX_CFG_TXD_DUMP				0x00004000  /* Self Clearing */
-#define	TX_CFG_TXSAO				0x00000004  /* R/W */
-#define	TX_CFG_TX_ON				0x00000002  /* R/W */
-#define	TX_CFG_STOP_TX				0x00000001  /* Self Clearing */
-
-#define HW_CFG					0x74
-#define	HW_CFG_TTM				0x00200000  /* R/W */
-#define	HW_CFG_SF				0x00100000  /* R/W */
-#define	HW_CFG_TX_FIF_SZ			0x000F0000  /* R/W */
-#define	HW_CFG_TR				0x00003000  /* R/W */
-#define	HW_CFG_PHY_CLK_SEL			0x00000060  /* R/W */
-#define	HW_CFG_PHY_CLK_SEL_INT_PHY		0x00000000 /* R/W */
-#define	HW_CFG_PHY_CLK_SEL_EXT_PHY		0x00000020 /* R/W */
-#define	HW_CFG_PHY_CLK_SEL_CLK_DIS		0x00000040 /* R/W */
-#define	HW_CFG_SMI_SEL				0x00000010  /* R/W */
-#define	HW_CFG_EXT_PHY_DET			0x00000008  /* RO */
-#define	HW_CFG_EXT_PHY_EN			0x00000004  /* R/W */
-#define	HW_CFG_32_16_BIT_MODE			0x00000004  /* RO */
-#define	HW_CFG_SRST_TO				0x00000002  /* RO */
-#define	HW_CFG_SRST				0x00000001  /* Self Clearing */
-
-#define RX_DP_CTRL				0x78
-#define	RX_DP_CTRL_RX_FFWD			0x80000000  /* R/W */
-#define	RX_DP_CTRL_FFWD_BUSY			0x80000000  /* RO */
-
-#define RX_FIFO_INF				0x7C
-#define	 RX_FIFO_INF_RXSUSED			0x00FF0000  /* RO */
-#define	 RX_FIFO_INF_RXDUSED			0x0000FFFF  /* RO */
-
-#define TX_FIFO_INF				0x80
-#define	TX_FIFO_INF_TSUSED			0x00FF0000  /* RO */
-#define	TX_FIFO_INF_TDFREE			0x0000FFFF  /* RO */
-
-#define PMT_CTRL				0x84
-#define	PMT_CTRL_PM_MODE			0x00003000  /* Self Clearing */
-#define	PMT_CTRL_PHY_RST			0x00000400  /* Self Clearing */
-#define	PMT_CTRL_WOL_EN				0x00000200  /* R/W */
-#define	PMT_CTRL_ED_EN				0x00000100  /* R/W */
-					/* R/W Not Affected by SW Reset */
-#define	PMT_CTRL_PME_TYPE			0x00000040
-#define	PMT_CTRL_WUPS				0x00000030  /* R/WC */
-#define	PMT_CTRL_WUPS_NOWAKE			0x00000000  /* R/WC */
-#define	PMT_CTRL_WUPS_ED			0x00000010  /* R/WC */
-#define	PMT_CTRL_WUPS_WOL			0x00000020  /* R/WC */
-#define	PMT_CTRL_WUPS_MULTI			0x00000030  /* R/WC */
-#define	PMT_CTRL_PME_IND			0x00000008  /* R/W */
-#define	PMT_CTRL_PME_POL			0x00000004  /* R/W */
-					/* R/W Not Affected by SW Reset */
-#define	PMT_CTRL_PME_EN				0x00000002
-#define	PMT_CTRL_READY				0x00000001  /* RO */
-
-#define GPIO_CFG				0x88
-#define	GPIO_CFG_LED3_EN			0x40000000  /* R/W */
-#define	GPIO_CFG_LED2_EN			0x20000000  /* R/W */
-#define	GPIO_CFG_LED1_EN			0x10000000  /* R/W */
-#define	GPIO_CFG_GPIO2_INT_POL			0x04000000  /* R/W */
-#define	GPIO_CFG_GPIO1_INT_POL			0x02000000  /* R/W */
-#define	GPIO_CFG_GPIO0_INT_POL			0x01000000  /* R/W */
-#define	GPIO_CFG_EEPR_EN			0x00700000  /* R/W */
-#define	GPIO_CFG_GPIOBUF2			0x00040000  /* R/W */
-#define	GPIO_CFG_GPIOBUF1			0x00020000  /* R/W */
-#define	GPIO_CFG_GPIOBUF0			0x00010000  /* R/W */
-#define	GPIO_CFG_GPIODIR2			0x00000400  /* R/W */
-#define	GPIO_CFG_GPIODIR1			0x00000200  /* R/W */
-#define	GPIO_CFG_GPIODIR0			0x00000100  /* R/W */
-#define	GPIO_CFG_GPIOD4				0x00000010  /* R/W */
-#define	GPIO_CFG_GPIOD3				0x00000008  /* R/W */
-#define	GPIO_CFG_GPIOD2				0x00000004  /* R/W */
-#define	GPIO_CFG_GPIOD1				0x00000002  /* R/W */
-#define	GPIO_CFG_GPIOD0				0x00000001  /* R/W */
-
-#define GPT_CFG					0x8C
-#define	GPT_CFG_TIMER_EN			0x20000000  /* R/W */
-#define	GPT_CFG_GPT_LOAD			0x0000FFFF  /* R/W */
-
-#define GPT_CNT					0x90
-#define	GPT_CNT_GPT_CNT				0x0000FFFF  /* RO */
-
-#define ENDIAN					0x98
-#define FREE_RUN				0x9C
-#define RX_DROP					0xA0
-#define MAC_CSR_CMD				0xA4
-#define	 MAC_CSR_CMD_CSR_BUSY			0x80000000  /* Self Clearing */
-#define	 MAC_CSR_CMD_R_NOT_W			0x40000000  /* R/W */
-#define	 MAC_CSR_CMD_CSR_ADDR			0x000000FF  /* R/W */
-
-#define MAC_CSR_DATA				0xA8
-#define AFC_CFG					0xAC
-#define		AFC_CFG_AFC_HI			0x00FF0000  /* R/W */
-#define		AFC_CFG_AFC_LO			0x0000FF00  /* R/W */
-#define		AFC_CFG_BACK_DUR		0x000000F0  /* R/W */
-#define		AFC_CFG_FCMULT			0x00000008  /* R/W */
-#define		AFC_CFG_FCBRD			0x00000004  /* R/W */
-#define		AFC_CFG_FCADD			0x00000002  /* R/W */
-#define		AFC_CFG_FCANY			0x00000001  /* R/W */
-
-#define E2P_CMD					0xB0
-#define		E2P_CMD_EPC_BUSY		0x80000000  /* Self Clearing */
-#define		E2P_CMD_EPC_CMD			0x70000000  /* R/W */
-#define		E2P_CMD_EPC_CMD_READ		0x00000000  /* R/W */
-#define		E2P_CMD_EPC_CMD_EWDS		0x10000000  /* R/W */
-#define		E2P_CMD_EPC_CMD_EWEN		0x20000000  /* R/W */
-#define		E2P_CMD_EPC_CMD_WRITE		0x30000000  /* R/W */
-#define		E2P_CMD_EPC_CMD_WRAL		0x40000000  /* R/W */
-#define		E2P_CMD_EPC_CMD_ERASE		0x50000000  /* R/W */
-#define		E2P_CMD_EPC_CMD_ERAL		0x60000000  /* R/W */
-#define		E2P_CMD_EPC_CMD_RELOAD		0x70000000  /* R/W */
-#define		E2P_CMD_EPC_TIMEOUT		0x00000200  /* RO */
-#define		E2P_CMD_MAC_ADDR_LOADED		0x00000100  /* RO */
-#define		E2P_CMD_EPC_ADDR		0x000000FF  /* R/W */
-
-#define E2P_DATA				0xB4
-#define	E2P_DATA_EEPROM_DATA			0x000000FF  /* R/W */
-/* end of LAN register offsets and bit definitions */
-
-/* MAC Control and Status registers */
-#define MAC_CR			0x01  /* R/W */
-
-/* MAC_CR - MAC Control Register */
-#define MAC_CR_RXALL			0x80000000
-/* TODO: delete this bit? It is not described in the data sheet. */
-#define MAC_CR_HBDIS			0x10000000
-#define MAC_CR_RCVOWN			0x00800000
-#define MAC_CR_LOOPBK			0x00200000
-#define MAC_CR_FDPX			0x00100000
-#define MAC_CR_MCPAS			0x00080000
-#define MAC_CR_PRMS			0x00040000
-#define MAC_CR_INVFILT			0x00020000
-#define MAC_CR_PASSBAD			0x00010000
-#define MAC_CR_HFILT			0x00008000
-#define MAC_CR_HPFILT			0x00002000
-#define MAC_CR_LCOLL			0x00001000
-#define MAC_CR_BCAST			0x00000800
-#define MAC_CR_DISRTY			0x00000400
-#define MAC_CR_PADSTR			0x00000100
-#define MAC_CR_BOLMT_MASK		0x000000C0
-#define MAC_CR_DFCHK			0x00000020
-#define MAC_CR_TXEN			0x00000008
-#define MAC_CR_RXEN			0x00000004
-
-#define ADDRH			0x02	  /* R/W mask 0x0000FFFFUL */
-#define ADDRL			0x03	  /* R/W mask 0xFFFFFFFFUL */
-#define HASHH			0x04	  /* R/W */
-#define HASHL			0x05	  /* R/W */
-
-#define MII_ACC			0x06	  /* R/W */
-#define MII_ACC_PHY_ADDR		0x0000F800
-#define MII_ACC_MIIRINDA		0x000007C0
-#define MII_ACC_MII_WRITE		0x00000002
-#define MII_ACC_MII_BUSY		0x00000001
-
-#define MII_DATA		0x07	  /* R/W mask 0x0000FFFFUL */
-
-#define FLOW			0x08	  /* R/W */
-#define FLOW_FCPT			0xFFFF0000
-#define FLOW_FCPASS			0x00000004
-#define FLOW_FCEN			0x00000002
-#define FLOW_FCBSY			0x00000001
-
-#define VLAN1			0x09	  /* R/W mask 0x0000FFFFUL */
-#define VLAN1_VTI1			0x0000ffff
-
-#define VLAN2			0x0A	  /* R/W mask 0x0000FFFFUL */
-#define VLAN2_VTI2			0x0000ffff
-
-#define WUFF			0x0B	  /* WO */
-
-#define WUCSR			0x0C	  /* R/W */
-#define WUCSR_GUE			0x00000200
-#define WUCSR_WUFR			0x00000040
-#define WUCSR_MPR			0x00000020
-#define WUCSR_WAKE_EN			0x00000004
-#define WUCSR_MPEN			0x00000002
-
-/* phy register offsets */
-#define PHY_BMCR		0x00
-#define PHY_BMSR		0x01
-#define PHY_PHYIDR1		0x02
-#define PHY_PHYIDR2		0x03
-#define PHY_ANAR		0x04
-#define PHY_ANLPAR		0x05
-#define PHY_ANER		0x06
-#define PHY_ANNPTR		0x07
-#define PHY_ANLPNP		0x08
-#define PHY_1000BTCR		0x09
-#define PHY_1000BTSR		0x0A
-#define PHY_EXSR		0x0F
-#define PHY_PHYSTS		0x10
-#define PHY_MIPSCR		0x11
-#define PHY_MIPGSR		0x12
-#define PHY_DCR			0x13
-#define PHY_FCSCR		0x14
-#define PHY_RECR		0x15
-#define PHY_PCSR		0x16
-#define PHY_LBR			0x17
-#define PHY_10BTSCR		0x18
-#define PHY_PHYCTRL		0x19
-
-/* PHY BMCR */
-#define PHY_BMCR_RESET		0x8000
-#define PHY_BMCR_LOOP		0x4000
-#define PHY_BMCR_100MB		0x2000
-#define PHY_BMCR_AUTON		0x1000
-#define PHY_BMCR_POWD		0x0800
-#define PHY_BMCR_ISO		0x0400
-#define PHY_BMCR_RST_NEG	0x0200
-#define PHY_BMCR_DPLX		0x0100
-#define PHY_BMCR_COL_TST	0x0080
-
-#define PHY_BMCR_SPEED_MASK	0x2040
-#define PHY_BMCR_1000_MBPS	0x0040
-#define PHY_BMCR_100_MBPS	0x2000
-#define PHY_BMCR_10_MBPS	0x0000
-
-/* phy BMSR */
-#define PHY_BMSR_100T4		0x8000
-#define PHY_BMSR_100TXF		0x4000
-#define PHY_BMSR_100TXH		0x2000
-#define PHY_BMSR_10TF		0x1000
-#define PHY_BMSR_10TH		0x0800
-#define PHY_BMSR_EXT_STAT	0x0100
-#define PHY_BMSR_PRE_SUP	0x0040
-#define PHY_BMSR_AUTN_COMP	0x0020
-#define PHY_BMSR_RF		0x0010
-#define PHY_BMSR_AUTN_ABLE	0x0008
-#define PHY_BMSR_LS		0x0004
-#define PHY_BMSR_JD		0x0002
-#define PHY_BMSR_EXT		0x0001
-
-/*phy ANLPAR */
-#define PHY_ANLPAR_NP		0x8000
-#define PHY_ANLPAR_ACK		0x4000
-#define PHY_ANLPAR_RF		0x2000
-#define PHY_ANLPAR_ASYMP	0x0800
-#define PHY_ANLPAR_PAUSE	0x0400
-#define PHY_ANLPAR_T4		0x0200
-#define PHY_ANLPAR_TXFD		0x0100
-#define PHY_ANLPAR_TX		0x0080
-#define PHY_ANLPAR_10FD		0x0040
-#define PHY_ANLPAR_10		0x0020
-#define PHY_ANLPAR_100		0x0380	/* we can run at 100 */
-/* phy ANLPAR 1000BASE-X */
-#define PHY_X_ANLPAR_NP		0x8000
-#define PHY_X_ANLPAR_ACK	0x4000
-#define PHY_X_ANLPAR_RF_MASK	0x3000
-#define PHY_X_ANLPAR_PAUSE_MASK	0x0180
-#define PHY_X_ANLPAR_HD		0x0040
-#define PHY_X_ANLPAR_FD		0x0020
-
-#define PHY_ANLPAR_PSB_MASK	0x001f
-#define PHY_ANLPAR_PSB_802_3	0x0001
-#define PHY_ANLPAR_PSB_802_9	0x0002
-
-/* phy 1000BTCR */
-#define PHY_1000BTCR_1000FD	0x0200
-#define PHY_1000BTCR_1000HD	0x0100
-
-/* phy 1000BTSR */
-#define PHY_1000BTSR_MSCF	0x8000
-#define PHY_1000BTSR_MSCR	0x4000
-#define PHY_1000BTSR_LRS	0x2000
-#define PHY_1000BTSR_RRS	0x1000
-#define PHY_1000BTSR_1000FD	0x0800
-#define PHY_1000BTSR_1000HD	0x0400
-
-/* phy EXSR */
-#define PHY_EXSR_1000XF		0x8000
-#define PHY_EXSR_1000XH		0x4000
-#define PHY_EXSR_1000TF		0x2000
-#define PHY_EXSR_1000TH		0x1000
-
-
-
-typedef struct {
-	VENDOR_DEVICE_PATH EthDevicePath;
-	EFI_DEVICE_PATH EndDevicePath;
-} ETH_DEVICE_PATH;
-
-//
-//  Private data for driver.
-//
-#define ETH_DXE_PRIVATE_DATA_SIGNATURE 	SIGNATURE_32( 'E', 'T', 'H', 'D' )
-
-typedef struct
-{
-	UINT32	Signature;
-	EFI_SIMPLE_NETWORK_PROTOCOL	Snp;
-	EFI_SIMPLE_NETWORK_MODE	Mode;
-	ETH_DEVICE_PATH		DevicePath;
-} ETH_DXE_PRIVATE_DATA;
-
-#define ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(a) \
-      CR( a, ETH_DXE_PRIVATE_DATA, Snp, ETH_DXE_PRIVATE_DATA_SIGNATURE )
-
-
-EFI_STATUS
-EFIAPI
-EthStart(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This
-);
-
-EFI_STATUS
-EFIAPI
-EthStop(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This
-);
-
-EFI_STATUS
-EFIAPI
-EthInitialize(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	UINTN							ExtraRxBufferSize,
-	UINTN							ExtraTxBufferSize
-);
-
-EFI_STATUS
-EFIAPI
-EthReset(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	BOOLEAN							ExtendedVerification
-);
-
-EFI_STATUS
-EFIAPI
-EthShutdown(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This
-);
-
-EFI_STATUS
-EFIAPI
-EthReceiveFilters(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	UINT32							Enable,
-	UINT32							Disable,
-	BOOLEAN							ResetMCastFilter,
-	UINTN							MCastFilterCnt,
-	EFI_MAC_ADDRESS				*MCastFilter
-);
-
-EFI_STATUS
-EFIAPI
-EthStationAddress(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	BOOLEAN							Reset,
-	EFI_MAC_ADDRESS				*New
-);
-
-EFI_STATUS
-EFIAPI
-EthStatistics(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	BOOLEAN							Reset,
-	UINTN							*StatisticsSize,
-	EFI_NETWORK_STATISTICS              *StatisticsTable
-);
-
-EFI_STATUS
-EFIAPI
-EthMCastIpToMac(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	BOOLEAN							IPv6,
-	EFI_IP_ADDRESS					*IP,
-	EFI_MAC_ADDRESS				*MAC
-);
-
-EFI_STATUS
-EFIAPI
-EthNvData(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	BOOLEAN							ReadWrite,
-	UINTN							Offset,
-	UINTN							BufferSize,
-	VOID							*Buffer
-);
-
-EFI_STATUS
-EFIAPI
-EthGetStatus(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	UINT32							*InterruptStatus,
-	VOID							**TxBuf
-);
-
-EFI_STATUS
-EFIAPI
-EthTransmit(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	UINTN							HeaderSize,
-	UINTN							BufferSize,
-	VOID							*Buffer,
-	EFI_MAC_ADDRESS				*SrcAddr,
-	EFI_MAC_ADDRESS				*DestAddr,
-	UINT16							*Protocol
-);
-
-EFI_STATUS
-EFIAPI
-EthReceive(
-	EFI_SIMPLE_NETWORK_PROTOCOL	*This,
-	UINTN							*HeaderSize,
-	UINTN							*BufferSize,
-	VOID							*Buffer,
-	EFI_MAC_ADDRESS				*SrcAddr,
-	EFI_MAC_ADDRESS				*DestAddr,
-	UINT16							*Protocol  
-);
-
-#endif // _Eth_Dxe_H__
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf
deleted file mode 100644
index e9f649e..0000000
--- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf
+++ /dev/null
@@ -1,59 +0,0 @@
-## @file
-#
-#  Component description file for GraphicsConsole module
-#
-#  This is the main routine for initializing the Graphics Console support routines.
-#
-#  Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
-#  This program and the accompanying materials
-#  are licensed and made available under the terms and conditions of the BSD License
-#  which accompanies this distribution. The full text of the license may be found at
-#  http://opensource.org/licenses/bsd-license.php
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-#
-##
-
-[Defines]
-  INF_VERSION                    = 0x00010005
-  BASE_NAME                      = EthDxe
-  FILE_GUID                        = 25ac458a-cf60-476e-861a-211c757657a6
-  MODULE_TYPE                   = UEFI_DRIVER
-  VERSION_STRING              = 1.0
-  ENTRY_POINT                    = EthDxeInitialize
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
-#
-#  DRIVER_BINDING                =  
-#  COMPONENT_NAME                =  
-#  COMPONENT_NAME2               =  
-#
-
-[Sources]
-  EthDxe.c
-  
-[Packages]
-  MdePkg/MdePkg.dec
-  MdeModulePkg/MdeModulePkg.dec
-  SamsungPlatformPkg/ExynosPkg/Exynos4210/ExynosPkg.dec
-  SamsungPlatformPkg/SamsungPlatformPkg.dec
-
-[LibraryClasses]
-  BaseLib
-  UefiLib
-  MemoryAllocationLib
-  UefiDriverEntryPoint
-  IoLib
-  TimerLib
-
-[Protocols]
-  gEfiSimpleNetworkProtocolGuid                ## TO_START
-
-[Guids]
-
-[Pcd]
-  gExynosPkgTokenSpaceGuid.PcdSMC911XBase
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/SimpleNetwork.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/SimpleNetwork.c
new file mode 100644
index 0000000..cad1693
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/SimpleNetwork.c
@@ -0,0 +1,1533 @@
+/** @file
+  Provides the Simple Network functions.
+
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ax88772.h"
+
+/**
+  This function updates the filtering on the receiver.
+
+  This support routine calls ::Ax88772MacAddressSet to update
+  the MAC address.  This routine then rebuilds the multicast
+  hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet.
+  Finally this routine enables the receiver by calling
+  ::Ax88772RxControl.
+
+  @param [in] pSimpleNetwork    Simple network mode pointer
+
+  @retval EFI_SUCCESS           This operation was successful.
+  @retval EFI_NOT_STARTED       The network interface was not started.
+  @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid
+                                EFI_SIMPLE_NETWORK_PROTOCOL structure.
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
+  @retval EFI_UNSUPPORTED       The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+ReceiveFilterUpdate (
+  IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork
+  )
+{
+  EFI_SIMPLE_NETWORK_MODE * pMode;
+  NIC_DEVICE * pNicDevice;
+  EFI_STATUS Status;
+  UINT32 Index;
+
+  DBG_ENTER ( );
+
+  DEBUG((DEBUG_WARN, "ReceiveFilterUpdate\n"));
+  //
+  // Set the MAC address
+  //
+  pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork );
+  pMode = pSimpleNetwork->Mode;
+  DEBUG((DEBUG_ERROR, "ReceiveFilterUpdate:Ax88772MacAddressSet\n"));
+  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 ( );
+  DEBUG((DEBUG_ERROR, "SN_GetStatus\n"));
+
+  //
+  // 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;
+      return EFI_SUCCESS;
+    }
+
+    //
+    // 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_RESORUCES  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 ( );
+  DEBUG((DEBUG_WARN, "SN_Initialize\n"));
+  
+  //
+  // 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 ( );
+  DEBUG((DEBUG_WARN, "SN_MCastIPtoMAC\n"));
+
+  //
+  // 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 ( );
+  DEBUG((DEBUG_WARN, "SN_NvData\n"));
+
+  //
+  // 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 ( );
+//  DEBUG((DEBUG_WARN, "SN_Receive\n"));
+  
+
+  //
+  // 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 ( );
+  DEBUG((DEBUG_WARN, "SN_ReceiveFilters\n"));
+
+  //
+  // 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 ( );
+  DEBUG((DEBUG_WARN, "SN_Reset\n"));
+
+  //
+  //  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 ( );
+  DEBUG((DEBUG_WARN, "SN_Setup\n"));
+
+  //
+  // 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 = AX88772_MAX_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;
+  pMode->PermanentAddress.Addr[0] = 0x00;
+  pMode->PermanentAddress.Addr[1] = 0x40;
+  pMode->PermanentAddress.Addr[2] = 0x5C;
+  pMode->PermanentAddress.Addr[3] = 0x26;
+  pMode->PermanentAddress.Addr[4] = 0x0A;
+  pMode->PermanentAddress.Addr[5] = 0x5B;
+  Status = Ax88772MacAddressSet (pNicDevice, &pMode->PermanentAddress.Addr[0]);
+  if (EFI_ERROR (Status)) {
+	DEBUG((DEBUG_ERROR, "SN_Setup:Ax88772MacAddressSet:Status:%x\n",Status));
+  }
+  Status = Ax88772MacAddressGet (
+                pNicDevice,
+                &pMode->PermanentAddress.Addr[0]);
+  if ( !EFI_ERROR ( Status )) {
+    //
+    //  Display the MAC address
+    //
+    /*pMode->PermanentAddress.Addr[0] = 0x00;
+    pMode->PermanentAddress.Addr[1] = 0x40;
+    pMode->PermanentAddress.Addr[2] = 0x5C;
+    pMode->PermanentAddress.Addr[3] = 0x26;
+    pMode->PermanentAddress.Addr[4] = 0x0A;
+    pMode->PermanentAddress.Addr[5] = 0x5B;*/
+
+    DEBUG (( DEBUG_MAC_ADDRESS | DEBUG_ERROR,
+              "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 ( );
+  DEBUG((DEBUG_WARN, "SN_Start\n"));
+  
+  //
+  // 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 = AX88772_MAX_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 ( );
+  DEBUG((DEBUG_WARN, "SN_StationAddress\n"));
+
+  DEBUG((DEBUG_ERROR, "SN_StationAddress\n"));
+  //
+  // 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
+      //
+      DEBUG((DEBUG_ERROR, "SN_StationAddress:Ax88772MacAddressSet\n"));
+      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 ( );
+  DEBUG((DEBUG_WARN, "SN_Statistics\n"));
+
+  //
+  // 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 ( );
+  DEBUG((DEBUG_WARN, "SN_Stop\n"));
+  
+  //
+  // 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 ( );
+  DEBUG((DEBUG_WARN, "SN_Shutdown\n"));
+  
+  //
+  // 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 ( );
+  DEBUG((DEBUG_ERROR, "SN_Transmit\n"));
+
+  //
+  // 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;
+
+      //
+      //  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_ERROR,
+                  "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_ERROR,
+                    "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_ERROR,
+              "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/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c
index cdd4102..92c4953 100644
--- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c
@@ -73,7 +73,7 @@ Set (
     case GPIO_MODE_INPUT:
       break;
     case GPIO_MODE_OUTPUT_0:
-         MmioAndThenOr32(OutputRegister, ~GPIO_SFN_MASK(Pin), GPIO_OP_EN(Pin));
+	 MmioAndThenOr32(OutputRegister, ~GPIO_SFN_MASK(Pin), GPIO_OP_DIS(Pin));
          MmioAndThenOr32((GpioBase(Port) + GPIO_DATAIN), ~GPIO_DATAIN_MASK(Pin), GPIO_DATA_LOW(Pin));
       break;
     case GPIO_MODE_OUTPUT_1:
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB.c
index e89ba4b..fb3b1b7 100644
--- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB.c
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB.c
@@ -39,7 +39,6 @@ enum usb_phy_type {
 	USB_PHY_HSIC1   = (0x1 << 2),
 };
 
-
 static void usb_clk_get(enum usb_clk_type clk_type)
 {
 	if( clk_type == USBOTG_CLK) {
@@ -55,6 +54,7 @@ static void usb_clk_get(enum usb_clk_type clk_type)
 	return;
 }
 
+#if 0
 static void usb_clk_put(enum usb_clk_type clk_type)
 {
 	if( clk_type == USBOTG_CLK) {
@@ -69,6 +69,7 @@ static void usb_clk_put(enum usb_clk_type clk_type)
 
 	return;
 }
+#endif
 
 //------------------------------------------------------------------------------------
 
@@ -89,10 +90,12 @@ void USBPHY_Ctr48MhzClk(UINT8 bEnable_48Mhz)
 	MmioWrite32(rUPHY_OHCICTRL, uTemp);
 }
 
+#if 0
 static int exynos5_usb_host_phy20_is_on(void)
 {
 	return (MmioRead32(EXYNOS5_USB2_PHY_HOST_CTRL0) & HOST_CTRL0_PHYSWRSTALL) ? 0 : 1;
 }
+#endif
 
 static void exynos5_usb_phy_control(enum usb_phy_type phy_type , int on)
 {
@@ -104,6 +107,7 @@ static void exynos5_usb_phy_control(enum usb_phy_type phy_type , int on)
 
 void exynos5_usb_phy20_init(void)
 {
+
 	EFI_STATUS    Status;
 	EXYNOS_GPIO *Gpio;
 	UINT32 hostphy_ctrl0;
@@ -115,26 +119,46 @@ void exynos5_usb_phy20_init(void)
 	Status = gBS->LocateProtocol(&gSamsungPlatformGpioProtocolGuid, NULL, (VOID **)&Gpio);
 	ASSERT_EFI_ERROR(Status);
 
-	if(PcdGetBool(PcdExynos5250Evt1))
-	{
-		Gpio->Set(Gpio, USB_2_EVT1, GPIO_MODE_OUTPUT_1);
-		Gpio->SetPull(Gpio, USB_2_EVT1, GPIO_PULL_NONE);
-	}
-
+	//if(PcdGetBool(PcdExynos5250Evt1))
+	//{
+		Gpio->Set(Gpio, USB_2_X3, GPIO_MODE_OUTPUT_0);
+		//Gpio->SetPull(Gpio, USB_2_X3, GPIO_PULL_NONE);
+		Gpio->Set(Gpio, USB_2_D1, GPIO_MODE_OUTPUT_0);
+		//Gpio->SetPull(Gpio, USB_2_D1, GPIO_PULL_NONE);
+	//}
+#if 0
 	if (exynos5_usb_host_phy20_is_on())
 	{
 		DEBUG ((EFI_D_ERROR, "Already power on PHY $$$\n"));
 		return;
 	}
+#endif
 
 	//  Must be enable usbhost & usbotg clk
-	usb_clk_get(USBHOST_CLK);
-	usb_clk_get(USBOTG_CLK);
+	//usb_clk_get(USBHOST_CLK);
+	//usb_clk_get(USBOTG_CLK);
 
-	MmioWrite32(ETC6PUD, (MmioRead32(ETC6PUD) & ~(0x3 << 14)) | (0x3 << 14));
+	MmioWrite32(0x10050230, 0x1);
+	//MmioWrite32(ETC6PUD, (MmioRead32(ETC6PUD) & ~(0x3 << 14)) | (0x3 << 14));
 
 	exynos5_usb_phy_control(USB_PHY1, PHY_ENABLE);
 
+	hostphy_ctrl0 = MmioRead32(EXYNOS5_USB2_PHY_HOST_CTRL0);
+	hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK | HOST_CTRL0_COMMONONN | HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL | HOST_CTRL0_SIDDQ | HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
+	MmioWrite32(EXYNOS5_USB2_PHY_HOST_CTRL0, hostphy_ctrl0);
+
+	hostphy_ctrl0 = MmioRead32(EXYNOS5_USB2_PHY_HOST_CTRL0);
+	hostphy_ctrl0 |= (CLKSEL_24M | HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
+	MmioWrite32(EXYNOS5_USB2_PHY_HOST_CTRL0, hostphy_ctrl0);
+	MicroSecondDelay(10);
+	MicroSecondDelay(10);
+	hostphy_ctrl0 = MmioRead32(EXYNOS5_USB2_PHY_HOST_CTRL0);
+	hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
+	MmioWrite32(EXYNOS5_USB2_PHY_HOST_CTRL0, hostphy_ctrl0);
+	MicroSecondDelay(20);
+	MicroSecondDelay(20);
+	
+#if 0
 	/* Host and Device should be set at the same time */
 	hostphy_ctrl0 = MmioRead32(EXYNOS5_USB2_PHY_HOST_CTRL0);
 	hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK);
@@ -155,18 +179,25 @@ void exynos5_usb_phy20_init(void)
 	MicroSecondDelay(10);
 	hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
 	MmioWrite32(EXYNOS5_USB2_PHY_HOST_CTRL0, hostphy_ctrl0);
+	MicroSecondDelay(20);
+	MicroSecondDelay(20);
+#endif
 
 	DEBUG ((EFI_D_ERROR, "exynos5_usb_phy20_init Clk set $$$\n"));
 
 	/* HSIC phy reset */
-	hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2) |HSIC_CTRL_PHYSWRST);
+	MmioAnd32(PHY_HSIC_CTRL1, ~(0x7 << 4));
+	MmioAnd32(PHY_HSIC_CTRL2, ~(0x7 << 4));
+	hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2) | HSIC_CTRL_PHYSWRST);
 	MmioWrite32(PHY_HSIC_CTRL1, hsic_ctrl);
 	MmioWrite32(PHY_HSIC_CTRL2, hsic_ctrl);
 	MicroSecondDelay(10);
 	MicroSecondDelay(10);
-	hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2));
-	MmioWrite32(PHY_HSIC_CTRL1, hsic_ctrl);
-	MmioWrite32(PHY_HSIC_CTRL2, hsic_ctrl);
+	MmioAnd32(PHY_HSIC_CTRL1, ~(HSIC_CTRL_PHYSWRST));
+	MmioAnd32(PHY_HSIC_CTRL2, ~(HSIC_CTRL_PHYSWRST));
+	//hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2));
+	//MmioWrite32(PHY_HSIC_CTRL1, hsic_ctrl);
+	//MmioWrite32(PHY_HSIC_CTRL2, hsic_ctrl);
 
 	MicroSecondDelay(80);
 	MicroSecondDelay(80);
@@ -176,11 +207,22 @@ void exynos5_usb_phy20_init(void)
 	ehcictrl |= (EHCICTRL_ENAINCRXALIGN | EHCICTRL_ENAINCR4 |EHCICTRL_ENAINCR8 | EHCICTRL_ENAINCR16);
 	MmioWrite32(PHY_HOST_EHCICTRL, ehcictrl);
 
+//	Gpio->Set(Gpio, USB_2_X3, GPIO_MODE_OUTPUT_1);
+//	MicroSecondDelay(8000);
+	Gpio->Set(Gpio, USB_2_D1, GPIO_MODE_OUTPUT_1);
+        MicroSecondDelay(8000);
+        Gpio->Set(Gpio, USB_2_X3, GPIO_MODE_OUTPUT_1);
+        MicroSecondDelay(8000);
+
 	DEBUG ((EFI_D_ERROR, "exynos5_usb_phy20_init END $$$\n"));
 }
 
 void exynos5_usb_phy20_off(void)
 {
+
+	MmioWrite32(EXYNOS5_USB2_PHY_HOST_CTRL0, HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL | HOST_CTRL0_SIDDQ | HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
+	exynos5_usb_phy_control(USB_PHY1, PHY_DISABLE);
+#if 0
 	UINT32 uTemp;
 
 	uTemp = MmioRead32(rUPHY_USBCTRL0);
@@ -189,9 +231,9 @@ void exynos5_usb_phy20_off(void)
 
 	usb_clk_put(USBOTG_CLK);
 	usb_clk_put(USBHOST_CLK);
+#endif
 }
 
-
 void exynos5_usb_phy30_init(void)
 {
 	UINT32 reg;
@@ -350,4 +392,3 @@ UINT32 exynos_xhci_change_mode(void)
 	DEBUG ((EFI_D_ERROR, "Change xHCI host mode %x\n", gctl));
 	return gctl;
 }
-
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.h
index 7f0e310..1b596d8 100644
--- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.h
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.h
@@ -36,6 +36,7 @@
 
 #include <IndustryStandard/Pci22.h>
 #include <IndustryStandard/Acpi.h>
+#include <Protocol/UsbIo.h>
 
 
 //#define OHCI_SUPPORT
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf
index f56fe6c..2c021c7 100644
--- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf
@@ -57,6 +57,7 @@
   gEfiPciHostBridgeResourceAllocationProtocolGuid
   gEfiPciIoProtocolGuid
   gSamsungPlatformGpioProtocolGuid      ## GPIO Protocol
+  gEfiUsbIoProtocolGuid
 
 [Depex]
   gEfiMetronomeArchProtocolGuid
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/ArmPlatform.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/ArmPlatform.h
index 4d5f7d8..5cc960b 100755
--- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/ArmPlatform.h
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/ArmPlatform.h
@@ -577,6 +577,7 @@
 
 #define GPIO_SFN_EN(x)		(2UL << (x*4))
 #define GPIO_OP_EN(x)		(1UL << (x*4))
+#define GPIO_OP_DIS(x)         (0UL << (x*4))
 
 #define GPIO_PUD_DIS(x)		(0UL << (x*2))
 #define GPIO_PDN_EN(x)		(1UL << (x*2))
@@ -671,6 +672,9 @@
 
 /* USB 2.0 GPIO Pin Configuration for GAIA Evt1 */
 #define USB_2_EVT1 GPIO(GPX2,PIN6)
+#define USB_2_X3 GPIO(GPX3,PIN5)
+#define USB_2_D1 GPIO(GPD1,PIN7)
+
 
 /* SDHC CH0 GPIO Pin Configuration for GAIA */
 #define SD_0_CLK	GPIO(GPC0,PIN0)
-- 
1.8.2

