Reviewed-by: Nate DeSimone <nathaniel.l.desim...@intel.com> > -----Original Message----- > From: Luo, Heng <heng....@intel.com> > Sent: Sunday, January 31, 2021 5:37 PM > To: devel@edk2.groups.io > Cc: Chaganty, Rangasai V <rangasai.v.chaga...@intel.com>; Desimone, > Nathaniel L <nathaniel.l.desim...@intel.com> > Subject: [PATCH 16/40] TigerlakeSiliconPkg/IpBlock: Add Gbe component > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171 > > Adds the following files: > * IpBlock/Gbe/IncludePrivate > * IpBlock/Gbe/Library > * IpBlock/Gbe/LibraryPrivate > > Cc: Sai Chaganty <rangasai.v.chaga...@intel.com> > Cc: Nate DeSimone <nathaniel.l.desim...@intel.com> > Signed-off-by: Heng Luo <heng....@intel.com> > --- > > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Library/GbeMd > iLib.h | 324 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++ > > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Register/GbeR > egs.h | 68 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++ > > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/Gb > eLib.c | 121 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > +++++ > > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/Pei > DxeSmmGbeLib.inf | 43 > +++++++++++++++++++++++++++++++++++++++++++ > > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGb > eMdiLib/GbeMdiLib.c | 388 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > ++++++++++++++++++++++++++++++++++++++++ > > Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmGb > eMdiLib/PeiDxeSmmGbeMdiLib.inf | 34 > ++++++++++++++++++++++++++++++++++ > 6 files changed, 978 insertions(+) > > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Library/Gbe > MdiLib.h > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Library/Gbe > MdiLib.h > new file mode 100644 > index 0000000000..b8274ed3dc > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Library/Gbe > MdiLib.h > @@ -0,0 +1,324 @@ > +/** @file > > + Header file for GbeMdiLib. > > + > > + Conventions: > > + > > + - Prefixes: > > + Definitions beginning with "R_" are registers > > + Definitions beginning with "B_" are bits within registers > > + Definitions beginning with "V_" are meaningful values within the bits > > + Definitions beginning with "S_" are register sizes > > + Definitions beginning with "N_" are the bit position > > + - In general, PCH registers are denoted by "_PCH_" in register names > > + - Registers / bits that are different between PCH generations are denoted > by > > + "_PCH_[generation_name]_" in register/bit names. > > + - Registers / bits that are specific to PCH-H denoted by "_H_" in > register/bit > names. > > + Registers / bits that are specific to PCH-LP denoted by "_LP_" in > register/bit names. > > + e.g., "_PCH_LP_" > > + Registers / bits names without or _LP_ apply for LP. > > + - Registers / bits that are different between SKUs are denoted by > "_[SKU_name]" > > + at the end of the register/bit names > > + - Registers / bits of new devices introduced in a PCH generation will be > just > named > > + as "_PCH_" without [generation_name] inserted. > > + > > + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > +**/ > > +#ifndef _GBE_MDI_LIB_H_ > > +#define _GBE_MDI_LIB_H_ > > + > > +// > > +// Maximum loop time for GbE status check > > +// 4000 * 50 = 200 mSec in total > > +// > > +#define GBE_MAX_LOOP_TIME 4000 > > +#define GBE_ACQUIRE_MDIO_DELAY 50 > > +#define GBE_MDI_SET_PAGE_DELAY 4000 // 4 mSec delay after setting > page > > + > > +// > > +// LAN PHY MDI settings > > +// > > +// MDI Control Register Bits > > +// 31:30 Reserved > > +// This field is reserved and returns 0. > > +// 29 Interrupt Enable. > > +// When this bit is set to 1 by software, it causes the device to > assert > > +// an interrupt indicating the end of an MDI cycle. > > +// 28 Ready. > > +// Set to 1 by the device at the end of MDI transaction (i.e., > indicates a > Read or > > +// Write has been completed. It should be reset to 0 by software at the > same time the > > +// command is written. > > +// 27:26 Opcode > > +// For an MDI write, the opcode equals 01b, and for MDI read, 10b. 00b > and > > +// 11b are reserved and should not be used. > > +// 25:21 PHYAdd > > +// PHY Address > > +// 20:16 RegAdd > > +// PHY Register Address > > +// 15:0 Data > > + > > +#define B_PHY_MDI_READY BIT28 > > +#define B_PHY_MDI_READ BIT27 > > +#define B_PHY_MDI_WRITE BIT26 > > +// > > +// PHY SPECIFIC registers > > +// > > +#define B_PHY_MDI_PHY_ADDRESS_02 BIT22 > > +// > > +// PHY GENERAL registers > > +// Registers 0 to 15 are defined by the specification > > +// Registers 16 to 31 are left available to the vendor > > +// > > +#define B_PHY_MDI_PHY_ADDRESS_01 BIT21 > > +#define B_PHY_MDI_PHY_ADDRESS_MASK (BIT25 | BIT24 | BIT23 | BIT22 > | BIT21) > > +// > > +// PHY Identifier Register 2 > > +// Bits [15:10] - PHY ID Number - The PHY identifier composed of bits 3 > through 18 > > +// of the Organizationally Unique > Identifier (OUI) > > +// Bits [9:4] - Device Model Number > > +// Bits [3:0] - Device Revision Number > > +// > > +#define R_PHY_MDI_GENEREAL_REGISTER_03_PHY_IDENTIFIER_2 > 0x00030000 > > + > > +#define MDI_REG_SHIFT(x) (x << 16) > > +#define B_PHY_MDI_PHY_REGISTER_MASK (BIT20 | BIT19 | BIT18 > | BIT17 | BIT16) > > +#define R_PHY_MDI_PHY_REG_SET_ADDRESS 0x00110000 // Used > after new page setting > > +#define R_PHY_MDI_PHY_REG_DATA_READ_WRITE 0x00120000 > > +#define R_PHY_MDI_PHY_REG_SET_PAGE 0x001F0000 > > + > > +// > > +// LAN PHY MDI registers and bits > > +// > > + > > +// > > +// Page 769 Port Control Registers > > +// 6020h (769 * 32) > > +// > > +#define PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS 769 > > +// > > +// Custom Mode Control PHY Address 01, Page 769, Register 16 > > +// > > +#define R_PHY_MDI_PAGE_769_REGISETER_16_CMC 0x0010 > > +// > > +// Custom Mode Control > > +// Page 769, Register 16, BIT 10 > > +// 0 - normal MDIO frequency access > > +// 1 - reduced MDIO frequency access (slow mdio) > > +// required for read during cable disconnect > > +// > > +#define > B_PHY_MDI_PAGE_769_REGISETER_16_CMC_MDIO_FREQ_ACCESS > BIT10 > > +// > > +// Port General Configuration PHY Address 01, Page 769, Register 17 > > +// > > +#define R_PHY_MDI_PAGE_769_REGISETER_17_PGC 0x0011 > > +// > > +// Page 769, Register 17, BIT 4 > > +// Enables host wake up > > +// > > +#define B_PHY_MDI_PAGE_769_REGISETER_17_PGC_HOST_WAKE_UP > BIT4 > > +// > > +// Page 769, Register 17, BIT 2 > > +// Globally enable the MAC power down feature while the > > +// GbE supports WoL. When set to 1b, > > +// pages 800 and 801 are enabled for > > +// configuration and Host_WU_Active is not blocked for writes. > > +// > > +#define B_PHY_MDI_PAGE_769_REGISETER_17_PGC_MACPD_ENABLE > BIT2 > > + > > +// > > +// Page 800 Wake Up Registers > > +// 6400h (800 * 32) > > +// > > +#define PHY_MDI_PAGE_800_WAKE_UP_REGISTERS 800 > > +// > > +// Wake Up Control - WUC PHY Address 01, Page 800, Register 1 > > +// 1h (Register 1) > > +// > > +#define R_PHY_MDI_PAGE_800_REGISETER_1_WUC 0x0001 > > +// > > +// Wake Up Control - (WUC) > > +// Page 800, Register 1, BIT 0 > > +// Advance Power Management Enable (APME) > > +// If set to 1b, APM wake up is enabled. > > +// > > +#define B_PHY_MDI_PAGE_800_REGISETER_1_WUC_APME BIT0 > > +// > > +// Receive Address Low - RAL PHY Address 01, Page 800, Register 16 > > +// 10h (Register 16) > > +// > > +#define R_PHY_MDI_PAGE_800_REGISETER_16_RAL0 0x0010 > > +// > > +// Receive Address Low - RAL PHY Address 01, Page 800, Register 17 > > +// 11h (Register 17) > > +// > > +#define R_PHY_MDI_PAGE_800_REGISETER_17_RAL1 0x0011 > > +// > > +// Receive Address High - RAH PHY Address 01, Page 800, Register 18 > > +// 12h (Register 18) > > +// > > +#define R_PHY_MDI_PAGE_800_REGISETER_18_RAH0 0x0012 > > +// > > +// Receive Address High - RAH PHY Address 01, Page 800, Register 19 > > +// 13h (Register 19) > > +// > > +#define R_PHY_MDI_PAGE_800_REGISETER_19_RAH1 0x0013 > > +// > > +// Setting AV (BIT15 RAH is divided on two registers) > > +// RAH Register 19, Page 800, BIT 31 > > +// > > +// Address valid (AV) > > +// When this bit is set, the relevant RAL and RAH are valid > > +// > > +#define B_PHY_MDI_PAGE_800_REGISETER_19_RAH1_ADDRESS_VALID > BIT15 > > +// > > +// Page 803 Host WoL Packet > > +// 6460h (803 * 32) > > +// > > +#define PHY_MDI_PAGE_803_HOST_WOL_PACKET 803 > > +// > > +// Host WoL Packet Clear - HWPC PHY Address 01, Page 803, Register 66 > > +// > > +#define R_PHY_MDI_PAGE_803_REGISETER_66_HWPC 0x0042 > > + > > + > > +/** > > + Change Extended Device Control Register BIT 11 to 1 which > > + forces the interface between the MAC and the Phy to be on SMBus. > > + Cleared on the assertion of PCI reset. > > + > > + @param [in] GbeBar GbE MMIO space > > + > > +**/ > > +VOID > > +GbeMdiForceMACtoSMB ( > > + IN UINT32 GbeBar > > + ); > > + > > +/** > > + Test for MDIO operation complete. > > + > > + @param [in] GbeBar GbE MMIO space > > + > > + @retval EFI_SUCCESS > > + @retval EFI_TIMEOUT > > +**/ > > +EFI_STATUS > > +GbeMdiWaitReady ( > > + IN UINT32 GbeBar > > + ); > > + > > +/** > > + Acquire MDIO software semaphore. > > + > > + 1. Ensure that MBARA offset F00h [5] = 1b > > + 2. Poll MBARA offset F00h [5] up to 200ms > > + > > + @param [in] GbeBar GbE MMIO space > > + > > + @retval EFI_SUCCESS > > + @retval EFI_TIMEOUT > > +**/ > > +EFI_STATUS > > +GbeMdiAcquireMdio ( > > + IN UINT32 GbeBar > > + ); > > + > > +/** > > + Release MDIO software semaphore by clearing MBARA offset F00h [5] > > + > > + @param [in] GbeBar GbE MMIO space > > +**/ > > +VOID > > +GbeMdiReleaseMdio ( > > + IN UINT32 GbeBar > > + ); > > + > > +/** > > + Sets page on MDI > > + Page setting is attempted twice. > > + If first attempt failes MAC and the Phy are force to be on SMBus > > + > > + @param [in] GbeBar GbE MMIO space > > + @param [in] Data Value to write in lower 16bits. > > + > > + @retval EFI_SUCCESS Page setting was successfull > > + @retval EFI_DEVICE_ERROR Returned if both attermps of setting page > failed > > +**/ > > +EFI_STATUS > > +GbeMdiSetPage ( > > + IN UINT32 GbeBar, > > + IN UINT32 Page > > + ); > > + > > +/** > > + Sets Register in current page. > > + > > + @param [in] GbeBar GbE MMIO space > > + @param [in] register Register number > > + > > + @return EFI_STATUS > > +**/ > > +EFI_STATUS > > +GbeMdiSetRegister ( > > + IN UINT32 GbeBar, > > + IN UINT32 Register > > + ); > > + > > + > > +/** > > + Perform MDI read. > > + > > + @param [in] GbeBar GbE MMIO space > > + @param [in] PhyAddress Phy Address General - 02 or Specific - 01 > > + @param [in] PhyRegister Phy Register > > + @param [out] ReadData Return Value > > + > > + @retval EFI_SUCCESS Based on response from GbeMdiWaitReady > > + @retval EFI_TIMEOUT Based on response from GbeMdiWaitReady > > + @retval EFI_INVALID_PARAMETER If Phy Address or Register validaton > failed > > +**/ > > +EFI_STATUS > > +GbeMdiRead ( > > + IN UINT32 GbeBar, > > + IN UINT32 PhyAddress, > > + IN UINT32 PhyRegister, > > + OUT UINT16 *ReadData > > + ); > > + > > +/** > > + Perform MDI write. > > + > > + @param [in] GbeBar GbE MMIO space > > + @param [in] PhyAddress Phy Address General - 02 or Specific - 01 > > + @param [in] PhyRegister Phy Register > > + @param [in] WriteData Value to write in lower 16bits. > > + > > + @retval EFI_SUCCESS Based on response from GbeMdiWaitReady > > + @retval EFI_TIMEOUT Based on response from GbeMdiWaitReady > > + @retval EFI_INVALID_PARAMETER If Phy Address or Register validaton > failed > > +**/ > > +EFI_STATUS > > +GbeMdiWrite ( > > + IN UINT32 GbeBar, > > + IN UINT32 PhyAddress, > > + IN UINT32 PhyRegister, > > + IN UINT32 WriteData > > + ); > > + > > +/** > > + Gets Phy Revision and Model Number > > + from PHY IDENTIFIER register 2 (offset 3) > > + > > + @param [in] GbeBar GbE MMIO space > > + @param [out] LanPhyRevision Return Value > > + > > + @return EFI_STATUS > > + @return EFI_INVALID_PARAMETER When GbeBar is incorrect > > +**/ > > +EFI_STATUS > > +GbeMdiGetLanPhyRevision ( > > + IN UINT32 GbeBar, > > + OUT UINT16 *LanPhyRevision > > + ); > > + > > +#endif // _GBE_MDI_LIB_H_ > > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Register/Gbe > Regs.h > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Register/Gb > eRegs.h > new file mode 100644 > index 0000000000..307f1e159e > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/IncludePrivate/Register/Gb > eRegs.h > @@ -0,0 +1,68 @@ > +/** @file > > + Register names for GbE device > > + > > + Conventions: > > + > > + - Register definition format: > > + > Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterS > pace_RegisterName > > + - Prefix: > > + Definitions beginning with "R_" are registers > > + Definitions beginning with "B_" are bits within registers > > + Definitions beginning with "V_" are meaningful values within the bits > > + Definitions beginning with "S_" are register size > > + Definitions beginning with "N_" are the bit position > > + - [GenerationName]: > > + Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.). > > + Register name without GenerationName applies to all generations. > > + - [ComponentName]: > > + This field indicates the component name that the register belongs to > (e.g. > PCH, SA etc.) > > + Register name without ComponentName applies to all components. > > + Register that is specific to -LP denoted by "_PCH_LP_" in component > name. > > + - SubsystemName: > > + This field indicates the subsystem name of the component that the > register belongs to > > + (e.g. PCIE, USB, SATA, GPIO, PMC etc.). > > + - RegisterSpace: > > + MEM - MMIO space register of subsystem. > > + IO - IO space register of subsystem. > > + PCR - Private configuration register of subsystem. > > + CFG - PCI configuration space register of subsystem. > > + - RegisterName: > > + Full register name. > > + > > + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > +**/ > > +#ifndef _GBE_REGS_H_ > > +#define _GBE_REGS_H_ > > + > > +#define R_GBE_CFG_MBARA 0x10 > > +#define N_GBE_CFG_MBARA_ALIGN 17 > > +#define R_GBE_CFG_PMCS 0xCC > > +#define B_GBE_CFG_PMCS_PS (BIT1 | BIT0) > > +#define V_GBE_CFG_PMCS_PS0 0x00 > > +// > > +// Gigabit Ethernet LAN Capabilities and Status Registers (Memory space) > > +// > > +#define R_GBE_MEM_CSR_CTRL 0 > > +// > > +// LANPHYPC: > > +// Connects to the LCD DEVICE_OFF# signal in the > > +// LAN Connected Device > > +// > > +#define B_GBE_MEM_CSR_CTRL_LANPHYPC_OVERRIDE BIT16 // When set > to 1 SW driver has the ability to control the LANPHYPC pin value. > > +#define B_GBE_MEM_CSR_CTRL_LANPHYPC_VAL BIT17 // When set to > 1 this bit will define the value of the LANPHYPC pin. > > +#define R_GBE_MEM_CSR_CTRL_EXT 0x0018 > > +#define B_GBE_MEM_CSR_CTRL_EXT_LPCD BIT2 //LCD Power Cycle > Done (LPCD). This bit indicates whether LCD power cycle is done > > + //- the bit is set > 50/100mSec after LANPHYPC pin > assertion. > > +#define B_GBE_MEM_CSR_CTRL_EXT_FORCE_SMB BIT11 > > +#define R_GBE_MEM_CSR_MDIC 0x0020 > > +#define B_GBE_MEM_CSR_MDIC_RB BIT28 > > +#define R_GBE_MEM_CSR_EXTCNF_CTRL 0x0F00 > > +#define B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG BIT5 > > +#define R_GBE_MEM_CSR_RAL 0x5400 > > +#define R_GBE_MEM_CSR_RAH 0x5404 > > +#define B_GBE_MEM_CSR_RAH_RAH 0x0000FFFF > > +#define R_GBE_MEM_CSR_WUC 0x5800 > > +#define B_GBE_MEM_CSR_WUC_APME BIT0 > > + > > +#endif > > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/ > GbeLib.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/ > GbeLib.c > new file mode 100644 > index 0000000000..3b51b9eb62 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/ > GbeLib.c > @@ -0,0 +1,121 @@ > +/** @file > > + Gbe Library. > > + All function in this library is available for PEI, DXE, and SMM, > > + But do not support UEFI RUNTIME environment call. > > + > > + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > +**/ > > + > > +#include <Base.h> > > +#include <Uefi/UefiBaseType.h> > > +#include <Library/IoLib.h> > > +#include <Library/DebugLib.h> > > +#include <Library/BaseLib.h> > > +#include <Library/PciSegmentLib.h> > > +#include <Library/PchInfoLib.h> > > +#include <Library/PchPcrLib.h> > > +#include <Library/PchCycleDecodingLib.h> > > +#include <Library/PmcPrivateLib.h> > > +#include <Library/SpiAccessLib.h> > > +#include <Library/GbeMdiLib.h> > > +#include <IndustryStandard/Pci30.h> > > +#include <Register/PchRegs.h> > > +#include <Register/GbeRegs.h> > > +#include <Library/PchPciBdfLib.h> > > + > > +/** > > + Check whether GbE region is valid > > + Check SPI region directly since GbE might be disabled in SW. > > + > > + @retval TRUE Gbe Region is valid > > + @retval FALSE Gbe Region is invalid > > +**/ > > +BOOLEAN > > +IsGbeRegionValid ( > > + VOID > > + ) > > +{ > > + return SpiIsGbeRegionValid (); > > +} > > + > > +/** > > + Check whether GBE controller is enabled in the platform. > > + > > + @retval TRUE GbE is enabled > > + @retval FALSE GbE is disabled > > +**/ > > +BOOLEAN > > +IsGbePresent ( > > + VOID > > + ) > > +{ > > + // > > + // Check PCH Support > > + // > > + if (!PchIsGbeSupported ()) { > > + return FALSE; > > + } > > + // > > + // Check PMC strap/fuse > > + // > > + if (!PmcIsGbeSupported ()) { > > + return FALSE; > > + } > > + // > > + // Check GbE NVM > > + // > > + if (IsGbeRegionValid () == FALSE) { > > + return FALSE; > > + } > > + return TRUE; > > +} > > + > > +/** > > + Verifies Gigabit Ethernet PCI Class Code > > + > > + @param [in] GbePciCfgBase GbE PCI Config Space Address > > + > > + @retval TRUE GbE Class Code match > > + @retval FALSE GbE Class Code does not match > > +**/ > > +BOOLEAN > > +STATIC > > +GbeCheckClassCode ( > > + UINT64 GbePciCfgBase > > + ) > > +{ > > + UINT8 BaseCode; > > + UINT8 SubClassCode; > > + > > + SubClassCode = PciSegmentRead8 (GbePciCfgBase + > PCI_CLASSCODE_OFFSET + 1); > > + BaseCode = PciSegmentRead8 (GbePciCfgBase + > PCI_CLASSCODE_OFFSET + 2); > > + > > + if ((BaseCode != PCI_CLASS_NETWORK) || (SubClassCode != > PCI_CLASS_NETWORK_ETHERNET)) { > > + DEBUG ((DEBUG_ERROR, "GbeCheckClassCode : BaseCode(0x%x) or > ClassCode(0x%x) is not supported\n", BaseCode, SubClassCode)); > > + ASSERT (FALSE); > > + return FALSE; > > + } > > + return TRUE; > > +} > > + > > +/** > > + Checks if Gbe is Enabled or Disabled > > + > > + @retval BOOLEAN TRUE if device is enabled, FALSE otherwise. > > +**/ > > +BOOLEAN > > +IsGbeEnabled ( > > + VOID > > + ) > > +{ > > + UINT64 GbePciBase; > > + > > + GbePciBase = GbePciCfgBase (); > > + > > + if (PciSegmentRead32 (GbePciBase) != 0xFFFFFFFF) { > > + return GbeCheckClassCode (GbePciBase); > > + } > > + > > + return FALSE; > > +} > > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/ > PeiDxeSmmGbeLib.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/ > PeiDxeSmmGbeLib.inf > new file mode 100644 > index 0000000000..4fef1288af > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/Library/PeiDxeSmmGbeLib/ > PeiDxeSmmGbeLib.inf > @@ -0,0 +1,43 @@ > +## @file > > +# Gbe Library. > > +# > > +# All function in this library is available for PEI, DXE, and SMM, > > +# But do not support UEFI RUNTIME environment call. > > +# > > +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +# > > +## > > + > > + > > +[Defines] > > +INF_VERSION = 0x00010017 > > +BASE_NAME = PeiDxeSmmGbeLib > > +FILE_GUID = FC022ED0-6EB3-43E1-A740-0BA27CBBD010 > > +VERSION_STRING = 1.0 > > +MODULE_TYPE = BASE > > +LIBRARY_CLASS = GbeLib > > + > > + > > +[LibraryClasses] > > +BaseLib > > +IoLib > > +DebugLib > > +PciSegmentLib > > +PchInfoLib > > +PchPcrLib > > +PchCycleDecodingLib > > +PmcPrivateLib > > +SpiAccessLib > > +GbeMdiLib > > +PchPciBdfLib > > + > > + > > +[Packages] > > +MdePkg/MdePkg.dec > > +TigerlakeSiliconPkg/SiPkg.dec > > + > > + > > +[Sources] > > +GbeLib.c > > + > > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmG > beMdiLib/GbeMdiLib.c > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmG > beMdiLib/GbeMdiLib.c > new file mode 100644 > index 0000000000..7917474406 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmG > beMdiLib/GbeMdiLib.c > @@ -0,0 +1,388 @@ > +/** @file > > + Gbe MDI Library. > > + All function in this library is available for PEI, DXE, and SMM, > > + But do not support UEFI RUNTIME environment call. > > + > > + Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > + SPDX-License-Identifier: BSD-2-Clause-Patent > > +**/ > > + > > +#include <Base.h> > > +#include <Uefi/UefiBaseType.h> > > +#include <Library/TimerLib.h> > > +#include <Library/IoLib.h> > > +#include <Library/DebugLib.h> > > +#include <Library/BaseLib.h> > > +#include <Library/GbeMdiLib.h> > > +#include <Register/GbeRegs.h> > > + > > + > > +/** > > + Validates both Phy Address and Regster. > > + > > + @param [in] PhyAddress > > + @param [in] PhyRegister > > + > > + @retval BOOLEAN TRUE Validation passed > > + FALSE If the data is not within its range > > + > > +**/ > > +BOOLEAN > > +IsPhyAddressRegisterValid ( > > + IN UINT32 PhyAddress, > > + IN UINT32 PhyRegister > > + ) > > +{ > > + if (((PhyAddress & (~B_PHY_MDI_PHY_ADDRESS_MASK)) != 0) || > ((PhyRegister & (~B_PHY_MDI_PHY_REGISTER_MASK)) != 0)) { > > + DEBUG ((DEBUG_ERROR, "IsPhyAddressRegisterValid validation failed! > PhyAddress: 0x%08X PhyRegister: 0x%08X \n", PhyAddress, PhyRegister)); > > + return FALSE; > > + } > > + return TRUE; > > +} > > + > > +/** > > + Change Extended Device Control Register BIT 11 to 1 which > > + forces the interface between the MAC and the Phy to be on SMBus. > > + Cleared on the assertion of PCI reset. > > + > > + @param [in] GbeBar GbE MMIO space > > + > > +**/ > > +VOID > > +GbeMdiForceMacToSmb ( > > + IN UINT32 GbeBar > > + ) > > +{ > > + MmioOr32 (GbeBar + R_GBE_MEM_CSR_CTRL_EXT, > B_GBE_MEM_CSR_CTRL_EXT_FORCE_SMB); > > +} > > + > > +/** > > + Test for MDIO operation complete. > > + > > + @param [in] GbeBar GbE MMIO space > > + > > + @retval EFI_SUCCESS > > + @retval EFI_TIMEOUT > > +**/ > > +EFI_STATUS > > +GbeMdiWaitReady ( > > + IN UINT32 GbeBar > > + ) > > +{ > > + UINT32 Count; > > + > > + for (Count = 0; Count < GBE_MAX_LOOP_TIME; ++Count) { > > + if (MmioRead32 (GbeBar + R_GBE_MEM_CSR_MDIC) & > B_GBE_MEM_CSR_MDIC_RB) { > > + return EFI_SUCCESS; > > + } > > + MicroSecondDelay (GBE_ACQUIRE_MDIO_DELAY); > > + } > > + DEBUG ((DEBUG_ERROR, "GbeMdiWaitReady Timeout reached. MDIO > operation failed to complete in %d micro seconds\n", > GBE_MAX_LOOP_TIME * GBE_ACQUIRE_MDIO_DELAY)); > > + return EFI_TIMEOUT; > > +} > > + > > +/** > > + Acquire MDIO software semaphore. > > + > > + 1. Ensure that MBARA offset F00h [5] = 1b > > + 2. Poll MBARA offset F00h [5] up to 200ms > > + > > + @param [in] GbeBar GbE MMIO space > > + > > + @retval EFI_SUCCESS > > + @retval EFI_TIMEOUT > > +**/ > > +EFI_STATUS > > +GbeMdiAcquireMdio ( > > + IN UINT32 GbeBar > > + ) > > +{ > > + UINT32 ExtCnfCtrl; > > + UINT32 Count; > > + > > + MmioOr32 (GbeBar + R_GBE_MEM_CSR_EXTCNF_CTRL, > B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG); > > + for (Count = 0; Count < GBE_MAX_LOOP_TIME; ++Count) { > > + ExtCnfCtrl = MmioRead32 (GbeBar + R_GBE_MEM_CSR_EXTCNF_CTRL); > > + if (ExtCnfCtrl & B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG) { > > + return EFI_SUCCESS; > > + } > > + MicroSecondDelay (GBE_ACQUIRE_MDIO_DELAY); > > + } > > + DEBUG ((DEBUG_ERROR, "GbeMdiAcquireMdio Timeout. Unable to > acquire MDIO Semaphore in %d micro seconds\n", GBE_MAX_LOOP_TIME * > GBE_ACQUIRE_MDIO_DELAY)); > > + return EFI_TIMEOUT; > > +} > > + > > +/** > > + Release MDIO software semaphore by clearing MBARA offset F00h [5] > > + > > + @param [in] GbeBar GbE MMIO space > > +**/ > > +VOID > > +GbeMdiReleaseMdio ( > > + IN UINT32 GbeBar > > + ) > > +{ > > + ASSERT (MmioRead32 (GbeBar + R_GBE_MEM_CSR_EXTCNF_CTRL) & > B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG); > > + MmioAnd32 (GbeBar + R_GBE_MEM_CSR_EXTCNF_CTRL, (UINT32) > ~B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG); > > + ASSERT ((MmioRead32 (GbeBar + R_GBE_MEM_CSR_EXTCNF_CTRL) & > B_GBE_MEM_CSR_EXTCNF_CTRL_SWFLAG) == 0); > > +} > > + > > +/** > > + Sets page on MDI > > + Page setting is attempted twice. > > + If first attempt failes MAC and the Phy are force to be on SMBus. > > + > > + Waits 4 mSec after page setting > > + > > + @param [in] GbeBar GbE MMIO space > > + @param [in] Data Value to write in lower 16bits. > > + > > + @retval EFI_SUCCESS Page setting was successfull > > + @retval EFI_DEVICE_ERROR Returned if both attermps of setting page > failed > > +**/ > > +EFI_STATUS > > +GbeMdiSetPage ( > > + IN UINT32 GbeBar, > > + IN UINT32 Page > > + ) > > +{ > > + EFI_STATUS Status; > > + > > + MmioWrite32 (GbeBar + R_GBE_MEM_CSR_MDIC, (~B_PHY_MDI_READY) > & (B_PHY_MDI_WRITE | B_PHY_MDI_PHY_ADDRESS_01 | > R_PHY_MDI_PHY_REG_SET_PAGE | ((Page * 32) & 0xFFFF))); > > + > > + Status = GbeMdiWaitReady (GbeBar); > > + > > + if (Status == EFI_TIMEOUT) { > > + DEBUG ((DEBUG_INFO, "GbeMdiSetPage Timeout reached. Forcing the > interface between the MAC and the Phy to be on SMBus\n")); > > + GbeMdiForceMacToSmb (GbeBar); > > + // > > + // Retry page setting > > + // > > + MmioWrite32 (GbeBar + R_GBE_MEM_CSR_MDIC, > (~B_PHY_MDI_READY) & (B_PHY_MDI_WRITE | > B_PHY_MDI_PHY_ADDRESS_01 | R_PHY_MDI_PHY_REG_SET_PAGE | ((Page > * 32) & 0xFFFF))); > > + Status = GbeMdiWaitReady (GbeBar); > > + if (Status == EFI_TIMEOUT) { > > + DEBUG ((DEBUG_ERROR, "GbeMdiSetPage retry page setting > failed!\n")); > > + return EFI_DEVICE_ERROR; > > + } > > + } > > + > > + // > > + // Delay required for page to set properly > > + // > > + MicroSecondDelay (GBE_MDI_SET_PAGE_DELAY); > > + > > + return Status; > > +} > > + > > +/** > > + Sets Register in current page. > > + > > + @param [in] GbeBar GbE MMIO space > > + @param [in] register Register number valid only in lower 16 Bits > > + > > + @return EFI_STATUS > > +**/ > > +EFI_STATUS > > +GbeMdiSetRegister ( > > + IN UINT32 GbeBar, > > + IN UINT32 Register > > + ) > > +{ > > + MmioWrite32 (GbeBar + R_GBE_MEM_CSR_MDIC, (~B_PHY_MDI_READY) > & (B_PHY_MDI_WRITE | B_PHY_MDI_PHY_ADDRESS_01 | > R_PHY_MDI_PHY_REG_SET_ADDRESS | (Register & 0xFFFF))); > > + return GbeMdiWaitReady (GbeBar); > > +} > > + > > +/** > > + Perform MDI write. > > + > > + @param [in] GbeBar GbE MMIO space > > + @param [in] PhyAddress Phy Address General - 02 or Specific - 01 > > + @param [in] PhyRegister Phy Register > > + @param [in] WriteData Value to write in lower 16bits. > > + > > + @retval EFI_SUCCESS Based on response from GbeMdiWaitReady > > + @retval EFI_TIMEOUT Based on response from GbeMdiWaitReady > > + @retval EFI_INVALID_PARAMETER If Phy Address or Register validaton > failed > > +**/ > > +EFI_STATUS > > +GbeMdiWrite ( > > + IN UINT32 GbeBar, > > + IN UINT32 PhyAddress, > > + IN UINT32 PhyRegister, > > + IN UINT32 WriteData > > + ) > > +{ > > + if(!IsPhyAddressRegisterValid (PhyAddress, PhyRegister)) { > > + DEBUG ((DEBUG_ERROR, "GbeMdiWrite PhyAddressRegister validaton > failed!\n")); > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + MmioWrite32 (GbeBar + R_GBE_MEM_CSR_MDIC, (~B_PHY_MDI_READY) > & (B_PHY_MDI_WRITE | PhyAddress | PhyRegister | (WriteData & 0xFFFF))); > > + return GbeMdiWaitReady (GbeBar); > > +} > > + > > +/** > > + Perform MDI read. > > + > > + @param [in] GbeBar GbE MMIO space > > + @param [in] PhyAddress Phy Address General - 02 or Specific - 01 > > + @param [in] PhyRegister Phy Register > > + @param [out] ReadData Return Value > > + > > + @retval EFI_SUCCESS Based on response from GbeMdiWaitReady > > + @retval EFI_TIMEOUT Based on response from GbeMdiWaitReady > > + @retval EFI_INVALID_PARAMETER If Phy Address or Register validaton > failed > > +**/ > > +EFI_STATUS > > +GbeMdiRead ( > > + IN UINT32 GbeBar, > > + IN UINT32 PhyAddress, > > + IN UINT32 PhyRegister, > > + OUT UINT16 *ReadData > > + ) > > +{ > > + EFI_STATUS Status; > > + > > + if(!IsPhyAddressRegisterValid (PhyAddress, PhyRegister)) { > > + DEBUG ((DEBUG_ERROR, "GbeMdiRead PhyAddressRegister validaton > failed!\n")); > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + MmioWrite32 (GbeBar + R_GBE_MEM_CSR_MDIC, (~B_PHY_MDI_READY) > & (B_PHY_MDI_READ | PhyAddress | PhyRegister)); > > + Status = GbeMdiWaitReady (GbeBar); > > + if (EFI_SUCCESS == Status) { > > + *ReadData = (UINT16) MmioRead32 (GbeBar + > R_GBE_MEM_CSR_MDIC); > > + } > > + return Status; > > +} > > + > > +/** > > + Gets Phy Revision and Model Number > > + from PHY IDENTIFIER register 2 (offset 3) > > + > > + @param [in] GbeBar GbE MMIO space > > + @param [out] LanPhyRevision Return Value > > + > > + @return EFI_STATUS > > + @return EFI_INVALID_PARAMETER When GbeBar is incorrect > > + When Phy register or address is out of bounds > > +**/ > > +EFI_STATUS > > +GbeMdiGetLanPhyRevision ( > > + IN UINT32 GbeBar, > > + OUT UINT16 *LanPhyRevision > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT8 LpcdLoop; > > + UINT8 Delay; > > + > > + if (!((GbeBar & 0xFFFFF000) > 0)) { > > + DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision GbeBar validation > failed! Bar: 0x%08X \n", GbeBar)); > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + Status = GbeMdiAcquireMdio (GbeBar); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to aquire > MDIO semaphore. Status: %r\n", Status)); > > + return Status; > > + } > > + > > + Status = GbeMdiSetPage (GbeBar, > PHY_MDI_PAGE_769_PORT_CONTROL_REGISTERS); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to Set Page > 769. Status: %r\n", Status)); > > + GbeMdiReleaseMdio (GbeBar); > > + return Status; > > + } > > + > > + // > > + // Set register to: Custom Mode Control > > + // Reduced MDIO frequency access (slow mdio) > > + // BIT 10 set to 1 > > + // > > + Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, > MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_16_CMC), BIT13 | > B_PHY_MDI_PAGE_769_REGISETER_16_CMC_MDIO_FREQ_ACCESS | BIT8 | > BIT7); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to enable > slow MDIO mode. Status: %r\n", Status)); > > + GbeMdiReleaseMdio (GbeBar); > > + return Status; > > + } > > + > > + // > > + // Read register PHY Version from PHY IDENTIFIER 2 (offset 0x3) > > + // Bits [9:4] - Device Model Number > > + // Bits [3:0] - Device Revision Number > > + // > > + Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_02, > R_PHY_MDI_GENEREAL_REGISTER_03_PHY_IDENTIFIER_2, LanPhyRevision); > > + > > + // > > + // Failed to obtain PHY REV > > + // > > + if (*LanPhyRevision == 0x0) { > > + if ((MmioRead32 (GbeBar + R_GBE_MEM_CSR_CTRL) & > (B_GBE_MEM_CSR_CTRL_LANPHYPC_OVERRIDE | > B_GBE_MEM_CSR_CTRL_LANPHYPC_VAL))) { > > + DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to read Phy > Revision. Other component tried to initialize GbE and failed.\n")); > > + Status = EFI_DEVICE_ERROR; > > + goto phy_exit; > > + } > > + DEBUG ((DEBUG_INFO, "GbeMdiGetLanPhyRevision failed to read > Revision. Overriding LANPHYPC\n", Status)); > > + // > > + // Taking over LANPHYPC > > + // 1. SW signal override - 1st cycle. > > + // 2. Turn LCD on - 2nd cycle. > > + // > > + MmioOr32 (GbeBar + R_GBE_MEM_CSR_CTRL, > B_GBE_MEM_CSR_CTRL_LANPHYPC_OVERRIDE); > > + MmioOr32 (GbeBar + R_GBE_MEM_CSR_CTRL, > B_GBE_MEM_CSR_CTRL_LANPHYPC_VAL); > > + > > + // > > + // Poll on LPCD for 100mSec > > + // > > + LpcdLoop = 101; > > + while (LpcdLoop > 0) { > > + if (MmioRead32 (GbeBar + R_GBE_MEM_CSR_CTRL_EXT) & > B_GBE_MEM_CSR_CTRL_EXT_LPCD) { > > + break; > > + } else { > > + LpcdLoop--; > > + MicroSecondDelay (1000); > > + } > > + } > > + > > + if (LpcdLoop > 0) { > > + Delay = 100; > > + Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_02, > R_PHY_MDI_GENEREAL_REGISTER_03_PHY_IDENTIFIER_2, LanPhyRevision); > > + while (*LanPhyRevision == 0 && Delay > 0) { > > + Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_02, > R_PHY_MDI_GENEREAL_REGISTER_03_PHY_IDENTIFIER_2, LanPhyRevision); > > + if (EFI_ERROR(Status)) { > > + break; > > + } > > + MicroSecondDelay (1000); > > + Delay --; > > + } > > + } > > + // > > + // Restore LANPHYPC > > + // 1. Turn LCD off - 1st cycle. > > + // 2. Remove SW signal override - 2nd cycle. > > + // > > + MmioAnd32 (GbeBar + R_GBE_MEM_CSR_CTRL, (UINT32) > ~B_GBE_MEM_CSR_CTRL_LANPHYPC_VAL); > > + MmioAnd32 (GbeBar + R_GBE_MEM_CSR_CTRL, (UINT32) > ~B_GBE_MEM_CSR_CTRL_LANPHYPC_OVERRIDE); > > + } > > + > > +phy_exit: > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to read > Revision and Model Number from PHY Identifier 2. Status: %r\n", Status)); > > + GbeMdiReleaseMdio (GbeBar); > > + return Status; > > + } > > + > > + // > > + // Switch back to normal MDIO frequency access > > + // > > + Status = GbeMdiWrite (GbeBar, B_PHY_MDI_PHY_ADDRESS_01, > MDI_REG_SHIFT (R_PHY_MDI_PAGE_769_REGISETER_16_CMC), > (~B_PHY_MDI_PAGE_769_REGISETER_16_CMC_MDIO_FREQ_ACCESS) & > (BIT13 | BIT8 | BIT7)); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_ERROR, "GbeMdiGetLanPhyRevision failed to disable > slow MDIO mode. Status: %r\n", Status)); > > + } > > + > > + GbeMdiReleaseMdio (GbeBar); > > + > > + return Status; > > +} > > + > > diff --git > a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmG > beMdiLib/PeiDxeSmmGbeMdiLib.inf > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmG > beMdiLib/PeiDxeSmmGbeMdiLib.inf > new file mode 100644 > index 0000000000..99a01177f6 > --- /dev/null > +++ > b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gbe/LibraryPrivate/PeiDxeSmmG > beMdiLib/PeiDxeSmmGbeMdiLib.inf > @@ -0,0 +1,34 @@ > +## @file > > +# Gbe MDI Library. > > +# > > +# All function in this library is available for PEI, DXE, and SMM, > > +# But do not support UEFI RUNTIME environment call. > > +# > > +# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR> > > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +# > > +## > > + > > + > > +[Defines] > > +INF_VERSION = 0x00010017 > > +BASE_NAME = PeiDxeSmmGbeMdiLib > > +FILE_GUID = 0360E6F6-892A-4852-BF98-15C0D30D8A48 > > +VERSION_STRING = 1.0 > > +MODULE_TYPE = BASE > > +LIBRARY_CLASS = GbeMdiLib > > + > > + > > +[LibraryClasses] > > +BaseLib > > +IoLib > > +DebugLib > > +TimerLib > > + > > +[Packages] > > +MdePkg/MdePkg.dec > > +TigerlakeSiliconPkg/SiPkg.dec > > + > > + > > +[Sources] > > +GbeMdiLib.c > > -- > 2.24.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#71149): https://edk2.groups.io/g/devel/message/71149 Mute This Topic: https://groups.io/mt/80274128/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-