summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrince Agyeman <prince.agyeman@intel.com>2020-02-25 16:58:32 -0800
committerNate DeSimone <nathaniel.l.desimone@intel.com>2020-03-02 14:38:57 -0800
commit068c6c48c639de8b14d2e77df0465f1b3b421d09 (patch)
treefe053690288ca53a98cabd12a3a70ee6caa17abb
parent852b889b94af3f02eca8c84eb3caeb771e26e946 (diff)
CoffeelakeSiliconPkg: Add Missing Library
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2408 Added GbeMdiLib implementation and added additional registers definitions needed by GbeMdilib. This fixes the linker errors seen during VS2017 builds Cc: Chasel Chiu <chasel.chiu@intel.com> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com> Signed-off-by: Prince Agyeman <prince.agyeman@intel.com> Reviewed-by: Chasel Chiu <chasel.chiu@intel.com> Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
-rw-r--r--Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h53
-rw-r--r--Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h14
-rw-r--r--Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGbeMdiLib/GbeMdiLib.c391
-rw-r--r--Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGbeMdiLib/PeiDxeSmmGbeMdiLib.inf32
-rw-r--r--Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf1
-rw-r--r--Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc4
6 files changed, 492 insertions, 3 deletions
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
index a6ce032e..280dee41 100644
--- a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Library/GbeMdiLib.h
@@ -21,7 +21,7 @@
- Registers / bits of new devices introduced in a PCH generation will be just named
as "_PCH_" without [generation_name] inserted.
- Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+ Copyright (c) 2019 - 2020 Intel Corporation. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -29,7 +29,35 @@
#ifndef _GBE_MDI_LIB_H_
#define _GBE_MDI_LIB_H_
+
+#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
+
+
+//
+// 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
+
//
+// LAN PHY MDI settings
+//
+#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
@@ -37,8 +65,22 @@
//
#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
//
@@ -131,6 +173,7 @@
**/
VOID
+EFIAPI
GbeMdiForceMACtoSMB (
IN UINT32 GbeBar
);
@@ -144,6 +187,7 @@ GbeMdiForceMACtoSMB (
@retval EFI_TIMEOUT
**/
EFI_STATUS
+EFIAPI
GbeMdiWaitReady (
IN UINT32 GbeBar
);
@@ -160,6 +204,7 @@ GbeMdiWaitReady (
@retval EFI_TIMEOUT
**/
EFI_STATUS
+EFIAPI
GbeMdiAcquireMdio (
IN UINT32 GbeBar
);
@@ -170,6 +215,7 @@ GbeMdiAcquireMdio (
@param [in] GbeBar GbE MMIO space
**/
VOID
+EFIAPI
GbeMdiReleaseMdio (
IN UINT32 GbeBar
);
@@ -186,6 +232,7 @@ GbeMdiReleaseMdio (
@retval EFI_DEVICE_ERROR Returned if both attermps of setting page failed
**/
EFI_STATUS
+EFIAPI
GbeMdiSetPage (
IN UINT32 GbeBar,
IN UINT32 Page
@@ -200,6 +247,7 @@ GbeMdiSetPage (
@return EFI_STATUS
**/
EFI_STATUS
+EFIAPI
GbeMdiSetRegister (
IN UINT32 GbeBar,
IN UINT32 Register
@@ -219,6 +267,7 @@ GbeMdiSetRegister (
@retval EFI_INVALID_PARAMETER If Phy Address or Register validaton failed
**/
EFI_STATUS
+EFIAPI
GbeMdiRead (
IN UINT32 GbeBar,
IN UINT32 PhyAddress,
@@ -239,6 +288,7 @@ GbeMdiRead (
@retval EFI_INVALID_PARAMETER If Phy Address or Register validaton failed
**/
EFI_STATUS
+EFIAPI
GbeMdiWrite (
IN UINT32 GbeBar,
IN UINT32 PhyAddress,
@@ -257,6 +307,7 @@ GbeMdiWrite (
@return EFI_INVALID_PARAMETER When GbeBar is incorrect
**/
EFI_STATUS
+EFIAPI
GbeMdiGetLanPhyRevision (
IN UINT32 GbeBar,
OUT UINT16 *LanPhyRevision
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
index f649873f..8efc9fad 100644
--- a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Include/Register/PchRegsLan.h
@@ -30,7 +30,7 @@
- RegisterName:
Full register name.
- Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+ Copyright (c) 2019 - 2020 Intel Corporation. All rights reserved. <BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -49,6 +49,17 @@
#define R_LAN_CFG_PMCS 0xCC
#define B_LAN_CFG_PMCS_PS (BIT1 | BIT0)
#define V_LAN_CFG_PMCS_PS0 0x00
+#define R_LAN_MEM_CSR_CTRL 0
+#define B_LAN_MEM_CSR_CTRL_LANPHYPC_OVERRIDE BIT16
+#define B_LAN_MEM_CSR_CTRL_LANPHYPC_VAL BIT17
+#define R_LAN_MEM_CSR_CTRL_EXT 0x0018
+#define B_LAN_MEM_CSR_CTRL_EXT_LPCD BIT2
+#define B_LAN_MEM_CSR_CTRL_EXT_FORCE_SMB BIT11
+#define R_LAN_MEM_CSR_MDIC 0x0020
+#define B_LAN_MEM_CSR_MDIC_RB BIT28
+#define B_LAN_MEM_CSR_MDIC_DATA 0xFFFF
+#define R_LAN_MEM_CSR_EXTCNF_CTRL 0x0F00
+#define B_LAN_MEM_CSR_EXTCNF_CTRL_SWFLAG BIT5
#define R_LAN_MEM_CSR_RAL 0x5400
#define R_LAN_MEM_CSR_RAH 0x5404
#define B_LAN_MEM_CSR_RAH_RAH 0x0000FFFF
@@ -56,3 +67,4 @@
#define B_LAN_MEM_CSR_WUC_APME BIT0
#endif
+
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGbeMdiLib/GbeMdiLib.c b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGbeMdiLib/GbeMdiLib.c
new file mode 100644
index 00000000..e5aa10de
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGbeMdiLib/GbeMdiLib.c
@@ -0,0 +1,391 @@
+/** @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) 2020 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+@par Specification Reference:
+**/
+
+#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/PchRegsLan.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
+EFIAPI
+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
+EFIAPI
+GbeMdiForceMacToSmb (
+ IN UINT32 GbeBar
+ )
+{
+ MmioOr32 (GbeBar + R_LAN_MEM_CSR_CTRL_EXT, B_LAN_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
+EFIAPI
+GbeMdiWaitReady (
+ IN UINT32 GbeBar
+ )
+{
+ UINT32 Count;
+
+ for (Count = 0; Count < GBE_MAX_LOOP_TIME; ++Count) {
+ if (MmioRead32 (GbeBar + R_LAN_MEM_CSR_MDIC) & B_LAN_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
+EFIAPI
+GbeMdiAcquireMdio (
+ IN UINT32 GbeBar
+ )
+{
+ UINT32 ExtCnfCtrl;
+ UINT32 Count;
+
+ MmioOr32 (GbeBar + R_LAN_MEM_CSR_EXTCNF_CTRL, B_LAN_MEM_CSR_EXTCNF_CTRL_SWFLAG);
+ for (Count = 0; Count < GBE_MAX_LOOP_TIME; ++Count) {
+ ExtCnfCtrl = MmioRead32 (GbeBar + R_LAN_MEM_CSR_EXTCNF_CTRL);
+ if (ExtCnfCtrl & B_LAN_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
+EFIAPI
+GbeMdiReleaseMdio (
+ IN UINT32 GbeBar
+ )
+{
+ ASSERT (MmioRead32 (GbeBar + R_LAN_MEM_CSR_EXTCNF_CTRL) & B_LAN_MEM_CSR_EXTCNF_CTRL_SWFLAG);
+ MmioAnd32 (GbeBar + R_LAN_MEM_CSR_EXTCNF_CTRL, (UINT32) ~B_LAN_MEM_CSR_EXTCNF_CTRL_SWFLAG);
+ ASSERT ((MmioRead32 (GbeBar + R_LAN_MEM_CSR_EXTCNF_CTRL) & B_LAN_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
+EFIAPI
+GbeMdiSetPage (
+ IN UINT32 GbeBar,
+ IN UINT32 Page
+ )
+{
+ EFI_STATUS Status;
+
+ MmioWrite32 (GbeBar + R_LAN_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_LAN_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
+EFIAPI
+GbeMdiSetRegister (
+ IN UINT32 GbeBar,
+ IN UINT32 Register
+ )
+{
+ MmioWrite32 (GbeBar + R_LAN_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
+EFIAPI
+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_LAN_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
+EFIAPI
+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_LAN_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_LAN_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
+EFIAPI
+GbeMdiGetLanPhyRevision (
+ IN UINT32 GbeBar,
+ OUT UINT16 *LanPhyRevision
+ )
+{
+ EFI_STATUS Status;
+ UINT8 LpcdLoop;
+
+ 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_LAN_MEM_CSR_CTRL) & (B_LAN_MEM_CSR_CTRL_LANPHYPC_OVERRIDE | B_LAN_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_LAN_MEM_CSR_CTRL, B_LAN_MEM_CSR_CTRL_LANPHYPC_OVERRIDE);
+ MmioOr32 (GbeBar + R_LAN_MEM_CSR_CTRL, B_LAN_MEM_CSR_CTRL_LANPHYPC_VAL);
+
+ //
+ // Poll on LPCD for 100mSec
+ //
+ LpcdLoop = 101;
+ while (LpcdLoop > 0) {
+ if (MmioRead32 (GbeBar + R_LAN_MEM_CSR_CTRL_EXT) & B_LAN_MEM_CSR_CTRL_EXT_LPCD) {
+ break;
+ } else {
+ LpcdLoop--;
+ MicroSecondDelay (1000);
+ }
+ }
+
+ if (LpcdLoop > 0) {
+ Status = GbeMdiRead (GbeBar, B_PHY_MDI_PHY_ADDRESS_02, R_PHY_MDI_GENEREAL_REGISTER_03_PHY_IDENTIFIER_2, LanPhyRevision);
+ }
+ //
+ // Restore LANPHYPC
+ // 1. Turn LCD off - 1st cycle.
+ // 2. Remove SW signal override - 2nd cycle.
+ //
+ MmioAnd32 (GbeBar + R_LAN_MEM_CSR_CTRL, (UINT32) ~B_LAN_MEM_CSR_CTRL_LANPHYPC_VAL);
+ MmioAnd32 (GbeBar + R_LAN_MEM_CSR_CTRL, (UINT32) ~B_LAN_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/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGbeMdiLib/PeiDxeSmmGbeMdiLib.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGbeMdiLib/PeiDxeSmmGbeMdiLib.inf
new file mode 100644
index 00000000..be547881
--- /dev/null
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/Library/PeiDxeSmmGbeMdiLib/PeiDxeSmmGbeMdiLib.inf
@@ -0,0 +1,32 @@
+## @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) 2020 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
+ CoffeelakeSiliconPkg/SiPkg.dec
+
+[Sources]
+ GbeMdiLib.c
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
index 267c4587..9418d7a4 100644
--- a/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/Pch/PchInit/Smm/PchInitSmm.inf
@@ -46,6 +46,7 @@ TimerLib
ConfigBlockLib
PmcPrivateLib
SataLib
+GbeMdiLib
[Packages]
MdePkg/MdePkg.dec
diff --git a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
index 7a9911e8..c6314214 100644
--- a/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
+++ b/Silicon/Intel/CoffeelakeSiliconPkg/SiPkgCommonLib.dsc
@@ -1,7 +1,7 @@
## @file
# Component description file for the Coffee Lake silicon package both PEI and DXE libraries DSC file.
#
-# Copyright (c) 2019 Intel Corporation. All rights reserved. <BR>
+# Copyright (c) 2019 - 2020 Intel Corporation. All rights reserved. <BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -34,6 +34,8 @@ DEFINE PCH = Cnl
PchPcieRpLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPcieRpLib/PeiDxeSmmPchPcieRpLib.inf
PchPcrLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchPcrLib/PeiDxeSmmPchPcrLib.inf
PmcLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
+ GbeMdiLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmGbeMdiLib/PeiDxeSmmGbeMdiLib.inf
+
PchSbiAccessLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmPchSbiAccessLib/PeiDxeSmmPchSbiAccessLib.inf
GpioLib|$(PLATFORM_SI_PACKAGE)/Pch/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf