* [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
@ 2019-07-08 7:05 Ooi, Tzy Way
2019-07-11 16:43 ` Leif Lindholm
0 siblings, 1 reply; 7+ messages in thread
From: Ooi, Tzy Way @ 2019-07-08 7:05 UTC (permalink / raw)
To: devel
Cc: Ooi Tzy Way, Ard BieSheuvel, Leif Lindholm, Michael D Kinney,
Loh Tien Hock
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=utf-8, Size: 167683 bytes --]
From: Ooi Tzy Way <tzy.way.ooi@intel.com>
Add driver support for the Ethernet MAC based on Synopsys DesignWare
3504-0 Universal 10/100/1000 Ethernet MAC and KSZ9031 PHY
Cc: Ard BieSheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Loh Tien Hock <tien.hock.loh@intel.com>
Contributed-under: Tianocore Contribution Agreement 1.1
Signed-off-by: Ooi Tzy Way <tzy.way.ooi@intel.com>
---
v6:
- Update to recent version for EDK2 specific file formats
- Update the directory layout to Silicon/Synopsys/DesignWare
- Add a DesignWare.dsc for building this driver
- Update the license
- Update the .c file to declare its own include file
- Remove __ in defining the header file
- Fix indentation
- Delete commented-out code
---
Silicon/Synopsys/DesignWare/DesignWare.dec | 24 +
Silicon/Synopsys/DesignWare/DesignWare.dsc | 39 +
Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.inf | 59 +
Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.h | 203 ++++
Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.h | 364 ++++++
Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.h | 322 +++++
Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/ComponentName.c | 318 +++++
Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DriverBinding.c | 372 ++++++
Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c | 1271 ++++++++++++++++++++
Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c | 672 +++++++++++
Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.c | 680 +++++++++++
11 files changed, 4324 insertions(+)
diff --git a/Silicon/Synopsys/DesignWare/DesignWare.dec b/Silicon/Synopsys/DesignWare/DesignWare.dec
new file mode 100755
index 000000000000..4010c1906224
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/DesignWare.dec
@@ -0,0 +1,24 @@
+ #Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved.
+ #SPDX-License-Identifier: BSD-2-Clause-Patent
+
+[Defines]
+ DEC_SPECIFICATION = 1.27
+ PACKAGE_NAME = DesignWarePkg
+ PACKAGE_GUID = 3b5936d8-c72d-412d-b4d9-3bf0dea73598
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+
+[Guids.common]
+ gDesignWareTokenSpaceGuid = { 0x89cb1241, 0xd283, 0x4543, { 0x88, 0x9c, 0x6b, 0x62, 0x36, 0x1a, 0x95, 0x7a } }
+ gDwEmacNetNonDiscoverableDeviceGuid = { 0x401950CD, 0xF9CD, 0x4A65, { 0xAD, 0x8E, 0x84, 0x9F, 0x3B, 0xAF, 0x23, 0x04 } }
+
+
diff --git a/Silicon/Synopsys/DesignWare/DesignWare.dsc b/Silicon/Synopsys/DesignWare/DesignWare.dsc
new file mode 100755
index 000000000000..4a38e568d38e
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/DesignWare.dsc
@@ -0,0 +1,39 @@
+## @file
+#
+# Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ PLATFORM_NAME = Synopsys
+ PLATFORM_GUID = 09b27b59-7195-4220-b81c-c1871c74d006
+ PLATFORM_VERSION = 0.1
+ OUTPUT_DIRECTORY = Build/Synopsys
+ SUPPORTED_ARCHITECTURES = AARCH64|ARM
+ BUILD_TARGETS = DEBUG|RELEASE
+ SKUID_IDENTIFIER = DEFAULT
+
+[LibraryClasses]
+ ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
+ ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+
+[Components]
+ Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.inf
\ No newline at end of file
diff --git a/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.inf b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.inf
new file mode 100755
index 000000000000..4ee03fd6f32c
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.inf
@@ -0,0 +1,59 @@
+#/** @file
+# DW Emac Simple Networking Protocol Driver (SNP) DXE Driver
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# The original software modules are licensed as follows:
+#
+# Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+[Defines]
+ INF_VERSION = 1.27
+ BASE_NAME = DwEmacSnpDxe
+ FILE_GUID = 06f3315f-9fe6-4938-b83f-2c072af802ba
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 0.1
+ ENTRY_POINT = DwEmacSnpDxeEntry
+
+[Sources.common]
+ ComponentName.c
+ DriverBinding.c
+ DwEmacSnpDxe.c
+ EmacDxeUtil.c
+ PhyDxeUtil.c
+ DwEmacSnpDxe.h
+ EmacDxeUtil.h
+ PhyDxeUtil.h
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ NetworkPkg/NetworkPkg.dec
+ Silicon/Synopsys/DesignWare/DesignWare.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ DmaLib
+ IoLib
+ NetLib
+ TimerLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Protocols]
+ gEdkiiNonDiscoverableDeviceProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiDriverBindingProtocolGuid
+ gEfiMetronomeArchProtocolGuid
+ gEfiSimpleNetworkProtocolGuid
+
+[Guids]
+ gDwEmacNetNonDiscoverableDeviceGuid ## TO_START
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.h b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.h
new file mode 100755
index 000000000000..44b6b8f487e1
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.h
@@ -0,0 +1,203 @@
+/** @file
+
+ Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ The original software modules are licensed as follows:
+
+ Copyright (c) 2012-2014, ARM Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef DWEMAC_SNP_DXE_H__
+#define DWEMAC_SNP_DXE_H__
+
+// Protocols used by this driver
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/ComponentName2.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/NonDiscoverableDevice.h>
+
+#include <Library/UefiLib.h>
+
+#include "PhyDxeUtil.h"
+#include "EmacDxeUtil.h"
+
+/*------------------------------------------------------------------------------
+ Information Structure
+------------------------------------------------------------------------------*/
+
+typedef struct {
+ MAC_ADDR_DEVICE_PATH MacAddrDP;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} SIMPLE_NETWORK_DEVICE_PATH;
+
+typedef struct {
+ // Driver signature
+ UINT32 Signature;
+ EFI_HANDLE ControllerHandle;
+
+ // EFI SNP protocol instances
+ EFI_SIMPLE_NETWORK_PROTOCOL Snp;
+ EFI_SIMPLE_NETWORK_MODE SnpMode;
+
+ // EFI Snp statistics instance
+ EFI_NETWORK_STATISTICS Stats;
+
+ EMAC_DRIVER MacDriver;
+ PHY_DRIVER PhyDriver;
+
+ NON_DISCOVERABLE_DEVICE *Dev;
+
+ EFI_LOCK Lock;
+
+ UINTN MacBase;
+
+ // Array of the recycled transmit buffer address
+ UINT64 *RecycledTxBuf;
+
+ // The maximum number of recycled buffer pointers in RecycledTxBuf.
+ UINT32 MaxRecycledTxBuf;
+
+ // Current number of recycled buffer pointers in RecycledTxBuf.
+ UINT32 RecycledTxBufCount;
+
+ // For TX buffer DmaUnmap
+ VOID *MappingTxbuf;
+
+} SIMPLE_NETWORK_DRIVER;
+
+extern EFI_COMPONENT_NAME_PROTOCOL gSnpComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gSnpComponentName2;
+
+#define SNP_DRIVER_SIGNATURE SIGNATURE_32('A', 'S', 'N', 'P')
+#define INSTANCE_FROM_SNP_THIS(a) CR(a, SIMPLE_NETWORK_DRIVER, Snp, SNP_DRIVER_SIGNATURE)
+#define SNP_TX_BUFFER_INCREASE 32
+#define SNP_MAX_TX_BUFFER_NUM 65536
+#define DESC_NUM 10
+#define ETH_BUFSIZE 0x800
+/*---------------------------------------------------------------------------------------------------------------------
+
+ UEFI-Compliant functions for EFI_SIMPLE_NETWORK_PROTOCOL
+
+ Refer to the Simple Network Protocol section (24.1) in the UEFI 2.8 Specification for related definitions
+
+---------------------------------------------------------------------------------------------------------------------*/
+
+EFI_STATUS
+EFIAPI
+SnpStart (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp
+ );
+
+EFI_STATUS
+EFIAPI
+SnpStop (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp
+ );
+
+EFI_STATUS
+EFIAPI
+SnpInitialize (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
+ IN UINTN ExtraRxBufferSize OPTIONAL,
+ IN UINTN ExtraTxBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+SnpReset (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
+ IN BOOLEAN ExtendedVerification
+ );
+
+EFI_STATUS
+EFIAPI
+SnpShutdown (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp
+ );
+
+EFI_STATUS
+EFIAPI
+SnpReceiveFilters (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
+ IN UINT32 Enable,
+ IN UINT32 Disable,
+ IN BOOLEAN ResetMCastFilter,
+ IN UINTN MCastFilterCnt OPTIONAL,
+ IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+SnpStationAddress (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
+ IN BOOLEAN Reset,
+ IN EFI_MAC_ADDRESS *NewMac
+);
+
+EFI_STATUS
+EFIAPI
+SnpStatistics (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
+ IN BOOLEAN Reset,
+ IN OUT UINTN *StatSize,
+ OUT EFI_NETWORK_STATISTICS *Statistics
+ );
+
+EFI_STATUS
+EFIAPI
+SnpMcastIptoMac (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
+ IN BOOLEAN IsIpv6,
+ IN EFI_IP_ADDRESS *Ip,
+ OUT EFI_MAC_ADDRESS *McastMac
+ );
+
+EFI_STATUS
+EFIAPI
+SnpNvData (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
+ IN BOOLEAN ReadWrite,
+ IN UINTN Offset,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+SnpGetStatus (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
+ OUT UINT32 *IrqStat OPTIONAL,
+ OUT VOID **TxBuff OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+SnpTransmit (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
+ IN UINTN HdrSize,
+ IN UINTN BuffSize,
+ IN VOID *Data,
+ IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
+ IN EFI_MAC_ADDRESS *DstAddr OPTIONAL,
+ IN UINT16 *Protocol OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+SnpReceive (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp,
+ OUT UINTN *HdrSize OPTIONAL,
+ IN OUT UINTN *BuffSize,
+ OUT VOID *Data,
+ OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
+ OUT EFI_MAC_ADDRESS *DstAddr OPTIONAL,
+ OUT UINT16 *Protocol OPTIONAL
+ );
+
+#endif // DWEMAC_SNP_DXE_H__
diff --git a/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.h b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.h
new file mode 100755
index 000000000000..49e4567a5c13
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.h
@@ -0,0 +1,364 @@
+/** @file
+
+ Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ The original software modules are licensed as follows:
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef EMAC_DXE_UTIL_H__
+#define EMAC_DXE_UTIL_H__
+
+#include <Protocol/SimpleNetwork.h>
+
+// Most common CRC32 Polynomial for little endian machines
+#define CRC_POLYNOMIAL 0xEDB88320
+#define HASH_TABLE_REG(n) 0x500 + (0x4 * n)
+#define RX_MAX_PACKET 1600
+
+#define CONFIG_ETH_BUFSIZE 2048
+#define CONFIG_TX_DESCR_NUM 10
+#define CONFIG_RX_DESCR_NUM 10
+#define TX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
+#define RX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
+
+// DMA status error bit
+#define RX_DMA_WRITE_DATA_TRANSFER_ERROR 0x0
+#define TX_DMA_READ_DATA_TRANSFER_ERROR 0x3
+#define RX_DMA_DESCRIPTOR_WRITE_ACCESS_ERROR 0x4
+#define TX_DMA_DESCRIPTOR_WRITE_ACCESS_ERROR 0x5
+#define RX_DMA_DESCRIPTOR_READ_ACCESS_ERROR 0x6
+#define TX_DMA_DESCRIPTOR_READ_ACCESS_ERROR 0x7
+
+// tx descriptor
+#define TDES0_OWN BIT31
+#define TDES0_TXINT BIT30
+#define TDES0_TXLAST BIT29
+#define TDES0_TXFIRST BIT28
+#define TDES0_TXCRCDIS BIT27
+#define TDES0_TXRINGEND BIT21
+#define TDES0_TXCHAIN BIT20
+
+#define TDES1_SIZE1MASK (0x1FFF << 0)
+#define TDES1_SIZE1SHFT (0)
+#define TDES1_SIZE2MASK (0x1FFF << 16)
+#define TDES1_SIZE2SHFT (16)
+
+// rx descriptor
+#define RDES0_FL_MASK 0x3fff
+#define RDES0_FL_SHIFT 16
+#define RDES1_CHAINED BIT14
+
+#define RDES0_CE BIT1
+#define RDES0_DBE BIT2
+#define RDES0_RE BIT3
+#define RDES0_RWT BIT4
+#define RDES0_LC BIT6
+#define RDES0_GF BIT7
+#define RDES0_OE BIT11
+#define RDES0_LE BIT12
+#define RDES0_SAF BIT13
+#define RDES0_DE BIT14
+#define RDES0_ES BIT15
+#define RDES0_AFM BIT30
+#define RDES0_OWN BIT31
+
+
+// emac config phy interface setting
+#define PHY_INTERFACE_MODE_GMII 0
+#define PHY_INTERFACE_MODE_MII 1
+#define PHY_INTERFACE_MODE_RGMII 2
+#define PHY_INTERFACE_MODE_RMII 3
+
+// DW emac mask
+#define DW_EMAC_DMAGRP_BUS_MODE_SWR_SET_MSK 0x00000001
+#define DW_EMAC_DMAGRP_BUS_MODE_FB_SET_MSK 0x00010000
+#define DW_EMAC_DMAGRP_BUS_MODE_PBL_SET_MSK 0x00003f00
+#define DW_EMAC_DMAGRP_BUS_MODE_PR_SET_MSK 0x0000c000
+#define DW_EMAC_DMAGRP_OPERATION_MODE_FTF_SET_MSK 0x00100000
+#define DW_EMAC_DMAGRP_OPERATION_MODE_TSF_SET_MSK 0x00200000
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_TIE_SET_MSK 0x00000001
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_RIE_SET_MSK 0x00000040
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_NIE_SET_MSK 0x00010000
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_AIE_SET_MSK 0x00008000
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_FBE_SET_MSK 0x00002000
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_UNE_SET_MSK 0x00000020
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_TSE_SET_MSK 0x00000002
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_TUE_SET_MSK 0x00000004
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_TJE_SET_MSK 0x00000008
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_OVE_SET_MSK 0x00000010
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_RUE_SET_MSK 0x00000080
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_RSE_SET_MSK 0x00000100
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_RWE_SET_MSK 0x00000200
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_ETE_SET_MSK 0x00000400
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_ERE_SET_MSK 0x00004000
+#define DW_EMAC_DMAGRP_OPERATION_MODE_ST_SET_MSK 0x00002000
+#define DW_EMAC_DMAGRP_OPERATION_MODE_SR_SET_MSK 0x00000002
+#define DW_EMAC_GMACGRP_MAC_CONFIGURATION_RE_SET_MSK 0x00000004
+#define DW_EMAC_GMACGRP_MAC_CONFIGURATION_TE_SET_MSK 0x00000008
+#define DW_EMAC_GMACGRP_MAC_FRAME_FILTER_RESET 0x00000000
+#define DW_EMAC_GMACGRP_MAC_FRAME_FILTER_HMC_SET_MSK 0x00000004
+#define DW_EMAC_GMACGRP_MAC_FRAME_FILTER_DBF_SET_MSK 0x00000020
+#define DW_EMAC_GMACGRP_MAC_FRAME_FILTER_PR_SET_MSK 0x00000001
+#define DW_EMAC_GMACGRP_MAC_FRAME_FILTER_PM_SET_MSK 0x00000010
+#define DW_EMAC_DMAGRP_OPERATION_MODE_ST_CLR_MSK 0xffffdfff
+#define DW_EMAC_GMACGRP_MAC_CONFIGURATION_RE_CLR_MSK 0xfffffffb
+#define DW_EMAC_GMACGRP_MAC_CONFIGURATION_TE_CLR_MSK 0xfffffff7
+#define DW_EMAC_DMAGRP_OPERATION_MODE_SR_CLR_MSK 0xfffffffd
+#define DW_EMAC_DMAGRP_STATUS_NIS_SET_MSK 0x00010000
+#define DW_EMAC_DMAGRP_STATUS_RI_SET_MSK 0x00000040
+#define DW_EMAC_DMAGRP_STATUS_TI_SET_MSK 0x00000001
+#define DW_EMAC_DMAGRP_STATUS_TU_SET_MSK 0x00000004
+#define DW_EMAC_DMAGRP_STATUS_ERI_SET_MSK 0x00004000
+#define DW_EMAC_DMAGRP_STATUS_AIS_SET_MSK 0x00008000
+#define DW_EMAC_DMAGRP_STATUS_TPS_SET_MSK 0x00000002
+#define DW_EMAC_DMAGRP_STATUS_TJT_SET_MSK 0x00000008
+#define DW_EMAC_DMAGRP_STATUS_OVF_SET_MSK 0x00000010
+#define DW_EMAC_DMAGRP_STATUS_UNF_SET_MSK 0x00000020
+#define DW_EMAC_DMAGRP_STATUS_RU_SET_MSK 0x00000080
+#define DW_EMAC_DMAGRP_STATUS_RPS_SET_MSK 0x00000100
+#define DW_EMAC_DMAGRP_STATUS_RWT_SET_MSK 0x00000200
+#define DW_EMAC_DMAGRP_STATUS_ETI_SET_MSK 0x00000400
+#define DW_EMAC_DMAGRP_STATUS_FBI_SET_MSK 0x00002000
+#define DW_EMAC_GMACGRP_MAC_CONFIGURATION_PS_SET_MSK 0x00008000
+#define DW_EMAC_GMACGRP_MAC_CONFIGURATION_FES_SET_MSK 0x00004000
+#define DW_EMAC_GMACGRP_MAC_CONFIGURATION_DM_SET_MSK 0x00000800
+#define DW_EMAC_GMACGRP_MAC_CONFIGURATION_BE_SET_MSK 0x00200000
+#define DW_EMAC_GMACGRP_MAC_CONFIGURATION_DO_SET_MSK 0x00002000
+
+#define DW_EMAC_DMAGRP_BUS_MODE_SWR_GET(value) (((value) & 0x00000001) >> 0)
+#define DW_EMAC_DMAGRP_STATUS_EB_GET(value) (((value) & 0x03800000) >> 23)
+#define DW_EMAC_GMACGRP_GMII_ADDRESS_GB_GET(value) (((value) & 0x00000001) >> 0)
+#define DW_EMAC_GMACGRP_GMII_DATA_GD_GET(value) (((value) & 0x0000ffff) >> 0)
+#define DW_EMAC_DMAGRP_OPERATION_MODE_FTF_GET(value) (((value) & 0x00100000) >> 20)
+
+// DW emac registers offset
+
+#define DW_EMAC_GMACGRP_MAC_CONFIGURATION_OFST 0x000
+#define DW_EMAC_GMACGRP_MAC_FRAME_FILTER_OFST 0x004
+#define DW_EMAC_GMACGRP_GMII_ADDRESS_OFST 0x010
+#define DW_EMAC_GMACGRP_GMII_DATA_OFST 0x014
+#define DW_EMAC_GMACGRP_FLOW_CONTROL_OFST 0x018
+#define DW_EMAC_GMACGRP_VLAN_TAG_OFST 0x01c
+#define DW_EMAC_GMACGRP_VERSION_OFST 0x020
+#define DW_EMAC_GMACGRP_DEBUG_OFST 0x024
+#define DW_EMAC_GMACGRP_LPI_CONTROL_STATUS_OFST 0x030
+#define DW_EMAC_GMACGRP_LPI_TIMERS_CONTROL_OFST 0x034
+#define DW_EMAC_GMACGRP_INTERRUPT_STATUS_OFST 0x038
+#define DW_EMAC_GMACGRP_INTERRUPT_MASK_OFST 0x03c
+#define DW_EMAC_GMACGRP_MAC_ADDRESS0_HIGH_OFST 0x040
+#define DW_EMAC_GMACGRP_MAC_ADDRESS0_LOW_OFST 0x044
+#define DW_EMAC_GMACGRP_MAC_ADDRESS1_HIGH_OFST 0x048
+#define DW_EMAC_GMACGRP_MAC_ADDRESS1_LOW_OFST 0x04c
+#define DW_EMAC_GMACGRP_MAC_ADDRESS2_HIGH_OFST 0x050
+#define DW_EMAC_GMACGRP_MAC_ADDRESS2_LOW_OFST 0x054
+#define DW_EMAC_GMACGRP_MAC_ADDRESS3_HIGH_OFST 0x058
+#define DW_EMAC_GMACGRP_MAC_ADDRESS3_LOW_OFST 0x05c
+#define DW_EMAC_GMACGRP_MAC_ADDRESS4_HIGH_OFST 0x060
+#define DW_EMAC_GMACGRP_MAC_ADDRESS4_LOW_OFST 0x064
+#define DW_EMAC_GMACGRP_MAC_ADDRESS5_HIGH_OFST 0x068
+#define DW_EMAC_GMACGRP_MAC_ADDRESS5_LOW_OFST 0x06c
+#define DW_EMAC_GMACGRP_MAC_ADDRESS6_HIGH_OFST 0x070
+#define DW_EMAC_GMACGRP_MAC_ADDRESS6_LOW_OFST 0x074
+#define DW_EMAC_GMACGRP_MAC_ADDRESS7_HIGH_OFST 0x078
+#define DW_EMAC_GMACGRP_MAC_ADDRESS7_LOW_OFST 0x07c
+#define DW_EMAC_GMACGRP_MAC_ADDRESS8_HIGH_OFST 0x080
+#define DW_EMAC_GMACGRP_MAC_ADDRESS8_LOW_OFST 0x084
+#define DW_EMAC_GMACGRP_MAC_ADDRESS9_HIGH_OFST 0x088
+#define DW_EMAC_GMACGRP_MAC_ADDRESS9_LOW_OFST 0x08c
+#define DW_EMAC_GMACGRP_MAC_ADDRESS10_HIGH_OFST 0x090
+#define DW_EMAC_GMACGRP_MAC_ADDRESS10_LOW_OFST 0x094
+#define DW_EMAC_GMACGRP_MAC_ADDRESS11_HIGH_OFST 0x098
+#define DW_EMAC_GMACGRP_MAC_ADDRESS11_LOW_OFST 0x09c
+#define DW_EMAC_GMACGRP_MAC_ADDRESS12_HIGH_OFST 0x0a0
+#define DW_EMAC_GMACGRP_MAC_ADDRESS12_LOW_OFST 0x0a4
+#define DW_EMAC_GMACGRP_MAC_ADDRESS13_HIGH_OFST 0x0a8
+#define DW_EMAC_GMACGRP_MAC_ADDRESS13_LOW_OFST 0x0ac
+#define DW_EMAC_GMACGRP_MAC_ADDRESS14_HIGH_OFST 0x0b0
+#define DW_EMAC_GMACGRP_MAC_ADDRESS14_LOW_OFST 0x0b4
+#define DW_EMAC_GMACGRP_MAC_ADDRESS15_HIGH_OFST 0x0b8
+#define DW_EMAC_GMACGRP_MAC_ADDRESS15_LOW_OFST 0x0bc
+#define DW_EMAC_GMACGRP_SGMII_RGMII_SMII_CONTROL_STATUS_OFST 0x0d8
+#define DW_EMAC_GMACGRP_WDOG_TIMEOUT_OFST 0x0dc
+#define DW_EMAC_GMACGRP_GENPIO_OFST 0x0e0
+#define DW_EMAC_GMACGRP_MMC_CONTROL_OFST 0x100
+#define DW_EMAC_GMACGRP_MMC_RECEIVE_INTERRUPT_OFST 0x104
+#define DW_EMAC_GMACGRP_MMC_TRANSMIT_INTERRUPT_OFST 0x108
+#define DW_EMAC_GMACGRP_MMC_RECEIVE_INTERRUPT_MASK_OFST 0x10c
+#define DW_EMAC_GMACGRP_MMC_TRANSMIT_INTERRUPT_MASK_OFST 0x110
+#define DW_EMAC_GMACGRP_TXOCTETCOUNT_GB_OFST 0x114
+#define DW_EMAC_GMACGRP_TXFRAMECOUNT_GB_OFST 0x118
+#define DW_EMAC_GMACGRP_TXBROADCASTFRAMES_G_OFST 0x11c
+#define DW_EMAC_GMACGRP_TXMULTICASTFRAMES_G_OFST 0x120
+#define DW_EMAC_GMACGRP_TXUNICASTFRAMES_GB_OFST 0x13c
+#define DW_EMAC_GMACGRP_TXLATECOL_OFST 0x158
+#define DW_EMAC_GMACGRP_TXEXESSCOL_OFST 0x15c
+#define DW_EMAC_GMACGRP_TXFRAMECOUNT_G_OFST 0x168
+#define DW_EMAC_GMACGRP_TXOVERSIZE_G_OFST 0x178
+#define DW_EMAC_GMACGRP_RXFRAMECOUNT_GB_OFST 0x180
+#define DW_EMAC_GMACGRP_RXOCTETCOUNT_GB_OFST 0x184
+#define DW_EMAC_GMACGRP_RXBROADCASTFRAMES_G_OFST 0x18c
+#define DW_EMAC_GMACGRP_RXMULTICASTFRAMES_G_OFST 0x190
+#define DW_EMAC_GMACGRP_RXCRCERROR_OFST 0x194
+#define DW_EMAC_GMACGRP_RXUNDERSIZE_G_OFST 0x1a4
+#define DW_EMAC_GMACGRP_RXOVERSIZE_G_OFST 0x1a8
+#define DW_EMAC_GMACGRP_RXUNICASTFRAMES_G_OFST 0x1c4
+#define DW_EMAC_DMAGRP_BUS_MODE_OFST 0x1000
+#define DW_EMAC_DMAGRP_TRANSMIT_POLL_DEMAND_OFST 0x1004
+#define DW_EMAC_DMAGRP_RECEIVE_POLL_DEMAND_OFST 0x1008
+#define DW_EMAC_DMAGRP_RECEIVE_DESCRIPTOR_LIST_ADDRESS_OFST 0x100c
+#define DW_EMAC_DMAGRP_TRANSMIT_DESCRIPTOR_LIST_ADDRESS_OFST 0x1010
+#define DW_EMAC_DMAGRP_STATUS_OFST 0x1014
+#define DW_EMAC_DMAGRP_OPERATION_MODE_OFST 0x1018
+#define DW_EMAC_DMAGRP_INTERRUPT_ENABLE_OFST 0x101c
+#define DW_EMAC_DMAGRP_MISSED_FRAME_AND_BUFFER_OVERFLOW_COUNTER_OFST 0x1020
+#define DW_EMAC_DMAGRP_RECEIVE_INTERRUPT_WATCHDOG_TIMER_OFST 0x1024
+#define DW_EMAC_DMAGRP_AXI_BUS_MODE_OFST 0x1028
+#define DW_EMAC_DMAGRP_AHB_OR_AXI_STATUS_OFST 0x102c
+#define DW_EMAC_DMAGRP_CURRENT_HOST_TRANSMIT_DESCRIPTOR_OFST 0x1048
+#define DW_EMAC_DMAGRP_CURRENT_HOST_RECEIVE_DESCRIPTOR_OFST 0x104c
+#define DW_EMAC_DMAGRP_CURRENT_HOST_TRANSMIT_BUFFER_ADDRESS_OFST 0x1050
+#define DW_EMAC_DMAGRP_CURRENT_HOST_RECEIVE_BUFFER_ADDRESS_OFST 0x1054
+#define DW_EMAC_DMAGRP_HW_FEATURE_OFST 0x1058
+
+typedef struct {
+ UINT32 Tdes0;
+ UINT32 Tdes1;
+ UINT32 Addr;
+ UINT32 AddrNext;
+} DESIGNWARE_HW_DESCRIPTOR;
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS AddrMap;
+ void *Mapping;
+} MAP_INFO;
+
+typedef struct {
+ DESIGNWARE_HW_DESCRIPTOR *TxdescRing[CONFIG_TX_DESCR_NUM];
+ DESIGNWARE_HW_DESCRIPTOR *RxdescRing[CONFIG_RX_DESCR_NUM];
+ CHAR8 TxBuffer[TX_TOTAL_BUFSIZE];
+ CHAR8 RxBuffer[RX_TOTAL_BUFSIZE];
+ MAP_INFO TxdescRingMap[CONFIG_TX_DESCR_NUM ];
+ MAP_INFO RxdescRingMap[CONFIG_RX_DESCR_NUM ];
+ MAP_INFO RxBufNum[CONFIG_TX_DESCR_NUM];
+ UINT32 TxCurrentDescriptorNum;
+ UINT32 TxNextDescriptorNum;
+ UINT32 RxCurrentDescriptorNum;
+ UINT32 RxNextDescriptorNum;
+} EMAC_DRIVER;
+
+VOID
+EFIAPI
+EmacSetMacAddress (
+ IN EFI_MAC_ADDRESS *MacAddress,
+ IN UINTN MacBaseAddress
+ );
+
+VOID
+EFIAPI
+EmacReadMacAddress (
+ OUT EFI_MAC_ADDRESS *MacAddress,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+EmacDxeInitialization (
+ IN EMAC_DRIVER *EmacDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+EmacDmaInit (
+ IN EMAC_DRIVER *EmacDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+EmacSetupTxdesc (
+ IN EMAC_DRIVER *EmacDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+EmacSetupRxdesc (
+ IN EMAC_DRIVER *EmacDriver,
+ IN UINTN MacBaseAddress
+ );
+
+VOID
+EFIAPI
+EmacStartTransmission (
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+EmacRxFilters (
+ IN UINT32 ReceiveFilterSetting,
+ IN BOOLEAN Reset,
+ IN UINTN NumMfilter OPTIONAL,
+ IN EFI_MAC_ADDRESS *Mfilter OPTIONAL,
+ IN UINTN MacBaseAddress
+ );
+
+UINT32
+EFIAPI
+GenEtherCrc32 (
+ IN EFI_MAC_ADDRESS *Mac,
+ IN UINT32 AddrLen
+ );
+
+UINT8
+EFIAPI
+BitReverse (
+ UINT8 Value
+ );
+
+VOID
+EFIAPI
+EmacStopTxRx (
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+EmacDmaStart (
+ IN UINTN MacBaseAddress
+ );
+
+
+VOID
+EFIAPI
+EmacGetDmaStatus (
+ OUT UINT32 *IrqStat OPTIONAL,
+ IN UINTN MacBaseAddress
+ );
+
+VOID
+EFIAPI
+EmacGetStatistic (
+ IN EFI_NETWORK_STATISTICS *Stats,
+ IN UINTN MacBaseAddress
+ );
+
+VOID
+EFIAPI
+EmacConfigAdjust (
+ IN UINT32 Speed,
+ IN UINT32 Duplex,
+ IN UINTN MacBaseAddress
+ );
+
+#endif // EMAC_DXE_UTIL_H__
diff --git a/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.h b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.h
new file mode 100755
index 000000000000..1fd391438417
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.h
@@ -0,0 +1,322 @@
+/** @file
+
+ Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ The original software modules are licensed as follows:
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+ Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#ifndef KSZ9031_PHY_DXE_H__
+#define KSZ9031_PHY_DXE_H__
+
+typedef struct {
+ UINT32 PhyAddr;
+ UINT32 PhyCurrentLink;
+ UINT32 PhyOldLink;
+} PHY_DRIVER;
+
+
+//
+// PHY Registers
+//
+#define PHY_BASIC_CTRL 0
+#define PHY_BASIC_STATUS 1
+#define PHY_ID1 2
+#define PHY_ID2 3
+#define PHY_AUTO_NEG_ADVERT 4
+#define PHY_AUTO_NEG_LINK_ABILITY 5
+#define PHY_AUTO_NEG_EXP 6
+#define PHY_1000BASE_T_CONTROL 9
+#define PHY_1000BASE_T_STATUS 10
+#define PHY_MODE 17
+#define PHY_SPECIAL_MODES 18
+#define PHY_SPECIAL_CTLR 27
+#define PHY_INT_SRC 29
+#define PHY_INT_MASK 30
+#define PHY_SPECIAL_PHY_CTLR 31
+
+// PHY control register bits
+#define PHYCTRL_COLL_TEST BIT7 // Collision test enable
+#define PHYCTRL_DUPLEX_MODE BIT8 // Set Duplex Mode
+#define PHYCTRL_RST_AUTO BIT9 // Restart Auto-Negotiation of Link abilities
+#define PHYCTRL_PD BIT11 // Power-Down switch
+#define PHYCTRL_AUTO_EN BIT12 // Auto-Negotiation Enable
+#define PHYCTRL_SPEED_SEL BIT13 // Link Speed Selection
+#define PHYCTRL_LOOPBK BIT14 // Set loopback mode
+#define PHYCTRL_RESET BIT15 // Do a PHY reset
+
+// PHY status register bits
+#define PHYSTS_EXT_CAP BIT0 // Extended Capabilities Register capability
+#define PHYSTS_JABBER BIT1 // Jabber condition detected
+#define PHYSTS_LINK_STS BIT2 // Link Status
+#define PHYSTS_AUTO_CAP BIT3 // Auto-Negotiation Capability
+#define PHYSTS_REMOTE_FAULT BIT4 // Remote fault detected
+#define PHYSTS_AUTO_COMP BIT5 // Auto-Negotiation Completed
+#define PHYSTS_10BASET_HDPLX BIT11 // 10Mbps Half-Duplex ability
+#define PHYSTS_10BASET_FDPLX BIT12 // 10Mbps Full-Duplex ability
+#define PHYSTS_100BASETX_HDPLX BIT13 // 100Mbps Half-Duplex ability
+#define PHYSTS_100BASETX_FDPLX BIT14 // 100Mbps Full-Duplex ability
+#define PHYSTS_100BASE_T4 BIT15 // Base T4 ability
+
+// PHY Auto-Negotiation advertisement
+#define PHYANA_SEL_MASK ((UINT32)0x1F) // Link type selector
+#define PHYANA_10BASET BIT5 // Advertise 10BASET capability
+#define PHYANA_10BASETFD BIT6 // Advertise 10BASET Full duplex capability
+#define PHYANA_100BASETX BIT7 // Advertise 100BASETX capability
+#define PHYANA_100BASETXFD BIT8 // Advertise 100 BASETX Full duplex capability
+#define PHYANA_PAUSE_OP_MASK (3 << 10) // Advertise PAUSE frame capability
+#define PHYANA_REMOTE_FAULT BIT13 // Remote fault detected
+
+#define PHYLPA_SLCT 0x001f // Same as advertise selector
+#define PHYLPA_10HALF 0x0020 // Can do 10mbps half-duplex
+#define PHYLPA_1000XFULL 0x0020 // Can do 1000BASE-X full-duplex
+#define PHYLPA_10FULL 0x0040 // Can do 10mbps full-duplex
+#define PHYLPA_1000XHALF 0x0040 // Can do 1000BASE-X half-duplex
+#define PHYLPA_100HALF 0x0080 // Can do 100mbps half-duplex
+#define PHYLPA_1000XPAUSE 0x0080 // Can do 1000BASE-X pause
+#define PHYLPA_100FULL 0x0100 // Can do 100mbps full-duplex
+#define PHYLPA_1000XPAUSE_ASYM 0x0100 // Can do 1000BASE-X pause asym
+#define PHYLPA_100BASE4 0x0200 // Can do 100mbps 4k packets
+#define PHYLPA_PAUSE_CAP 0x0400 // Can pause
+#define PHYLPA_PAUSE_ASYM 0x0800 // Can pause asymetrically
+#define PHYLPA_RESV 0x1000 // Unused
+#define PHYLPA_RFAULT 0x2000 // Link partner faulted
+#define PHYLPA_LPACK 0x4000 // Link partner acked us
+#define PHYLPA_NPAGE 0x8000 // Next page bit
+
+#define PHYLPA_DUPLEX (LPA_10FULL | LPA_100FULL)
+#define PHYLPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+// 1000BASE-T Status register
+#define PHYLPA_1000FULL 0x0800 // Link partner 1000BASE-T full duplex
+#define PHYLPA_1000HALF 0x0400 // Link partner 1000BASE-T half duplex
+
+// 1000BASE-T Control register
+#define PHYADVERTISE_1000FULL 0x0200 // Advertise 1000BASE-T full duplex
+#define PHYADVERTISE_1000HALF 0x0100 // Advertise 1000BASE-T half duplex
+
+#define SPEED_1000 1000
+#define SPEED_100 100
+#define SPEED_10 10
+
+#define DUPLEX_FULL 1
+#define DUPLEX_HALF 0
+
+// PHY Super Special control/status
+#define PHYSSCS_HCDSPEED_MASK (7 << 2) // Speed indication
+#define PHYSSCS_AUTODONE BIT12 // Auto-Negotiation Done
+
+// Flags for PHY reset
+#define PHY_RESET_PMT BIT0
+#define PHY_RESET_BCR BIT1
+#define PHY_RESET_CHECK_LINK BIT2
+
+// Flags for auto negotiation
+#define AUTO_NEGOTIATE_COLLISION_TEST BIT0
+#define AUTO_NEGOTIATE_ADVERTISE_ALL BIT1
+
+
+// Micrel KSZ9031 Extended registers
+#define PHY_KSZ9031RN_CONTROL_PAD_SKEW_REG 4
+#define PHY_KSZ9031RN_RX_DATA_PAD_SKEW_REG 5
+#define PHY_KSZ9031RN_TX_DATA_PAD_SKEW_REG 6
+#define PHY_KSZ9031RN_CLK_PAD_SKEW_REG 8
+
+// Data operations
+#define PHY_KSZ9031_MOD_DATA_NO_POST_INC 0x1
+#define PHY_KSZ9031_MOD_DATA_POST_INC_RW 0x2
+#define PHY_KSZ9031_MOD_DATA_POST_INC_W 0x3
+
+#define PHY_KSZ9031RN_MMD_CTRL_REG 0x0d
+#define PHY_KSZ9031RN_MMD_REGDATA_REG 0x0e
+
+#define PHY_KSZ9031RN_CLK_SKEW_CLR_MASK 0x3FF
+#define PHY_KSZ9031RN_CONTROL_SKEW_CLR_MASK 0xFF
+#define PHY_KSZ9031RN_RX_DATA_SKEW_CLR_MASK 0xFF
+#define PHY_KSZ9031RN_TX_DATA_SKEW_CLR_MASK 0xFF
+
+#define PHY_KSZ9031RN_CLK_PAD_SKEW_VALUE 0x3FC
+#define PHY_KSZ9031RN_CONTROL_PAD_SKEW_VALUE 0x70
+#define PHY_KSZ9031RN_RX_DATA_PAD_SKEW_VALUE 0x7777
+#define PHY_KSZ9031RN_TX_DATA_PAD_SKEW_VALUE 0x0
+
+
+#define PHY_KSZ9031RN_DEV_ADDR 0x2
+
+// MMD Address 0h, Auto-Negotiation FLP burst transmit timing
+#define PHY_KSZ9031RN_MMD_DEV_ADDR_00 0x00
+#define PHY_KSZ9031RN_MMD_D0_FLP_LO_REG 3
+#define PHY_KSZ9031RN_MMD_D0_FLP_16MS_LO 0x1A80
+#define PHY_KSZ9031RN_MMD_D0_FLP_HI_REG 4
+#define PHY_KSZ9031RN_MMD_D0_FLP_16MS_HI 0x0006
+
+// HPS MII
+#define MII_BUSY (1 << 0)
+#define MII_WRITE (1 << 1)
+#define MII_CLKRANGE_60_100M (0x0)
+#define MII_CLKRANGE_100_150M (0x4)
+#define MII_CLKRANGE_20_35M (0x8)
+#define MII_CLKRANGE_35_60M (0xC)
+#define MII_CLKRANGE_150_250M (0x10)
+#define MII_CLKRANGE_250_300M (0x14)
+
+#define MIIADDRSHIFT (11)
+#define MIIREGSHIFT (6)
+#define MII_REGMSK (0x1F << 6)
+#define MII_ADDRMSK (0x1F << 11)
+
+// Others
+#define PHY_INVALID_ID 0xFFFF
+#define LINK_UP 1
+#define LINK_DOWN 0
+#define PHY_TIMEOUT 200000
+
+
+EFI_STATUS
+EFIAPI
+PhyDxeInitialization (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PhyDetectDevice (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PhyConfig (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PhySoftReset (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PhyReadId (
+ IN UINT32 PhyAddr,
+ IN UINTN MacBaseAddress
+ );
+
+VOID
+EFIAPI
+PhyConfigSkew (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+VOID
+EFIAPI
+PhyDisplayConfigSkew (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+VOID
+EFIAPI
+PhyConfigFlpBurstTiming (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+VOID
+EFIAPI
+PhyDisplayFlpBurstTiming (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PhyAutoNego (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PhyLinkAdjustEmacConfig (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PhyCheckLinkStatus (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PhyReadCapability (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINT32 *Speed,
+ IN UINT32 *Duplex,
+ IN UINTN MacBaseAddress
+ );
+
+VOID
+EFIAPI
+PhyDisplayAbility (
+ IN UINT32 Speed,
+ IN UINT32 Duplex
+ );
+
+EFI_STATUS
+EFIAPI
+PhyRead (
+ IN UINT32 Addr,
+ IN UINT32 Reg,
+ OUT UINT32 *Data,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PhyWrite (
+ IN UINT32 Addr,
+ IN UINT32 Reg,
+ IN UINT32 Data,
+ IN UINTN MacBaseAddress
+ );
+
+EFI_STATUS
+EFIAPI
+Phy9031ExtendedWrite (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINT32 Mode,
+ IN UINT32 DevAddr,
+ IN UINT32 Regnum,
+ IN UINT16 Val,
+ IN UINTN MacBaseAddress
+ );
+
+UINT32
+EFIAPI
+Phy9031ExtendedRead (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINT32 Mode,
+ IN UINT32 DevAddr,
+ IN UINT32 Regnum,
+ IN UINTN MacBaseAddress
+ );
+
+#endif /* KSZ9031_PHY_DXE_H__ */
diff --git a/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/ComponentName.c b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/ComponentName.c
new file mode 100755
index 000000000000..bd29d08daee1
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/ComponentName.c
@@ -0,0 +1,318 @@
+/** @file
+ Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ The original software modules are licensed as follows:
+
+ Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+
+**/
+
+#include "DwEmacSnpDxe.h"
+
+//
+// EFI Component Name Functions
+//
+/**
+ 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 This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] 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 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] 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
+SnpGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] 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 ChildHandle[in] 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 Language[in] 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 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] 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
+SnpGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gSnpComponentName = {
+ SnpGetDriverName,
+ SnpGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gSnpComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SnpGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) SnpGetControllerName,
+ "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSnpNameTable[] = {
+ {
+ "eng;en",
+ L"SNP DesignWare EMAC 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 This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] 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 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] 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
+SnpGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mSnpNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gSnpComponentName)
+ );
+}
+
+/**
+ 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 This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] 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 ChildHandle[in] 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 Language[in] 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 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] 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
+SnpGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DriverBinding.c b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DriverBinding.c
new file mode 100755
index 000000000000..a77899f2c55a
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DriverBinding.c
@@ -0,0 +1,372 @@
+/** @file
+
+ Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+ **/
+
+#include "DwEmacSnpDxe.h"
+
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DmaLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/NetLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+STATIC
+EFI_STATUS
+EFIAPI
+DriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+STATIC
+EFI_STATUS
+EFIAPI
+DriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+STATIC
+EFI_STATUS
+EFIAPI
+DriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+STATIC
+EFI_DRIVER_BINDING_PROTOCOL mDriverBinding = {
+ DriverSupported,
+ DriverStart,
+ DriverStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+STATIC
+SIMPLE_NETWORK_DEVICE_PATH PathTemplate = {
+ {
+ {
+ MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP,
+ {(UINT8)(sizeof (MAC_ADDR_DEVICE_PATH)), (UINT8)((sizeof (MAC_ADDR_DEVICE_PATH)) >> 8)}
+ },
+ {{ 0 }},
+ 0
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}
+ }
+};
+
+STATIC
+EFI_STATUS
+EFIAPI
+DriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ NON_DISCOVERABLE_DEVICE *Dev;
+ EFI_STATUS Status;
+
+ // Connect to the non-discoverable device
+ Status = gBS->OpenProtocol (Controller,
+ &gEdkiiNonDiscoverableDeviceProtocolGuid,
+ (VOID **)&Dev,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Clean up.
+ gBS->CloseProtocol (Controller,
+ &gEdkiiNonDiscoverableDeviceProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+DriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ SIMPLE_NETWORK_DRIVER *Snp;
+ EFI_SIMPLE_NETWORK_MODE *SnpMode;
+ SIMPLE_NETWORK_DEVICE_PATH *DevicePath;
+ UINT64 DefaultMacAddress;
+ EFI_MAC_ADDRESS *SwapMacAddressPtr;
+ UINTN DescriptorSize;
+ UINTN BufferSize;
+ UINTN *RxBufferAddr;
+ EFI_PHYSICAL_ADDRESS RxBufferAddrMap;
+
+ // Allocate Resources
+ Snp = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (SIMPLE_NETWORK_DRIVER)));
+ if (Snp == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gBS->OpenProtocol (Controller,
+ &gEdkiiNonDiscoverableDeviceProtocolGuid,
+ (VOID **)&Snp->Dev,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+ // Size for descriptor
+ DescriptorSize = EFI_PAGES_TO_SIZE (sizeof (DESIGNWARE_HW_DESCRIPTOR));
+ // Size for transmit and receive buffer
+ BufferSize = ETH_BUFSIZE;
+
+ for (int Index=0; Index < DESC_NUM; Index++) {
+ //DMA TxdescRing allocate buffer and map
+ Status = DmaAllocateBuffer (EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (sizeof (DESIGNWARE_HW_DESCRIPTOR)), (VOID *)&Snp->MacDriver.TxdescRing[Index]);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a () for TxdescRing: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ Status = DmaMap (MapOperationBusMasterCommonBuffer, Snp->MacDriver.TxdescRing[Index],
+ &DescriptorSize, &Snp->MacDriver.TxdescRingMap[Index].AddrMap, &Snp->MacDriver.TxdescRingMap[Index].Mapping);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a () for TxdescRing: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ // DMA RxdescRing allocte buffer and map
+ Status = DmaAllocateBuffer (EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (sizeof (DESIGNWARE_HW_DESCRIPTOR)), (VOID *)&Snp->MacDriver.RxdescRing[Index]);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a () for RxdescRing: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ Status = DmaMap (MapOperationBusMasterCommonBuffer, Snp->MacDriver.RxdescRing[Index],
+ &DescriptorSize, &Snp->MacDriver.RxdescRingMap[Index].AddrMap, &Snp->MacDriver.RxdescRingMap[Index].Mapping);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a () for RxdescRing: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ //DMA mapping for receive buffer
+ RxBufferAddr = (VOID *)Snp->MacDriver.RxBuffer + (Index * BufferSize);
+ Status = DmaMap (MapOperationBusMasterWrite, (VOID *) RxBufferAddr,
+ &BufferSize, &RxBufferAddrMap, &Snp->MacDriver.RxBufNum[Index].Mapping);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a () for Rxbuffer: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+ Snp->MacDriver.RxBufNum[Index].AddrMap= RxBufferAddrMap;
+ }
+
+ DevicePath = (SIMPLE_NETWORK_DEVICE_PATH*)AllocateCopyPool (sizeof (SIMPLE_NETWORK_DEVICE_PATH), &PathTemplate);
+ if (DevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Initialized signature (used by INSTANCE_FROM_SNP_THIS macro)
+ Snp->Signature = SNP_DRIVER_SIGNATURE;
+
+ EfiInitializeLock (&Snp->Lock, TPL_CALLBACK);
+
+ // Initialize pointers
+ SnpMode = &Snp->SnpMode;
+ Snp->Snp.Mode = SnpMode;
+
+ // Get MAC controller base address
+ Snp->MacBase = (UINTN)Snp->Dev->Resources[0].AddrRangeMin;
+
+ // Assign fields and func pointers
+ Snp->Snp.Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION;
+ Snp->Snp.WaitForPacket = NULL;
+ Snp->Snp.Initialize = SnpInitialize;
+ Snp->Snp.Start = SnpStart;
+ Snp->Snp.Stop = SnpStop;
+ Snp->Snp.Reset = SnpReset;
+ Snp->Snp.Shutdown = SnpShutdown;
+ Snp->Snp.ReceiveFilters = SnpReceiveFilters;
+ Snp->Snp.StationAddress = SnpStationAddress;
+ Snp->Snp.Statistics = SnpStatistics;
+ Snp->Snp.MCastIpToMac = SnpMcastIptoMac;
+ Snp->Snp.NvData = SnpNvData;
+ Snp->Snp.GetStatus = SnpGetStatus;
+ Snp->Snp.Transmit = SnpTransmit;
+ Snp->Snp.Receive = SnpReceive;
+
+ Snp->RecycledTxBuf = AllocatePool (sizeof (UINT64) * SNP_TX_BUFFER_INCREASE);
+ if (Snp->RecycledTxBuf == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+
+ Snp->MaxRecycledTxBuf = SNP_TX_BUFFER_INCREASE;
+ Snp->RecycledTxBufCount = 0;
+
+ // Start completing simple network mode structure
+ SnpMode->State = EfiSimpleNetworkStopped;
+ SnpMode->HwAddressSize = NET_ETHER_ADDR_LEN; // HW address is 6 bytes
+ SnpMode->MediaHeaderSize = sizeof (ETHER_HEAD);
+ SnpMode->MaxPacketSize = EFI_PAGE_SIZE; // Preamble + SOF + Ether Frame (with VLAN tag +4bytes)
+ SnpMode->NvRamSize = 0; // No NVRAM with this device
+ SnpMode->NvRamAccessSize = 0; // No NVRAM with this device
+
+ // Update network mode information
+ SnpMode->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;
+
+ // We do not intend to receive anything for the time being.
+ SnpMode->ReceiveFilterSetting = 0;
+
+ // EMAC has 64bit hash table, can filter 64 MCast MAC Addresses
+ SnpMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT;
+ SnpMode->MCastFilterCount = 0;
+ ZeroMem (&SnpMode->MCastFilter, MAX_MCAST_FILTER_CNT * sizeof (EFI_MAC_ADDRESS));
+
+ // Set the interface type (1: Ethernet or 6: IEEE 802 Networks)
+ SnpMode->IfType = NET_IFTYPE_ETHERNET;
+
+ // Mac address is changeable as it is loaded from erasable memory
+ SnpMode->MacAddressChangeable = TRUE;
+
+ // Can only transmit one packet at a time
+ SnpMode->MultipleTxSupported = FALSE;
+
+ // MediaPresent checks for cable connection and partner link
+ SnpMode->MediaPresentSupported = TRUE;
+ SnpMode->MediaPresent = FALSE;
+
+ // Set broadcast address
+ SetMem (&SnpMode->BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF);
+
+ //Set current address
+ DefaultMacAddress = Snp->Dev->Resources[1].AddrRangeMin;
+ // Swap PCD human readable form to correct endianess
+ SwapMacAddressPtr = (EFI_MAC_ADDRESS *) &DefaultMacAddress;
+ SnpMode->CurrentAddress.Addr[0] = SwapMacAddressPtr->Addr[5];
+ SnpMode->CurrentAddress.Addr[1] = SwapMacAddressPtr->Addr[4];
+ SnpMode->CurrentAddress.Addr[2] = SwapMacAddressPtr->Addr[3];
+ SnpMode->CurrentAddress.Addr[3] = SwapMacAddressPtr->Addr[2];
+ SnpMode->CurrentAddress.Addr[4] = SwapMacAddressPtr->Addr[1];
+ SnpMode->CurrentAddress.Addr[5] = SwapMacAddressPtr->Addr[0];
+
+ // Assign fields for device path
+ CopyMem (&DevicePath->MacAddrDP.MacAddress, &Snp->Snp.Mode->CurrentAddress, NET_ETHER_ADDR_LEN);
+ DevicePath->MacAddrDP.IfType = Snp->Snp.Mode->IfType;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiSimpleNetworkProtocolGuid, &(Snp->Snp),
+ &gEfiDevicePathProtocolGuid, DevicePath,
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ gBS->CloseProtocol (Controller,
+ &gEdkiiNonDiscoverableDeviceProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ FreePages (Snp, EFI_SIZE_TO_PAGES (sizeof (SIMPLE_NETWORK_DRIVER)));
+ } else {
+ Snp->ControllerHandle = Controller;
+ }
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+DriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_NETWORK_PROTOCOL *SnpProtocol;
+ SIMPLE_NETWORK_DRIVER *Snp;
+
+ Status = gBS->HandleProtocol (
+ Controller,
+ &gEfiSimpleNetworkProtocolGuid,
+ (VOID **)&SnpProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (): HandleProtocol: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ Snp = INSTANCE_FROM_SNP_THIS(SnpProtocol);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiSimpleNetworkProtocolGuid,
+ &Snp->Snp,
+ NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a (): UninstallMultipleProtocolInterfaces: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+
+ FreePool (Snp->RecycledTxBuf);
+ FreePages (Snp, EFI_SIZE_TO_PAGES (sizeof (SIMPLE_NETWORK_DRIVER)));
+
+ return Status;
+}
+
+
+/**
+ UEFI Driver Entry Point API
+ @param ImageHandle EFI_HANDLE.
+ @param SystemTable EFI_SYSTEM_TABLE.
+ @return EFI_SUCCESS Success.
+ EFI_DEVICE_ERROR Fail.
+**/
+
+EFI_STATUS
+EFIAPI
+DwEmacSnpDxeEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &mDriverBinding,
+ ImageHandle,
+ &gSnpComponentName,
+ &gSnpComponentName2
+ );
+
+ return Status;
+
+}
\ No newline at end of file
diff --git a/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c
new file mode 100755
index 000000000000..5f9915548b08
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c
@@ -0,0 +1,1271 @@
+/** @file
+ DW EMAC SNP DXE driver
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ The original software modules are licensed as follows:
+
+ Copyright (c) 2012 - 2014, ARM Limited. All rights reserved.
+ Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "DwEmacSnpDxe.h"
+#include "EmacDxeUtil.h"
+#include "PhyDxeUtil.h"
+
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/NetLib.h>
+#include <Library/DmaLib.h>
+
+/**
+ Change the state of a network interface from "stopped" to "started."
+
+ This function starts a network interface. If the network interface successfully
+ starts, then EFI_SUCCESS will be returned.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The network interface was started.
+ @retval EFI_ALREADY_STARTED The network interface is already in the started state.
+ @retval EFI_INVALID_PARAMETER This 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 This function is not supported by the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpStart (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This
+ )
+{
+ SIMPLE_NETWORK_DRIVER *Snp;
+
+ DEBUG ((DEBUG_INFO,"SNP:DXE: %a ()\r\n", __FUNCTION__));
+
+ // Check Snp instance
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+ // Check state
+ if ((Snp->SnpMode.State == EfiSimpleNetworkStarted) ||
+ (Snp->SnpMode.State == EfiSimpleNetworkInitialized) ) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ // Change state
+ Snp->SnpMode.State = EfiSimpleNetworkStarted;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Changes the state of a network interface from "started" to "stopped."
+
+ This function stops a network interface. This call is only valid if the network
+ interface is in the started state. If the network interface was successfully
+ stopped, then EFI_SUCCESS will be returned.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL
+ instance.
+
+
+ @retval EFI_SUCCESS The network interface was stopped.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER This 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 This function is not supported by the network
+ interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpStop (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This
+ )
+{
+ SIMPLE_NETWORK_DRIVER *Snp;
+
+ DEBUG ((DEBUG_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__));
+
+ // Check Snp Instance
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+ // Check state of the driver
+ if (Snp->SnpMode.State == EfiSimpleNetworkStopped) {
+ return EFI_NOT_STARTED;
+ }
+
+ // Stop the Tx and Rx
+ EmacStopTxRx (Snp->MacBase);
+ // Change the state
+ switch (Snp->SnpMode.State) {
+ case EfiSimpleNetworkStarted:
+ case EfiSimpleNetworkInitialized:
+ Snp->SnpMode.State = EfiSimpleNetworkStopped;
+ break;
+ default:
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Put the device into a power saving mode
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Resets a 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 function allocates the transmit and receive buffers required by the network
+ interface. If this allocation fails, then EFI_OUT_OF_RESOURCES is returned.
+ If the allocation succeeds and the network interface is successfully initialized,
+ then EFI_SUCCESS will be returned.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+
+ @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
+ that the driver should allocate for the network interface.
+ Some network interfaces will not be able to use the
+ extra buffer, and the caller will not know if it is
+ actually being used.
+ @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
+ that the driver should allocate for the network interface.
+ Some network interfaces will not be able to use the
+ extra buffer, and the caller will not know if it is
+ actually being used.
+
+ @retval EFI_SUCCESS The network interface was initialized.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and
+ receive buffers.
+ @retval EFI_INVALID_PARAMETER This 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
+SnpInitialize (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN UINTN ExtraRxBufferSize OPTIONAL,
+ IN UINTN ExtraTxBufferSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ SIMPLE_NETWORK_DRIVER *Snp;
+
+
+ DEBUG ((DEBUG_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__));
+
+ // Check Snp Instance
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+ // First check that driver has not already been initialized
+ if (Snp->SnpMode.State == EfiSimpleNetworkInitialized) {
+ return EFI_SUCCESS;
+ } else if (Snp->SnpMode.State == EfiSimpleNetworkStopped) {
+ return EFI_NOT_STARTED;
+ }
+
+ // Init PHY
+ Status = PhyDxeInitialization (&Snp->PhyDriver, Snp->MacBase);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Init EMAC
+ Status = EmacDxeInitialization (&Snp->MacDriver, Snp->MacBase);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Set MAC Address
+ EmacSetMacAddress (&Snp->SnpMode.CurrentAddress, Snp->MacBase);
+ EmacReadMacAddress (&Snp->SnpMode.CurrentAddress, Snp->MacBase);
+
+ // Init Link
+ DEBUG ((DEBUG_INFO, "SNP:DXE: Auto-Negotiating Ethernet PHY Link ...\n"));
+ Status = PhyLinkAdjustEmacConfig (&Snp->PhyDriver, Snp->MacBase);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_INFO, "SNP:DXE: Link is Down - Network Cable is not plugged in?\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ EmacStartTransmission (Snp->MacBase);
+
+ // Declare the driver as initialized
+ Snp->SnpMode.State = EfiSimpleNetworkInitialized;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Resets a network adapter and reinitializes it with the parameters that were
+ provided in the previous call to Initialize().
+
+ This function 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 emptied and all pending interrupts are cleared.
+ Receive filters, the station address, the statistics, and the multicast-IP-to-HW
+ MAC addresses are not reset by this call. If the network interface was
+ successfully reset, then EFI_SUCCESS will be returned. If the driver has not
+ been initialized, EFI_DEVICE_ERROR will be returned.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+ @param ExtendedVerification Indicates that the driver may perform a more
+ exhaustive verification operation of the device
+ during reset.
+
+ @retval EFI_SUCCESS The network interface was reset.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpReset (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ EFI_STATUS Status;
+ SIMPLE_NETWORK_DRIVER *Snp;
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+
+ DEBUG ((DEBUG_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__));
+
+ // Check Snp Instance
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // First check that driver has not already been initialized
+ if (Snp->SnpMode.State == EfiSimpleNetworkStarted) {
+ return EFI_DEVICE_ERROR;
+ } else if (Snp->SnpMode.State == EfiSimpleNetworkStopped) {
+ return EFI_NOT_STARTED;
+ }
+
+ // Initiate a PHY reset
+ Status = PhySoftReset (&Snp->PhyDriver, Snp->MacBase);
+ if (EFI_ERROR (Status)) {
+ Snp->SnpMode.State = EfiSimpleNetworkStopped;
+ return EFI_NOT_STARTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Resets a network adapter and leaves it in a state that is safe for another
+ driver to initialize.
+
+ 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 the Initialize() and Stop() calls may be used. If the
+ network interface was successfully shutdown, then EFI_SUCCESS will be returned.
+ If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
+
+ @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The network interface was shutdown.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER This 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
+SnpShutdown (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This
+ )
+{
+ SIMPLE_NETWORK_DRIVER *Snp;
+
+ DEBUG ((DEBUG_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__));
+
+ // Check Snp Instance
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+ // First check that driver has not already been initialized
+ if (Snp->SnpMode.State == EfiSimpleNetworkStarted) {
+ return EFI_DEVICE_ERROR;
+ } else if (Snp->SnpMode.State == EfiSimpleNetworkStopped) {
+ return EFI_NOT_STARTED;
+ }
+
+ EmacStopTxRx (Snp->MacBase);
+
+ Snp->SnpMode.State = EfiSimpleNetworkStopped;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Manages the multicast receive filters of a network interface.
+
+ This function is used enable and disable the hardware and software receive
+ filters for the underlying network device.
+ The receive filter change is broken down into three steps:
+ * The filter mask bits that are set (ON) in the Enable parameter are added to
+ the current receive filter settings.
+ * The filter mask bits that are set (ON) in the Disable parameter are subtracted
+ from the updated receive filter settings.
+ * If the resulting receive filter setting 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 enabling or disabling receive filter settings, software should verify
+ the new settings by checking the Snp->Mode->ReceiveFilterSettings,
+ 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.
+ Note: Note: To disable all receive filter hardware, the network driver must
+ be Shutdown() and Stopped(). Calling ReceiveFilters() with Disable set to
+ Snp->Mode->ReceiveFilterSettings will make it so no more packets are
+ returned by the Receive() function, but the receive hardware may still be
+ moving packets into system memory before inspecting and discarding them.
+ Unexpected system errors, reboots and hangs can occur if an OS is loaded
+ and the network devices are not Shutdown() and Stopped().
+ 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. If the network interface does not allow the multicast
+ receive filter list to be modified, then EFI_INVALID_PARAMETER will be returned.
+ If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
+ If the receive filter mask and multicast receive filter list have been
+ successfully updated on the network interface, EFI_SUCCESS will be returned.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+ @param Enable A bit mask of receive filters to enable on the network
+ interface.
+ @param 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 ResetMCastFilter Set to TRUE to reset the contents of the multicast
+ receive filters on the network interface to their
+ default values.
+ @param MCastFilterCnt Number of multicast HW MAC addresses in the new MCastFilter
+ list. This value must be less than or equal to the
+ MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE.
+ This field is optional if ResetMCastFilter is TRUE.
+ @param MCastFilter A pointer to a list of new multicast receive filter HW
+ MAC addresses. This list will replace any existing
+ multicast HW MAC address list. This field is optional
+ if ResetMCastFilter is TRUE.
+
+ @retval EFI_SUCCESS The multicast receive filter list was updated.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ * This is NULL
+ * There are bits set in Enable that are not set
+ in Snp->Mode->ReceiveFilterMask
+ * There are bits set in Disable that are not set
+ in Snp->Mode->ReceiveFilterMask
+ * Multicast is being enabled (the
+ EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit is
+ set in Enable, it is not set in Disable, and
+ ResetMCastFilter is FALSE) and MCastFilterCount
+ is zero
+ * Multicast is being enabled and MCastFilterCount
+ is greater than Snp->Mode->MaxMCastFilterCount
+ * Multicast is being enabled and MCastFilter is NULL
+ * Multicast is being enabled and one or more of
+ the addresses in the MCastFilter list are not
+ valid multicast MAC addresses
+ @retval EFI_DEVICE_ERROR One or more of the following conditions is TRUE:
+ * The network interface has been started but has
+ not been initialized
+ * An unexpected error was returned by the
+ underlying network driver or device
+ @retval EFI_UNSUPPORTED This function is not supported by the network
+ interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpReceiveFilters (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN UINT32 Enable,
+ IN UINT32 Disable,
+ IN BOOLEAN ResetMCastFilter,
+ IN UINTN MCastFilterCnt OPTIONAL,
+ IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL
+ )
+{
+ UINT32 ReceiveFilterSetting;
+ SIMPLE_NETWORK_DRIVER *Snp;
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+
+ // Check Snp Instance
+ if (Snp == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check that driver was started and initialised
+ if (Snp->SnpMode.State == EfiSimpleNetworkStarted) {
+ return EFI_DEVICE_ERROR;
+ } else if (Snp->SnpMode.State == EfiSimpleNetworkStopped) {
+ return EFI_NOT_STARTED;
+ }
+
+ // Check that bits set in Enable/Disable are set in ReceiveFilterMask
+ if ((Enable & (~Snp->SnpMode.ReceiveFilterMask)) ||
+ (Disable & (~Snp->SnpMode.ReceiveFilterMask)) ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Get the filter mask bits that are set in Enable parameter or Disable Parameter
+ // Same bits that are set in Enable/Disable parameters, then bits in the Disable parameter takes precedance
+ ReceiveFilterSetting = (Snp->SnpMode.ReceiveFilterSetting | Enable) & (~Disable);
+
+ EmacRxFilters (ReceiveFilterSetting, ResetMCastFilter, MCastFilterCnt, MCastFilter, Snp->MacBase);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Modifies or resets the current station address, if supported.
+
+ This function modifies or resets the current station address of a network
+ interface, if supported. If Reset is TRUE, then the current station address is
+ set to the network interface's permanent address. If Reset is FALSE, and the
+ network interface allows its station address to be modified, then the current
+ station address is changed to the address specified by New. If the network
+ interface does not allow its station address to be modified, then
+ EFI_INVALID_PARAMETER will be returned. If the station address is successfully
+ updated on the network interface, EFI_SUCCESS will be returned. If the driver
+ has not been initialized, EFI_DEVICE_ERROR will be returned.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+ @param Reset Flag used to reset the station address to the network interface's
+ permanent address.
+ @param NewMac New station address to be used for the network interface.
+
+
+ @retval EFI_SUCCESS The network interface's station address was updated.
+ @retval EFI_NOT_STARTED The Simple Network Protocol interface has not been
+ started by calling Start().
+ @retval EFI_INVALID_PARAMETER The New station address was not accepted by the NIC.
+ @retval EFI_INVALID_PARAMETER Reset is FALSE and New is NULL.
+ @retval EFI_DEVICE_ERROR The Simple Network Protocol interface has not
+ been initialized by calling Initialize().
+ @retval EFI_DEVICE_ERROR An error occurred attempting to set the new
+ station address.
+ @retval EFI_UNSUPPORTED The NIC does not support changing the network
+ interface's station address.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpStationAddress (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN BOOLEAN Reset,
+ IN EFI_MAC_ADDRESS *NewMac
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+
+/**
+ Resets or collects the statistics on a network interface.
+
+ 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 the statistics that are collected by the network interface, then a partial
+ buffer of statistics is returned in StatisticsTable, StatisticsSize is set to
+ the size required to collect all the available statistics, and
+ EFI_BUFFER_TOO_SMALL is returned.
+ If StatisticsSize is big enough for all the statistics, then StatisticsTable
+ will be filled, StatisticsSize will be set to the size of the returned
+ StatisticsTable structure, and EFI_SUCCESS is returned.
+ If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
+ If Reset is FALSE, and both StatisticsSize and StatisticsTable are NULL, then
+ no operations will be performed, and EFI_SUCCESS will be returned.
+ If Reset is TRUE, then all of the supported statistics counters on this network
+ interface will be reset to zero.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+ @param Reset Set to TRUE to reset the statistics for the network interface.
+ @param StatSize On input the size, in bytes, of StatisticsTable. On output
+ the size, in bytes, of the resulting table of statistics.
+ @param Statistics A pointer to the EFI_NETWORK_STATISTICS structure that
+ contains the statistics. Type EFI_NETWORK_STATISTICS is
+ defined in "Related Definitions" below.
+
+ @retval EFI_SUCCESS The requested operation succeeded.
+ @retval EFI_NOT_STARTED The Simple Network Protocol interface has not been
+ started by calling Start().
+ @retval EFI_BUFFER_TOO_SMALL StatisticsSize is not NULL and StatisticsTable is
+ NULL. The current buffer size that is needed to
+ hold all the statistics is returned in StatisticsSize.
+ @retval EFI_BUFFER_TOO_SMALL StatisticsSize is not NULL and StatisticsTable is
+ not NULL. The current buffer size that is needed
+ to hold all the statistics is returned in
+ StatisticsSize. A partial set of statistics is
+ returned in StatisticsTable.
+ @retval EFI_INVALID_PARAMETER StatisticsSize is NULL and StatisticsTable is not
+ NULL.
+ @retval EFI_DEVICE_ERROR The Simple Network Protocol interface has not
+ been initialized by calling Initialize().
+ @retval EFI_DEVICE_ERROR An error was encountered collecting statistics
+ from the NIC.
+ @retval EFI_UNSUPPORTED The NIC does not support collecting statistics
+ from the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpStatistics (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN BOOLEAN Reset,
+ IN OUT UINTN *StatSize,
+ OUT EFI_NETWORK_STATISTICS *Statistics
+ )
+{
+
+ SIMPLE_NETWORK_DRIVER *Snp;
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+
+ DEBUG ((DEBUG_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__));
+
+ // Check Snp instance
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check that driver was started and initialised
+ if (Snp->SnpMode.State == EfiSimpleNetworkStarted) {
+ return EFI_DEVICE_ERROR;
+ } else if (Snp->SnpMode.State == EfiSimpleNetworkStopped) {
+ return EFI_NOT_STARTED;
+ }
+
+ // Check the parameters
+ if ((StatSize == NULL) && (Statistics != NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Do a reset if required
+ if (Reset) {
+ ZeroMem (&Snp->Stats, sizeof(EFI_NETWORK_STATISTICS));
+ }
+
+ // Check buffer size
+ if (*StatSize < sizeof(EFI_NETWORK_STATISTICS)) {
+ *StatSize = sizeof(EFI_NETWORK_STATISTICS);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ // read statistic counters
+ EmacGetStatistic (&Snp->Stats, Snp->MacBase);
+
+ // Fill in the statistics
+ CopyMem (&Statistics, &Snp->Stats, sizeof(EFI_NETWORK_STATISTICS));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Converts a multicast IP address to a multicast HW MAC address.
+
+ This function converts a multicast IP address to a multicast HW MAC address
+ for all packet transactions. If the mapping is accepted, then EFI_SUCCESS will
+ be returned.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+ @param IsIpv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460].
+ Set to FALSE if the multicast IP address is IPv4 [RFC 791].
+ @param Ip The multicast IP address that is to be converted to a multicast
+ HW MAC address.
+ @param McastMac The multicast HW MAC address that is to be generated from IP.
+
+ @retval EFI_SUCCESS The multicast IP address was mapped to the
+ multicast HW MAC address.
+ @retval EFI_NOT_STARTED The Simple Network Protocol interface has not
+ been started by calling Start().
+ @retval EFI_INVALID_PARAMETER IP is NULL.
+ @retval EFI_INVALID_PARAMETER MAC is NULL.
+ @retval EFI_INVALID_PARAMETER IP does not point to a valid IPv4 or IPv6
+ multicast address.
+ @retval EFI_DEVICE_ERROR The Simple Network Protocol interface has not
+ been initialized by calling Initialize().
+ @retval EFI_UNSUPPORTED IPv6 is TRUE and the implementation does not
+ support IPv6 multicast to MAC address conversion.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpMcastIptoMac (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN BOOLEAN IsIpv6,
+ IN EFI_IP_ADDRESS *Ip,
+ OUT EFI_MAC_ADDRESS *McastMac
+ )
+{
+
+ DEBUG ((DEBUG_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__));
+
+ // Check Snp instance
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SIMPLE_NETWORK_DRIVER *Snp;
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+
+ // Check that driver was started and initialised
+ if (Snp->SnpMode.State == EfiSimpleNetworkStarted) {
+ return EFI_DEVICE_ERROR;
+ } else if (Snp->SnpMode.State == EfiSimpleNetworkStopped) {
+ return EFI_NOT_STARTED;
+ }
+
+ // Check parameters
+ if ((McastMac == NULL) || (Ip == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Make sure MAC address is empty
+ ZeroMem (McastMac, sizeof(EFI_MAC_ADDRESS));
+
+ // If we need ipv4 address
+ if (!IsIpv6) {
+ // Most significant 25 bits of a multicast HW address are set.
+ // 01-00-5E is the IPv4 Ethernet Multicast Address (see RFC 1112)
+ McastMac->Addr[0] = 0x01;
+ McastMac->Addr[1] = 0x00;
+ McastMac->Addr[2] = 0x5E;
+
+ // Lower 23 bits from ipv4 address
+ McastMac->Addr[3] = (Ip->v4.Addr[1] & 0x7F); // Clear the most significant bit (25th bit of MAC must be 0)
+ McastMac->Addr[4] = Ip->v4.Addr[2];
+ McastMac->Addr[5] = Ip->v4.Addr[3];
+ } else {
+ // Most significant 16 bits of multicast v6 HW address are set
+ // 33-33 is the IPv6 Ethernet Multicast Address (see RFC 2464)
+ McastMac->Addr[0] = 0x33;
+ McastMac->Addr[1] = 0x33;
+
+ // lower four octets are taken from ipv6 address
+ McastMac->Addr[2] = Ip->v6.Addr[8];
+ McastMac->Addr[3] = Ip->v6.Addr[9];
+ McastMac->Addr[4] = Ip->v6.Addr[10];
+ McastMac->Addr[5] = Ip->v6.Addr[11];
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Performs read and write operations on the NVRAM device attached to a network
+ interface.
+
+ This function performs read and write operations on the NVRAM device attached
+ to a network interface. If ReadWrite is TRUE, a read operation is performed.
+ If ReadWrite is FALSE, a write operation is performed. Offset specifies the
+ byte offset at which to start either operation. Offset must be a multiple of
+ NvRamAccessSize , and it must have a value between zero and NvRamSize.
+ BufferSize specifies the length of the read or write operation. BufferSize must
+ also be a multiple of NvRamAccessSize, and Offset + BufferSize must not exceed
+ NvRamSize.
+ If any of the above conditions is not met, then EFI_INVALID_PARAMETER will be
+ returned.
+ If all the conditions are met and the operation is "read," the NVRAM device
+ attached to the network interface will be read into Buffer and EFI_SUCCESS
+ will be returned. If this is a write operation, the contents of Buffer will be
+ used to update the contents of the NVRAM device attached to the network
+ interface and EFI_SUCCESS will be returned.
+
+ It does the basic checking on the input parameters and retrieves snp structure
+ and then calls the read_nvdata() call which does the actual reading
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+ @param ReadWrite TRUE for read operations, FALSE for write operations.
+ @param 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. (See EFI_SIMPLE_NETWORK_MODE)
+ @param BufferSize The number of bytes to read or write from the NVRAM device.
+ This must also be a multiple of NvramAccessSize.
+ @param Buffer A pointer to the data buffer.
+
+ @retval EFI_SUCCESS The NVRAM access was performed.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ * The This parameter is NULL
+ * The This parameter does not point to a valid
+ EFI_SIMPLE_NETWORK_PROTOCOL structure
+ * The Offset parameter is not a multiple of
+ EFI_SIMPLE_NETWORK_MODE.NvRamAccessSize
+ * The Offset parameter is not less than
+ EFI_SIMPLE_NETWORK_MODE.NvRamSize
+ * The BufferSize parameter is not a multiple of
+ EFI_SIMPLE_NETWORK_MODE.NvRamAccessSize
+ * The Buffer parameter is NULL
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network
+ interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network
+ interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpNvData (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN BOOLEAN ReadWrite,
+ IN UINTN Offset,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Reads the current interrupt status and recycled transmit buffer status from a
+ network interface.
+
+ This function gets the current interrupt and recycled transmit buffer status
+ from the network interface. The interrupt status is returned as a bit mask in
+ InterruptStatus. If InterruptStatus is NULL, the interrupt status will not be
+ read. If TxBuf is not NULL, a recycled transmit buffer address will be retrieved.
+ 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. If
+ the status of the network interface is successfully collected, EFI_SUCCESS
+ will be returned. If the driver has not been initialized, EFI_DEVICE_ERROR will
+ be returned.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+ @param IrqStat A pointer to the bit mask of the currently active
+ interrupts (see "Related Definitions"). 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 the 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 TxBuff 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 no transmit buffers to recycle and TxBuf is not NULL,
+ TxBuf will be set to NULL.
+
+ @retval EFI_SUCCESS The status of the network interface was retrieved.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER This 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
+SnpGetStatus (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ OUT UINT32 *IrqStat OPTIONAL,
+ OUT VOID **TxBuff OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ SIMPLE_NETWORK_DRIVER *Snp;
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+
+ // Check preliminaries
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Snp->SnpMode.State != EfiSimpleNetworkInitialized) {
+ return EFI_NOT_STARTED;
+ }
+
+ // Update the media status
+ Status = PhyLinkAdjustEmacConfig (&Snp->PhyDriver, Snp->MacBase);
+ if (EFI_ERROR(Status)) {
+ Snp->SnpMode.MediaPresent = FALSE;
+ } else {
+ Snp->SnpMode.MediaPresent = TRUE;
+ }
+
+ // TxBuff
+ if (TxBuff != NULL) {
+ //
+ // Get a recycled buf from Snp->RecycledTxBuf
+ //
+ if (Snp->RecycledTxBufCount == 0) {
+ *TxBuff = NULL;
+ } else {
+ Snp->RecycledTxBufCount--;
+ *TxBuff = (VOID *)(UINTN) Snp->RecycledTxBuf[Snp->RecycledTxBufCount];
+ }
+ }
+
+ // Check DMA Irq status
+ EmacGetDmaStatus (IrqStat, Snp->MacBase);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Places a packet in the transmit queue of a network interface.
+
+ This function places the packet specified by Header and Buffer on the transmit
+ queue. If HeaderSize is nonzero and HeaderSize is not equal to
+ This->Mode->MediaHeaderSize, then EFI_INVALID_PARAMETER will be returned. If
+ BufferSize is less than This->Mode->MediaHeaderSize, then EFI_BUFFER_TOO_SMALL
+ will be returned. If Buffer is NULL, then EFI_INVALID_PARAMETER will be
+ returned. If HeaderSize is nonzero and DestAddr or Protocol is NULL, then
+ EFI_INVALID_PARAMETER will be returned. If the transmit engine of the network
+ interface is busy, then EFI_NOT_READY will be returned. If this packet can be
+ accepted by the transmit engine of the network interface, the packet contents
+ specified by Buffer will be placed on the transmit queue of the network
+ interface, and EFI_SUCCESS will be returned. GetStatus() can be used to
+ determine when the packet has actually been transmitted. The contents of the
+ Buffer must not be modified until the packet has actually been transmitted.
+ The Transmit() function performs nonblocking I/O. A caller who wants to perform
+ blocking I/O, should call Transmit(), and then GetStatus() until the
+ transmitted buffer shows up in the recycled transmit buffer.
+ If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+ @param HdrSize The size, in bytes, of the media header to be filled in by the
+ Transmit() function. If HeaderSize is nonzero, then it must
+ be equal to This->Mode->MediaHeaderSize and the DestAddr and
+ Protocol parameters must not be NULL.
+ @param BuffSize The size, in bytes, of the entire packet (media header and
+ data) to be transmitted through the network interface.
+ @param Data A pointer to the packet (media header followed by data) to be
+ transmitted. This parameter cannot be NULL. If HeaderSize is
+ zero, then the media header in 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 SrcAddr The source HW MAC address. If HeaderSize is zero, then this
+ parameter is ignored. If HeaderSize is nonzero and SrcAddr
+ is NULL, then This->Mode->CurrentAddress is used for the
+ source HW MAC address.
+ @param DstAddr The destination HW MAC address. If HeaderSize is zero, then
+ this parameter is ignored.
+ @param Protocol The type of header to build. If HeaderSize is zero, then this
+ parameter is ignored. See RFC 1700, section "Ether Types,"
+ for examples.
+
+ @retval EFI_SUCCESS The packet was placed on the transmit queue.
+ @retval EFI_NOT_STARTED The network interface has not been 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 One or more of the parameters has an unsupported
+ value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+ @retval EFI_ACCESS_DENIED Error acquire global lock for operation.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpTransmit (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN UINTN HdrSize,
+ IN UINTN BuffSize,
+ IN VOID *Data,
+ IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
+ IN EFI_MAC_ADDRESS *DstAddr OPTIONAL,
+ IN UINT16 *Protocol OPTIONAL
+ )
+{
+ SIMPLE_NETWORK_DRIVER *Snp;
+ UINT32 DescNum;
+ DESIGNWARE_HW_DESCRIPTOR *TxDescriptor;
+ DESIGNWARE_HW_DESCRIPTOR *TxDescriptorMap;
+ UINT8 *EthernetPacket;
+ UINT64 *Tmp;
+ EFI_STATUS Status;
+ UINTN BufferSizeBuf;
+ EFI_PHYSICAL_ADDRESS TxBufferAddrMap;
+
+ BufferSizeBuf = ETH_BUFSIZE;
+ EthernetPacket = Data;
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+
+ if (EFI_ERROR (EfiAcquireLockOrFail (&Snp->Lock))) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ if ((Snp->MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASE) >= SNP_MAX_TX_BUFFER_NUM) {
+ return EFI_NOT_READY;
+ }
+
+ // Check preliminaries
+ if ((This == NULL) || (Data == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Snp->SnpMode.State != EfiSimpleNetworkInitialized) {
+ return EFI_NOT_STARTED;
+ }
+
+ Snp->MacDriver.TxCurrentDescriptorNum = Snp->MacDriver.TxNextDescriptorNum;
+ DescNum = Snp->MacDriver.TxCurrentDescriptorNum;
+
+ TxDescriptor = Snp->MacDriver.TxdescRing[DescNum];
+ TxDescriptorMap = (VOID *)Snp->MacDriver.TxdescRingMap[DescNum].AddrMap;
+
+ // Ensure header is correct size if non-zero
+ if (HdrSize) {
+ if (HdrSize != Snp->SnpMode.MediaHeaderSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((DstAddr == NULL) || (Protocol == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ // Ensure buffer size is valid
+ if (BuffSize < Snp->SnpMode.MediaHeaderSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (HdrSize) {
+ EthernetPacket[0] = DstAddr->Addr[0];
+ EthernetPacket[1] = DstAddr->Addr[1];
+ EthernetPacket[2] = DstAddr->Addr[2];
+ EthernetPacket[3] = DstAddr->Addr[3];
+ EthernetPacket[4] = DstAddr->Addr[4];
+ EthernetPacket[5] = DstAddr->Addr[5];
+
+ EthernetPacket[6] = SrcAddr->Addr[0];
+ EthernetPacket[7] = SrcAddr->Addr[1];
+ EthernetPacket[8] = SrcAddr->Addr[2];
+ EthernetPacket[9] = SrcAddr->Addr[3];
+ EthernetPacket[10] = SrcAddr->Addr[4];
+ EthernetPacket[11] = SrcAddr->Addr[5];
+
+ EthernetPacket[13] = *Protocol & 0xFF;
+ EthernetPacket[12] = (*Protocol & 0xFF00) >> 8;
+ }
+
+ CopyMem ((VOID *)(UINTN)TxDescriptor->Addr, EthernetPacket, BuffSize);
+
+ Status = DmaMap (MapOperationBusMasterRead, (VOID *)(UINTN)TxDescriptor->Addr,
+ &BufferSizeBuf, &TxBufferAddrMap, &Snp->MappingTxbuf);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a () for Txbuffer: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+ TxDescriptorMap->Addr = TxBufferAddrMap;
+
+ TxDescriptor->Tdes1 = (BuffSize << TDES1_SIZE1SHFT) &
+ TDES1_SIZE1MASK;
+
+ TxDescriptor->Tdes0 |= (TDES0_TXFIRST |
+ TDES0_TXLAST |
+ TDES0_OWN);
+
+ // Increase descriptor number
+ DescNum++;
+
+ if (DescNum >= CONFIG_TX_DESCR_NUM) {
+ DescNum = 0;
+ }
+
+ Snp->MacDriver.TxNextDescriptorNum = DescNum;
+
+ if (Snp->RecycledTxBufCount < Snp->MaxRecycledTxBuf) {
+ Snp->RecycledTxBuf[Snp->RecycledTxBufCount] = (UINT64) Data;
+ Snp->RecycledTxBufCount ++;
+ } else {
+ Tmp = AllocatePool (sizeof (UINT64) * (Snp->MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASE));
+ if (Tmp == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+ CopyMem (Tmp, Snp->RecycledTxBuf, sizeof (UINT64) * Snp->RecycledTxBufCount);
+ FreePool (Snp->RecycledTxBuf);
+ Snp->RecycledTxBuf = Tmp;
+ Snp->MaxRecycledTxBuf += SNP_TX_BUFFER_INCREASE;
+ }
+
+ // Start the transmission
+ EmacDmaStart (Snp->MacBase);
+
+ DmaUnmap (Snp->MappingTxbuf);
+ EfiReleaseLock (&Snp->Lock);
+ return EFI_SUCCESS;
+}
+
+/**
+ Receives a packet from a network interface.
+
+ This function retrieves one packet from the receive queue of a 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 updated 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. EFI_SUCCESS will be
+ returned if a packet was successfully received.
+ 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.
+ If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
+
+ @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+ @param HdrSize The size, in bytes, of the media header received on the network
+ interface. If this parameter is NULL, then the media header size
+ will not be returned.
+ @param BuffSize On entry, the size, in bytes, of Buffer. On exit, the size, in
+ bytes, of the packet that was received on the network interface.
+ @param Data A pointer to the data buffer to receive both the media
+ header and the data.
+ @param SrcAddr The source HW MAC address. If this parameter is NULL, the HW
+ MAC source address will not be extracted from the media header.
+ @param DstAddr The destination HW MAC address. If this parameter is NULL,
+ the HW MAC destination address will not be extracted from
+ the media header.
+ @param Protocol The media header type. If this parameter is NULL, then the
+ protocol will not be extracted from the media header. See
+ RFC 1700 section "Ether Types" for examples.
+
+ @retval EFI_SUCCESS The received data was stored in Buffer, and
+ BufferSize has been updated to the number of
+ bytes received.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_NOT_READY No packets have been received on the network interface.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the received packets.
+ BufferSize has been updated to the required size.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ * The This parameter is NULL
+ * The This parameter does not point to a valid
+ EFI_SIMPLE_NETWORK_PROTOCOL structure.
+ * The BufferSize parameter is NULL
+ * The Buffer parameter is NULL
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_ACCESS_DENIED Error acquire global lock for operation.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpReceive (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ OUT UINTN *HdrSize OPTIONAL,
+ IN OUT UINTN *BuffSize,
+ OUT VOID *Data,
+ OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
+ OUT EFI_MAC_ADDRESS *DstAddr OPTIONAL,
+ OUT UINT16 *Protocol OPTIONAL
+ )
+{
+ SIMPLE_NETWORK_DRIVER *Snp;
+ EFI_MAC_ADDRESS Dst;
+ EFI_MAC_ADDRESS Src;
+ UINT32 Length;
+ UINT32 DescriptorStatus;
+ UINT8 *RawData;
+ UINT32 DescNum;
+ DESIGNWARE_HW_DESCRIPTOR *RxDescriptor;
+ DESIGNWARE_HW_DESCRIPTOR *RxDescriptorMap;
+ UINTN BufferSizeBuf;
+ UINTN *RxBufferAddr;
+ EFI_PHYSICAL_ADDRESS RxBufferAddrMap;
+ EFI_STATUS Status;
+
+ BufferSizeBuf = ETH_BUFSIZE;
+
+ Snp = INSTANCE_FROM_SNP_THIS (This);
+
+ // Check preliminaries
+ if ((This == NULL) || (Data == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Snp->SnpMode.State != EfiSimpleNetworkInitialized) {
+ return EFI_NOT_STARTED;
+ }
+
+ if (EFI_ERROR (EfiAcquireLockOrFail (&Snp->Lock))) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ Snp->MacDriver.RxCurrentDescriptorNum = Snp->MacDriver.RxNextDescriptorNum;
+ DescNum = Snp->MacDriver.RxCurrentDescriptorNum;
+ RxDescriptor = Snp->MacDriver.RxdescRing[DescNum];
+ RxBufferAddr = (VOID *)Snp->MacDriver.RxBuffer + (DescNum * BufferSizeBuf);
+ RxDescriptorMap = (VOID *)Snp->MacDriver.RxdescRingMap[DescNum].AddrMap;
+
+ RawData = (UINT8 *) Data;
+
+ DescriptorStatus = RxDescriptor->Tdes0;
+ if (DescriptorStatus & ((UINT32)RDES0_OWN)) {
+ goto ReleaseLock;
+ }
+
+ if (DescriptorStatus & RDES0_SAF) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error: Source Address Filter Fail\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (DescriptorStatus & RDES0_AFM) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error: Destination Address Filter Fail\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (DescriptorStatus & RDES0_ES) {
+ // Check for errors
+ if (DescriptorStatus & RDES0_RE) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error: Receive Error\n"));
+ }
+ if (DescriptorStatus & RDES0_DE) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error: Receive Error\n"));
+ }
+ if (DescriptorStatus & RDES0_RWT) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error: Watchdog Timeout\n"));
+ }
+ if (DescriptorStatus & RDES0_LC) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error: Late Collision\n"));
+ }
+ if (DescriptorStatus & RDES0_GF) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error: Giant Frame\n"));
+ }
+ if (DescriptorStatus & RDES0_OE) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error: Overflow Error\n"));
+ }
+ if (DescriptorStatus & RDES0_LE) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error:Length Error\n"));
+ }
+ if (DescriptorStatus & RDES0_DBE) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error: Dribble Bit Error\n"));
+ }
+
+ // Check descriptor error status
+ if (DescriptorStatus & RDES0_CE) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Rx Descritpor Status Error: CRC Error\n"));
+ }
+ return EFI_DEVICE_ERROR;
+ }
+
+ Length = (DescriptorStatus >> RDES0_FL_SHIFT) & RDES0_FL_MASK;
+ if (!Length) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Error: Invalid Frame Packet length \r\n"));
+ return EFI_NOT_READY;
+ }
+ // Check buffer size
+ if (*BuffSize < Length) {
+ DEBUG ((DEBUG_WARN, "SNP:DXE: Error: Buffer size is too small\n"));
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ *BuffSize = Length;
+
+ if (HdrSize != NULL)
+ *HdrSize = Snp->SnpMode.MediaHeaderSize;
+
+ DmaUnmap (Snp->MacDriver.RxBufNum[DescNum].Mapping);
+ Snp->MacDriver.RxBufNum[DescNum].Mapping = NULL;
+
+ CopyMem (RawData, (VOID *)RxBufferAddr, *BuffSize);
+
+ if (DstAddr != NULL) {
+ Dst.Addr[0] = RawData[0];
+ Dst.Addr[1] = RawData[1];
+ Dst.Addr[2] = RawData[2];
+ Dst.Addr[3] = RawData[3];
+ Dst.Addr[4] = RawData[4];
+ Dst.Addr[5] = RawData[5];
+ CopyMem (DstAddr, &Dst, NET_ETHER_ADDR_LEN);
+ DEBUG ((DEBUG_INFO, "received from source address %x %x\r\n", DstAddr, &Dst));
+ }
+
+ // Get the source address
+ if (SrcAddr != NULL) {
+ Src.Addr[0] = RawData[6];
+ Src.Addr[1] = RawData[7];
+ Src.Addr[2] = RawData[8];
+ Src.Addr[3] = RawData[9];
+ Src.Addr[4] = RawData[10];
+ Src.Addr[5] = RawData[11];
+ DEBUG ((DEBUG_INFO, "received from source address %x %x\r\n", SrcAddr, &Src));
+ CopyMem (SrcAddr, &Src, NET_ETHER_ADDR_LEN);
+ }
+
+ // Get the protocol
+ if (Protocol != NULL) {
+ *Protocol = NTOHS (RawData[12] | (RawData[13] >> 8) | (RawData[14] >> 16) | (RawData[15] >> 24));
+ }
+
+ // DMA map for the current receive buffer
+ Status = DmaMap (MapOperationBusMasterWrite, (VOID *)RxBufferAddr,
+ &BufferSizeBuf, &RxBufferAddrMap, &Snp->MacDriver.RxBufNum[DescNum].Mapping);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a () for Rxbuffer: %r\n", __FUNCTION__, Status));
+ return Status;
+ }
+ Snp->MacDriver.RxBufNum[DescNum].AddrMap = RxBufferAddrMap;
+ RxDescriptorMap->Addr = Snp->MacDriver.RxBufNum[DescNum].AddrMap;
+
+ RxDescriptor->Tdes0 |= (UINT32)RDES0_OWN;
+
+ // Increase descriptor number
+ DescNum++;
+
+ if (DescNum >= CONFIG_RX_DESCR_NUM) {
+ DescNum = 0;
+ }
+ Snp->MacDriver.RxNextDescriptorNum = DescNum;
+
+ EfiReleaseLock (&Snp->Lock);
+ return EFI_SUCCESS;
+
+ReleaseLock:
+ EfiReleaseLock (&Snp->Lock);
+ return EFI_NOT_READY;
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c
new file mode 100755
index 000000000000..4711282ad6fe
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c
@@ -0,0 +1,672 @@
+/** @file
+
+ Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ The original software modules are licensed as follows:
+
+ Copyright (c) 2012 - 2014, ARM Limited. All rights reserved.
+ Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "EmacDxeUtil.h"
+#include "PhyDxeUtil.h"
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+VOID
+EFIAPI
+EmacSetMacAddress (
+ IN EFI_MAC_ADDRESS *MacAddress,
+ IN UINTN MacBaseAddress
+ )
+{
+ DEBUG ((DEBUG_INFO, "SNP:MAC: %a ()\r\n", __FUNCTION__));
+
+ // Note: This MAC_ADDR0 registers programming sequence cannot be swap:
+ // Must program HIGH Offset first before LOW Offset
+ // because synchronization is triggered when MAC Address0 Low Register are written.
+ MmioWrite32 (MacBaseAddress + DW_EMAC_GMACGRP_MAC_ADDRESS0_HIGH_OFST,
+ (UINT32)(MacAddress->Addr[4] & 0xFF) |
+ ((MacAddress->Addr[5] & 0xFF) << 8)
+ );
+ // MacAddress->Addr[0,1,2] is the 3 bytes OUI
+ MmioWrite32 (MacBaseAddress + DW_EMAC_GMACGRP_MAC_ADDRESS0_LOW_OFST,
+ (MacAddress->Addr[0] & 0xFF) |
+ ((MacAddress->Addr[1] & 0xFF) << 8) |
+ ((MacAddress->Addr[2] & 0xFF) << 16) |
+ ((MacAddress->Addr[3] & 0xFF) << 24)
+ );
+
+ DEBUG ((DEBUG_INFO, "SNP:MAC: gmacgrp_mac_address0_low = 0x%08X \r\n",
+ MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_MAC_ADDRESS0_LOW_OFST)));
+ DEBUG ((DEBUG_INFO, "SNP:MAC: gmacgrp_mac_address0_high = 0x%08X \r\n",
+ MmioRead32 (MacBaseAddress +DW_EMAC_GMACGRP_MAC_ADDRESS0_HIGH_OFST)));
+}
+
+
+VOID
+EFIAPI
+EmacReadMacAddress (
+ OUT EFI_MAC_ADDRESS *MacAddress,
+ IN UINTN MacBaseAddress
+ )
+{
+ UINT32 MacAddrHighValue;
+ UINT32 MacAddrLowValue;
+
+ DEBUG ((DEBUG_INFO, "SNP:MAC: %a ()\r\n", __FUNCTION__));
+
+ // Read the Mac Addr high register
+ MacAddrHighValue = (MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_MAC_ADDRESS0_HIGH_OFST) & 0xFFFF);
+ // Read the Mac Addr low register
+ MacAddrLowValue = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_MAC_ADDRESS0_LOW_OFST);
+
+ SetMem (MacAddress, sizeof(*MacAddress), 0);
+ MacAddress->Addr[0] = (MacAddrLowValue & 0xFF);
+ MacAddress->Addr[1] = (MacAddrLowValue & 0xFF00) >> 8;
+ MacAddress->Addr[2] = (MacAddrLowValue & 0xFF0000) >> 16;
+ MacAddress->Addr[3] = (MacAddrLowValue & 0xFF000000) >> 24;
+ MacAddress->Addr[4] = (MacAddrHighValue & 0xFF);
+ MacAddress->Addr[5] = (MacAddrHighValue & 0xFF00) >> 8;
+
+ DEBUG ((DEBUG_INFO, "SNP:MAC: MAC Address = %02X:%02X:%02X:%02X:%02X:%02X\r\n",
+ MacAddress->Addr[0], MacAddress->Addr[1], MacAddress->Addr[2],
+ MacAddress->Addr[3], MacAddress->Addr[4], MacAddress->Addr[5]
+ ));
+}
+
+EFI_STATUS
+EFIAPI
+EmacDxeInitialization (
+ IN EMAC_DRIVER *EmacDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ DEBUG ((DEBUG_INFO, "SNP:MAC: %a ()\r\n", __FUNCTION__));
+
+ // Init EMAC DMA
+ EmacDmaInit (EmacDriver, MacBaseAddress);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+EmacDmaInit (
+ IN EMAC_DRIVER *EmacDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ UINT32 DmaConf;
+ UINT32 DmaOpmode;
+ UINT32 InterruptEnable;
+
+ DEBUG ((DEBUG_INFO, "SNP:MAC: %a ()\r\n", __FUNCTION__));
+
+ // This section provides the instructions for initializing the DMA registers in the proper sequence. This
+ // initialization sequence can be done after the EMAC interface initialization has been completed. Perform
+ // the following steps to initialize the DMA:
+ // 1. Provide a software reset to reset all of the EMAC internal registers and logic. (DMA Register 0 (Bus
+ // Mode Register) bit 0).
+
+ MmioOr32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_BUS_MODE_OFST,
+ DW_EMAC_DMAGRP_BUS_MODE_SWR_SET_MSK);
+
+ // 2. Wait for the completion of the reset process (poll bit 0 of the DMA Register 0 (Bus Mode Register),
+ // which is only cleared after the reset operation is completed).
+ while (DW_EMAC_DMAGRP_BUS_MODE_SWR_GET (MmioRead32 (MacBaseAddress + DW_EMAC_DMAGRP_BUS_MODE_OFST)));
+
+ // 3. Poll the bits of Register 11 (AHB or AXI Status) to confirm that all previously initiated (before
+ // software reset) or ongoing transactions are complete.
+ // Note: If the application cannot poll the register after soft reset (because of performance reasons), then
+ // it is recommended that you continue with the next steps and check this register again (as
+ // mentioned in 12 on page 1-72) before triggering the DMA operations.
+
+ // 4. Program the following fields to initialize the Bus Mode Register by setting values in DMA Register 0
+ // (Bus Mode Register):
+ // Mixed Burst and AAL
+ // Fixed burst or undefined burst
+ // Burst length values and burst mode values
+ // Descriptor Length (only valid if Ring Mode is used)
+ // TX and RX DMA Arbitration scheme
+ // 5. Program the interface options in Register 10 (AXI Bus Mode Register). If fixed burst-length is enabled,
+ // then select the maximum burst-length possible on the bus (bits[7:1]).
+
+ DmaConf = DW_EMAC_DMAGRP_BUS_MODE_FB_SET_MSK | DW_EMAC_DMAGRP_BUS_MODE_PBL_SET_MSK | DW_EMAC_DMAGRP_BUS_MODE_PR_SET_MSK;
+ MmioOr32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_BUS_MODE_OFST,
+ DmaConf);
+
+ // 6. Create a proper descriptor chain for transmit and receive. In addition, ensure that the receive descriptors
+ // are owned by DMA (bit 31 of descriptor should be set). When OSF mode is used, at least two
+ // descriptors are required.
+ // 7. Make sure that your software creates three or more different transmit or receive descriptors in the
+ // chain before reusing any of the descriptors.
+ // 8. Initialize receive and transmit descriptor list address with the base address of the transmit and receive
+ // descriptor (Register 3 (Receive Descriptor List Address Register) and Register 4 (Transmit Descriptor
+ // List Address Register) respectively).
+
+ EmacSetupTxdesc (EmacDriver, MacBaseAddress);
+ EmacSetupRxdesc (EmacDriver, MacBaseAddress);
+
+ // 9. Program the following fields to initialize the mode of operation in Register 6 (Operation Mode
+ // Register):
+ // Receive and Transmit Store And Forward
+ // Receive and Transmit Threshold Control (RTC and TTC)
+ // Hardware Flow Control enable
+ // Flow Control Activation and De-activation thresholds for MTL Receive and Transmit FIFO buffers
+ // (RFA and RFD)
+ // Error frame and undersized good frame forwarding enable
+ // OSF Mode
+
+ DmaOpmode = DW_EMAC_DMAGRP_OPERATION_MODE_FTF_SET_MSK | DW_EMAC_DMAGRP_OPERATION_MODE_TSF_SET_MSK;
+ MmioOr32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_OPERATION_MODE_OFST,
+ DmaOpmode);
+ //while (DW_EMAC_DMAGRP_OPERATION_MODE_FTF_GET (MmioRead32 (MacBaseAddress + DW_EMAC_DMAGRP_OPERATION_MODE_OFST)));
+
+ // 10.Clear the interrupt requests, by writing to those bits of the status register (interrupt bits only) that are
+ // set. For example, by writing 1 into bit 16, the normal interrupt summary clears this bit (DMA Register 5 (Status Register)).
+ MmioOr32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_STATUS_OFST,
+ 0x1FFFF);
+
+ // 11.Enable the interrupts by programming Register 7 (Interrupt Enable Register).
+ InterruptEnable = DW_EMAC_DMAGRP_INTERRUPT_ENABLE_TIE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_RIE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_NIE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_AIE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_FBE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_UNE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_TSE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_TUE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_TJE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_OVE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_RUE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_RSE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_RWE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_ETE_SET_MSK |
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_ERE_SET_MSK;
+ MmioWrite32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_INTERRUPT_ENABLE_OFST,
+ InterruptEnable);
+
+ // 12.Read Register 11 (AHB or AXI Status) to confirm that all previous transactions are complete.
+ // Note: If any previous transaction is still in progress when you read the Register 11 (AHB or AXI
+ // Status), then it is strongly recommended to check the slave components addressed by the
+ // master interface.
+ if (MmioRead32 (MacBaseAddress + DW_EMAC_DMAGRP_AHB_OR_AXI_STATUS_OFST) != 0) {
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Error! Previous AXI transaction is still in progress\r\n"));
+ //check the slave components addressed by the master interface
+ return EFI_DEVICE_ERROR;
+ }
+
+ DmaOpmode = DW_EMAC_DMAGRP_OPERATION_MODE_ST_SET_MSK | DW_EMAC_DMAGRP_OPERATION_MODE_SR_SET_MSK;
+ MmioOr32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_OPERATION_MODE_OFST,
+ DmaOpmode);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+EmacSetupTxdesc (
+ IN EMAC_DRIVER *EmacDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ INTN Index;
+ DESIGNWARE_HW_DESCRIPTOR *TxDescriptor;
+
+ for (Index = 0; Index < CONFIG_TX_DESCR_NUM; Index++) {
+ TxDescriptor = (VOID *)EmacDriver->TxdescRingMap[Index].AddrMap;
+ TxDescriptor->Addr = (UINT32)(UINTN)&EmacDriver->TxBuffer[Index * CONFIG_ETH_BUFSIZE];
+ TxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->TxdescRingMap[Index + 1].AddrMap;
+ TxDescriptor->Tdes0 = TDES0_TXCHAIN;
+ TxDescriptor->Tdes1 = 0;
+ }
+
+ // Correcting the last pointer of the chain
+ TxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->TxdescRingMap[0].AddrMap;
+
+ // Write the address of tx descriptor list
+ MmioWrite32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_TRANSMIT_DESCRIPTOR_LIST_ADDRESS_OFST,
+ (UINT32)(UINTN)EmacDriver->TxdescRingMap[0].AddrMap);
+
+ // Initialize the descriptor number
+ EmacDriver->TxCurrentDescriptorNum = 0;
+ EmacDriver->TxNextDescriptorNum = 0;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+EmacSetupRxdesc (
+ IN EMAC_DRIVER *EmacDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ INTN Index;
+ DESIGNWARE_HW_DESCRIPTOR *RxDescriptor;
+
+ for (Index = 0; Index < CONFIG_RX_DESCR_NUM; Index++) {
+ RxDescriptor = (VOID *)EmacDriver->RxdescRingMap[Index].AddrMap;
+ RxDescriptor->Addr = EmacDriver->RxBufNum[Index].AddrMap;
+ RxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->RxdescRingMap[Index + 1].AddrMap;
+ RxDescriptor->Tdes0 = RDES0_OWN;
+ RxDescriptor->Tdes1 = RDES1_CHAINED | RX_MAX_PACKET;
+ }
+
+ // Correcting the last pointer of the chain
+ RxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->RxdescRingMap[0].AddrMap;
+
+ // Write the address of tx descriptor list
+ MmioWrite32(MacBaseAddress +
+ DW_EMAC_DMAGRP_RECEIVE_DESCRIPTOR_LIST_ADDRESS_OFST,
+ (UINT32)(UINTN)EmacDriver->RxdescRingMap[0].AddrMap);
+
+ // Initialize the descriptor number
+ EmacDriver->RxCurrentDescriptorNum = 0;
+ EmacDriver->RxNextDescriptorNum = 0;
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+EFIAPI
+EmacStartTransmission (
+ IN UINTN MacBaseAddress
+ )
+{
+ DEBUG ((DEBUG_INFO, "SNP:MAC: %a ()\r\n", __FUNCTION__));
+ MmioOr32 (MacBaseAddress +
+ DW_EMAC_GMACGRP_MAC_CONFIGURATION_OFST,
+ DW_EMAC_GMACGRP_MAC_CONFIGURATION_RE_SET_MSK |
+ DW_EMAC_GMACGRP_MAC_CONFIGURATION_TE_SET_MSK
+ );
+}
+
+
+EFI_STATUS
+EFIAPI
+EmacRxFilters (
+ IN UINT32 ReceiveFilterSetting,
+ IN BOOLEAN Reset,
+ IN UINTN NumMfilter OPTIONAL,
+ IN EFI_MAC_ADDRESS *Mfilter OPTIONAL,
+ IN UINTN MacBaseAddress
+ )
+{
+ UINT32 MacFilter;
+ UINT32 Crc;
+ UINT32 Count;
+ UINT32 HashReg;
+ UINT32 HashBit;
+ UINT32 Reg;
+ UINT32 Val;
+
+ // If reset then clear the filter registers
+ if (Reset) {
+ for (Count = 0; Count < NumMfilter; Count++)
+ {
+ MmioWrite32 (MacBaseAddress + HASH_TABLE_REG(Count), 0x00000000);
+ }
+ }
+
+ // Set MacFilter to the reset value of the DW_EMAC_GMACGRP_MAC_FRAME_FILTER register.
+ MacFilter = DW_EMAC_GMACGRP_MAC_FRAME_FILTER_RESET;
+
+ if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) {
+ MacFilter |= DW_EMAC_GMACGRP_MAC_FRAME_FILTER_HMC_SET_MSK;
+
+ // Set the hash tables
+ if ((NumMfilter > 0) && (!Reset)) {
+ // Go through each filter address and set appropriate bits on hash table
+ for (Count = 0; Count < NumMfilter; Count++) {
+ // Generate a 32-bit CRC
+ Crc = GenEtherCrc32 (&Mfilter[Count], 6);
+ // reserve CRC + take upper 8 bit = take lower 8 bit and reverse it
+ Val = BitReverse(Crc & 0xff);
+ // The most significant bits determines the register to be used (Hash Table Register X),
+ // and the least significant five bits determine the bit within the register.
+ // For example, a hash value of 8b'10111111 selects Bit 31 of the Hash Table Register 5.
+ HashReg = (Val >> 5);
+ HashBit = (Val & 0x1f);
+
+ Reg = MmioRead32 (MacBaseAddress + HASH_TABLE_REG(HashReg));
+ // set 1 to HashBit of HashReg
+ // for example, set 1 to bit 31 to Reg 5 as in above example
+ Reg |= (1 << HashBit);
+ MmioWrite32(MacBaseAddress + HASH_TABLE_REG(HashReg), Reg);
+ }
+ }
+ }
+
+ if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) == 0) {
+ MacFilter |= DW_EMAC_GMACGRP_MAC_FRAME_FILTER_DBF_SET_MSK;
+ }
+
+ if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) {
+ MacFilter |= DW_EMAC_GMACGRP_MAC_FRAME_FILTER_PR_SET_MSK;
+ }
+
+ if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) {
+ MacFilter |= ( DW_EMAC_GMACGRP_MAC_FRAME_FILTER_PM_SET_MSK);
+ }
+
+ // Set MacFilter to EMAC register
+ MmioWrite32 (MacBaseAddress + DW_EMAC_GMACGRP_MAC_FRAME_FILTER_OFST, MacFilter);
+ return EFI_SUCCESS;
+}
+
+
+UINT32
+EFIAPI
+GenEtherCrc32 (
+ IN EFI_MAC_ADDRESS *Mac,
+ IN UINT32 AddrLen
+ )
+{
+ INT32 Iter;
+ UINT32 Remainder;
+ UINT8 *Ptr;
+
+ Iter = 0;
+ Remainder = 0xFFFFFFFF; // 0xFFFFFFFF is standard seed for Ethernet
+
+ // Convert Mac Address to array of bytes
+ Ptr = (UINT8 *)Mac;
+
+ // Generate the Crc bit-by-bit (LSB first)
+ while (AddrLen--) {
+ Remainder ^= *Ptr++;
+ for (Iter = 0; Iter < 8; Iter++) {
+ // Check if exponent is set
+ if (Remainder & 1) {
+ Remainder = (Remainder >> 1) ^ CRC_POLYNOMIAL;
+ } else {
+ Remainder = (Remainder >> 1) ^ 0;
+ }
+ }
+ }
+
+ return (~Remainder);
+}
+
+
+STATIC CONST UINT8 NibbleTab[] = {
+ /* 0x0 0000 -> 0000 */ 0x0,
+ /* 0x1 0001 -> 1000 */ 0x8,
+ /* 0x2 0010 -> 0100 */ 0x4,
+ /* 0x3 0011 -> 1100 */ 0xc,
+ /* 0x4 0100 -> 0010 */ 0x2,
+ /* 0x5 0101 -> 1010 */ 0xa,
+ /* 0x6 0110 -> 0110 */ 0x6,
+ /* 0x7 0111 -> 1110 */ 0xe,
+ /* 0x8 1000 -> 0001 */ 0x1,
+ /* 0x9 1001 -> 1001 */ 0x9,
+ /* 0xa 1010 -> 0101 */ 0x5,
+ /* 0xb 1011 -> 1101 */ 0xd,
+ /* 0xc 1100 -> 0011 */ 0x3,
+ /* 0xd 1101 -> 1011 */ 0xb,
+ /* 0xe 1110 -> 0111 */ 0x7,
+ /* 0xf 1111 -> 1111 */ 0xf
+};
+
+UINT8
+EFIAPI
+BitReverse (
+ UINT8 Value
+ )
+{
+ return (NibbleTab[Value & 0xf] << 4) | NibbleTab[Value >> 4];
+}
+
+
+VOID
+EFIAPI
+EmacStopTxRx (
+ IN UINTN MacBaseAddress
+ )
+{
+ DEBUG ((DEBUG_INFO, "SNP:MAC: %a ()\r\n", __FUNCTION__));
+
+ // Stop DMA TX
+ MmioAnd32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_OPERATION_MODE_OFST,
+ DW_EMAC_DMAGRP_OPERATION_MODE_ST_CLR_MSK);
+
+ // Flush TX
+ MmioOr32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_OPERATION_MODE_OFST,
+ DW_EMAC_DMAGRP_OPERATION_MODE_FTF_SET_MSK);
+
+ // Stop transmitters
+ MmioAnd32 (MacBaseAddress +
+ DW_EMAC_GMACGRP_MAC_CONFIGURATION_OFST,
+ DW_EMAC_GMACGRP_MAC_CONFIGURATION_RE_CLR_MSK &
+ DW_EMAC_GMACGRP_MAC_CONFIGURATION_TE_CLR_MSK);
+
+ // Stop DMA RX
+ MmioAnd32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_OPERATION_MODE_OFST,
+ DW_EMAC_DMAGRP_OPERATION_MODE_SR_CLR_MSK);
+
+}
+
+
+EFI_STATUS
+EFIAPI
+EmacDmaStart (
+ IN UINTN MacBaseAddress
+ )
+{
+ // Start the transmission
+ MmioWrite32(MacBaseAddress +
+ DW_EMAC_DMAGRP_TRANSMIT_POLL_DEMAND_OFST,
+ 0x1);
+ return EFI_SUCCESS;
+}
+
+
+VOID
+EFIAPI
+EmacGetDmaStatus (
+ OUT UINT32 *IrqStat OPTIONAL,
+ IN UINTN MacBaseAddress
+ )
+{
+ UINT32 DmaStatus;
+ UINT32 ErrorBit;
+ UINT32 Mask = 0;
+
+ DmaStatus = MmioRead32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_STATUS_OFST);
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_NIS_SET_MSK) {
+ Mask |= DW_EMAC_DMAGRP_STATUS_NIS_SET_MSK;
+ // Rx interrupt
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_RI_SET_MSK) {
+ *IrqStat |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
+ Mask |= DW_EMAC_DMAGRP_STATUS_RI_SET_MSK;
+ } else {
+ *IrqStat &= ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
+ }
+ // Tx interrupt
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_TI_SET_MSK) {
+ *IrqStat |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
+ Mask |= DW_EMAC_DMAGRP_STATUS_TI_SET_MSK;
+ } else {
+ *IrqStat &= ~EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
+ }
+ // Tx Buffer
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_TU_SET_MSK){
+ Mask |= DW_EMAC_DMAGRP_STATUS_TU_SET_MSK;
+ }
+ // Early receive interrupt
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_ERI_SET_MSK) {
+ Mask |= DW_EMAC_DMAGRP_STATUS_ERI_SET_MSK;
+ }
+ }
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_AIS_SET_MSK) {
+ Mask |= DW_EMAC_DMAGRP_STATUS_AIS_SET_MSK;
+ // Transmit process stop
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_TPS_SET_MSK) {
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Transmit process stop\n"));
+ Mask |= DW_EMAC_DMAGRP_STATUS_TPS_SET_MSK;
+ }
+ // Transmit jabber timeout
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_TJT_SET_MSK) {
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Transmit jabber timeout\n"));
+ Mask |= DW_EMAC_DMAGRP_STATUS_TJT_SET_MSK;
+ }
+ // Receive FIFO overflow
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_OVF_SET_MSK) {
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Receive FIFO overflow\n"));
+ Mask |= DW_EMAC_DMAGRP_STATUS_OVF_SET_MSK;
+ }
+ // Transmit FIFO underflow
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_UNF_SET_MSK) {
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Receive FIFO underflow\n"));
+ Mask |= DW_EMAC_DMAGRP_STATUS_UNF_SET_MSK;
+ }
+ // Receive buffer unavailable
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_RU_SET_MSK) {
+ Mask |= DW_EMAC_DMAGRP_STATUS_RU_SET_MSK;
+ }
+
+ // Receive process stop
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_RPS_SET_MSK) {
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Receive process stop\n"));
+ Mask |= DW_EMAC_DMAGRP_STATUS_RPS_SET_MSK;
+ }
+ // Receive watchdog timeout
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_RWT_SET_MSK) {
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Receive watchdog timeout\n"));
+ Mask |= DW_EMAC_DMAGRP_STATUS_RWT_SET_MSK;
+ }
+ // Early transmit interrupt
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_ETI_SET_MSK) {
+ Mask |= DW_EMAC_DMAGRP_STATUS_ETI_SET_MSK;
+ }
+ // Fatal bus error
+ if (DmaStatus & DW_EMAC_DMAGRP_STATUS_FBI_SET_MSK) {
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Fatal bus error:\n"));
+ Mask |= DW_EMAC_DMAGRP_STATUS_FBI_SET_MSK;
+
+ ErrorBit = DW_EMAC_DMAGRP_STATUS_EB_GET (DmaStatus);
+ switch (ErrorBit) {
+ case RX_DMA_WRITE_DATA_TRANSFER_ERROR:
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Rx Dma write data transfer error\n"));
+ break;
+ case TX_DMA_READ_DATA_TRANSFER_ERROR:
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Tx Dma read data transfer error\n"));
+ break;
+ case RX_DMA_DESCRIPTOR_WRITE_ACCESS_ERROR:
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Rx Dma descriptor write access error\n"));
+ break;
+ case RX_DMA_DESCRIPTOR_READ_ACCESS_ERROR:
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Rx Dma descriptor read access error\n"));
+ break;
+ case TX_DMA_DESCRIPTOR_WRITE_ACCESS_ERROR:
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Tx Dma descriptor write access error\n"));
+ break;
+ case TX_DMA_DESCRIPTOR_READ_ACCESS_ERROR:
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Tx Dma descriptor read access error\n"));
+ break;
+ default:
+ DEBUG ((DEBUG_INFO, "SNP:MAC: Undefined error\n"));
+ break;
+ }
+ }
+ }
+ MmioOr32 (MacBaseAddress +
+ DW_EMAC_DMAGRP_STATUS_OFST,
+ Mask);
+}
+
+
+VOID
+EFIAPI
+EmacGetStatistic (
+ OUT EFI_NETWORK_STATISTICS *Statistic,
+ IN UINTN MacBaseAddress
+ )
+{
+ EFI_NETWORK_STATISTICS *Stats;
+
+ DEBUG ((DEBUG_INFO, "SNP:MAC: %a ()\r\n", __FUNCTION__));
+
+ // Allocate Resources
+ Stats = AllocateZeroPool (sizeof (EFI_NETWORK_STATISTICS));
+ if (Stats == NULL) {
+ return;
+ }
+
+ Stats->RxTotalFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_RXFRAMECOUNT_GB_OFST);
+ Stats->RxUndersizeFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_RXUNDERSIZE_G_OFST);
+ Stats->RxOversizeFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_RXOVERSIZE_G_OFST);
+ Stats->RxUnicastFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_RXUNICASTFRAMES_G_OFST);
+ Stats->RxBroadcastFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_RXBROADCASTFRAMES_G_OFST);
+ Stats->RxMulticastFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_RXMULTICASTFRAMES_G_OFST);
+ Stats->RxCrcErrorFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_RXCRCERROR_OFST);
+ Stats->RxTotalBytes = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_RXOCTETCOUNT_GB_OFST);
+ Stats->RxGoodFrames = Stats->RxUnicastFrames + Stats->RxBroadcastFrames + Stats->RxMulticastFrames;
+
+ Stats->TxTotalFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_TXFRAMECOUNT_GB_OFST);
+ Stats->TxGoodFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_TXFRAMECOUNT_G_OFST);
+ Stats->TxOversizeFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_TXOVERSIZE_G_OFST);
+ Stats->TxUnicastFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_TXUNICASTFRAMES_GB_OFST);
+ Stats->TxBroadcastFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_TXBROADCASTFRAMES_G_OFST);
+ Stats->TxMulticastFrames = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_TXMULTICASTFRAMES_G_OFST);
+ Stats->TxTotalBytes = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_TXOCTETCOUNT_GB_OFST);
+ Stats->Collisions = MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_TXLATECOL_OFST) +
+ MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_TXEXESSCOL_OFST);
+
+ // Fill in the statistics
+ CopyMem (Statistic, Stats, sizeof (EFI_NETWORK_STATISTICS));
+}
+
+
+VOID
+EFIAPI
+EmacConfigAdjust (
+ IN UINT32 Speed,
+ IN UINT32 Duplex,
+ IN UINTN MacBaseAddress
+ )
+{
+ UINT32 Config;
+
+ Config = 0;
+ if (Speed != SPEED_1000) {
+ Config |= DW_EMAC_GMACGRP_MAC_CONFIGURATION_PS_SET_MSK;
+ }
+ if (Speed == SPEED_100) {
+ Config |= DW_EMAC_GMACGRP_MAC_CONFIGURATION_FES_SET_MSK;
+ }
+ if (Duplex == DUPLEX_FULL) {
+ Config |= DW_EMAC_GMACGRP_MAC_CONFIGURATION_DM_SET_MSK;
+ }
+ MmioOr32 (MacBaseAddress +
+ DW_EMAC_GMACGRP_MAC_CONFIGURATION_OFST,
+ DW_EMAC_GMACGRP_MAC_CONFIGURATION_BE_SET_MSK |
+ DW_EMAC_GMACGRP_MAC_CONFIGURATION_DO_SET_MSK |
+ Config);
+
+}
diff --git a/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.c b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.c
new file mode 100755
index 000000000000..d7643daf2827
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.c
@@ -0,0 +1,680 @@
+/** @file
+
+ Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ The original software modules are licensed as follows:
+
+ Copyright (c) 2012 - 2014, ARM Limited. All rights reserved.
+ Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "PhyDxeUtil.h"
+#include "EmacDxeUtil.h"
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiLib.h>
+
+EFI_STATUS
+EFIAPI
+PhyDxeInitialization (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__));
+
+ // initialize the phyaddr
+ PhyDriver->PhyAddr = 0;
+ PhyDriver->PhyCurrentLink = LINK_DOWN;
+ PhyDriver->PhyOldLink = LINK_DOWN;
+
+ Status = PhyDetectDevice (PhyDriver, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ PhyConfig (PhyDriver, MacBaseAddress);
+
+ return EFI_SUCCESS;
+}
+
+
+// PHY detect device
+EFI_STATUS
+EFIAPI
+PhyDetectDevice (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ UINT32 PhyAddr;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__));
+
+ for (PhyAddr = 0; PhyAddr < 32; PhyAddr++) {
+ Status = PhyReadId (PhyAddr, MacBaseAddress);
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ PhyDriver->PhyAddr = PhyAddr;
+ return EFI_SUCCESS;
+ }
+
+ DEBUG ((DEBUG_INFO, "SNP:PHY: Fail to detect Ethernet PHY!\r\n"));
+ return EFI_NOT_FOUND;
+
+}
+
+
+EFI_STATUS
+EFIAPI
+PhyConfig (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__));
+
+ Status = PhySoftReset (PhyDriver, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Configure TX/RX Skew
+ PhyConfigSkew (PhyDriver, MacBaseAddress);
+
+ // Read back and display Skew settings
+ PhyDisplayConfigSkew (PhyDriver, MacBaseAddress);
+
+ // Configure AN FLP Burst Trasmit timing interval
+ PhyConfigFlpBurstTiming (PhyDriver, MacBaseAddress);
+ PhyDisplayFlpBurstTiming (PhyDriver, MacBaseAddress);
+
+ // Configure AN and Advertise
+ PhyAutoNego (PhyDriver, MacBaseAddress);
+
+ return EFI_SUCCESS;
+}
+
+
+// Perform PHY software reset
+EFI_STATUS
+EFIAPI
+PhySoftReset (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ UINT32 TimeOut;
+ UINT32 Data32;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__));
+
+ // PHY Basic Control Register reset
+ PhyWrite (PhyDriver->PhyAddr, PHY_BASIC_CTRL, PHYCTRL_RESET, MacBaseAddress);
+
+ // Wait for completion
+ TimeOut = 0;
+ do {
+ // Read PHY_BASIC_CTRL register from PHY
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_BASIC_CTRL, &Data32, MacBaseAddress);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ // Wait until PHYCTRL_RESET become zero
+ if ((Data32 & PHYCTRL_RESET) == 0) {
+ break;
+ }
+ MicroSecondDelay(1);
+ } while (TimeOut++ < PHY_TIMEOUT);
+ if (TimeOut >= PHY_TIMEOUT) {
+ DEBUG ((DEBUG_INFO, "SNP:PHY: ERROR! PhySoftReset timeout\n"));
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+// PHY read ID
+EFI_STATUS
+EFIAPI
+PhyReadId (
+ IN UINT32 PhyAddr,
+ IN UINTN MacBaseAddress
+ )
+{
+ EFI_STATUS Status;
+ UINT32 PhyId1;
+ UINT32 PhyId2;
+
+ Status = PhyRead (PhyAddr, PHY_ID1, &PhyId1, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = PhyRead (PhyAddr, PHY_ID2, &PhyId2, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (PhyId1 == PHY_INVALID_ID || PhyId2 == PHY_INVALID_ID) {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((DEBUG_INFO, "SNP:PHY: Ethernet PHY detected. PHY_ID1=0x%04X, PHY_ID2=0x%04X, PHY_ADDR=0x%02X\r\n",
+ PhyId1, PhyId2, PhyAddr));
+ return EFI_SUCCESS;
+}
+
+
+VOID
+EFIAPI
+PhyConfigSkew (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ Phy9031ExtendedWrite (PhyDriver,
+ PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_DEV_ADDR, PHY_KSZ9031RN_CONTROL_PAD_SKEW_REG,
+ PHY_KSZ9031RN_CONTROL_PAD_SKEW_VALUE,
+ MacBaseAddress);
+ Phy9031ExtendedWrite (PhyDriver,
+ PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_DEV_ADDR, PHY_KSZ9031RN_CLK_PAD_SKEW_REG,
+ PHY_KSZ9031RN_CLK_PAD_SKEW_VALUE,
+ MacBaseAddress);
+ Phy9031ExtendedWrite (PhyDriver,
+ PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_DEV_ADDR,
+ PHY_KSZ9031RN_RX_DATA_PAD_SKEW_REG,
+ PHY_KSZ9031RN_RX_DATA_PAD_SKEW_VALUE,
+ MacBaseAddress);
+ Phy9031ExtendedWrite (PhyDriver,
+ PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_DEV_ADDR,
+ PHY_KSZ9031RN_TX_DATA_PAD_SKEW_REG,
+ PHY_KSZ9031RN_TX_DATA_PAD_SKEW_VALUE,
+ MacBaseAddress);
+}
+
+
+VOID
+EFIAPI
+PhyDisplayConfigSkew (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ // Display skew configuration
+ DEBUG ((DEBUG_INFO, "SNP:PHY: Control Signal Pad Skew = 0x%04X\r\n",
+ Phy9031ExtendedRead (PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_DEV_ADDR, PHY_KSZ9031RN_CONTROL_PAD_SKEW_REG, MacBaseAddress)));
+
+ DEBUG ((DEBUG_INFO, "SNP:PHY: RGMII Clock Pad Skew = 0x%04X\r\n",
+ Phy9031ExtendedRead (PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_DEV_ADDR, PHY_KSZ9031RN_CLK_PAD_SKEW_REG, MacBaseAddress)));
+
+ DEBUG ((DEBUG_INFO, "SNP:PHY: RGMII RX Data Pad Skew = 0x%04X\r\n",
+ Phy9031ExtendedRead (PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_DEV_ADDR, PHY_KSZ9031RN_RX_DATA_PAD_SKEW_REG, MacBaseAddress)));
+
+ DEBUG ((DEBUG_INFO, "SNP:PHY: RGMII TX Data Pad Skew = 0x%04X\r\n",
+ Phy9031ExtendedRead (PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_DEV_ADDR, PHY_KSZ9031RN_TX_DATA_PAD_SKEW_REG, MacBaseAddress)));
+}
+
+VOID
+EFIAPI
+PhyConfigFlpBurstTiming (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ Phy9031ExtendedWrite (PhyDriver,
+ PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_MMD_DEV_ADDR_00,
+ PHY_KSZ9031RN_MMD_D0_FLP_LO_REG,
+ PHY_KSZ9031RN_MMD_D0_FLP_16MS_LO,
+ MacBaseAddress);
+ Phy9031ExtendedWrite (PhyDriver,
+ PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_MMD_DEV_ADDR_00,
+ PHY_KSZ9031RN_MMD_D0_FLP_HI_REG,
+ PHY_KSZ9031RN_MMD_D0_FLP_16MS_HI,
+ MacBaseAddress);
+}
+
+VOID
+EFIAPI
+PhyDisplayFlpBurstTiming (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ // Display Auto-Negotiation FLP burst transmit timing
+ DEBUG ((DEBUG_INFO, "SNP:PHY: AN FLP Burst Transmit - LO = 0x%04X\r\n",
+ Phy9031ExtendedRead (PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC,
+ PHY_KSZ9031RN_MMD_DEV_ADDR_00, PHY_KSZ9031RN_MMD_D0_FLP_LO_REG, MacBaseAddress)));
+ DEBUG ((DEBUG_INFO, "SNP:PHY: AN FLP Burst Transmit - HI = 0x%04X\r\n",
+ Phy9031ExtendedRead (PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC, PHY_KSZ9031RN_MMD_DEV_ADDR_00,
+ PHY_KSZ9031RN_MMD_D0_FLP_HI_REG, MacBaseAddress)));
+}
+
+// Do auto-negotiation
+EFI_STATUS
+EFIAPI
+PhyAutoNego (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ EFI_STATUS Status;
+ UINT32 PhyControl;
+ UINT32 PhyStatus;
+ UINT32 Features;
+
+ DEBUG ((DEBUG_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__));
+
+ // Read PHY Status
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_BASIC_STATUS, &PhyStatus, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Check PHY Status if auto-negotiation is supported
+ if ((PhyStatus & PHYSTS_AUTO_CAP) == 0) {
+ DEBUG ((DEBUG_INFO, "SNP:PHY: Auto-negotiation is not supported.\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Read PHY Auto-Nego Advertise capabilities register for 10/100 Base-T
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_AUTO_NEG_ADVERT, &Features, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Set Advertise capabilities for 10Base-T/10Base-T full-duplex/100Base-T/100Base-T full-duplex
+ Features |= (PHYANA_10BASET | PHYANA_10BASETFD | PHYANA_100BASETX | PHYANA_100BASETXFD);
+ PhyWrite (PhyDriver->PhyAddr, PHY_AUTO_NEG_ADVERT, Features, MacBaseAddress);
+
+ // Read PHY Auto-Nego Advertise capabilities register for 1000 Base-T
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_1000BASE_T_CONTROL, &Features, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Set Advertise capabilities for 1000 Base-T/1000 Base-T full-duplex
+ Features |= (PHYADVERTISE_1000FULL | PHYADVERTISE_1000HALF);
+ PhyWrite (PhyDriver->PhyAddr, PHY_1000BASE_T_CONTROL, Features, MacBaseAddress);
+
+ // Read control register
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_BASIC_CTRL, &PhyControl, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ // Enable Auto-Negotiation
+ PhyControl |= PHYCTRL_AUTO_EN;
+ // Restart auto-negotiation
+ PhyControl |= PHYCTRL_RST_AUTO;
+ // Write this configuration
+ PhyWrite (PhyDriver->PhyAddr, PHY_BASIC_CTRL, PhyControl, MacBaseAddress);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PhyLinkAdjustEmacConfig (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ UINT32 Speed;
+ UINT32 Duplex;
+ EFI_STATUS Status;
+
+ //DEBUG ((DEBUG_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__));
+
+ Status = EFI_SUCCESS;
+ Speed = SPEED_10;
+ Duplex = DUPLEX_HALF;
+
+ Status = PhyCheckLinkStatus (PhyDriver, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ PhyDriver->PhyCurrentLink = LINK_DOWN;
+ } else {
+ PhyDriver->PhyCurrentLink = LINK_UP;
+ }
+
+ if (PhyDriver->PhyOldLink != PhyDriver->PhyCurrentLink) {
+ if (PhyDriver->PhyCurrentLink == LINK_UP) {
+ DEBUG ((DEBUG_INFO, "SNP:PHY: Link is up - Network Cable is Plugged\r\n"));
+ PhyReadCapability (PhyDriver, &Speed, &Duplex, MacBaseAddress);
+ EmacConfigAdjust (Speed, Duplex, MacBaseAddress);
+ Status = EFI_SUCCESS;
+ } else {
+ DEBUG ((DEBUG_INFO, "SNP:PHY: Link is Down - Network Cable is Unplugged?\r\n"));
+ Status = EFI_NOT_READY;
+ }
+ } else if (PhyDriver->PhyCurrentLink == LINK_DOWN) {
+ Status = EFI_NOT_READY;
+ }
+
+ PhyDriver->PhyOldLink = PhyDriver->PhyCurrentLink;
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+PhyCheckLinkStatus (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINTN MacBaseAddress
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Data32;
+ UINTN TimeOut;
+ UINT32 PhyBasicStatus;
+
+ // Get the PHY Status
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_BASIC_STATUS, &PhyBasicStatus, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // if Link is already up then dont need to proceed anymore
+ if (PhyBasicStatus & PHYSTS_LINK_STS) {
+ return EFI_SUCCESS;
+ }
+
+ // Wait until it is up or until Time Out
+ TimeOut = 0;
+ do {
+ // Read PHY_BASIC_STATUS register from PHY
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_BASIC_STATUS, &Data32, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ // Wait until PHYSTS_LINK_STS become one
+ if (Data32 & PHYSTS_LINK_STS) {
+ // Link is up
+ break;
+ }
+ MicroSecondDelay (1);
+ } while (TimeOut++ < PHY_TIMEOUT);
+ if (TimeOut >= PHY_TIMEOUT) {
+ // Link is down
+ return EFI_TIMEOUT;
+ }
+
+ // Wait until autonego process has completed
+ TimeOut = 0;
+ do {
+ // Read PHY_BASIC_STATUS register from PHY
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_BASIC_STATUS, &Data32, MacBaseAddress);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ // Wait until PHYSTS_AUTO_COMP become one
+ if (Data32 & PHYSTS_AUTO_COMP) {
+ DEBUG ((DEBUG_INFO, "SNP:PHY: Auto Negotiation completed\r\n"));
+ break;
+ }
+ MicroSecondDelay (1);
+ } while (TimeOut++ < PHY_TIMEOUT);
+ if (TimeOut >= PHY_TIMEOUT) {
+ DEBUG ((DEBUG_INFO, "SNP:PHY: Error! Auto Negotiation timeout\n"));
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PhyReadCapability (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINT32 *Speed,
+ IN UINT32 *Duplex,
+ IN UINTN MacBaseAddress
+ )
+{
+ EFI_STATUS Status;
+ UINT32 PartnerAbilityGb;
+ UINT32 AdvertisingGb;
+ UINT32 CommonAbilityGb;
+ UINT32 PartnerAbility;
+ UINT32 Advertising;
+ UINT32 CommonAbility;
+
+ // For 1000 Base-T
+
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_1000BASE_T_STATUS, &PartnerAbilityGb, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_1000BASE_T_CONTROL, &AdvertisingGb, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CommonAbilityGb = PartnerAbilityGb & (AdvertisingGb << 2);
+
+ // For 10/100 Base-T
+
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_AUTO_NEG_LINK_ABILITY, &PartnerAbility, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_AUTO_NEG_EXP, &Advertising, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CommonAbility = PartnerAbility & Advertising;
+
+ // Determine the Speed and Duplex
+ if (PartnerAbilityGb & (PHYLPA_1000FULL | PHYLPA_1000HALF)) {
+ *Speed = SPEED_1000;
+ if (CommonAbilityGb & PHYLPA_1000FULL) {
+ *Duplex = DUPLEX_FULL;
+ }
+ } else if (CommonAbility & (PHYLPA_100FULL | PHYLPA_100HALF)) {
+ *Speed = SPEED_100;
+ if (CommonAbility & PHYLPA_100FULL) {
+ *Duplex = DUPLEX_FULL;
+ } else if (CommonAbility & PHYLPA_10FULL) {
+ *Duplex = DUPLEX_FULL;
+ }
+ }
+
+ PhyDisplayAbility (*Speed, *Duplex);
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+EFIAPI
+PhyDisplayAbility (
+ IN UINT32 Speed,
+ IN UINT32 Duplex
+ )
+{
+
+ DEBUG ((DEBUG_INFO, "SNP:PHY: "));
+ switch (Speed) {
+ case SPEED_1000:
+ DEBUG ((DEBUG_INFO, "1 Gbps - "));
+ break;
+ case SPEED_100:
+ DEBUG ((DEBUG_INFO, "100 Mbps - "));
+ break;
+ case SPEED_10:
+ DEBUG ((DEBUG_INFO, "10 Mbps - "));
+ break;
+ default:
+ DEBUG ((DEBUG_INFO, "Invalid link speed"));
+ break;
+ }
+
+ switch (Duplex) {
+ case DUPLEX_FULL:
+ DEBUG ((DEBUG_INFO, "Full Duplex\n"));
+ break;
+ case DUPLEX_HALF:
+ DEBUG ((DEBUG_INFO, "Half Duplex\n"));
+ break;
+ default:
+ DEBUG ((DEBUG_INFO, "Invalid duplex mode\n"));
+ break;
+ }
+}
+
+
+// Function to read from MII register (PHY Access)
+EFI_STATUS
+EFIAPI
+PhyRead (
+ IN UINT32 Addr,
+ IN UINT32 Reg,
+ OUT UINT32 *Data,
+ IN UINTN MacBaseAddress
+ )
+{
+ UINT32 MiiConfig;
+ UINT32 Count;
+
+ // Check it is a valid Reg
+ ASSERT (Reg < 31);
+
+ MiiConfig = ((Addr << MIIADDRSHIFT) & MII_ADDRMSK) |
+ ((Reg << MIIREGSHIFT) & MII_REGMSK)|
+ MII_CLKRANGE_150_250M |
+ MII_BUSY;
+
+ // write this config to register
+ MmioWrite32 (MacBaseAddress + DW_EMAC_GMACGRP_GMII_ADDRESS_OFST, MiiConfig);
+
+ // Wait for busy bit to clear
+ Count = 0;
+ while (Count < 10000) {
+ if (!(DW_EMAC_GMACGRP_GMII_ADDRESS_GB_GET (MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_GMII_ADDRESS_OFST)))) {
+ *Data = DW_EMAC_GMACGRP_GMII_DATA_GD_GET (MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_GMII_DATA_OFST));
+ return EFI_SUCCESS;
+ }
+ MemoryFence ();
+ Count++;
+ };
+ DEBUG ((DEBUG_INFO, "SNP:PHY: MDIO busy bit timeout\r\n"));
+ return EFI_TIMEOUT;
+}
+
+
+// Function to write to the MII register (PHY Access)
+EFI_STATUS
+EFIAPI
+PhyWrite (
+ IN UINT32 Addr,
+ IN UINT32 Reg,
+ IN UINT32 Data,
+ IN UINTN MacBaseAddress
+ )
+{
+ UINT32 MiiConfig;
+ UINT32 Count;
+
+ // Check it is a valid Reg
+ ASSERT(Reg < 31);
+
+ MiiConfig = ((Addr << MIIADDRSHIFT) & MII_ADDRMSK) |
+ ((Reg << MIIREGSHIFT) & MII_REGMSK)|
+ MII_WRITE |
+ MII_CLKRANGE_150_250M |
+ MII_BUSY;
+ // Write the desired value to the register first
+ MmioWrite32 (MacBaseAddress + DW_EMAC_GMACGRP_GMII_DATA_OFST, (Data & 0xFFFF));
+
+ // write this config to register
+ MmioWrite32 (MacBaseAddress + DW_EMAC_GMACGRP_GMII_ADDRESS_OFST, MiiConfig);
+
+ // Wait for busy bit to clear
+ Count = 0;
+ while (Count < 1000) {
+ if (!(DW_EMAC_GMACGRP_GMII_ADDRESS_GB_GET (MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_GMII_ADDRESS_OFST)))) {
+ return EFI_SUCCESS;
+ }
+ MemoryFence ();
+ Count++;
+ };
+
+ return EFI_TIMEOUT;
+}
+
+
+EFI_STATUS
+EFIAPI
+Phy9031ExtendedWrite (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINT32 Mode,
+ IN UINT32 DevAddr,
+ IN UINT32 Regnum,
+ IN UINT16 Val,
+ IN UINTN MacBaseAddress
+ )
+{
+ PhyWrite (PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_CTRL_REG, DevAddr, MacBaseAddress);
+ PhyWrite (PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_REGDATA_REG, Regnum, MacBaseAddress);
+ PhyWrite (PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_CTRL_REG, (Mode << 14) | DevAddr, MacBaseAddress);
+ return PhyWrite (PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_REGDATA_REG, Val, MacBaseAddress);
+}
+
+
+UINT32
+EFIAPI
+Phy9031ExtendedRead (
+ IN PHY_DRIVER *PhyDriver,
+ IN UINT32 Mode,
+ IN UINT32 DevAddr,
+ IN UINT32 Regnum,
+ IN UINTN MacBaseAddress
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Data32;
+
+ PhyWrite (PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_CTRL_REG, DevAddr, MacBaseAddress);
+ PhyWrite (PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_REGDATA_REG, Regnum, MacBaseAddress);
+ PhyWrite (PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_CTRL_REG, (Mode << 14) | DevAddr, MacBaseAddress);
+
+ Status = PhyRead (PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_REGDATA_REG, &Data32, MacBaseAddress);
+ if (EFI_ERROR (Status)) {
+ return 0;
+ }
+
+ return Data32;
+}
+
+
--
2.17.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
2019-07-08 7:05 [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver Ooi, Tzy Way
@ 2019-07-11 16:43 ` Leif Lindholm
2019-07-16 9:37 ` [edk2-devel] " Ooi, Tzy Way
0 siblings, 1 reply; 7+ messages in thread
From: Leif Lindholm @ 2019-07-11 16:43 UTC (permalink / raw)
To: tzy.way.ooi; +Cc: devel, Ard BieSheuvel, Michael D Kinney, Loh Tien Hock
Hi Tzy Way,
Nearly there, but please make sure BaseTools/Scripts/PatchCheck.py
runs without warnings or errors (there are quite a few still in this
version).
Building the .dsc using current edk2 fails with
'MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf is not found in packages path'
The path needs to be updated to NetworkPkg/Library/DxeNetLib/DxeNetLib.inf.
Secondly, could you add NOOPT as a BUILD_TARGET, in addition to DEBUG
and RELEASE?
Also, Debian's gcc 8.3 throws a set of compilation errors (both DEBUG
and RELEASE) when building for AARCH64:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c: In function <E2><80><98>EmacSetupTxdesc<E2><80><99>:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:236:81: error: iteration 9 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
TxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->TxdescRingMap[Index + 1].AddrMap;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:233:3: note: within this loop
for (Index = 0; Index < CONFIG_TX_DESCR_NUM; Index++) {
^~~
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c: In function <E2><80><98>EmacSetupRxdesc<E2><80><99>:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:270:81: error: iteration 9 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
RxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->RxdescRingMap[Index + 1].AddrMap;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:267:3: note: within this loop
for (Index = 0; Index < CONFIG_RX_DESCR_NUM; Index++) {
^~~
cc1: all warnings being treated as errors
It also throws the following errors when building for ARM:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c: In function <E2><80><98>SnpTransmit<E2><80><99>:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:962:21: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
TxDescriptorMap = (VOID *)Snp->MacDriver.TxdescRingMap[DescNum].AddrMap;
^
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:1026:51: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
Snp->RecycledTxBuf[Snp->RecycledTxBufCount] = (UINT64) Data;
^
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c: In function <E2><80><98>SnpReceive<E2><80><99>:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:1143:21: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
RxDescriptorMap = (VOID *)Snp->MacDriver.RxdescRingMap[DescNum].AddrMap;
^
cc1: all warnings being treated as errors
Could you please look into and address these issues for the next version?
Best Regards,
Leif
On Mon, Jul 08, 2019 at 03:05:07PM +0800, tzy.way.ooi@intel.com wrote:
> From: Ooi Tzy Way <tzy.way.ooi@intel.com>
>
> Add driver support for the Ethernet MAC based on Synopsys DesignWare
> 3504-0 Universal 10/100/1000 Ethernet MAC and KSZ9031 PHY
>
> Cc: Ard BieSheuvel <ard.biesheuvel@linaro.org>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Loh Tien Hock <tien.hock.loh@intel.com>
>
> Contributed-under: Tianocore Contribution Agreement 1.1
> Signed-off-by: Ooi Tzy Way <tzy.way.ooi@intel.com>
>
> ---
> v6:
> - Update to recent version for EDK2 specific file formats
> - Update the directory layout to Silicon/Synopsys/DesignWare
> - Add a DesignWare.dsc for building this driver
> - Update the license
> - Update the .c file to declare its own include file
> - Remove __ in defining the header file
> - Fix indentation
> - Delete commented-out code
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
2019-07-11 16:43 ` Leif Lindholm
@ 2019-07-16 9:37 ` Ooi, Tzy Way
2019-07-16 17:22 ` Leif Lindholm
0 siblings, 1 reply; 7+ messages in thread
From: Ooi, Tzy Way @ 2019-07-16 9:37 UTC (permalink / raw)
To: devel@edk2.groups.io, leif.lindholm@linaro.org
Cc: Ard BieSheuvel, Kinney, Michael D, Loh, Tien Hock
Hi Leif,
I am new to the compilation tools. May I know if you can share to me how to run the compilation with Debian's gcc 8.3 so that I can see the same warning described below? Currently, I am using linaro toolchain 7.2.1 and follow the guide in the link below to compile the source code.
https://github.com/tianocore/edk2-platforms
I am not able to see any warning in the compilation messages. Wonder if I need to enable something, for example some CFLAGS during compilation?
Thank you in advance.
Best regards,
Tzy Way
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Leif Lindholm
Sent: Friday, July 12, 2019 12:43 AM
To: Ooi, Tzy Way <tzy.way.ooi@intel.com>
Cc: devel@edk2.groups.io; Ard BieSheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Loh, Tien Hock <tien.hock.loh@intel.com>
Subject: Re: [edk2-devel] [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
Hi Tzy Way,
Nearly there, but please make sure BaseTools/Scripts/PatchCheck.py runs without warnings or errors (there are quite a few still in this version).
Building the .dsc using current edk2 fails with 'MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf is not found in packages path'
The path needs to be updated to NetworkPkg/Library/DxeNetLib/DxeNetLib.inf.
Secondly, could you add NOOPT as a BUILD_TARGET, in addition to DEBUG and RELEASE?
Also, Debian's gcc 8.3 throws a set of compilation errors (both DEBUG and RELEASE) when building for AARCH64:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c: In function <E2><80><98>EmacSetupTxdesc<E2><80><99>:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:236:81: error: iteration 9 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
TxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->TxdescRingMap[Index + 1].AddrMap;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:233:3: note: within this loop
for (Index = 0; Index < CONFIG_TX_DESCR_NUM; Index++) {
^~~
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c: In function <E2><80><98>EmacSetupRxdesc<E2><80><99>:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:270:81: error: iteration 9 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
RxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->RxdescRingMap[Index + 1].AddrMap;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:267:3: note: within this loop
for (Index = 0; Index < CONFIG_RX_DESCR_NUM; Index++) {
^~~
cc1: all warnings being treated as errors
It also throws the following errors when building for ARM:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c: In function <E2><80><98>SnpTransmit<E2><80><99>:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:962:21: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
TxDescriptorMap = (VOID *)Snp->MacDriver.TxdescRingMap[DescNum].AddrMap;
^
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:1026:51: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
Snp->RecycledTxBuf[Snp->RecycledTxBufCount] = (UINT64) Data;
^
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c: In function <E2><80><98>SnpReceive<E2><80><99>:
/work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:1143:21: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
RxDescriptorMap = (VOID *)Snp->MacDriver.RxdescRingMap[DescNum].AddrMap;
^
cc1: all warnings being treated as errors
Could you please look into and address these issues for the next version?
Best Regards,
Leif
On Mon, Jul 08, 2019 at 03:05:07PM +0800, tzy.way.ooi@intel.com wrote:
> From: Ooi Tzy Way <tzy.way.ooi@intel.com>
>
> Add driver support for the Ethernet MAC based on Synopsys DesignWare
> 3504-0 Universal 10/100/1000 Ethernet MAC and KSZ9031 PHY
>
> Cc: Ard BieSheuvel <ard.biesheuvel@linaro.org>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Loh Tien Hock <tien.hock.loh@intel.com>
>
> Contributed-under: Tianocore Contribution Agreement 1.1
> Signed-off-by: Ooi Tzy Way <tzy.way.ooi@intel.com>
>
> ---
> v6:
> - Update to recent version for EDK2 specific file formats
> - Update the directory layout to Silicon/Synopsys/DesignWare
> - Add a DesignWare.dsc for building this driver
> - Update the license
> - Update the .c file to declare its own include file
> - Remove __ in defining the header file
> - Fix indentation
> - Delete commented-out code
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
2019-07-16 9:37 ` [edk2-devel] " Ooi, Tzy Way
@ 2019-07-16 17:22 ` Leif Lindholm
2019-07-17 9:25 ` Ooi, Tzy Way
0 siblings, 1 reply; 7+ messages in thread
From: Leif Lindholm @ 2019-07-16 17:22 UTC (permalink / raw)
To: Ooi, Tzy Way
Cc: devel@edk2.groups.io, Ard BieSheuvel, Kinney, Michael D,
Loh, Tien Hock
Hi Tzy Way,
On Tue, Jul 16, 2019 at 09:37:38AM +0000, Ooi, Tzy Way wrote:
> I am new to the compilation tools. May I know if you can share to me
> how to run the compilation with Debian's gcc 8.3 so that I can see
> the same warning described below? Currently, I am using linaro
> toolchain 7.2.1 and follow the guide in the link below to compile
> the source code.
>
> https://github.com/tianocore/edk2-platforms
>
> I am not able to see any warning in the compilation messages. Wonder
> if I need to enable something, for example some CFLAGS during
> compilation?
Yeah, the tools are getting stricter all the time - but we don't want
to merge code we can't build with the toolchains included in current
long-term supported Linux distributions.
What does your setup look like today - are you on Windows or Linux?
If Linux, can you use WSL?
Cross compilation tools for both ARM and AARCH64 (and the very latest
ones Ia32/X64) are available in several current Linux distributions
(and hence in WSL).
Best Regards,
Leif
>
> Thank you in advance.
>
> Best regards,
> Tzy Way
>
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Leif Lindholm
> Sent: Friday, July 12, 2019 12:43 AM
> To: Ooi, Tzy Way <tzy.way.ooi@intel.com>
> Cc: devel@edk2.groups.io; Ard BieSheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Loh, Tien Hock <tien.hock.loh@intel.com>
> Subject: Re: [edk2-devel] [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
>
> Hi Tzy Way,
>
> Nearly there, but please make sure BaseTools/Scripts/PatchCheck.py runs without warnings or errors (there are quite a few still in this version).
>
> Building the .dsc using current edk2 fails with 'MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf is not found in packages path'
> The path needs to be updated to NetworkPkg/Library/DxeNetLib/DxeNetLib.inf.
>
> Secondly, could you add NOOPT as a BUILD_TARGET, in addition to DEBUG and RELEASE?
>
> Also, Debian's gcc 8.3 throws a set of compilation errors (both DEBUG and RELEASE) when building for AARCH64:
>
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c: In function <E2><80><98>EmacSetupTxdesc<E2><80><99>:
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:236:81: error: iteration 9 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
> TxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->TxdescRingMap[Index + 1].AddrMap;
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:233:3: note: within this loop
> for (Index = 0; Index < CONFIG_TX_DESCR_NUM; Index++) {
> ^~~
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c: In function <E2><80><98>EmacSetupRxdesc<E2><80><99>:
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:270:81: error: iteration 9 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
> RxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->RxdescRingMap[Index + 1].AddrMap;
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:267:3: note: within this loop
> for (Index = 0; Index < CONFIG_RX_DESCR_NUM; Index++) {
> ^~~
> cc1: all warnings being treated as errors
>
>
> It also throws the following errors when building for ARM:
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c: In function <E2><80><98>SnpTransmit<E2><80><99>:
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:962:21: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
> TxDescriptorMap = (VOID *)Snp->MacDriver.TxdescRingMap[DescNum].AddrMap;
> ^
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:1026:51: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
> Snp->RecycledTxBuf[Snp->RecycledTxBufCount] = (UINT64) Data;
> ^
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c: In function <E2><80><98>SnpReceive<E2><80><99>:
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:1143:21: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
> RxDescriptorMap = (VOID *)Snp->MacDriver.RxdescRingMap[DescNum].AddrMap;
> ^
> cc1: all warnings being treated as errors
>
>
> Could you please look into and address these issues for the next version?
>
> Best Regards,
>
> Leif
>
> On Mon, Jul 08, 2019 at 03:05:07PM +0800, tzy.way.ooi@intel.com wrote:
> > From: Ooi Tzy Way <tzy.way.ooi@intel.com>
> >
> > Add driver support for the Ethernet MAC based on Synopsys DesignWare
> > 3504-0 Universal 10/100/1000 Ethernet MAC and KSZ9031 PHY
> >
> > Cc: Ard BieSheuvel <ard.biesheuvel@linaro.org>
> > Cc: Leif Lindholm <leif.lindholm@linaro.org>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Loh Tien Hock <tien.hock.loh@intel.com>
> >
> > Contributed-under: Tianocore Contribution Agreement 1.1
> > Signed-off-by: Ooi Tzy Way <tzy.way.ooi@intel.com>
> >
> > ---
> > v6:
> > - Update to recent version for EDK2 specific file formats
> > - Update the directory layout to Silicon/Synopsys/DesignWare
> > - Add a DesignWare.dsc for building this driver
> > - Update the license
> > - Update the .c file to declare its own include file
> > - Remove __ in defining the header file
> > - Fix indentation
> > - Delete commented-out code
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
2019-07-16 17:22 ` Leif Lindholm
@ 2019-07-17 9:25 ` Ooi, Tzy Way
2019-07-17 11:44 ` Leif Lindholm
0 siblings, 1 reply; 7+ messages in thread
From: Ooi, Tzy Way @ 2019-07-17 9:25 UTC (permalink / raw)
To: Leif Lindholm
Cc: devel@edk2.groups.io, Ard BieSheuvel, Kinney, Michael D,
Loh, Tien Hock
Hi Leif,
Ya. I am on Linux. I managed to replicated the warning that you have provided in the previous email thread by using the gcc 8.3.
Currently, I'm looking at the compiler warning/error. While I am fixing the issue when compiling the source code, I encountered another issue where the compiler complain "undefined reference to __stack_chk_fail". I check from google and it can be solved by setting -fnostack-protector. Hence, I would like to ask if is it ok to set this to the CFLAGs for the compiler?
Thank you
Best regards,
Tzy Way
-----Original Message-----
From: Leif Lindholm <leif.lindholm@linaro.org>
Sent: Wednesday, July 17, 2019 1:22 AM
To: Ooi, Tzy Way <tzy.way.ooi@intel.com>
Cc: devel@edk2.groups.io; Ard BieSheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Loh, Tien Hock <tien.hock.loh@intel.com>
Subject: Re: [edk2-devel] [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
Hi Tzy Way,
On Tue, Jul 16, 2019 at 09:37:38AM +0000, Ooi, Tzy Way wrote:
> I am new to the compilation tools. May I know if you can share to me
> how to run the compilation with Debian's gcc 8.3 so that I can see the
> same warning described below? Currently, I am using linaro toolchain
> 7.2.1 and follow the guide in the link below to compile the source
> code.
>
> https://github.com/tianocore/edk2-platforms
>
> I am not able to see any warning in the compilation messages. Wonder
> if I need to enable something, for example some CFLAGS during
> compilation?
Yeah, the tools are getting stricter all the time - but we don't want to merge code we can't build with the toolchains included in current long-term supported Linux distributions.
What does your setup look like today - are you on Windows or Linux?
If Linux, can you use WSL?
Cross compilation tools for both ARM and AARCH64 (and the very latest ones Ia32/X64) are available in several current Linux distributions (and hence in WSL).
Best Regards,
Leif
>
> Thank you in advance.
>
> Best regards,
> Tzy Way
>
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Leif
> Lindholm
> Sent: Friday, July 12, 2019 12:43 AM
> To: Ooi, Tzy Way <tzy.way.ooi@intel.com>
> Cc: devel@edk2.groups.io; Ard BieSheuvel <ard.biesheuvel@linaro.org>;
> Kinney, Michael D <michael.d.kinney@intel.com>; Loh, Tien Hock
> <tien.hock.loh@intel.com>
> Subject: Re: [edk2-devel] [PATCH v6 edk2-platforms 1/1]
> Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC
> driver
>
> Hi Tzy Way,
>
> Nearly there, but please make sure BaseTools/Scripts/PatchCheck.py runs without warnings or errors (there are quite a few still in this version).
>
> Building the .dsc using current edk2 fails with 'MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf is not found in packages path'
> The path needs to be updated to NetworkPkg/Library/DxeNetLib/DxeNetLib.inf.
>
> Secondly, could you add NOOPT as a BUILD_TARGET, in addition to DEBUG and RELEASE?
>
> Also, Debian's gcc 8.3 throws a set of compilation errors (both DEBUG and RELEASE) when building for AARCH64:
>
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c: In function <E2><80><98>EmacSetupTxdesc<E2><80><99>:
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:236:81: error: iteration 9 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
> TxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->TxdescRingMap[Index + 1].AddrMap;
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:233:3: note: within this loop
> for (Index = 0; Index < CONFIG_TX_DESCR_NUM; Index++) {
> ^~~
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c: In function <E2><80><98>EmacSetupRxdesc<E2><80><99>:
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:270:81: error: iteration 9 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
> RxDescriptor->AddrNext = (UINT32)(UINTN)EmacDriver->RxdescRingMap[Index + 1].AddrMap;
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c:267:3: note: within this loop
> for (Index = 0; Index < CONFIG_RX_DESCR_NUM; Index++) {
> ^~~
> cc1: all warnings being treated as errors
>
>
> It also throws the following errors when building for ARM:
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c: In function <E2><80><98>SnpTransmit<E2><80><99>:
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:962:21: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
> TxDescriptorMap = (VOID *)Snp->MacDriver.TxdescRingMap[DescNum].AddrMap;
> ^
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:1026:51: error: cast from pointer to integer of different size [-Werror=pointer-to-int-cast]
> Snp->RecycledTxBuf[Snp->RecycledTxBufCount] = (UINT64) Data;
> ^
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c: In function <E2><80><98>SnpReceive<E2><80><99>:
> /work/git/edk2-platforms/Silicon/Synopsys/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c:1143:21: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
> RxDescriptorMap = (VOID *)Snp->MacDriver.RxdescRingMap[DescNum].AddrMap;
> ^
> cc1: all warnings being treated as errors
>
>
> Could you please look into and address these issues for the next version?
>
> Best Regards,
>
> Leif
>
> On Mon, Jul 08, 2019 at 03:05:07PM +0800, tzy.way.ooi@intel.com wrote:
> > From: Ooi Tzy Way <tzy.way.ooi@intel.com>
> >
> > Add driver support for the Ethernet MAC based on Synopsys DesignWare
> > 3504-0 Universal 10/100/1000 Ethernet MAC and KSZ9031 PHY
> >
> > Cc: Ard BieSheuvel <ard.biesheuvel@linaro.org>
> > Cc: Leif Lindholm <leif.lindholm@linaro.org>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Loh Tien Hock <tien.hock.loh@intel.com>
> >
> > Contributed-under: Tianocore Contribution Agreement 1.1
> > Signed-off-by: Ooi Tzy Way <tzy.way.ooi@intel.com>
> >
> > ---
> > v6:
> > - Update to recent version for EDK2 specific file formats
> > - Update the directory layout to Silicon/Synopsys/DesignWare
> > - Add a DesignWare.dsc for building this driver
> > - Update the license
> > - Update the .c file to declare its own include file
> > - Remove __ in defining the header file
> > - Fix indentation
> > - Delete commented-out code
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
2019-07-17 9:25 ` Ooi, Tzy Way
@ 2019-07-17 11:44 ` Leif Lindholm
2019-07-19 6:41 ` Ooi, Tzy Way
0 siblings, 1 reply; 7+ messages in thread
From: Leif Lindholm @ 2019-07-17 11:44 UTC (permalink / raw)
To: Ooi, Tzy Way
Cc: devel@edk2.groups.io, Ard BieSheuvel, Kinney, Michael D,
Loh, Tien Hock
Hi Tzy Way,
On Wed, Jul 17, 2019 at 09:25:49AM +0000, Ooi, Tzy Way wrote:
> Ya. I am on Linux. I managed to replicated the warning that you have
> provided in the previous email thread by using the gcc 8.3.
Excellent.
> Currently, I'm looking at the compiler warning/error. While I am
> fixing the issue when compiling the source code, I encountered
> another issue where the compiler complain "undefined reference to
> __stack_chk_fail". I check from google and it can be solved by
> setting -fnostack-protector. Hence, I would like to ask if is it ok
> to set this to the CFLAGs for the compiler?
We don't need that workaround - since we have a proper way of handling
it in MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
Adding a NULL resolution to the appropriate [LibraryClasses] section
in the .dsc should resolve this for you.
See (for example) edk2/EmbeddedPkg/EmbeddedPkg.dsc for guidance.
Best Regards,
Leif
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
2019-07-17 11:44 ` Leif Lindholm
@ 2019-07-19 6:41 ` Ooi, Tzy Way
0 siblings, 0 replies; 7+ messages in thread
From: Ooi, Tzy Way @ 2019-07-19 6:41 UTC (permalink / raw)
To: Leif Lindholm
Cc: devel@edk2.groups.io, Ard BieSheuvel, Kinney, Michael D,
Loh, Tien Hock
Hi Leif,
Thank you very much. The solution provided help to resolve the issue.
Best regards,
Tzy Way
-----Original Message-----
From: Leif Lindholm <leif.lindholm@linaro.org>
Sent: Wednesday, July 17, 2019 7:44 PM
To: Ooi, Tzy Way <tzy.way.ooi@intel.com>
Cc: devel@edk2.groups.io; Ard BieSheuvel <ard.biesheuvel@linaro.org>; Kinney, Michael D <michael.d.kinney@intel.com>; Loh, Tien Hock <tien.hock.loh@intel.com>
Subject: Re: [edk2-devel] [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver
Hi Tzy Way,
On Wed, Jul 17, 2019 at 09:25:49AM +0000, Ooi, Tzy Way wrote:
> Ya. I am on Linux. I managed to replicated the warning that you have
> provided in the previous email thread by using the gcc 8.3.
Excellent.
> Currently, I'm looking at the compiler warning/error. While I am
> fixing the issue when compiling the source code, I encountered another
> issue where the compiler complain "undefined reference to
> __stack_chk_fail". I check from google and it can be solved by setting
> -fnostack-protector. Hence, I would like to ask if is it ok to set
> this to the CFLAGs for the compiler?
We don't need that workaround - since we have a proper way of handling it in MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
Adding a NULL resolution to the appropriate [LibraryClasses] section in the .dsc should resolve this for you.
See (for example) edk2/EmbeddedPkg/EmbeddedPkg.dsc for guidance.
Best Regards,
Leif
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2019-07-19 6:41 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-07-08 7:05 [PATCH v6 edk2-platforms 1/1] Silicon/Synopsys/Designware/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver Ooi, Tzy Way
2019-07-11 16:43 ` Leif Lindholm
2019-07-16 9:37 ` [edk2-devel] " Ooi, Tzy Way
2019-07-16 17:22 ` Leif Lindholm
2019-07-17 9:25 ` Ooi, Tzy Way
2019-07-17 11:44 ` Leif Lindholm
2019-07-19 6:41 ` Ooi, Tzy Way
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox