From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=V4G8A7T4; spf=pass (domain: linaro.org, ip: 209.85.166.195, mailfrom: ard.biesheuvel@linaro.org) Received: from mail-it1-f195.google.com (mail-it1-f195.google.com [209.85.166.195]) by groups.io with SMTP; Thu, 16 May 2019 12:37:24 -0700 Received: by mail-it1-f195.google.com with SMTP id q65so8118692itg.2 for ; Thu, 16 May 2019 12:37:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=i4+qOnVonA0wU/OQp1pZMjm5kW28Ej8LBCu2kYamwgU=; b=V4G8A7T4sarKBto1+EmUqwmy25G9FAeeyFXHanoDp/A1IuAgGey3mhzJGIcDOxGQ9b /0CkMg9+JLwCdfrxiCTeo7RdkuMOYT3TJ1gndu+LkIkYqUWpyQjmfHQ90+GqmrZMvgru 2TT7X8LmUs5VCwbslyKGD+9CWOSJ8pAjloVTmXuuN9D1+1ce8I+7zeR+IXpQvhLUWbkR W2uw3/zNX4s/po1HNmeWFKoVkwsdLiSKHZ76FD5kGcPqHMMt9mWC3wQe7lk0Ul14XunH 9ynIKGtbgHSuy48420DmC8i7So5hu7JbceFsMyGEExslrrL0t9x37vRb0yeSEd61kS9D Sa5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=i4+qOnVonA0wU/OQp1pZMjm5kW28Ej8LBCu2kYamwgU=; b=bBkiZR7bi7czwXgM08pzyRPJw4eNEyOut5WjhVUcFT9UfOLeIi1AWCeMnc5tdthO7f fr/2CtoCENrp+JpzUawCNNPgfebleHtOG+27Wsqf6G74eZnBqq6BnA7TtGlr5IC5U4As y1mJ0lxBm9/rs9VHEo1utdE2JsDQo4yLhthTQQNzge7Ram90G4WkspWFsOj97JgnAhJw vYvkglm3QOel/krmNTarat9bN2iGmhFWq+zaklB318s3SlCbNCziYe4isT9clpSr7B0n u0aj1J/VlvqfSYgbh6IpZoM9n6uVFxSh4QptxyU1dBKLFsWZto/8waYwCPJ269ScGFGb nJ6g== X-Gm-Message-State: APjAAAVkvBdJA/NGqBQGnVqfsBf2xUaN/2MzD9qtjd8JeBqqMultyuLT cPfVdklvamcPlxXA07YsKbZqhCs6o8SD7e8ToaGkXg== X-Google-Smtp-Source: APXvYqwXZLEVrnJJ3WqK897wZp97UmKP5o0fobC3KhA6XDkGFwi1a5Tw0qmtSoEkuKmNxEJVjNwDNkoJ0Kuk/8X+3aA= X-Received: by 2002:a05:660c:4c2:: with SMTP id v2mr14970181itk.71.1558035442500; Thu, 16 May 2019 12:37:22 -0700 (PDT) MIME-Version: 1.0 References: <20190508092200.2805-1-tzy.way.ooi@intel.com> In-Reply-To: <20190508092200.2805-1-tzy.way.ooi@intel.com> From: "Ard Biesheuvel" Date: Thu, 16 May 2019 21:37:07 +0200 Message-ID: Subject: Re: [PATCH v4 edk2-platforms 1/1] Silicon/DesignWare/Driver: DwEmacSnpDxe: Add DesignWare EMAC driver To: tzy.way.ooi@intel.com Cc: edk2-devel-groups-io , Leif Lindholm , Michael D Kinney , Loh Tien Hock Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, 8 May 2019 at 11:22, wrote: > > From: Ooi Tzy Way > > Add driver support for the Ethernet MAC based on Synopsys DesignWare > 3504-0 Universal 10/100/1000 Ethernet MAC and KSZ9031 PHY > Are these discrete components? If so, I wonder whether we should use some kind of abstraction for the PHY operations. > Cc: Ard BieSheuvel > Cc: Leif Lindholm > Cc: Michael D Kinney > Cc: Loh Tien Hock Please use spaces before < > > Contributed-under: Tianocore Contribution Agreement 1.1 > Signed-off-by: Ooi Tzy Way > > --- > v4: > - Describe the device with non-discoverable device protocol > - Expose the MMIO base address in the EFI ACPI address space descriptor > - Remove cache maintainence and use DmaLib for non-coherent DMA access > --- > Silicon/DesignWare/DesignWare.dec | 34 + > Silicon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.inf | 82 ++ > Silicon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.h | 229 ++++ > Silicon/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.h | 392 ++++++ > Silicon/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.h | 341 ++++++ > Silicon/DesignWare/Drivers/DwEmacSnpDxe/ComponentName.c | 327 +++++ > Silicon/DesignWare/Drivers/DwEmacSnpDxe/DriverBinding.c | 450 +++++++ > Silicon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c | 1273 ++++++++= ++++++++++++ > Silicon/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c | 684 ++++++++= +++ > Silicon/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.c | 621 ++++++++= ++ > 10 files changed, 4433 insertions(+) > > diff --git a/Silicon/DesignWare/DesignWare.dec b/Silicon/DesignWare/Desig= nWare.dec > new file mode 100755 > index 000000000000..bad81fb6a023 > --- /dev/null > +++ b/Silicon/DesignWare/DesignWare.dec > @@ -0,0 +1,34 @@ > + #Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved. > + #This program and the accompanying materials > + #are licensed and made available under the terms and conditions of the= BSD License > + #which accompanies this distribution. The full text of the license ma= y be found at > + #http://opensource.org/licenses/bsd-license.php > + #THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + #WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR = IMPLIED. > + > +[Defines] > + DEC_SPECIFICATION =3D 0x00010005 Please use the most recent version for EDK2 specific file formats (Note tha= t you can use, e.g., 1.27 instead of 0x0001001B) > + PACKAGE_NAME =3D DesignWarePkg > + PACKAGE_GUID =3D 3b5936d8-c72d-412d-b4d9-3bf0dea7359= 8 > + PACKAGE_VERSION =3D 0.1 > + > +########################################################################= ######## > +# > +# Include Section - list of Include Paths that are provided by this pack= age. > +# 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 =3D { 0x89cb1241, 0xd283, 0x4543, { 0x88, 0x= 9c, 0x6b, 0x62, 0x36, 0x1a, 0x95, 0x7a } } > + gDwEmacNetNonDiscoverableDeviceGuid =3D { 0x401950CD, 0xF9CD, 0x4A65, = { 0xAD, 0x8E, 0x84, 0x9F, 0x3B, 0xAF, 0x23, 0x04 } } > + > + > +[PcdsFixedAtBuild.common] > + gDesignWareTokenSpaceGuid.PcdDwEmacDefaultMacAddress|0|UINT64|0x300000= 50 > + gDesignWareTokenSpaceGuid.PcdDwEmacDxeBaseAddress|0|UINT32|0x30000051 > + The base address should not be specified via a PCD. This is what I was tryi= ng to explain when I told you to use the driver model: it is the *platform* th= at instantiates the non-discoverable device protocol, and this driver only bin= ds to it using the driver model. The protocol should not be instantiated by th= is driver. > + > diff --git a/Silicon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.inf b/S= ilicon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.inf > new file mode 100755 > index 000000000000..09e7f1e77f69 > --- /dev/null > +++ b/Silicon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.inf > @@ -0,0 +1,82 @@ > +#/** @file > +# DW Emac Simple Networking Protocol Driver (SNP) DXE Driver > +# > +# Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved. > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the= BSD License > +# which accompanies this distribution. The full text of the license ma= y be found at > +# http://opensource.org/licenses/bsd-license.php > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR = IMPLIED. > +# > +# The original software modules are licensed as follows: > +# > +# Copyright (c) 2012-2014, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the= BSD License > +# which accompanies this distribution. The full text of the license ma= y be found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR = IMPLIED. > +# > +#**/ > +[Defines] > + INF_VERSION =3D 0x00010005 Please use the latest version of the INF spec > + BASE_NAME =3D DwEmacSnpDxe > + FILE_GUID =3D 06f3315f-9fe6-4938-b83f-2c072af802b= a > + MODULE_TYPE =3D DXE_DRIVER This should be a UEFI driver not a DXE driver. > + VERSION_STRING =3D 0.1 > + ENTRY_POINT =3D DwEmacSnpDxeEntry > + > +[Sources.common] > + ComponentName.c > + DriverBinding.c > + DwEmacSnpDxe.c > + EmacDxeUtil.c > + PhyDxeUtil.c > + DwEmacSnpDxe.h > + EmacDxeUtil.h > + PhyDxeUtil.h > + > +[Packages] > + ArmPkg/ArmPkg.dec Why do you need ArmPkg? > + EmbeddedPkg/EmbeddedPkg.dec > + NetworkPkg/NetworkPkg.dec > + MdeModulePkg/MdeModulePkg.dec > + MdePkg/MdePkg.dec > + Silicon/DesignWare/DesignWare.dec > + > +[LibraryClasses] > + BaseLib > + UefiLib > + NetLib > + UefiDriverEntryPoint > + BaseMemoryLib > + ArmLib Why do you need ArmLib? > + IoLib > + TimerLib > + DevicePathLib > + DebugLib > + PrintLib > + NonDiscoverableDeviceRegistrationLib > + DmaLib > + > +[Protocols] > + gEfiSimpleNetworkProtocolGuid > + gEfiMetronomeArchProtocolGuid > + gEfiPxeBaseCodeProtocolGuid > + gEfiDevicePathProtocolGuid > + gEfiDriverBindingProtocolGuid > + gEdkiiNonDiscoverableDeviceProtocolGuid > + > +[Guids] > + gDwEmacNetNonDiscoverableDeviceGuid > + > +[Pcd] > + gDesignWareTokenSpaceGuid.PcdDwEmacDefaultMacAddress > + gDesignWareTokenSpaceGuid.PcdDwEmacDxeBaseAddress > + > +[Depex] > + TRUE You can drop this for a UEFI driver. > diff --git a/Silicon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.h b/Sil= icon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.h > new file mode 100755 > index 000000000000..677fdad8bd5d > --- /dev/null > +++ b/Silicon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.h > @@ -0,0 +1,229 @@ > +/** @file > + > + Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > + > + The original software modules are licensed as follows: > + > + Copyright (c) 2012-2014, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD 3 Clause LICENSE ON AN "AS IS= " BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > +**/ > + > + > +#ifndef __DWEMAC_SNP_DXE_H__ > +#define __DWEMAC_SNP_DXE_H__ > + > +#include > +#include > +#include Do you really need all of the above? > + > +// Protocols used by this driver > +#include > +#include > +#include > +#include > +#include > + > +// Libraries used by this driver > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include Why do you need ArmLib.h? > +#include > +#include > + > +#include "PhyDxeUtil.h" > +#include "EmacDxeUtil.h" > + > +/*----------------------------------------------------------------------= -------- > + Information Structure > +------------------------------------------------------------------------= ------*/ > + > +typedef struct { > + MAC_ADDR_DEVICE_PATH MacAddrDP; > + EFI_DEVICE_PATH_PROTOCOL End; > +} EFI_SIMPLE_NETWORK_DEVICE_PATH; Don't use a EFI_ prefix for driver local data structures. > + > +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; > + > + // 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 DmaUnmap > + VOID *MappingTxdesc; > + VOID *MappingRxdesc; > + VOID *MappingTxbuf; > + VOID *MappingRxbuf; > + Please clean up the indentation of the member names: use the same level for= all. > +} EFI_SIMPLE_NETWORK_DRIVER; > + Don't use a EFI_ prefix for driver local data structures. > +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, EFI_SIMPLE_NETWORK= _DRIVER, Snp, SNP_DRIVER_SIGNATURE) > +#define SNP_TX_BUFFER_INCREASEMENT 32 INCREASE not INCREASEMENT > +#define SNP_MAX_TX_BUFFER_NUM 65536 > + > +/*----------------------------------------------------------------------= ----------------------------------------------- > + > + UEFI-Compliant functions for EFI_SIMPLE_NETWORK_PROTOCOL > + > + Refer to the Simple Network Protocol section (21.1) in the UEFI 2.3.1 = 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/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.h b/Sili= con/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.h > new file mode 100755 > index 000000000000..872923252e73 > --- /dev/null > +++ b/Silicon/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.h > @@ -0,0 +1,392 @@ > +/** @file > + > + Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > + > + 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. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD 3 Clause LICENSE ON AN "AS IS= " BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > +**/ > + > + > +#ifndef __EMAC_DXE_UTIL_H__ > +#define __EMAC_DXE_UTIL_H__ > + > +#include Why do you need this? > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include Why? > + > +// Protocols used by this driver > +#include > +#include > +#include > +#include > + > + > +// 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) >> 2= 3) > +#define DW_EMAC_GMACGRP_GMII_ADDRESS_GB_GET(value) (((value) & 0x0000000= 1) >> 0) > +#define DW_EMAC_GMACGRP_GMII_DATA_GD_GET(value) (((value) & 0x0000ffff) = >> 0) > +#define DW_EMAC_DMAGRP_OPERATION_MODE_FTF_GET(value) (((value) & 0x00100= 000) >> 20) > + > +// DW emac registers offset > +//#define DWEMAC_OFST = ((UINT32)PcdGet32 (P= cdDwEmacDxeBaseAddress)) > +#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 0= x0d8 > +#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 { > + 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]; > + EFI_PHYSICAL_ADDRESS TxdescRingMap[CONFIG_TX_DESCR_NUM]; > + EFI_PHYSICAL_ADDRESS RxdescRingMap[CONFIG_RX_DESCR_NUM]; > + EFI_PHYSICAL_ADDRESS TxBufferMap[TX_TOTAL_BUFSIZE]; > + EFI_PHYSICAL_ADDRESS RxBufferMap[RX_TOTAL_BUFSIZE]; > + UINT32 TxCurrentDescriptorNum; > + UINT32 TxNextDescriptorNum; > + UINT32 RxCurrentDescriptorNum; > + UINT32 RxNextDescriptorNum; > +} EMAC_DRIVER; > + > +VOID > +EFIAPI > +EmacChooseInterface ( > + IN UINT32 MacInterface > + ); > + > +VOID > +EFIAPI > +EmacSetMacAddress ( > + IN EFI_MAC_ADDRESS *MacAddress, > + IN UINT32 MacBaseAddress > + ); > + > +VOID > +EFIAPI > +EmacReadMacAddress ( > + OUT EFI_MAC_ADDRESS *MacAddress, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +EmacDxeInitialization ( > + IN EMAC_DRIVER *EmacDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +EmacDmaInit ( > + IN EMAC_DRIVER *EmacDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +EmacSetupTxdesc ( > + IN EMAC_DRIVER *EmacDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +EmacSetupRxdesc ( > + IN EMAC_DRIVER *EmacDriver, > + IN UINT32 MacBaseAddress > + ); > + > +VOID > +EFIAPI > +EmacStartTransmission ( > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +EmacRxFilters ( > + IN UINT32 ReceiveFilterSetting, > + IN BOOLEAN Reset, > + IN UINTN NumMfilter OPTIONAL, > + IN EFI_MAC_ADDRESS *Mfilter OPTIONAL, > + IN UINT32 MacBaseAddress > + ); > + > +UINT32 > +EFIAPI > +GenEtherCrc32 ( > + IN EFI_MAC_ADDRESS *Mac, > + IN UINT32 AddrLen > + ); > + > +UINT8 > +EFIAPI > +BitReverse ( > + UINT8 X > + ); > + > +VOID > +EFIAPI > +EmacStopTxRx ( > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +EmacDmaStart ( > + IN UINT32 MacBaseAddress > + ); > + > +VOID > +EFIAPI > +EmacGetDmaStatus ( > + OUT UINT32 *IrqStat OPTIONAL, > + IN UINT32 MacBaseAddress > + ); > + > +VOID > +EFIAPI > +EmacGetStatistic ( > + IN EFI_NETWORK_STATISTICS* Stats, > + IN UINT32 MacBaseAddress > + ); > + > +VOID > +EFIAPI > +EmacConfigAdjust ( > + IN UINT32 Speed, > + IN UINT32 Duplex, > + IN UINT32 MacBaseAddress > + ); > + > +#endif // __EMAC_DXE_UTIL_H__ > diff --git a/Silicon/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.h b/Silic= on/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.h > new file mode 100755 > index 000000000000..6fff3d61688a > --- /dev/null > +++ b/Silicon/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.h > @@ -0,0 +1,341 @@ > +/** @file > + > + Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > + > + 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. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD 3 Clause LICENSE ON AN "AS IS= " BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > +**/ > + > + > +#ifndef __PHY_DXE_H__ > +#define __PHY_DXE_H__ > + > +#include Why? > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + In general, please only include headers that your code actually uses. > +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 Please fix the indentation > + > +// 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 > + Please align indented part with the code below. In fact, could you please clean up the indentation in general? > +// PHY status register bits > +#define PHYSTS_EXT_CAP BIT0 // E= xtended Capabilities Register capability > +#define PHYSTS_JABBER BIT1 // J= abber condition detected > +#define PHYSTS_LINK_STS BIT2 // L= ink Status > +#define PHYSTS_AUTO_CAP BIT3 // A= uto-Negotiation Capability > +#define PHYSTS_REMOTE_FAULT BIT4 // R= emote fault detected > +#define PHYSTS_AUTO_COMP BIT5 // A= uto-Negotiation Completed > +#define PHYSTS_10BASET_HDPLX BIT11 // 1= 0Mbps Half-Duplex ability > +#define PHYSTS_10BASET_FDPLX BIT12 // 1= 0Mbps Full-Duplex ability > +#define PHYSTS_100BASETX_HDPLX BIT13 // 1= 00Mbps Half-Duplex ability > +#define PHYSTS_100BASETX_FDPLX BIT14 // 1= 00Mbps Full-Duplex ability > +#define PHYSTS_100BASE_T4 BIT15 // B= ase T4 ability > + > +// PHY Auto-Negotiation advertisement > +#define PHYANA_SEL_MASK ((UINT32)0x1F) // L= ink type selector > +#define PHYANA_10BASET BIT5 // A= dvertise 10BASET capability > +#define PHYANA_10BASETFD BIT6 // A= dvertise 10BASET Full duplex capability > +#define PHYANA_100BASETX BIT7 // A= dvertise 100BASETX capability > +#define PHYANA_100BASETXFD BIT8 // A= dvertise 100 BASETX Full duplex capability > +#define PHYANA_PAUSE_OP_MASK (3 << 10) // A= dvertise PAUSE frame capability > +#define PHYANA_REMOTE_FAULT BIT13 // R= emote fault detected > + > +#define PHYLPA_SLCT 0x001f // Same a= s 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 1000BAS= E-X pause asym > +#define PHYLPA_100BASE4 0x0200 /= / Can do 100mbps 4k packets > +#define PHYLPA_PAUSE_CAP 0x0400 // Can pa= use > +#define PHYLPA_PAUSE_ASYM 0x0800 // Can pa= use asymetrically > +#define PHYLPA_RESV 0x1000 // Unused > +#define PHYLPA_RFAULT 0x2000 // Link p= artner faulted > +#define PHYLPA_LPACK 0x4000 // Link p= artner acked us > +#define PHYLPA_NPAGE 0x8000 // Next p= age bit > + > +#define PHYLPA_DUPLEX (LPA_10FULL | LPA_100FUL= L) > +#define PHYLPA_100 (LPA_100FULL | L= PA_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 1000BA= SE-T full duplex */ > +#define PHYADVERTISE_1000HALF 0x0100 /* Advertise 1000BA= SE-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) // Sp= eed indication > +#define PHYSSCS_AUTODONE BIT12 // A= uto-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 > + Please also clean up the indentation of the function parameters below. > + > +EFI_STATUS > +EFIAPI > +PhyDxeInitialization ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +PhyDetectDevice ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +PhyConfig ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +PhySoftReset ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +PhyReadId ( > + IN UINT32 PhyAddr, > + IN UINT32 MacBaseAddress > + ); > + > +VOID > +EFIAPI > +PhyConfigSkew ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +VOID > +EFIAPI > +PhyDisplayConfigSkew ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +VOID > +EFIAPI > +PhyConfigFlpBurstTiming ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +VOID > +EFIAPI > +PhyDisplayFlpBurstTiming ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +PhyAutoNego ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +PhyLinkAdjustEmacConfig ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +PhyCheckLinkStatus ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +PhyReadCapability ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32* Speed, > + IN UINT32* Duplex, > + IN UINT32 MacBaseAddress > + ); > + > +VOID > +EFIAPI > +PhyDisplayAbility ( > + IN UINT32 Speed, > + IN UINT32 Duplex > + ); > + > +EFI_STATUS > +EFIAPI > +PhyRead ( > + IN UINT32 Addr, > + IN UINT32 Reg, > + OUT UINT32 *Data, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +PhyWrite ( > + IN UINT32 Addr, > + IN UINT32 Reg, > + IN UINT32 Data, > + IN UINT32 MacBaseAddress > + ); > + > +EFI_STATUS > +EFIAPI > +Phy9031ExtendedWrite ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 Mode, > + IN UINT32 DevAddr, > + IN UINT32 Regnum, > + IN UINT16 Val, > + IN UINT32 MacBaseAddress > + ); > + > +UINT32 > +EFIAPI > +Phy9031ExtendedRead ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 Mode, > + IN UINT32 DevAddr, > + IN UINT32 Regnum, > + IN UINT32 MacBaseAddress > + ); > + > + > +#endif /* __PHY_DXE_H__ */ > diff --git a/Silicon/DesignWare/Drivers/DwEmacSnpDxe/ComponentName.c b/Si= licon/DesignWare/Drivers/DwEmacSnpDxe/ComponentName.c > new file mode 100755 > index 000000000000..08e91fae396e > --- /dev/null > +++ b/Silicon/DesignWare/Drivers/DwEmacSnpDxe/ComponentName.c > @@ -0,0 +1,327 @@ > +/** @file > +Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > + > + The original software modules are licensed as follows: > + > + Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.
> + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > + > +Module Name: > + > + ComponentName.c > + > +Abstract: > + > + > +**/ > + > +#include "DwEmacSnpDxe.h" > + > +// > +// EFI Component Name Functions > +// > +/** > + Retrieves a Unicode string that is the user readable name of the drive= r. > + > + This function retrieves the user readable name of a driver in the form= of a > + Unicode string. If the driver specified by This has a user readable na= me in > + the language specified by Language, then a pointer to the driver name = is > + returned in DriverName, and EFI_SUCCESS is returned. If the driver spe= cified > + by This does not support the language specified by Language, > + then EFI_UNSUPPORTED is returned. > + > + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PRO= TOCOL or > + EFI_COMPONENT_NAME_PROTOCOL instance. > + > + @param Language[in] A pointer to a Null-terminated ASCII str= ing > + array indicating the language. This is t= he > + language of the driver name that the cal= ler is > + requesting, and it must match one of the > + languages specified in SupportedLanguage= s. The > + number of languages supported by a drive= r is up > + to the driver writer. Language is specif= ied > + in RFC 4646 or ISO 639-2 language code f= ormat. > + > + @param DriverName[out] A pointer to the Unicode string to retur= n. > + This Unicode string is the name of the > + driver specified by This in the language > + specified by Language. > + > + @retval EFI_SUCCESS The Unicode string for the Driver specif= ied by > + This and the language specified by Langu= age was > + returned in DriverName. > + > + @retval EFI_INVALID_PARAMETER Language is NULL. > + > + @retval EFI_INVALID_PARAMETER DriverName is NULL. > + > + @retval EFI_UNSUPPORTED The driver specified by This does not su= pport > + the language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +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 contr= oller > + that is being managed by a driver. > + > + This function retrieves the user readable name of the controller speci= fied by > + ControllerHandle and ChildHandle in the form of a Unicode string. If t= he > + driver specified by This has a user readable name in the language spec= ified by > + Language, then a pointer to the controller name is returned in Control= lerName, > + and EFI_SUCCESS is returned. If the driver specified by This is not c= urrently > + managing the controller specified by ControllerHandle and ChildHandle, > + then EFI_UNSUPPORTED is returned. If the driver specified by This doe= s not > + support the language specified by Language, then EFI_UNSUPPORTED is re= turned. > + > + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PRO= TOCOL or > + EFI_COMPONENT_NAME_PROTOCOL instance. > + > + @param ControllerHandle[in] The handle of a controller that the driv= er > + specified by This is managing. This han= dle > + specifies the controller whose name is t= o be > + returned. > + > + @param ChildHandle[in] The handle of the child controller to re= trieve > + the name of. This is an optional parame= ter that > + may be NULL. It will be NULL for device > + drivers. It will also be NULL for a bus= drivers > + that wish to retrieve the name of the bu= s > + controller. It will not be NULL for a b= us > + driver that wishes to retrieve the name = of a > + child controller. > + > + @param Language[in] A pointer to a Null-terminated ASCII str= ing > + array indicating the language. This is = the > + language of the driver name that the cal= ler is > + requesting, and it must match one of the > + languages specified in SupportedLanguage= s. The > + number of languages supported by a drive= r is up > + to the driver writer. Language is specif= ied in > + RFC 4646 or ISO 639-2 language code form= at. > + > + @param ControllerName[out] A pointer to the Unicode string to retur= n. > + This Unicode string is the name of the > + controller specified by ControllerHandle= and > + ChildHandle in the language specified by > + Language from the point of view of the d= river > + specified by This. > + > + @retval EFI_SUCCESS The Unicode string for the user readable= name in > + the language specified by Language for t= he > + driver specified by This was returned in > + DriverName. > + > + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HAND= LE. > + > + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a = valid > + EFI_HANDLE. > + > + @retval EFI_INVALID_PARAMETER Language is NULL. > + > + @retval EFI_INVALID_PARAMETER ControllerName is NULL. > + > + @retval EFI_UNSUPPORTED The driver specified by This is not curr= ently > + managing the controller specified by > + ControllerHandle and ChildHandle. > + > + @retval EFI_UNSUPPORTED The driver specified by This does not su= pport > + the language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +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 gSnpComponent= Name =3D { > + SnpGetDriverName, > + SnpGetControllerName, > + "eng" > +}; > + > +// > +// EFI Component Name 2 Protocol > +// > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gSnpComponent= Name2 =3D { > + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) SnpGetDriverName, > + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) SnpGetControllerName, > + "en" > +}; > + > + > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mSnpNameTable[] = =3D { > + { > + "eng;en", > + L"SNP DesignWare EMAC Driver" > + }, > + { > + NULL, > + NULL > + } > +}; > + > +/** > + Retrieves a Unicode string that is the user readable name of the drive= r. > + > + This function retrieves the user readable name of a driver in the form= of a > + Unicode string. If the driver specified by This has a user readable na= me in > + the language specified by Language, then a pointer to the driver name = is > + returned in DriverName, and EFI_SUCCESS is returned. If the driver spe= cified > + by This does not support the language specified by Language, > + then EFI_UNSUPPORTED is returned. > + > + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PRO= TOCOL or > + EFI_COMPONENT_NAME_PROTOCOL instance. > + > + @param Language[in] A pointer to a Null-terminated ASCII str= ing > + array indicating the language. This is t= he > + language of the driver name that the cal= ler is > + requesting, and it must match one of the > + languages specified in SupportedLanguage= s. The > + number of languages supported by a drive= r is up > + to the driver writer. Language is specif= ied > + in RFC 4646 or ISO 639-2 language code f= ormat. > + > + @param DriverName[out] A pointer to the Unicode string to retur= n. > + This Unicode string is the name of the > + driver specified by This in the language > + specified by Language. > + > + @retval EFI_SUCCESS The Unicode string for the Driver specif= ied by > + This and the language specified by Langu= age was > + returned in DriverName. > + > + @retval EFI_INVALID_PARAMETER Language is NULL. > + > + @retval EFI_INVALID_PARAMETER DriverName is NULL. > + > + @retval EFI_UNSUPPORTED The driver specified by This does not su= pport > + the language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +SnpGetDriverName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN CHAR8 *Language, > + OUT CHAR16 **DriverName > + ) > +{ > + return LookupUnicodeString2 ( > + Language, > + This->SupportedLanguages, > + mSnpNameTable, > + DriverName, > + (BOOLEAN)(This =3D=3D &gSnpComponentName) > + ); > +} > + > +/** > + Retrieves a Unicode string that is the user readable name of the contr= oller > + that is being managed by a driver. > + > + This function retrieves the user readable name of the controller speci= fied by > + ControllerHandle and ChildHandle in the form of a Unicode string. If t= he > + driver specified by This has a user readable name in the language spec= ified by > + Language, then a pointer to the controller name is returned in Control= lerName, > + and EFI_SUCCESS is returned. If the driver specified by This is not c= urrently > + managing the controller specified by ControllerHandle and ChildHandle, > + then EFI_UNSUPPORTED is returned. If the driver specified by This doe= s not > + support the language specified by Language, then EFI_UNSUPPORTED is re= turned. > + > + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PRO= TOCOL or > + EFI_COMPONENT_NAME_PROTOCOL instance. > + > + @param ControllerHandle[in] The handle of a controller that the driv= er > + specified by This is managing. This han= dle > + specifies the controller whose name is t= o be > + returned. > + > + @param ChildHandle[in] The handle of the child controller to re= trieve > + the name of. This is an optional parame= ter that > + may be NULL. It will be NULL for device > + drivers. It will also be NULL for a bus= drivers > + that wish to retrieve the name of the bu= s > + controller. It will not be NULL for a b= us > + driver that wishes to retrieve the name = of a > + child controller. > + > + @param Language[in] A pointer to a Null-terminated ASCII str= ing > + array indicating the language. This is = the > + language of the driver name that the cal= ler is > + requesting, and it must match one of the > + languages specified in SupportedLanguage= s. The > + number of languages supported by a drive= r is up > + to the driver writer. Language is specif= ied in > + RFC 4646 or ISO 639-2 language code form= at. > + > + @param ControllerName[out] A pointer to the Unicode string to retur= n. > + This Unicode string is the name of the > + controller specified by ControllerHandle= and > + ChildHandle in the language specified by > + Language from the point of view of the d= river > + specified by This. > + > + @retval EFI_SUCCESS The Unicode string for the user readable= name in > + the language specified by Language for t= he > + driver specified by This was returned in > + DriverName. > + > + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HAND= LE. > + > + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a = valid > + EFI_HANDLE. > + > + @retval EFI_INVALID_PARAMETER Language is NULL. > + > + @retval EFI_INVALID_PARAMETER ControllerName is NULL. > + > + @retval EFI_UNSUPPORTED The driver specified by This is not curr= ently > + managing the controller specified by > + ControllerHandle and ChildHandle. > + > + @retval EFI_UNSUPPORTED The driver specified by This does not su= pport > + the language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +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/DesignWare/Drivers/DwEmacSnpDxe/DriverBinding.c b/Si= licon/DesignWare/Drivers/DwEmacSnpDxe/DriverBinding.c > new file mode 100755 > index 000000000000..2b750c03d432 > --- /dev/null > +++ b/Silicon/DesignWare/Drivers/DwEmacSnpDxe/DriverBinding.c > @@ -0,0 +1,450 @@ > +/** @file > + > + Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > + **/ > + > +#include "DwEmacSnpDxe.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 =3D { > + DriverSupported, > + DriverStart, > + DriverStop, > + 0xa, > + NULL, > + NULL > +}; > + > +EFI_SIMPLE_NETWORK_DEVICE_PATH PathTemplate =3D { Can this be STATIC? > + { > + { > + MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, > + { (UINT8) (sizeof(MAC_ADDR_DEVICE_PATH)), (UINT8) ((sizeof(MAC_ADD= R_DEVICE_PATH)) >> 8) } > + }, > + { { 0 } }, > + 0 > + }, > + { > + END_DEVICE_PATH_TYPE, > + END_ENTIRE_DEVICE_PATH_SUBTYPE, > + { sizeof(EFI_DEVICE_PATH_PROTOCOL), 0 } > + } > +}; > + > +STATIC EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR mDwEmacNetDesc[] =3D { > + { > + ACPI_ADDRESS_SPACE_DESCRIPTOR, // Desc > + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3, // Len > + ACPI_ADDRESS_SPACE_TYPE_MEM, // ResType > + 0, // GenFlag > + 0, // SpecificFlag > + 32, // AddrSpaceGranul= arity > + FixedPcdGet32 (PcdDwEmacDxeBaseAddress), // AddrRangeMin > + FixedPcdGet32 (PcdDwEmacDxeBaseAddress) + > + SIZE_4KB - 1, // AddrRangeMax > + 0, // AddrTranslation= Offset > + SIZE_4KB, // AddrLen > + }, { > + ACPI_ADDRESS_SPACE_DESCRIPTOR, // Desc > + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3, // Len > + ACPI_ADDRESS_SPACE_TYPE_MEM, // ResType > + 0, // GenFlag > + 0, // SpecificFlag > + 32, // AddrSpaceGranul= arity > + FixedPcdGet32 (PcdDwEmacDefaultMacAddress), // AddrRangeMin > + FixedPcdGet32 (PcdDwEmacDefaultMacAddress), // AddrRangeMax > + 0, // AddrTranslation= Offset > + 1, // AddrLen > + }, { > + ACPI_END_TAG_DESCRIPTOR // Desc > + } > +}; This address space descriptor should be created by the platform, not by thi= s driver. > + > +STATIC > +EFI_STATUS > +RegisterDevice ( > + IN EFI_GUID *TypeGuid, > + IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc, > + OUT EFI_HANDLE *Handle > + ) > +{ > + NON_DISCOVERABLE_DEVICE *Device; > + EFI_STATUS Status; > + > + Device =3D (NON_DISCOVERABLE_DEVICE *)AllocateZeroPool (sizeof (*Devic= e)); > + if (Device =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + Device->Type =3D TypeGuid; > + Device->DmaType =3D NonDiscoverableDeviceDmaTypeNonCoherent; > + Device->Resources =3D Desc; > + > + Status =3D gBS->InstallMultipleProtocolInterfaces (Handle, > + &gEdkiiNonDiscoverableDeviceProtocolGuid, Device, > + NULL); > + if (EFI_ERROR (Status)) { > + goto FreeDevice; > + } > + return EFI_SUCCESS; > + > + FreeDevice: Don't indent labels. > + FreePool (Device); > + > + return Status; > +} > + > + > +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 =3D gBS->OpenProtocol (Controller, > + &gEdkiiNonDiscoverableDeviceProtocolGuid, > + (VOID **) &Dev, Please drop the space after the cast > + This->DriverBindingHandle, > + Controller, > + EFI_OPEN_PROTOCOL_BY_DRIVER); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (CompareGuid (Dev->Type, &gDwEmacNetNonDiscoverableDeviceGuid) && > + Dev->DmaType =3D=3D NonDiscoverableDeviceDmaTypeNonCoherent) { I think we can drop this check: if a platform is integrated with cache cohe= rent DMA and the cache coherent DmaLib is used, things should simply work as wel= l. > + Status =3D EFI_SUCCESS; > + } else { > + Status =3D EFI_UNSUPPORTED; > + } > + > + // 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; > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + EFI_SIMPLE_NETWORK_MODE *SnpMode; > + EFI_SIMPLE_NETWORK_DEVICE_PATH *DevicePath; > + UINT64 DefaultMacAddress; > + EFI_MAC_ADDRESS *SwapMacAddressPtr; Please indent the * above as if it were the first character of the variable name. > + UINTN BufferSize; > + UINTN BufferSizeBuf; > + > + // Allocate Resources > + Snp =3D AllocatePages (EFI_SIZE_TO_PAGES (sizeof (EFI_SIMPLE_NETWORK_D= RIVER))); > + if (Snp =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + BufferSize =3D EFI_PAGES_TO_SIZE ((sizeof (DESIGNWARE_HW_DESCRIPTOR))*= 10); Where does the '10' come from? Why not 9 or 11? And please make it a macro (and put spaces around '*') > + BufferSizeBuf =3D EFI_PAGES_TO_SIZE ((sizeof (CHAR8))*10*2048); And these numbers? And what does BufferSizeBuf mean? > + > + // DMA Allocte Buffer and Map for TxdescRing Allocate > + Status =3D DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (= (sizeof (DESIGNWARE_HW_DESCRIPTOR))*10), (VOID*)&Snp->MacDriver.TxdescRing)= ; Please wrap overly long lines. > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "CreateDwEmacSnpDxe: DmaAllocateBuffer TxdescRi= ng: %r\n", Status)); Please use %a and __FUNCTION__ for the function name in the debug string (n= ote that the function is not called CreateDwEmacSnpDxe() so this message is ver= y misleading) > + return Status; > + } > + Status =3D DmaMap (MapOperationBusMasterCommonBuffer, Snp->MacDriver.T= xdescRing[0], &BufferSize, &Snp->MacDriver.TxdescRingMap[0], &Snp->MappingT= xdesc); Why the [0]? How many descriptors are you mapping? > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "CreateDwEmacSnpDxe: DmaMap TxdescRing: %r\n", = Status)); Wrong function name - use %a and __FUNCTION__ instead. > + return Status; > + } > + > + // DMA Allocte Buffer and Map for RxdescRing > + Status =3D DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (= (sizeof (DESIGNWARE_HW_DESCRIPTOR))*10), (VOID*)&Snp->MacDriver.RxdescRing)= ; > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "CreateDwEmacSnpDxe: DmaAllocateBuffer RxdescRi= ng: %r\n", Status)); > + return Status; > + } > + Status =3D DmaMap (MapOperationBusMasterCommonBuffer, Snp->MacDriver.R= xdescRing[0], &BufferSize, &Snp->MacDriver.RxdescRingMap[0], &Snp->MappingR= xdesc); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "CreateDwEmacSnpDxe: DmaMap RxdescRing: %r\n", = Status)); > + return Status; > + } > + Same as above for rx > + // DMA Allocte Buffer and Map for TxBuffer > + Status =3D DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (= (sizeof (CHAR8))*10*2048), (VOID*)&Snp->MacDriver.TxBuffer); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "CreateDwEmacSnpDxe: DmaAllocateBuffer TxBuffer= : %r\n", Status)); > + return Status; > + } > + Status =3D DmaMap (MapOperationBusMasterCommonBuffer, Snp->MacDriver.T= xBuffer[0], &BufferSizeBuf, &Snp->MacDriver.TxBufferMap[0], &Snp->MappingTx= buf); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "CreateDwEmacSnpDxe: DmaMap TxBuffer: %r\n", St= atus)); > + return Status; > + } > + Why are you using common buffers for TX and RX buffers? This means you are copying data in and out of uncached buffers, which is terribly slow. Instea= d, you should use DmaMap() and DmaUnmap() to map ordinary buffers passed to th= e SNP layer - the DMA library will perform the required cache maintenance to ensure that the device and the CPU see the correct data. > + // DMA Allocte Buffer and Map for RxBuffer > + Status =3D DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (= (sizeof (CHAR8))*10*2048), (VOID*)&Snp->MacDriver.RxBuffer); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "CreateDwEmacSnpDxe: DmaAllocateBuffer RxBuffer= : %r\n", Status)); > + return Status; > + } > + Status =3D DmaMap (MapOperationBusMasterWrite, Snp->MacDriver.RxBuffer= [0], &BufferSizeBuf, &Snp->MacDriver.RxBufferMap[0], &Snp->MappingRxbuf); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "CreateDwEmacSnpDxe: DmaMap RxBuffer: %r\n", St= atus)); > + return Status; > + } > + > + > + DevicePath =3D (EFI_SIMPLE_NETWORK_DEVICE_PATH*)AllocateCopyPool (size= of (EFI_SIMPLE_NETWORK_DEVICE_PATH), &PathTemplate); > + if (DevicePath =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + Status =3D gBS->OpenProtocol (Controller, > + &gEdkiiNonDiscoverableDeviceProtocolGuid, > + (VOID **)&Snp->Dev, > + This->DriverBindingHandle, > + Controller, > + EFI_OPEN_PROTOCOL_BY_DRIVER); > + Move this to the beginning, and handle any errors. > + // Initialized signature (used by INSTANCE_FROM_SNP_THIS macro) > + Snp->Signature =3D SNP_DRIVER_SIGNATURE; > + > + EfiInitializeLock (&Snp->Lock, TPL_CALLBACK); > + > + // Initialize pointers > + SnpMode =3D &(Snp->SnpMode); No need for () > + Snp->Snp.Mode =3D SnpMode; > + > + // Assign fields and func pointers > + Snp->Snp.Revision =3D EFI_SIMPLE_NETWORK_PROTOCOL_REVISION; > + Snp->Snp.WaitForPacket =3D NULL; > + Snp->Snp.Initialize =3D SnpInitialize; > + Snp->Snp.Start =3D SnpStart; > + Snp->Snp.Stop =3D SnpStop; > + Snp->Snp.Reset =3D SnpReset; > + Snp->Snp.Shutdown =3D SnpShutdown; > + Snp->Snp.ReceiveFilters =3D SnpReceiveFilters; > + Snp->Snp.StationAddress =3D SnpStationAddress; > + Snp->Snp.Statistics =3D SnpStatistics; > + Snp->Snp.MCastIpToMac =3D SnpMcastIptoMac; > + Snp->Snp.NvData =3D SnpNvData; > + Snp->Snp.GetStatus =3D SnpGetStatus; > + Snp->Snp.Transmit =3D SnpTransmit; > + Snp->Snp.Receive =3D SnpReceive; > + > + Snp->RecycledTxBuf =3D AllocatePool (sizeof (UINT64) * SNP_TX_BUFFER_I= NCREASEMENT); > + if (Snp->RecycledTxBuf =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + } > + > + Snp->MaxRecycledTxBuf =3D SNP_TX_BUFFER_INCREASEMENT; > + Snp->RecycledTxBufCount =3D 0; > + > + // Start completing simple network mode structure > + SnpMode->State =3D EfiSimpleNetworkStopped; > + SnpMode->HwAddressSize =3D NET_ETHER_ADDR_LEN; // HW address is 6 byte= s > + SnpMode->MediaHeaderSize =3D sizeof(ETHER_HEAD); // Not sure of this Please make sure this is correct. Also, use a space before ( > + SnpMode->MaxPacketSize =3D EFI_PAGE_SIZE; // Preamble + SOF + Ether Fr= ame (with VLAN tag +4bytes) > + SnpMode->NvRamSize =3D 0; // No NVRAM with this device > + SnpMode->NvRamAccessSize =3D 0; // No NVRAM with this device > + > + // Update network mode information > + SnpMode->ReceiveFilterMask =3D EFI_SIMPLE_NETWORK_RECEIVE_UNICAST = | > + EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST | > + EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST | > + EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS | > + EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MU= LTICAST; > + > + // We do not intend to receive anything for the time being. > + SnpMode->ReceiveFilterSetting =3D 0; > + > + // EMAC has 64bit hash table, can filter 64 MCast MAC Addresses > + SnpMode->MaxMCastFilterCount =3D MAX_MCAST_FILTER_CNT; > + SnpMode->MCastFilterCount =3D 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 =3D NET_IFTYPE_ETHERNET; > + > + // Mac address is changeable as it is loaded from erasable memory > + SnpMode->MacAddressChangeable =3D TRUE; > + > + // Can only transmit one packet at a time > + SnpMode->MultipleTxSupported =3D FALSE; > + > + // MediaPresent checks for cable connection and partner link > + SnpMode->MediaPresentSupported =3D TRUE; > + SnpMode->MediaPresent =3D FALSE; > + > + // Set broadcast address > + SetMem (&SnpMode->BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF); > + > + //Set current address > + DefaultMacAddress =3D Snp->Dev->Resources[1].AddrRangeMin; > + // Swap PCD human readable form to correct endianess > + SwapMacAddressPtr =3D (EFI_MAC_ADDRESS *) &DefaultMacAddress; > + SnpMode->CurrentAddress.Addr[0] =3D SwapMacAddressPtr->Addr[5]; > + SnpMode->CurrentAddress.Addr[1] =3D SwapMacAddressPtr->Addr[4]; > + SnpMode->CurrentAddress.Addr[2] =3D SwapMacAddressPtr->Addr[3]; > + SnpMode->CurrentAddress.Addr[3] =3D SwapMacAddressPtr->Addr[2]; > + SnpMode->CurrentAddress.Addr[4] =3D SwapMacAddressPtr->Addr[1]; > + SnpMode->CurrentAddress.Addr[5] =3D SwapMacAddressPtr->Addr[0]; > + > + // Assign fields for device path > + CopyMem (&DevicePath->MacAddrDP.MacAddress, &Snp->Snp.Mode->CurrentAdd= ress, NET_ETHER_ADDR_LEN); > + DevicePath->MacAddrDP.IfType =3D Snp->Snp.Mode->IfType; > + > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > + &Controller, > + &gEfiSimpleNetworkProtocolGuid, &(Snp->Snp), > + &gEfiDevicePathProtocolGuid, DevicePath= , > + NULL > + ); > + Please fix the indentation > + if (EFI_ERROR(Status)) { > + gBS->CloseProtocol (Controller, > + &gEdkiiNonDiscoverableDeviceProtocolGuid, > + This->DriverBindingHandle, > + Controller); > + > + FreePages (Snp, EFI_SIZE_TO_PAGES (sizeof (EFI_SIMPLE_NETWORK_DRIVER))= ); Please fix the indentation > + } else { > + Snp->ControllerHandle =3D 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; > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + > + Status =3D gBS->HandleProtocol ( > + Controller, > + &gEfiSimpleNetworkProtocolGuid, > + (VOID**)&SnpProtocol Space before ** please > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "DriverStop: HandleProtocol: %r\n", Status)); Please use %a and __FUNCTION__ > + return Status; > + } > + > + Snp =3D INSTANCE_FROM_SNP_THIS(SnpProtocol); > + > + Status =3D gBS->UninstallMultipleProtocolInterfaces ( > + Controller, > + &gEfiSimpleNetworkProtocolGuid, > + &Snp->Snp, > + NULL); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "DriverStop: UninstallMultipleProtocolInterface= s: %r\n", > + Status)); > + return Status; > + } > + > + DmaUnmap(Snp->MappingTxdesc); > + DmaUnmap(Snp->MappingRxdesc); > + DmaUnmap(Snp->MappingTxbuf); > + DmaUnmap(Snp->MappingRxbuf); > + Space before ( > + FreePool (Snp->RecycledTxBuf); > + FreePages (Snp, EFI_SIZE_TO_PAGES (sizeof (EFI_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; > + EFI_HANDLE Handle; > + > + Handle =3D NULL; > + Status =3D RegisterDevice (&gDwEmacNetNonDiscoverableDeviceGuid, mDwEm= acNetDesc, > + &Handle); > + ASSERT_EFI_ERROR (Status); > + As i mentioned above, registering the device should be the responsibility o= f a platform driver, not the device driver > + Status =3D EfiLibInstallDriverBindingComponentName2 ( > + ImageHandle, > + SystemTable, > + &mDriverBinding, > + ImageHandle, > + &gSnpComponentName, > + &gSnpComponentName2 > + ); > + > + return Status; > + > +} > \ No newline at end of file Fix this please > diff --git a/Silicon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c b/Sil= icon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c > new file mode 100755 > index 000000000000..cee1584c599e > --- /dev/null > +++ b/Silicon/DesignWare/Drivers/DwEmacSnpDxe/DwEmacSnpDxe.c > @@ -0,0 +1,1273 @@ > +/** @file > + DW EMAC SNP DXE driver > + > + Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > + > + 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. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD 3 Clause LICENSE ON AN "AS IS= " BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > +**/ > + > +#include "DwEmacSnpDxe.h" > +#include "EmacDxeUtil.h" > +#include "PhyDxeUtil.h" > + > +/** > + Change the state of a network interface from "stopped" to "started." > + > + This function starts a network interface. If the network interface suc= cessfully > + starts, then EFI_SUCCESS will be returned. > + > + @param Snp A pointer to the EFI_SIMPLE_NETWORK_PRO= TOCOL 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 poin= t to a valid > + EFI_SIMPLE_NETWORK_PROTOCOL structure. > + @retval EFI_DEVICE_ERROR The command could not be sent to the ne= twork interface. > + @retval EFI_UNSUPPORTED This function is not supported by the n= etwork interface. > + > +**/ > +EFI_STATUS > +EFIAPI > +SnpStart ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *This > + ) > +{ > + EFI_SIMPLE_NETWORK_DRIVER *Snp; Blank line after variable declarations > + DEBUG ((EFI_D_INFO,"SNP:DXE: %a ()\r\n", __FUNCTION__)); > + Use DEBUG_ constants not EFI_D_ constants (applies everywhere) > + // Check Snp instance > + if (This =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Snp =3D INSTANCE_FROM_SNP_THIS(This); > + // Check state > + if ((Snp->SnpMode.State =3D=3D EfiSimpleNetworkStarted) || > + (Snp->SnpMode.State =3D=3D EfiSimpleNetworkInitialized) ) { > + return EFI_ALREADY_STARTED; > + } > + > + // Change state > + Snp->SnpMode.State =3D 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 th= e network > + interface is in the started state. If the network interface was succes= sfully > + stopped, then EFI_SUCCESS will be returned. > + > + @param Snp A pointer to the EFI_SIMPLE_NETWORK_PR= OTOCOL > + instance. > + > + > + @retval EFI_SUCCESS The network interface was stopped. > + @retval EFI_NOT_STARTED The network interface has not been sta= rted. > + @retval EFI_INVALID_PARAMETER This parameter was NULL or did not poi= nt to a > + valid EFI_SIMPLE_NETWORK_PROTOCOL stru= cture. > + @retval EFI_DEVICE_ERROR The command could not be sent to the n= etwork > + interface. > + @retval EFI_UNSUPPORTED This function is not supported by the = network > + interface. > + > +**/ > +EFI_STATUS > +EFIAPI > +SnpStop ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL* This > + ) > +{ > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + UINT32 MacBase; > + DEBUG ((EFI_D_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__)); > + Same as above > + // Check Snp Instance > + if (This =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Snp =3D INSTANCE_FROM_SNP_THIS(This); > + // Check state of the driver > + if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStopped) { > + return EFI_NOT_STARTED; > + } > + > + //Get MAC base address > + MacBase =3D (UINT32)Snp->Dev->Resources[0].AddrRangeMin; > + Can you add the base address to the driver struct directly, rather than do this triple dereference in every driver method? Also, a base address should be EFI_PHYSICAL_ADDRESS or UINTN, never UINT32. > + // Stop the Tx and Rx > + EmacStopTxRx (MacBase); > + // Change the state > + switch (Snp->SnpMode.State) { > + case EfiSimpleNetworkStarted: > + case EfiSimpleNetworkInitialized: > + Snp->SnpMode.State =3D 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 buffer= s > + required by the network interface; optionally, also requests allocatio= n of > + additional transmit and receive buffers. > + > + This function allocates the transmit and receive buffers required by t= he network > + interface. If this allocation fails, then EFI_OUT_OF_RESOURCES is retu= rned. > + If the allocation succeeds and the network interface is successfully i= nitialized, > + 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 buf= fer space > + that the driver should allocate for the netw= ork interface. > + Some network interfaces will not be able to = use the > + extra buffer, and the caller will not know i= f it is > + actually being used. > + @param ExtraTxBufferSize The size, in bytes, of the extra transmit bu= ffer space > + that the driver should allocate for the netw= ork interface. > + Some network interfaces will not be able to = use the > + extra buffer, and the caller will not know i= f it is > + actually being used. > + > + @retval EFI_SUCCESS The network interface was initialized. > + @retval EFI_NOT_STARTED The network interface has not been start= ed. > + @retval EFI_OUT_OF_RESOURCES There was not enough memory for the tran= smit 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 net= work 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; > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + UINT32 MacBase; > + > + DEBUG ((EFI_D_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__)); > + > + // Check Snp Instance > + if (This =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Snp =3D INSTANCE_FROM_SNP_THIS (This); > + // First check that driver has not already been initialized > + if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkInitialized) { > + return EFI_SUCCESS; > + } else Put else and if on the same line > + if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStopped) { > + return EFI_NOT_STARTED; > + } > + > + //Get MAC base address > + MacBase =3D (UINT32)Snp->Dev->Resources[0].AddrRangeMin; > + > + // Init PHY > + Status =3D PhyDxeInitialization (&Snp->PhyDriver, MacBase); > + if (EFI_ERROR (Status)) { > + return EFI_DEVICE_ERROR; > + } > + > + // Init EMAC > + Status =3D EmacDxeInitialization (&Snp->MacDriver, MacBase); > + if (EFI_ERROR (Status)) { > + return EFI_DEVICE_ERROR; > + } > + > + // Set MAC Address > + EmacSetMacAddress (&Snp->SnpMode.CurrentAddress, MacBase); > + EmacReadMacAddress(&Snp->SnpMode.CurrentAddress, MacBase); Space before ( > + > + // Init Link > + Print (L"SNP:DXE: Auto-Negotiating Ethernet PHY Link ...\r\n"); Don't use Print() for debug messages. This goes straight to the console > + Status =3D PhyLinkAdjustEmacConfig (&Snp->PhyDriver, MacBase); > + if (EFI_ERROR(Status)) { Space before ( > + Print (L"SNP:DXE: Link is Down - Network Cable is not plugged in?\r\= n"); > + return EFI_DEVICE_ERROR; > + } > + > + EmacStartTransmission (MacBase); > + > + // Declare the driver as initialized > + Snp->SnpMode.State =3D 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 p= arameters > + 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 multicas= t-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 h= as not > + been initialized, EFI_DEVICE_ERROR will be returned. > + > + @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOC= OL instance. > + @param ExtendedVerification Indicates that the driver may perform a mo= re > + exhaustive verification operation of the d= evice > + during reset. > + > + @retval EFI_SUCCESS The network interface was reset. > + @retval EFI_NOT_STARTED The network interface has not been start= ed. > + @retval EFI_INVALID_PARAMETER One or more of the parameters has an uns= upported value. > + @retval EFI_DEVICE_ERROR The command could not be sent to the net= work interface. > + @retval EFI_UNSUPPORTED This function is not supported by the ne= twork interface. > + > +**/ > +EFI_STATUS > +EFIAPI > +SnpReset ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, > + IN BOOLEAN ExtendedVerification > + ) > +{ > + EFI_STATUS Status; > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + UINT32 MacBase; > + > + Snp =3D INSTANCE_FROM_SNP_THIS (This); > + > + DEBUG ((EFI_D_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__)); > + > + // Check Snp Instance > + if (This =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // First check that driver has not already been initialized > + if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStarted) { > + return EFI_DEVICE_ERROR; > + } else if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStopped) { > + return EFI_NOT_STARTED; > + } > + > + // Get MAC base address > + MacBase =3D (UINT32)Snp->Dev->Resources[0].AddrRangeMin; > + > + // Initiate a PHY reset > + Status =3D PhySoftReset (&Snp->PhyDriver, MacBase); > + if (EFI_ERROR (Status)) { > + Snp->SnpMode.State =3D EfiSimpleNetworkStopped; > + return EFI_NOT_STARTED; > + } > + > + return EFI_SUCCESS; > +} > + > + > +/** > + Resets a network adapter and leaves it in a state that is safe for ano= ther > + driver to initialize. > + > + This function releases the memory buffers assigned in the Initialize()= call. > + Pending transmits and receives are lost, and interrupts are cleared an= d disabled. > + After this call, only the Initialize() and Stop() calls may be used. I= f the > + network interface was successfully shutdown, then EFI_SUCCESS will be = returned. > + If the driver has not been initialized, EFI_DEVICE_ERROR will be retur= ned. > + > + @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 start= ed. > + @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 net= work interface. > + > +**/ > +EFI_STATUS > +EFIAPI > +SnpShutdown ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL* This > + ) > +{ > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + UINT32 MacBase; > + DEBUG ((EFI_D_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__)); > + > + // Check Snp Instance > + if (This =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Snp =3D INSTANCE_FROM_SNP_THIS (This); > + // First check that driver has not already been initialized > + if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStarted) { > + return EFI_DEVICE_ERROR; > + } else if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStopped) { > + return EFI_NOT_STARTED; > + } > + > + //Get MAC base address > + MacBase =3D (UINT32)Snp->Dev->Resources[0].AddrRangeMin; > + > + EmacStopTxRx (MacBase); > + > + Snp->SnpMode.State =3D EfiSimpleNetworkStopped; > + > + return EFI_SUCCESS; > +} > + > + > +/** > + Manages the multicast receive filters of a network interface. > + > + This function is used enable and disable the hardware and software rec= eive > + 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 a= dded 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 hard= ware a > + more liberal setting is selected. > + If the same bits are set in the Enable and Disable parameters, then th= e bits > + in the Disable parameter takes precedence. > + If the ResetMCastFilter parameter is TRUE, then the multicast address = list > + filter is disabled (irregardless of what other multicast bits are set = in the > + Enable and Disable parameters). The SNP->Mode->MCastFilterCount field = is set > + to zero. The Snp->Mode->MCastFilter contents are undefined. > + After enabling or disabling receive filter settings, software should v= erify > + 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 r= eceive > + filter settings if the requested setting can not be honored. For exa= mple, if > + a request for four multicast addresses is made and the underlying ha= rdware > + only supports two multicast addresses the driver might set the promi= scuous > + or promiscuous multicast receive filters instead. The receiving soft= ware is > + responsible for discarding any extra packets that get through the ha= rdware > + receive filters. > + Note: Note: To disable all receive filter hardware, the network driv= er must > + be Shutdown() and Stopped(). Calling ReceiveFilters() with Disable= set to > + Snp->Mode->ReceiveFilterSettings will make it so no more packets a= re > + returned by the Receive() function, but the receive hardware may s= till 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 filte= r list. > + If ResetMCastFilter is FALSE, and this network interface allows the mu= lticast > + receive filter list to be modified, then the MCastFilterCnt and MCastF= ilter > + are used to update the current multicast receive filter list. The modi= fied > + receive filter list settings can be found in the MCastFilter field of > + EFI_SIMPLE_NETWORK_MODE. If the network interface does not allow the m= ulticast > + 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 retur= ned. > + If the receive filter mask and multicast receive filter list have been > + successfully updated on the network interface, EFI_SUCCESS will be ret= urned. > + > + @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL i= nstance. > + @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 th= e network > + interface. For backward compatibility with EFI= 1.1 > + platforms, the EFI_SIMPLE_NETWORK_RECEIVE_MULT= ICAST bit > + must be set when the ResetMCastFilter paramete= r is TRUE. > + @param ResetMCastFilter Set to TRUE to reset the contents of the multi= cast > + receive filters on the network interface to th= eir > + default values. > + @param MCastFilterCnt Number of multicast HW MAC addresses in the ne= w MCastFilter > + list. This value must be less than or equal to= the > + MCastFilterCnt field of EFI_SIMPLE_NETWORK_MOD= E. > + This field is optional if ResetMCastFilter is = TRUE. > + @param MCastFilter A pointer to a list of new multicast receive f= ilter HW > + MAC addresses. This list will replace any exis= ting > + multicast HW MAC address list. This field is o= ptional > + if ResetMCastFilter is TRUE. > + > + @retval EFI_SUCCESS The multicast receive filter list was u= pdated. > + @retval EFI_NOT_STARTED The network interface has not been star= ted. > + @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 ar= e 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 Disab= le, and > + ResetMCastFilter is FALSE) and MCastF= ilterCount > + is zero > + * Multicast is being enabled and MCastF= ilterCount > + is greater than Snp->Mode->MaxMCastFi= lterCount > + * Multicast is being enabled and MCastF= ilter 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 starte= d but has > + not been initialized > + * An unexpected error was returned by t= he > + underlying network driver or device > + @retval EFI_UNSUPPORTED This function is not supported by the n= etwork > + 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; > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + UINT32 MacBase; > + > + Snp =3D INSTANCE_FROM_SNP_THIS (This); > + > + // Check Snp Instance > + if (Snp =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // Check that driver was started and initialised > + if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStarted) { > + return EFI_DEVICE_ERROR; > + } else if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStopped) { > + return EFI_NOT_STARTED; > + } > + > + if ((Enable & (~Snp->SnpMode.ReceiveFilterMask)) || > + (Disable & (~Snp->SnpMode.ReceiveFilterMask)) ) { Please clarify the voodoo bitwise boolean logic with a comment. > + return EFI_INVALID_PARAMETER; > + } > + > + //Get MAC base address > + MacBase =3D (UINT32)Snp->Dev->Resources[0].AddrRangeMin; > + > + ReceiveFilterSetting =3D (Snp->SnpMode.ReceiveFilterSetting | Enable) = & (~Disable); > + Same here. > + EmacRxFilters (ReceiveFilterSetting, ResetMCastFilter, MCastFilterCnt,= MCastFilter, MacBase); > + > + return EFI_SUCCESS; > +} > + > + > +/** > + Modifies or resets the current station address, if supported. > + > + This function modifies or resets the current station address of a netw= ork > + interface, if supported. If Reset is TRUE, then the current station ad= dress is > + set to the network interface's permanent address. If Reset is FALSE, a= nd 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 net= work > + interface does not allow its station address to be modified, then > + EFI_INVALID_PARAMETER will be returned. If the station address is succ= essfully > + 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 interfa= ce. > + > + > + @retval EFI_SUCCESS The network interface's station address = was updated. > + @retval EFI_NOT_STARTED The Simple Network Protocol interface ha= s 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 ha= s 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 ne= twork > + 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; Further up, you set a property saying that the MAC address is changeble, no= ? > +} > + > + > + > +/** > + 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 en= ough 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 Statistic= sTable > + 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 retur= ned. > + If Reset is FALSE, and both StatisticsSize and StatisticsTable are NUL= L, then > + no operations will be performed, and EFI_SUCCESS will be returned. > + If Reset is TRUE, then all of the supported statistics counters on thi= s network > + interface will be reset to zero. > + > + @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL in= stance. > + @param Reset Set to TRUE to reset the statistics for the net= work interface. > + @param StatSize On input the size, in bytes, of StatisticsTable= . On output > + the size, in bytes, of the resulting table of s= tatistics. > + @param Statistics A pointer to the EFI_NETWORK_STATISTICS structu= re that > + contains the statistics. Type EFI_NETWORK_STATI= STICS is > + defined in "Related Definitions" below. > + > + @retval EFI_SUCCESS The requested operation succeeded. > + @retval EFI_NOT_STARTED The Simple Network Protocol interface ha= s not been > + started by calling Start(). > + @retval EFI_BUFFER_TOO_SMALL StatisticsSize is not NULL and Statistic= sTable is > + NULL. The current buffer size that is ne= eded to > + hold all the statistics is returned in S= tatisticsSize. > + @retval EFI_BUFFER_TOO_SMALL StatisticsSize is not NULL and Statistic= sTable is > + not NULL. The current buffer size that i= s needed > + to hold all the statistics is returned i= n > + StatisticsSize. A partial set of statist= ics is > + returned in StatisticsTable. > + @retval EFI_INVALID_PARAMETER StatisticsSize is NULL and StatisticsTab= le is not > + NULL. > + @retval EFI_DEVICE_ERROR The Simple Network Protocol interface ha= s not > + been initialized by calling Initialize()= . > + @retval EFI_DEVICE_ERROR An error was encountered collecting stat= istics > + from the NIC. > + @retval EFI_UNSUPPORTED The NIC does not support collecting stat= istics > + 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 > + ) > +{ > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + UINT32 MacBase; > + > + Snp =3D INSTANCE_FROM_SNP_THIS (This); > + > + DEBUG ((EFI_D_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__)); > + > + // Check Snp instance > + if (This =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // Check that driver was started and initialised > + if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStarted) { > + return EFI_DEVICE_ERROR; > + } else if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStopped) { > + return EFI_NOT_STARTED; > + } > + > + // Check pointless condition Wait what?? > + if ((!Reset) && (StatSize =3D=3D NULL) && (Statistics =3D=3D NULL)) { > + return EFI_SUCCESS; > + } > + > + // Check the parameters > + if ((StatSize =3D=3D NULL) && (Statistics !=3D 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 =3D sizeof(EFI_NETWORK_STATISTICS); > + return EFI_BUFFER_TOO_SMALL; > + } > + > + //Get MAC base address > + MacBase =3D (UINT32)Snp->Dev->Resources[0].AddrRangeMin; > + > + // read statistic counters > + EmacGetStatistic (&Snp->Stats, MacBase); > + > + // Fill in the statistics > + CopyMem(&Statistics, &Snp->Stats, sizeof(EFI_NETWORK_STATISTICS)); Space before ( > + > + 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 ad= dress > + for all packet transactions. If the mapping is accepted, then EFI_SUCC= ESS will > + be returned. > + > + @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instan= ce. > + @param IsIpv6 Set to TRUE if the multicast IP address is IPv6 [RF= C 2460]. > + Set to FALSE if the multicast IP address is IPv4 [R= FC 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 generate= d from IP. > + > + @retval EFI_SUCCESS The multicast IP address was mapped to t= he > + multicast HW MAC address. > + @retval EFI_NOT_STARTED The Simple Network Protocol interface ha= s 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 IPv= 6 > + multicast address. > + @retval EFI_DEVICE_ERROR The Simple Network Protocol interface ha= s not > + been initialized by calling Initialize()= . > + @retval EFI_UNSUPPORTED IPv6 is TRUE and the implementation does= not > + support IPv6 multicast to MAC address co= nversion. > + > +**/ > +EFI_STATUS > +EFIAPI > +SnpMcastIptoMac ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, > + IN BOOLEAN IsIpv6, > + IN EFI_IP_ADDRESS *Ip, > + OUT EFI_MAC_ADDRESS *McastMac > + ) > +{ > + > + DEBUG ((EFI_D_INFO, "SNP:DXE: %a ()\r\n", __FUNCTION__)); > + > + // Check Snp instance > + if (This =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + > + Snp =3D INSTANCE_FROM_SNP_THIS (This); > + > + // Check that driver was started and initialised > + if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStarted) { > + return EFI_DEVICE_ERROR; > + } else if (Snp->SnpMode.State =3D=3D EfiSimpleNetworkStopped) { > + return EFI_NOT_STARTED; > + } > + > + // Check parameters > + if ((McastMac =3D=3D NULL) || (Ip =3D=3D 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] =3D 0x01; > + McastMac->Addr[1] =3D 0x00; > + McastMac->Addr[2] =3D 0x5E; > + > + // Lower 23 bits from ipv4 address > + McastMac->Addr[3] =3D (Ip->v4.Addr[1] & 0x7F); // Clear the most sig= nificant bit (25th bit of MAC must be 0) > + McastMac->Addr[4] =3D Ip->v4.Addr[2]; > + McastMac->Addr[5] =3D 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] =3D 0x33; > + McastMac->Addr[1] =3D 0x33; > + > + // lower four octets are taken from ipv6 address > + McastMac->Addr[2] =3D Ip->v6.Addr[8]; > + McastMac->Addr[3] =3D Ip->v6.Addr[9]; > + McastMac->Addr[4] =3D Ip->v6.Addr[10]; > + McastMac->Addr[5] =3D Ip->v6.Addr[11]; > + } > + > + return EFI_SUCCESS; > +} > + > + > +/** > + Performs read and write operations on the NVRAM device attached to a n= etwork > + interface. > + > + This function performs read and write operations on the NVRAM device a= ttached > + to a network interface. If ReadWrite is TRUE, a read operation is perf= ormed. > + If ReadWrite is FALSE, a write operation is performed. Offset specifie= s the > + byte offset at which to start either operation. Offset must be a multi= ple of > + NvRamAccessSize , and it must have a value between zero and NvRamSize. > + BufferSize specifies the length of the read or write operation. Buffer= Size must > + also be a multiple of NvRamAccessSize, and Offset + BufferSize must no= t 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 d= evice > + attached to the network interface will be read into Buffer and EFI_SUC= CESS > + 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 networ= k > + interface and EFI_SUCCESS will be returned. > + > + It does the basic checking on the input parameters and retrieves snp s= tructure > + and then calls the read_nvdata() call which does the actual reading > + > + @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instanc= e. > + @param ReadWrite TRUE for read operations, FALSE for write operations= . > + @param Offset Byte offset in the NVRAM device at which to start th= e read or > + write operation. This must be a multiple of NvRamAcc= essSize > + and less than NvRamSize. (See EFI_SIMPLE_NETWORK_MOD= E) > + @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 start= ed. > + @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.NvRamAccessSiz= e > + * The Offset parameter is not less than > + EFI_SIMPLE_NETWORK_MODE.NvRamSize > + * The BufferSize parameter is not a mult= iple of > + EFI_SIMPLE_NETWORK_MODE.NvRamAccessSiz= e > + * The Buffer parameter is NULL > + @retval EFI_DEVICE_ERROR The command could not be sent to the net= work > + interface. > + @retval EFI_UNSUPPORTED This function is not supported by the ne= twork > + 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 b= uffer has > + been successfully transmitted, and the status for that buffer is clear= ed. If > + the status of the network interface is successfully collected, EFI_SUC= CESS > + will be returned. If the driver has not been initialized, EFI_DEVICE_E= RROR will > + be returned. > + > + @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL in= stance. > + @param IrqStat A pointer to the bit mask of the currently acti= ve > + 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 r= ead, it > + will also be cleared. Clearing the transmit int= errupt does > + not empty the recycled transmit buffer array. > + @param TxBuff Recycled transmit buffer address. The network i= nterface > + will not transmit if its internal recycled tran= smit > + buffer array is full. Reading the transmit buff= er does > + not clear the transmit interrupt. If this is NU= LL, 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 start= ed. > + @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 net= work > + interface. > + > +**/ > +EFI_STATUS > +EFIAPI > +SnpGetStatus ( > + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, > + OUT UINT32 *IrqStat OPTIONAL, > + OUT VOID **TxBuff OPTIONAL > + ) > +{ > + EFI_STATUS Status; > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + UINT32 MacBase; > + > + Snp =3D INSTANCE_FROM_SNP_THIS (This); > + > + // Check preliminaries > + if (This =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + if (Snp->SnpMode.State !=3D EfiSimpleNetworkInitialized) { > + return EFI_NOT_STARTED; > + } > + > + // Get MAC base address > + MacBase =3D (UINT32)Snp->Dev->Resources[0].AddrRangeMin; > + > + // Update the media status > + Status =3D PhyLinkAdjustEmacConfig (&Snp->PhyDriver, MacBase); > + if (EFI_ERROR(Status)) { > + Snp->SnpMode.MediaPresent =3D FALSE; > + } else { > + Snp->SnpMode.MediaPresent =3D TRUE; > + } > + > + // TxBuff > + if (TxBuff !=3D NULL) { > + // > + // Get a recycled buf from Snp->RecycledTxBuf > + // > + if (Snp->RecycledTxBufCount =3D=3D 0) { > + *TxBuff =3D NULL; > + } else { > + Snp->RecycledTxBufCount--; > + *TxBuff =3D (VOID *) (UINTN) Snp->RecycledTxBuf[Snp->RecycledTxBuf= Count]; No space after () casts > + } > + } > + > + // Check DMA Irq status > + EmacGetDmaStatus (IrqStat, 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 return= ed. If > + BufferSize is less than This->Mode->MediaHeaderSize, then EFI_BUFFER_T= OO_SMALL > + will be returned. If Buffer is NULL, then EFI_INVALID_PARAMETER will b= e > + returned. If HeaderSize is nonzero and DestAddr or Protocol is NULL, t= hen > + 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 c= ontents > + specified by Buffer will be placed on the transmit queue of the networ= k > + interface, and EFI_SUCCESS will be returned. GetStatus() can be used t= o > + determine when the packet has actually been transmitted. The contents = of the > + Buffer must not be modified until the packet has actually been transmi= tted. > + The Transmit() function performs nonblocking I/O. A caller who wants t= o 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 retur= ned. > + > + @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instanc= e. > + @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 Dest= Addr and > + Protocol parameters must not be NULL. > + @param BuffSize The size, in bytes, of the entire packet (media head= er and > + data) to be transmitted through the network interfac= e. > + @param Data A pointer to the packet (media header followed by da= ta) to be > + transmitted. This parameter cannot be NULL. If Heade= rSize is > + zero, then the media header in Buffer must already b= e 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, th= en this > + parameter is ignored. If HeaderSize is nonzero and S= rcAddr > + is NULL, then This->Mode->CurrentAddress is used for= the > + source HW MAC address. > + @param DstAddr The destination HW MAC address. If HeaderSize is zer= o, 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 T= ypes," > + for examples. > + > + @retval EFI_SUCCESS The packet was placed on the transmit qu= eue. > + @retval EFI_NOT_STARTED The network interface has not been start= ed. > + @retval EFI_NOT_READY The network interface is too busy to acc= ept this > + transmit request. > + @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small. > + @retval EFI_INVALID_PARAMETER One or more of the parameters has an uns= upported > + value. > + @retval EFI_DEVICE_ERROR The command could not be sent to the net= work interface. > + @retval EFI_UNSUPPORTED This function is not supported by the ne= twork interface. > + > +**/ > +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 > + ) > +{ > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + UINT32 DescNum; > + DESIGNWARE_HW_DESCRIPTOR *TxDescriptor; > + UINT8* EthernetPacket; > + UINT64 *Tmp; > + UINT32 MacBase; > + > + EthernetPacket =3D Data; > + > + Snp =3D INSTANCE_FROM_SNP_THIS (This); > + > + if (EFI_ERROR (EfiAcquireLockOrFail (&Snp->Lock))) { > + return EFI_ACCESS_DENIED; This is not a documented return code for this method. > + } > + > + // Check preliminaries > + if ((This =3D=3D NULL) || (Data =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + if (Snp->SnpMode.State !=3D EfiSimpleNetworkInitialized) { > + return EFI_NOT_STARTED; > + } > + > + Snp->MacDriver.TxCurrentDescriptorNum =3D Snp->MacDriver.TxNextDescrip= torNum; > + DescNum =3D Snp->MacDriver.TxCurrentDescriptorNum; > + > + TxDescriptor =3D Snp->MacDriver.TxdescRing[0] + (DescNum);; Please check your array layout. Indexing from the *value* of element 0 is almost certainly wrong. > + > + // Ensure header is correct size if non-zero > + if (HdrSize) { > + if (HdrSize !=3D Snp->SnpMode.MediaHeaderSize) { > + return EFI_INVALID_PARAMETER; > + } > + > + if ((DstAddr =3D=3D NULL) || (Protocol =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + } > + > + // Ensure buffer size is valid > + if (BuffSize < Snp->SnpMode.MediaHeaderSize) { > + return EFI_BUFFER_TOO_SMALL; > + } > + > + > + if (HdrSize) { > + EthernetPacket[0] =3D DstAddr->Addr[0]; > + EthernetPacket[1] =3D DstAddr->Addr[1]; > + EthernetPacket[2] =3D DstAddr->Addr[2]; > + EthernetPacket[3] =3D DstAddr->Addr[3]; > + EthernetPacket[4] =3D DstAddr->Addr[4]; > + EthernetPacket[5] =3D DstAddr->Addr[5]; > + > + EthernetPacket[6] =3D SrcAddr->Addr[0]; > + EthernetPacket[7] =3D SrcAddr->Addr[1]; > + EthernetPacket[8] =3D SrcAddr->Addr[2]; > + EthernetPacket[9] =3D SrcAddr->Addr[3]; > + EthernetPacket[10] =3D SrcAddr->Addr[4]; > + EthernetPacket[11] =3D SrcAddr->Addr[5]; > + > + EthernetPacket[13] =3D *Protocol & 0xFF; > + EthernetPacket[12] =3D (*Protocol & 0xFF00) >> 8; > + } > + > + CopyMem((VOID*)(UINTN)TxDescriptor->Addr, EthernetPacket, BuffSize); > + I am aware that TX is usually not a hot path in UEFI, but we should still try to map a buffer directly rather than copy the contents into uncached memory. Also, put a space before ( > + TxDescriptor->Tdes1 =3D (BuffSize << TDES1_SIZE1SHFT) & > + TDES1_SIZE1MASK; > + > + TxDescriptor->Tdes0 |=3D (TDES0_TXFIRST | > + TDES0_TXLAST | > + TDES0_OWN); > + > + // Increase descriptor number > + DescNum++; > + if (DescNum >=3D CONFIG_TX_DESCR_NUM) > + DescNum =3D 0; > + Always use { } with conditionals in EDK2 code > + Snp->MacDriver.TxNextDescriptorNum =3D DescNum; > + > + if ((Snp->MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT) >=3D SNP_MAX_= TX_BUFFER_NUM) { > + return EFI_NOT_READY; > + } > + > + if (Snp->RecycledTxBufCount < Snp->MaxRecycledTxBuf) { > + Snp->RecycledTxBuf[Snp->RecycledTxBufCount] =3D (UINT64) Data; > + Snp->RecycledTxBufCount ++; > + } else { > + Tmp =3D AllocatePool (sizeof (UINT64) * (Snp->MaxRecycledTxBuf + SNP= _TX_BUFFER_INCREASEMENT)); > + if (Tmp =3D=3D NULL) { > + return EFI_DEVICE_ERROR; > + } > + CopyMem (Tmp, Snp->RecycledTxBuf, sizeof (UINT64) * Snp->RecycledTxB= ufCount); > + FreePool (Snp->RecycledTxBuf); > + Snp->RecycledTxBuf =3D Tmp; > + Snp->MaxRecycledTxBuf +=3D SNP_TX_BUFFER_INCREASEMENT; Here you double the size of the TX recycle buffer array, but you never reco= rd 'Data' in it. Are you sure that is correct? > + } > + > + // Get MAC base address > + MacBase =3D (UINT32)Snp->Dev->Resources[0].AddrRangeMin; > + > + // Start the transmission > + EmacDmaStart (MacBase); > + > + 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 t= he packet > + is smaller than BufferSize, then the contents of the packet will be pl= aced in > + Buffer, and BufferSize will be updated with the actual size of the pac= ket. > + In addition, if SrcAddr, DestAddr, and Protocol are not NULL, then the= se 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 th= e receive > + packet will be placed in BufferSize and EFI_BUFFER_TOO_SMALL will be r= eturned. > + If the driver has not been initialized, EFI_DEVICE_ERROR will be retur= ned. > + > + @param Snp A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instanc= e. > + @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, th= e size, in > + bytes, of the packet that was received on the networ= k interface. > + @param Data A pointer to the data buffer to receive both the med= ia > + 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 me= dia 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, th= en 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 numbe= r of > + bytes received. > + @retval EFI_NOT_STARTED The network interface has not been start= ed. > + @retval EFI_NOT_READY No packets have been received on the net= work interface. > + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the received= packets. > + BufferSize has been updated to the requi= red 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 net= work interface. > + > +**/ > +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 > + ) > +{ > + EFI_SIMPLE_NETWORK_DRIVER *Snp; > + EFI_MAC_ADDRESS Dst; > + EFI_MAC_ADDRESS Src; > + UINT32 Length, DesciptorStatus; DescriptorStatus. Also, please don't declare multiple variables on a single line. > + UINT8* RawData; > + UINT32 DescNum; > + DESIGNWARE_HW_DESCRIPTOR *RxDescriptor; Fix indentation please. > + > + Snp =3D INSTANCE_FROM_SNP_THIS (This); > + > + // Check preliminaries > + if ((This =3D=3D NULL) || (Data =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (Snp->SnpMode.State !=3D EfiSimpleNetworkInitialized) { > + return EFI_NOT_STARTED; > + } > + > + Snp =3D INSTANCE_FROM_SNP_THIS (This); > + > + if (EFI_ERROR (EfiAcquireLockOrFail (&Snp->Lock))) { > + return EFI_ACCESS_DENIED; Undocumented return code. > + } > + > + Snp->MacDriver.RxCurrentDescriptorNum =3D Snp->MacDriver.RxNextDescrip= torNum; > + DescNum =3D Snp->MacDriver.RxCurrentDescriptorNum; > + RxDescriptor =3D Snp->MacDriver.RxdescRing[0]+(DescNum); > + > + RawData =3D (UINT8*) Data; > + > + DesciptorStatus =3D RxDescriptor->Tdes0; > + > + if (DesciptorStatus & ((UINT32)RDES0_OWN)) { > + goto ReleaseLock; > + } > + > + > + if (DesciptorStatus & RDES0_SAF) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error: Source Add= ress Filter Fail\n")); Descritpor -> Descriptor > + return EFI_DEVICE_ERROR; > + } > + > + if (DesciptorStatus & RDES0_AFM) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error: Destinatio= n Address Filter Fail\n")); > + return EFI_DEVICE_ERROR; > + } > + > + if (DesciptorStatus & RDES0_ES) { > + // Check for errors > + if (DesciptorStatus & RDES0_RE) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error: Receive = Error\n")); > + } > + if (DesciptorStatus & RDES0_DE) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error: Receive = Error\n")); > + } > + if (DesciptorStatus & RDES0_RWT) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error: Watchdog= Timeout\n")); > + } > + if (DesciptorStatus & RDES0_LC) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error: Late Col= lision\n")); > + } > + if (DesciptorStatus & RDES0_GF) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error: Giant Fr= ame\n")); > + } > + if (DesciptorStatus & RDES0_OE) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error: Overflow= Error\n")); > + } > + if (DesciptorStatus & RDES0_LE) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error:Length Er= ror\n")); > + } > + if (DesciptorStatus & RDES0_DBE) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error: Dribble = Bit Error\n")); > + } > + > + // Check descriptor error status > + if (DesciptorStatus & RDES0_CE) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Rx Descritpor Status Error: CRC Erro= r\n")); > + } > + return EFI_DEVICE_ERROR; > + } > + > + Length =3D (DesciptorStatus >> RDES0_FL_SHIFT) & RDES0_FL_MASK; > + if (!Length) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Error: Invalid Frame Packet length \r\= n")); > + return EFI_NOT_READY; > + } > + // Check buffer size > + if (*BuffSize < Length) { > + DEBUG ((EFI_D_WARN, "SNP:DXE: Error: Buffer size is too small\n")); > + return EFI_BUFFER_TOO_SMALL; > + } > + *BuffSize =3D Length; > + > + if (HdrSize !=3D NULL) > + *HdrSize =3D Snp->SnpMode.MediaHeaderSize; > + > + CopyMem (RawData, (VOID*)(UINTN) RxDescriptor->Addr, *BuffSize); > + This copy is much slower than necessary since the RX buffers have been allocated via the DmaLib API and mapped as common buffers. Please use normal allocations, and use directional mappings. > + if (DstAddr !=3D NULL) { > + Dst.Addr[0] =3D RawData[0]; > + Dst.Addr[1] =3D RawData[1]; > + Dst.Addr[2] =3D RawData[2]; > + Dst.Addr[3] =3D RawData[3]; > + Dst.Addr[4] =3D RawData[4]; > + Dst.Addr[5] =3D RawData[5]; > + CopyMem (DstAddr, &Dst, NET_ETHER_ADDR_LEN); > +Print(L"received from source address %x %x\n\n", DstAddr, &Dst); Dont use print() in drivers > + } > + > + // Get the source address > + if (SrcAddr !=3D NULL) { > + Src.Addr[0] =3D RawData[6]; > + Src.Addr[1] =3D RawData[7]; > + Src.Addr[2] =3D RawData[8]; > + Src.Addr[3] =3D RawData[9]; > + Src.Addr[4] =3D RawData[10]; > + Src.Addr[5] =3D RawData[11]; > +Print(L"received from source address %x %x\n\n", SrcAddr, &Src); same here > + CopyMem (SrcAddr,&Src, NET_ETHER_ADDR_LEN); > + } > + > + // Get the protocol > + if (Protocol !=3D NULL) { > + *Protocol =3D NTOHS (RawData[12] | (RawData[13] >> 8) | (RawData[14] = >> 16) | (RawData[15] >> 24)); > + } > + > + RxDescriptor->Tdes0 |=3D (UINT32)RDES0_OWN; > + > + DescNum++; > + > + if (DescNum >=3D CONFIG_RX_DESCR_NUM) > + DescNum =3D 0; > + > + Snp->MacDriver.RxNextDescriptorNum =3D DescNum; > + > + EfiReleaseLock (&Snp->Lock); > + > + return EFI_SUCCESS; > + > + ReleaseLock: Don't indent labels > + EfiReleaseLock (&Snp->Lock); > + return EFI_NOT_READY; > + > +} > + > diff --git a/Silicon/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c b/Sili= con/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c > new file mode 100755 > index 000000000000..a7f29f6cd0c7 > --- /dev/null > +++ b/Silicon/DesignWare/Drivers/DwEmacSnpDxe/EmacDxeUtil.c > @@ -0,0 +1,684 @@ > +/** @file > + > + Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > + > + 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. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD 3 Clause LICENSE ON AN "AS IS= " BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > +**/ > + > +#include "EmacDxeUtil.h" > +#include "PhyDxeUtil.h" > + > +VOID > +EFIAPI > +EmacSetMacAddress ( > + IN EFI_MAC_ADDRESS *MacAddress, > + IN UINT32 MacBaseAddress > + ) > +{ > + DEBUG ((EFI_D_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 ((EFI_D_INFO, "SNP:MAC: gmacgrp_mac_address0_low =3D 0x%08X \r\= n", MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_MAC_ADDRESS0_LOW_OFST))); > + DEBUG ((EFI_D_INFO, "SNP:MAC: gmacgrp_mac_address0_high =3D 0x%08X \r\= n", MmioRead32 (MacBaseAddress +DW_EMAC_GMACGRP_MAC_ADDRESS0_HIGH_OFST))); > +} > + > + > +VOID > +EFIAPI > +EmacReadMacAddress ( > + OUT EFI_MAC_ADDRESS *MacAddress, > + IN UINT32 MacBaseAddress > + ) > +{ > + UINT32 MacAddrHighValue; > + UINT32 MacAddrLowValue; > + > + DEBUG ((EFI_D_INFO, "SNP:MAC: %a ()\r\n", __FUNCTION__)); > + > + // Read the Mac Addr high register > + MacAddrHighValue =3D (MmioRead32 (MacBaseAddress +DW_EMAC_GMACGRP_MAC_= ADDRESS0_HIGH_OFST) & 0xFFFF); > + // Read the Mac Addr low register > + MacAddrLowValue =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMACGRP_MAC_A= DDRESS0_LOW_OFST); > + > + SetMem (MacAddress, sizeof(*MacAddress), 0); > + MacAddress->Addr[0] =3D (MacAddrLowValue & 0xFF); > + MacAddress->Addr[1] =3D (MacAddrLowValue & 0xFF00) >> 8; > + MacAddress->Addr[2] =3D (MacAddrLowValue & 0xFF0000) >> 16; > + MacAddress->Addr[3] =3D (MacAddrLowValue & 0xFF000000) >> 24; > + MacAddress->Addr[4] =3D (MacAddrHighValue & 0xFF); > + MacAddress->Addr[5] =3D (MacAddrHighValue & 0xFF00) >> 8; > + > + DEBUG ((EFI_D_INFO, "SNP:MAC: MAC Address =3D %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 UINT32 MacBaseAddress > + ) > +{ > + DEBUG ((EFI_D_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 UINT32 MacBaseAddress > + ) > +{ > + UINT32 DmaConf; > + UINT32 DmaOpmode; > + UINT32 InterruptEnable; > + > + DEBUG ((EFI_D_INFO, "SNP:MAC: %a ()\r\n", __FUNCTION__)); > + > + // This section provides the instructions for initializing the DMA reg= isters in the proper sequence. This > + // initialization sequence can be done after the EMAC interface initia= lization has been completed. Perform > + // the following steps to initialize the DMA: > + // 1. Provide a software reset to reset all of the EMAC internal regis= ters and logic. (DMA Register 0 (Bus > + // Mode Register) =E2=80=93 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 + D= W_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 t= his register again (as > + // mentioned in 12 on page 1-72) before triggering the DMA operations.= =E2=80=A0 > + > + // 4. Program the following fields to initialize the Bus Mode Register= by setting values in DMA Register 0 > + // (Bus Mode Register): > + // =E2=80=A2 Mixed Burst and AAL > + // =E2=80=A2 Fixed burst or undefined burst > + // =E2=80=A2 Burst length values and burst mode values > + // =E2=80=A2 Descriptor Length (only valid if Ring Mode is used) > + // =E2=80=A2 TX and RX DMA Arbitration scheme > + // 5. Program the interface options in Register 10 (AXI Bus Mode Regis= ter). If fixed burst-length is enabled, > + // then select the maximum burst-length possible on the bus (bits[7:1]= ).=E2=80=A0 > + > + DmaConf =3D DW_EMAC_DMAGRP_BUS_MODE_FB_SET_MSK | DW_EMAC_DMAGRP_BUS_MO= DE_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 ad= dition, ensure that the receive descriptors > + // are owned by DMA (bit 31 of descriptor should be set). When OSF mod= e is used, at least two > + // descriptors are required. > + // 7. Make sure that your software creates three or more different tra= nsmit 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) a= nd 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): > + // =E2=80=A2 Receive and Transmit Store And Forward=E2=80=A0 > + // =E2=80=A2 Receive and Transmit Threshold Control (RTC and TTC)=E2= =80=A0 > + // =E2=80=A2 Hardware Flow Control enable=E2=80=A0 > + // =E2=80=A2 Flow Control Activation and De-activation thresholds for = MTL Receive and Transmit FIFO buffers > + // (RFA and RFD)=E2=80=A0 > + // =E2=80=A2 Error frame and undersized good frame forwarding enable= =E2=80=A0 > + // =E2=80=A2 OSF Mode=E2=80=A0 > + > + DmaOpmode =3D DW_EMAC_DMAGRP_OPERATION_MODE_FTF_SET_MSK | DW_EMAC_DMAG= RP_OPERATION_MODE_TSF_SET_MSK; > + MmioOr32 (MacBaseAddress + > + DW_EMAC_DMAGRP_OPERATION_MODE_OFST, > + DmaOpmode); > + //while (DW_EMAC_DMAGRP_OPERATION_MODE_FTF_GET (MmioRead32 (MacBaseAdd= ress + DW_EMAC_DMAGRP_OPERATION_MODE_OFST))); > + > + // 10.Clear the interrupt requests, by writing to those bits of the st= atus register (interrupt bits only) that are > + // set. For example, by writing 1 into bit 16, the normal interrupt su= mmary 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 Enabl= e Register). > + InterruptEnable =3D 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 previou= s transactions are complete.=E2=80=A0 > + // Note: If any previous transaction is still in progress when you rea= d the Register 11 (AHB or AXI > + // Status), then it is strongly recommended to check the slave compone= nts addressed by the > + // master interface. > + if (MmioRead32 (MacBaseAddress + DW_EMAC_DMAGRP_AHB_OR_AXI_STATUS_OFST= ) !=3D 0) { > + DEBUG ((EFI_D_INFO, "SNP:MAC: Error! Previous AXI transaction is sti= ll in progress\r\n")); > + //check the slave components addressed by the master interface > + return EFI_DEVICE_ERROR; > + } > + > + DmaOpmode =3D DW_EMAC_DMAGRP_OPERATION_MODE_ST_SET_MSK | DW_EMAC_DMAGR= P_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 UINT32 MacBaseAddress > + ) > +{ > + INTN Index; > + DESIGNWARE_HW_DESCRIPTOR *TxDescriptor; > + > + for (Index =3D 0; Index < CONFIG_TX_DESCR_NUM; Index++) { > + TxDescriptor =3D (VOID*)EmacDriver->TxdescRingMap[0]+(Index*16);; > + TxDescriptor->Addr =3D (UINT32)(UINTN) EmacDriver->TxBufferMap[0]= + (Index*2048); > + TxDescriptor->AddrNext =3D (UINT32)(UINTN) EmacDriver->TxdescRing= Map[0] + ((Index + 1)*16); > + TxDescriptor->Tdes0 =3D TDES0_TXCHAIN; > + TxDescriptor->Tdes1 =3D 0; > + } > + > + // Correcting the last pointer of the chain > + TxDescriptor->AddrNext =3D (UINT32)(UINTN) EmacDriver->TxdescRingMap[0= ]; > + > + // Write the address of tx descriptor list > + MmioWrite32(MacBaseAddress + > + DW_EMAC_DMAGRP_TRANSMIT_DESCRIPTOR_LIST_ADDRESS_OFST, > + (UINT32)(UINTN) EmacDriver->TxdescRingMap[0]); > + > + // Initialize the descriptor number > + EmacDriver->TxCurrentDescriptorNum =3D 0; > + EmacDriver->TxNextDescriptorNum =3D 0; > + > + return EFI_SUCCESS; > +} > + > + > +EFI_STATUS > +EFIAPI > +EmacSetupRxdesc ( > + IN EMAC_DRIVER *EmacDriver, > + IN UINT32 MacBaseAddress > + ) > +{ > + INTN Index; > + DESIGNWARE_HW_DESCRIPTOR *RxDescriptor; > + > + for (Index =3D 0; Index < CONFIG_RX_DESCR_NUM; Index++) { > + RxDescriptor =3D (VOID*) (EmacDriver->RxdescRingMap[0] + (Index*1= 6)); > + RxDescriptor->Addr =3D (UINT32)(UINTN) EmacDriver->RxBufferMap[0] + = (Index*2048); > + RxDescriptor->AddrNext =3D (UINT32)(UINTN) EmacDriver->RxdescRingMap= [0] + ((Index + 1)*16); > + RxDescriptor->Tdes0 =3D RDES0_OWN; > + RxDescriptor->Tdes1 =3D RDES1_CHAINED | RX_MAX_PACKET; > + } > + > + // Correcting the last pointer of the chain > + RxDescriptor->AddrNext =3D (UINT32)(UINTN) EmacDriver->RxdescRingMap[0= ]; > + > + // Write the address of tx descriptor list > + MmioWrite32(MacBaseAddress + > + DW_EMAC_DMAGRP_RECEIVE_DESCRIPTOR_LIST_ADDRESS_OFST, > + (UINT32)(UINTN) EmacDriver->RxdescRingMap[0]); > + > + // Initialize the descriptor number > + EmacDriver->RxCurrentDescriptorNum =3D 0; > + EmacDriver->RxNextDescriptorNum =3D 0; > + > + return EFI_SUCCESS; > +} > + > + > +VOID > +EFIAPI > +EmacStartTransmission ( > + IN UINT32 MacBaseAddress > + ) > +{ > + DEBUG ((EFI_D_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 UINT32 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 =3D 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 =3D DW_EMAC_GMACGRP_MAC_FRAME_FILTER_RESET; > + > + if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) { > + //DEBUG ((EFI_D_INFO, "SNP:MAC: Enable Unicast Frame Reception\n")); > + } > + > + if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) { > + > + //DEBUG ((EFI_D_INFO, "SNP:MAC: Enable Hash Multicast Frame Receptio= n\n")); > + MacFilter |=3D 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 =3D 0; Count < NumMfilter; Count++) { > + // Generate a 32-bit CRC > + Crc =3D GenEtherCrc32 (&Mfilter[Count], 6); > + // reserve CRC + take upper 8 bit =3D take lower 8 bit and rever= se it > + Val =3D 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 th= e Hash Table Register 5. > + HashReg =3D (Val >> 5); > + HashBit =3D (Val & 31); > + > + Reg =3D MmioRead32(MacBaseAddress + HASH_TABLE_REG(HashReg)); Space before '(' (applies everywhere) > + // set 1 to HashBit of HashReg > + // for example, set 1 to bit 31 to Reg 5 as in above example > + Reg |=3D (1 << HashBit); > + MmioWrite32(MacBaseAddress + HASH_TABLE_REG(HashReg), Reg); > + } > + } > + } > + > + if ((ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) =3D= =3D 0) { > + MacFilter |=3D DW_EMAC_GMACGRP_MAC_FRAME_FILTER_DBF_SET_MSK; > + } else if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST= ) { > + } > + > + if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) { > + MacFilter |=3D DW_EMAC_GMACGRP_MAC_FRAME_FILTER_PR_SET_MSK; > + } > + > + if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULT= ICAST) { > + MacFilter |=3D ( 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 =3D 0; > + Remainder =3D 0xFFFFFFFF; // 0xFFFFFFFF is standard seed for Ethern= et > + > + // Convert Mac Address to array of bytes > + Ptr =3D (UINT8*)Mac; > + > + // Generate the Crc bit-by-bit (LSB first) > + while (AddrLen--) { > + Remainder ^=3D *Ptr++; > + for (Iter =3D 0;Iter < 8;Iter++) { > + // Check if exponent is set > + if (Remainder & 1) { > + Remainder =3D (Remainder >> 1) ^ CRC_POLYNOMIAL; > + } else { > + Remainder =3D (Remainder >> 1) ^ 0; > + } > + } > + } > + > + return (~Remainder); > +} > + > + > +STATIC CONST UINT8 NibbleTab[] =3D { > + /* 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 X > + ) > +{ > + return (NibbleTab[X & 0xf] << 4) | NibbleTab[X >> 4]; > +} > + > + > +VOID > +EFIAPI > +EmacStopTxRx ( > + IN UINT32 MacBaseAddress > + ) > +{ > + DEBUG ((EFI_D_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 UINT32 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 UINT32 MacBaseAddress > + ) > +{ > + UINT32 DmaStatus; > + UINT32 ErrorBit; > + UINT32 Mask =3D 0; > + > + DmaStatus =3D MmioRead32 (MacBaseAddress + > + DW_EMAC_DMAGRP_STATUS_OFST); > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_NIS_SET_MSK) { > + Mask |=3D DW_EMAC_DMAGRP_STATUS_NIS_SET_MSK; > + // Rx interrupt > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_RI_SET_MSK) { > + *IrqStat |=3D EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT; > + Mask |=3D DW_EMAC_DMAGRP_STATUS_RI_SET_MSK; > + } else { > + *IrqStat &=3D ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT; > + } > + // Tx interrupt > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_TI_SET_MSK) { > + *IrqStat |=3D EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT; > + Mask |=3D DW_EMAC_DMAGRP_STATUS_TI_SET_MSK; > + } else { > + *IrqStat &=3D ~EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT; > + } > + // Tx Buffer > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_TU_SET_MSK){ > + Mask |=3D DW_EMAC_DMAGRP_STATUS_TU_SET_MSK; > + } > + // Early receive interrupt > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_ERI_SET_MSK) { > + Mask |=3D DW_EMAC_DMAGRP_STATUS_ERI_SET_MSK; > + } > + } > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_AIS_SET_MSK) { > + Mask |=3D DW_EMAC_DMAGRP_STATUS_AIS_SET_MSK; > + // Transmit process stop > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_TPS_SET_MSK) { > + DEBUG ((EFI_D_INFO, "SNP:MAC: Transmit process stop\n")); > + Mask |=3D DW_EMAC_DMAGRP_STATUS_TPS_SET_MSK; > + } > + // Transmit jabber timeout > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_TJT_SET_MSK) { > + DEBUG ((EFI_D_INFO, "SNP:MAC: Transmit jabber timeout\n")); > + Mask |=3D DW_EMAC_DMAGRP_STATUS_TJT_SET_MSK; > + } > + // Receive FIFO overflow > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_OVF_SET_MSK) { > + DEBUG ((EFI_D_INFO, "SNP:MAC: Receive FIFO overflow\n")); > + Mask |=3D DW_EMAC_DMAGRP_STATUS_OVF_SET_MSK; > + } > + // Transmit FIFO underflow > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_UNF_SET_MSK) { > + DEBUG ((EFI_D_INFO, "SNP:MAC: Receive FIFO underflow\n")); > + Mask |=3D DW_EMAC_DMAGRP_STATUS_UNF_SET_MSK; > + } > + // Receive buffer unavailable > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_RU_SET_MSK) { > + //DEBUG ((EFI_D_INFO, "SNP:MAC: Receive buffer unavailable\n")); > + Mask |=3D DW_EMAC_DMAGRP_STATUS_RU_SET_MSK; > + } > + > + // Receive process stop > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_RPS_SET_MSK) { > + DEBUG ((EFI_D_INFO, "SNP:MAC: Receive process stop\n")); > + Mask |=3D DW_EMAC_DMAGRP_STATUS_RPS_SET_MSK; > + } > + // Receive watchdog timeout > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_RWT_SET_MSK) { > + DEBUG ((EFI_D_INFO, "SNP:MAC: Receive watchdog timeout\n")); > + Mask |=3D DW_EMAC_DMAGRP_STATUS_RWT_SET_MSK; > + } > + // Early transmit interrupt > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_ETI_SET_MSK) { > + //DEBUG ((EFI_D_INFO, "SNP:MAC: Early transmit interrupt\n")); > + Mask |=3D DW_EMAC_DMAGRP_STATUS_ETI_SET_MSK; > + } > + // Fatal bus error > + if (DmaStatus & DW_EMAC_DMAGRP_STATUS_FBI_SET_MSK) { > + DEBUG ((EFI_D_INFO, "SNP:MAC: Fatal bus error:\n")); > + Mask |=3D DW_EMAC_DMAGRP_STATUS_FBI_SET_MSK; > + > + ErrorBit =3D DW_EMAC_DMAGRP_STATUS_EB_GET (DmaStatus); > + switch (ErrorBit) { > + case RX_DMA_WRITE_DATA_TRANSFER_ERROR: > + DEBUG ((EFI_D_INFO, "SNP:MAC: Rx Dma write data transfer error= \n")); > + break; > + case TX_DMA_READ_DATA_TRANSFER_ERROR: > + DEBUG ((EFI_D_INFO, "SNP:MAC: Tx Dma read data transfer error\= n")); > + break; > + case RX_DMA_DESCRIPTOR_WRITE_ACCESS_ERROR: > + DEBUG ((EFI_D_INFO, "SNP:MAC: Rx Dma descriptor write access e= rror\n")); > + break; > + case RX_DMA_DESCRIPTOR_READ_ACCESS_ERROR: > + DEBUG ((EFI_D_INFO, "SNP:MAC: Rx Dma descriptor read access er= ror\n")); > + break; > + case TX_DMA_DESCRIPTOR_WRITE_ACCESS_ERROR: > + DEBUG ((EFI_D_INFO, "SNP:MAC: Tx Dma descriptor write access e= rror\n")); > + break; > + case TX_DMA_DESCRIPTOR_READ_ACCESS_ERROR: > + DEBUG ((EFI_D_INFO, "SNP:MAC: Tx Dma descriptor read access er= ror\n")); > + break; > + default: > + DEBUG ((EFI_D_INFO, "SNP:MAC: Undefined error\n")); > + break; > + } > + } > + } > + MmioOr32 (MacBaseAddress + > + DW_EMAC_DMAGRP_STATUS_OFST, > + Mask); > +} > + > + > +VOID > +EFIAPI > +EmacGetStatistic ( > + OUT EFI_NETWORK_STATISTICS* Statistic, > + IN UINT32 MacBaseAddress > + ) > +{ > + EFI_NETWORK_STATISTICS* Stats; > + > + DEBUG ((EFI_D_INFO, "SNP:MAC: %a ()\r\n", __FUNCTION__)); > + > + // Allocate Resources > + Stats =3D AllocateZeroPool (sizeof (EFI_NETWORK_STATISTICS)); > + if (Stats =3D=3D NULL) { > + return; > + } > + > + Stats->RxTotalFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_RXFRAMECOUNT_GB_OFST); > + Stats->RxUndersizeFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_RXUNDERSIZE_G_OFST); > + Stats->RxOversizeFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_RXOVERSIZE_G_OFST); > + Stats->RxUnicastFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_RXUNICASTFRAMES_G_OFST); > + Stats->RxBroadcastFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_RXBROADCASTFRAMES_G_OFST); > + Stats->RxMulticastFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_RXMULTICASTFRAMES_G_OFST); > + Stats->RxCrcErrorFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_RXCRCERROR_OFST); > + Stats->RxTotalBytes =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_RXOCTETCOUNT_GB_OFST); > + Stats->RxGoodFrames =3D Stats->RxUnicastFrames + Stats->RxBroadca= stFrames + Stats->RxMulticastFrames; > + > + Stats->TxTotalFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_TXFRAMECOUNT_GB_OFST); > + Stats->TxGoodFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_TXFRAMECOUNT_G_OFST); > + Stats->TxOversizeFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_TXOVERSIZE_G_OFST); > + Stats->TxUnicastFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_TXUNICASTFRAMES_GB_OFST); > + Stats->TxBroadcastFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_TXBROADCASTFRAMES_G_OFST); > + Stats->TxMulticastFrames =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_TXMULTICASTFRAMES_G_OFST); > + Stats->TxTotalBytes =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_TXOCTETCOUNT_GB_OFST); > + Stats->Collisions =3D MmioRead32 (MacBaseAddress + DW_EMAC_GMAC= GRP_TXLATECOL_OFST) + > + MmioRead32 (MacBaseAddress + DW_EMAC_GMACGR= P_TXEXESSCOL_OFST); > + > + // Fill in the statistics > + CopyMem(Statistic, Stats, sizeof(EFI_NETWORK_STATISTICS)); > +} > + > + > +VOID > +EFIAPI > +EmacConfigAdjust ( > + IN UINT32 Speed, > + IN UINT32 Duplex, > + IN UINT32 MacBaseAddress > + ) > +{ > + UINT32 Config; > + > + Config =3D0; > + if (Speed !=3D SPEED_1000) > + Config |=3D DW_EMAC_GMACGRP_MAC_CONFIGURATION_PS_SET_MSK; > + > + if (Speed =3D=3D SPEED_100) > + Config |=3D DW_EMAC_GMACGRP_MAC_CONFIGURATION_FES_SET_MSK; > + > + if (Duplex =3D=3D DUPLEX_FULL) > + Config |=3D 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/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.c b/Silic= on/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.c > new file mode 100755 > index 000000000000..65a53b651814 > --- /dev/null > +++ b/Silicon/DesignWare/Drivers/DwEmacSnpDxe/PhyDxeUtil.c > @@ -0,0 +1,621 @@ > +/** @file > + > + Copyright (c) 2011 - 2019, Intel Corporaton. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > + > + 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. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the = BSD License > + which accompanies this distribution. The full text of the license may= be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD 3 Clause LICENSE ON AN "AS IS= " BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR I= MPLIED. > +**/ > + > + > +#include "PhyDxeUtil.h" > +#include "EmacDxeUtil.h" > + > +EFI_STATUS > +EFIAPI > +PhyDxeInitialization ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ) > +{ > + DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + // initialize the phyaddr > + PhyDriver->PhyAddr =3D 0; > + PhyDriver->PhyCurrentLink =3D LINK_DOWN; > + PhyDriver->PhyOldLink =3D LINK_DOWN; > + > + if (PhyDetectDevice (PhyDriver, MacBaseAddress) !=3D EFI_SUCCESS) { Use a status variable and EFI_ERROR() > + return EFI_NOT_FOUND; > + } > + > + PhyConfig (PhyDriver, MacBaseAddress); > + > + return EFI_SUCCESS; > +} > + > + > +// PHY detect device > +EFI_STATUS > +EFIAPI > +PhyDetectDevice ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ) > +{ > + UINT32 PhyAddr; > + > + DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + for (PhyAddr =3D 0; PhyAddr < 32; PhyAddr++) { > + if (PhyReadId (PhyAddr, MacBaseAddress) =3D=3D EFI_SUCCESS) { Please use a Status variable and EFI_ERROR() here, and handle the error condition not the success condition. > + PhyDriver->PhyAddr =3D PhyAddr; > + return EFI_SUCCESS; > + } > + } > + Print (L"SNP:PHY: Fail to detect Ethernet PHY!\r\n"); Don't use print() in drivers > + return EFI_NOT_FOUND; > +} > + > + > +EFI_STATUS > +EFIAPI > +PhyConfig ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ) > +{ > + EFI_STATUS Status; > + > + DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + Status =3D 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 UINT32 MacBaseAddress > + ) > +{ > + UINT32 TimeOut; > + UINT32 Data32; > + EFI_STATUS Status; > + > + DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + // PHY Basic Control Register reset > + PhyWrite (PhyDriver->PhyAddr, PHY_BASIC_CTRL, PHYCTRL_RESET, MacBaseAd= dress); > + > + // Wait for completion > + TimeOut =3D 0; > + do { > + // Read PHY_BASIC_CTRL register from PHY > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_BASIC_CTRL, &Data32, Mac= BaseAddress); > + if (EFI_ERROR(Status)) { > + return Status; > + } > + // Wait until PHYCTRL_RESET become zero > + if ((Data32 & PHYCTRL_RESET) =3D=3D 0) { > + break; > + } > + MicroSecondDelay(1); > + } while (TimeOut++ < PHY_TIMEOUT); > + if (TimeOut >=3D PHY_TIMEOUT) { > + DEBUG ((EFI_D_INFO, "SNP:PHY: ERROR! PhySoftReset timeout\n")); > + return EFI_TIMEOUT; > + } > + > + return EFI_SUCCESS; > +} > + > + > +// PHY read ID > +EFI_STATUS > +EFIAPI > +PhyReadId ( > + IN UINT32 PhyAddr, > + IN UINT32 MacBaseAddress > + ) > +{ > + EFI_STATUS Status; > + UINT32 PhyId1; > + UINT32 PhyId2; > + > + //DEBUG ((EFI_D_INFO, "SNP:PHY: %a (0x%02X)\r\n", __FUNCTION__, PhyAdd= r)); > + > + Status =3D PhyRead (PhyAddr, PHY_ID1, &PhyId1, MacBaseAddress); > + if (EFI_ERROR(Status)) return Status; Use proper { } and put the return statement on a separate line. > + Status =3D PhyRead (PhyAddr, PHY_ID2, &PhyId2, MacBaseAddress); > + if (EFI_ERROR(Status)) return Status; Same here > + > + if (PhyId1 =3D=3D PHY_INVALID_ID || PhyId2 =3D=3D PHY_INVALID_ID) { > + return EFI_NOT_FOUND; > + } > + > + DEBUG ((EFI_D_INFO, "SNP:PHY: Ethernet PHY detected. PHY_ID1=3D0x%04X,= PHY_ID2=3D0x%04X, PHY_ADDR=3D0x%02X\r\n", PhyId1, PhyId2, PhyAddr)); > + return EFI_SUCCESS; > +} > + > + > +VOID > +EFIAPI > +PhyConfigSkew ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ) > +{ > + Phy9031ExtendedWrite(PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC, PHY_= KSZ9031RN_DEV_ADDR, PHY_KSZ9031RN_CONTROL_PAD_SKEW_REG, PHY_KSZ9031RN_CONTR= OL_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_P= AD_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_DA= TA_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_DA= TA_PAD_SKEW_VALUE, MacBaseAddress); > + Wrap overly long lines > +} > + > + > +VOID > +EFIAPI > +PhyDisplayConfigSkew ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ) > +{ > + // Display skew configuration > + DEBUG ((EFI_D_INFO, "SNP:PHY: Control Signal Pad Skew =3D 0x%04X\r\n",= Phy9031ExtendedRead(PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC, PHY_KSZ90= 31RN_DEV_ADDR, PHY_KSZ9031RN_CONTROL_PAD_SKEW_REG, MacBaseAddress))); > + DEBUG ((EFI_D_INFO, "SNP:PHY: RGMII Clock Pad Skew =3D 0x%04X\r\n",= Phy9031ExtendedRead(PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC, PHY_KSZ90= 31RN_DEV_ADDR, PHY_KSZ9031RN_CLK_PAD_SKEW_REG, MacBaseAddress))); > + DEBUG ((EFI_D_INFO, "SNP:PHY: RGMII RX Data Pad Skew =3D 0x%04X\r\n",= Phy9031ExtendedRead(PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC, PHY_KSZ90= 31RN_DEV_ADDR, PHY_KSZ9031RN_RX_DATA_PAD_SKEW_REG, MacBaseAddress))); > + DEBUG ((EFI_D_INFO, "SNP:PHY: RGMII TX Data Pad Skew =3D 0x%04X\r\n",= Phy9031ExtendedRead(PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC, PHY_KSZ90= 31RN_DEV_ADDR, PHY_KSZ9031RN_TX_DATA_PAD_SKEW_REG, MacBaseAddress))); Same here > +} > + > +VOID > +EFIAPI > +PhyConfigFlpBurstTiming ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 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_M= MD_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_M= MD_D0_FLP_16MS_HI, MacBaseAddress); and here > +} > + > +VOID > +EFIAPI > +PhyDisplayFlpBurstTiming ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ) > +{ > + // Display Auto-Negotiation FLP burst transmit timing > + DEBUG ((EFI_D_INFO, "SNP:PHY: AN FLP Burst Transmit - LO =3D 0x%04X\r\= n", Phy9031ExtendedRead(PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC, PHY_KS= Z9031RN_MMD_DEV_ADDR_00, PHY_KSZ9031RN_MMD_D0_FLP_LO_REG, MacBaseAddress)))= ; > + DEBUG ((EFI_D_INFO, "SNP:PHY: AN FLP Burst Transmit - HI =3D 0x%04X\r\= n", Phy9031ExtendedRead(PhyDriver, PHY_KSZ9031_MOD_DATA_NO_POST_INC, PHY_KS= Z9031RN_MMD_DEV_ADDR_00, PHY_KSZ9031RN_MMD_D0_FLP_HI_REG, MacBaseAddress)))= ; > +} > + > +// Do auto-negotiation > +EFI_STATUS > +EFIAPI > +PhyAutoNego ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ) > +{ > + EFI_STATUS Status; > + UINT32 PhyControl; > + UINT32 PhyStatus; > + UINT32 Features; > + > + DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + // Read PHY Status > + Status =3D 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) =3D=3D 0) { > + DEBUG ((EFI_D_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 =3D 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/100Bas= e-T/100Base-T full-duplex > + Features |=3D (PHYANA_10BASET | PHYANA_10BASETFD | PHYANA_100BASETX | = PHYANA_100BASETXFD); > + PhyWrite (PhyDriver->PhyAddr, PHY_AUTO_NEG_ADVERT, Features, MacBaseAd= dress); > + > + // Read PHY Auto-Nego Advertise capabilities register for 1000 Base-T > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_1000BASE_T_CONTROL, &Featu= res, MacBaseAddress); > + if (EFI_ERROR(Status)) return Status; > + > + // Set Advertise capabilities for 1000 Base-T/1000 Base-T full-duplex > + Features |=3D (PHYADVERTISE_1000FULL | PHYADVERTISE_1000HALF); > + PhyWrite (PhyDriver->PhyAddr, PHY_1000BASE_T_CONTROL, Features, MacBas= eAddress); > + > + // Read control register > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_BASIC_CTRL, &PhyControl, M= acBaseAddress); > + if (EFI_ERROR(Status)) return Status; > + > + // Enable Auto-Negotiation > + PhyControl |=3D PHYCTRL_AUTO_EN; > + // Restart auto-negotiation > + PhyControl |=3D PHYCTRL_RST_AUTO; > + // Write this configuration > + PhyWrite (PhyDriver->PhyAddr, PHY_BASIC_CTRL, PhyControl, MacBaseAddre= ss); > + > + return EFI_SUCCESS; > +} > + > + > +EFI_STATUS > +EFIAPI > +PhyLinkAdjustEmacConfig ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ) > +{ > + UINT32 Speed; > + UINT32 Duplex; > + EFI_STATUS Status; > + > + //DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + Status =3D EFI_SUCCESS; > + Speed =3D SPEED_10; > + Duplex =3D DUPLEX_HALF; > + > + if (PhyCheckLinkStatus (PhyDriver, MacBaseAddress) =3D=3D EFI_SUCCESS)= { Use a status variable and EFI_ERROR() > + PhyDriver->PhyCurrentLink =3D LINK_UP; > + } else { > + PhyDriver->PhyCurrentLink =3D LINK_DOWN; > + } > + > + if (PhyDriver->PhyOldLink !=3D PhyDriver->PhyCurrentLink) { > + if (PhyDriver->PhyCurrentLink =3D=3D LINK_UP) { > + Print (L"SNP:PHY: Link is up - Network Cable is Plugged\r\n"); > + PhyReadCapability (PhyDriver, &Speed, &Duplex, MacBaseAddress); > + EmacConfigAdjust (Speed, Duplex, MacBaseAddress); > + Status =3D EFI_SUCCESS; > + } else { > + Print (L"SNP:PHY: Link is Down - Network Cable is Unplugged?\r\n")= ; > + Status =3D EFI_NOT_READY; > + } Don't use print() in drivers. > + } else if (PhyDriver->PhyCurrentLink =3D=3D LINK_DOWN) { > + Status =3D EFI_NOT_READY; > + } > + > + PhyDriver->PhyOldLink =3D PhyDriver->PhyCurrentLink; > + > + return Status; > +} > + > + > +EFI_STATUS > +EFIAPI > +PhyCheckLinkStatus ( > + IN PHY_DRIVER* PhyDriver, > + IN UINT32 MacBaseAddress > + ) > +{ > + EFI_STATUS Status; > + UINT32 Data32; > + UINTN TimeOut; > + UINT32 PhyBasicStatus; > + > + //DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + // Get the PHY Status > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_BASIC_STATUS, &PhyBasicSta= tus, 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 =3D 0; > + do { > + // Read PHY_BASIC_STATUS register from PHY > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_BASIC_STATUS, &Data32, M= acBaseAddress); > + 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 >=3D PHY_TIMEOUT) { > + // Link is down > + return EFI_TIMEOUT; > + } > + > + // Wait until autonego process has completed > + TimeOut =3D 0; > + do { > + // Read PHY_BASIC_STATUS register from PHY > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_BASIC_STATUS, &Data32, M= acBaseAddress); > + if (EFI_ERROR(Status)) { Space before ( > + return Status; > + } > + // Wait until PHYSTS_AUTO_COMP become one > + if (Data32 & PHYSTS_AUTO_COMP) { > + DEBUG ((EFI_D_INFO, "SNP:PHY: Auto Negotiation completed\r\n")); > + break; > + } > + MicroSecondDelay(1); > + } while (TimeOut++ < PHY_TIMEOUT); > + if (TimeOut >=3D PHY_TIMEOUT) { > + DEBUG ((EFI_D_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 UINT32 MacBaseAddress > + ) > +{ > + EFI_STATUS Status; > + UINT32 PartnerAbilityGb; > + UINT32 AdvertisingGb; > + UINT32 CommonAbilityGb; > + UINT32 PartnerAbility; > + UINT32 Advertising; > + UINT32 CommonAbility; > + > + //DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + // For 1000 Base-T > + > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_1000BASE_T_STATUS, &Partne= rAbilityGb, MacBaseAddress); > + if (EFI_ERROR(Status)) return Status; > + > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_1000BASE_T_CONTROL, &Adver= tisingGb, MacBaseAddress); > + if (EFI_ERROR(Status)) return Status; > + > + CommonAbilityGb =3D PartnerAbilityGb & (AdvertisingGb << 2); > + > + // For 10/100 Base-T > + > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_AUTO_NEG_LINK_ABILITY, &Pa= rtnerAbility, MacBaseAddress); > + if (EFI_ERROR(Status)) return Status; > + > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_AUTO_NEG_EXP, &Advertising= , MacBaseAddress); > + if (EFI_ERROR(Status)) return Status; > + > + CommonAbility =3D PartnerAbility & Advertising; > + > + // Determine the Speed and Duplex > + if (PartnerAbilityGb & (PHYLPA_1000FULL | PHYLPA_1000HALF)) { > + *Speed =3D SPEED_1000; > + if (CommonAbilityGb & PHYLPA_1000FULL) { > + *Duplex =3D DUPLEX_FULL; > + } > + } else if (CommonAbility & (PHYLPA_100FULL | PHYLPA_100HALF)) { > + *Speed =3D SPEED_100; > + if (CommonAbility & PHYLPA_100FULL) { > + *Duplex =3D DUPLEX_FULL; > + } else if (CommonAbility & PHYLPA_10FULL) { > + *Duplex =3D DUPLEX_FULL; > + } > + } > + > + PhyDisplayAbility (*Speed, *Duplex); > + > + return EFI_SUCCESS; > +} > + > + > +VOID > +EFIAPI > +PhyDisplayAbility ( > + IN UINT32 Speed, > + IN UINT32 Duplex > + ) > +{ > + //DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + Print (L"SNP:PHY: "); > + switch (Speed) { > + case SPEED_1000: > + Print (L"1 Gbps - "); > + break; > + case SPEED_100: > + Print (L"100 Mbps - "); > + break; > + case SPEED_10: > + Print (L"10 Mbps - "); > + break; > + default: > + Print (L"Invalid link speed"); > + break; > + } > + > + switch (Duplex) { > + case DUPLEX_FULL: > + Print (L"Full Duplex\n"); > + break; > + case DUPLEX_HALF: > + Print (L"Half Duplex\n"); > + break; > + default: > + Print (L"Invalid duplex mode\n"); > + break; > + } Don't use print() in drivers. > +} > + > + > +// Function to read from MII register (PHY Access) > +EFI_STATUS > +EFIAPI > +PhyRead ( > + IN UINT32 Addr, > + IN UINT32 Reg, > + OUT UINT32 *Data, > + IN UINT32 MacBaseAddress > + ) > +{ > + UINT32 MiiConfig; > + UINT32 Count; > + > + //DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + // Check it is a valid Reg > + ASSERT(Reg < 31); > + > + MiiConfig =3D ((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, MiiCon= fig); > + > + // Wait for busy bit to clear > + Count =3D 0; > + while (Count < 10000) { > + if (!(DW_EMAC_GMACGRP_GMII_ADDRESS_GB_GET(MmioRead32(MacBaseAddress = + DW_EMAC_GMACGRP_GMII_ADDRESS_OFST)))) > + { > + *Data =3D DW_EMAC_GMACGRP_GMII_DATA_GD_GET(MmioRead32(MacBaseAddre= ss + DW_EMAC_GMACGRP_GMII_DATA_OFST)); > + return EFI_SUCCESS; > + } Please fix indentation > + Count++; > + }; > + DEBUG ((EFI_D_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 UINT32 MacBaseAddress > + ) > +{ > + UINT32 MiiConfig; > + UINT32 Count; > + > + //DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + // Check it is a valid Reg > + ASSERT(Reg < 31); > + > + MiiConfig =3D ((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, MiiCon= fig); Space before ( > + > + // Wait for busy bit to clear > + Count =3D 0; > + while (Count < 1000) { > + if (!(DW_EMAC_GMACGRP_GMII_ADDRESS_GB_GET(MmioRead32(MacBaseAddres= s + DW_EMAC_GMACGRP_GMII_ADDRESS_OFST)))) > + return EFI_SUCCESS; Use { } Should you add a MemoryFence() here? > + 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 UINT32 MacBaseAddress > + ) > +{ > + //DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + PhyWrite(PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_CTRL_REG, DevAddr, MacB= aseAddress); > + PhyWrite(PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_REGDATA_REG, Regnum, Ma= cBaseAddress); > + PhyWrite(PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_CTRL_REG, (Mode << 14) = | DevAddr, MacBaseAddress); Space before ( > + 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 UINT32 MacBaseAddress > + ) > +{ > + EFI_STATUS Status; > + UINT32 Data32; > + > + //DEBUG ((EFI_D_INFO, "SNP:PHY: %a ()\r\n", __FUNCTION__)); > + > + PhyWrite(PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_CTRL_REG, DevAddr, MacB= aseAddress); > + PhyWrite(PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_REGDATA_REG, Regnum, Ma= cBaseAddress); > + PhyWrite(PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_CTRL_REG, (Mode << 14) = | DevAddr, MacBaseAddress); > + Space before ( > + Status =3D PhyRead (PhyDriver->PhyAddr, PHY_KSZ9031RN_MMD_REGDATA_REG,= &Data32, MacBaseAddress); > + if (EFI_ERROR(Status)) return 0; Use { } and put return on a separate line > + > + return Data32; > +} > + > + > -- > 2.17.1 >