[edk2-devel] [PATCH 16/40] TigerlakeSiliconPkg/IpBlock: Add Gbe component

Nate DeSimone nathaniel.l.desimone at intel.com
Thu Feb 4 03:54:08 UTC 2021


Reviewed-by: Nate DeSimone <nathaniel.l.desimone at intel.com>

> -----Original Message-----
> From: Luo, Heng <heng.luo at intel.com>
> Sent: Sunday, January 31, 2021 5:37 PM
> To: devel at edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty at intel.com>; Desimone,
> Nathaniel L <nathaniel.l.desimone at 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.chaganty at intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
> Signed-off-by: Heng Luo <heng.luo at 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/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list