aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAndy Chiu <andy.chiu@sifive.com>2022-11-01 11:58:00 +0800
committerMichal Simek <michal.simek@amd.com>2022-12-05 08:55:54 +0100
commitf3558be91e5086f1673d47ba8c430e7640b32e71 (patch)
treedb75fa9d753979e3f672b956c3091c75d06b9b9a /drivers
parente23544cffe7057d678846498ec0fbf21eff9bc95 (diff)
downloadu-boot-f3558be91e5086f1673d47ba8c430e7640b32e71.zip
u-boot-f3558be91e5086f1673d47ba8c430e7640b32e71.tar.gz
u-boot-f3558be91e5086f1673d47ba8c430e7640b32e71.tar.bz2
net: xilinx_axi: check PCS/PMA PHY status in setup_phy
Both PCS/PMA PHY and the external PHY need to have a valid link status in order to have Ethernet traffic. Check and wait this status at setup_phy() so that we could diagnose if there is a PHY issue. Signed-off-by: Andy Chiu <andy.chiu@sifive.com> Reviewed-by: Greentime Hu <greentime.hu@sifive.com> Link: https://lore.kernel.org/r/20221101035800.912644-3-andy.chiu@sifive.com Signed-off-by: Michal Simek <michal.simek@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/xilinx_axi_emac.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
index 5a4d838..3e99199 100644
--- a/drivers/net/xilinx_axi_emac.c
+++ b/drivers/net/xilinx_axi_emac.c
@@ -342,6 +342,45 @@ static int axiemac_phy_init(struct udevice *dev)
return 0;
}
+static int pcs_pma_startup(struct axidma_priv *priv)
+{
+ u32 rc, retry_cnt = 0;
+ u16 mii_reg;
+
+ rc = phyread(priv, priv->pcsaddr, MII_BMCR, &mii_reg);
+ if (rc)
+ goto failed_mdio;
+
+ if (!(mii_reg & BMCR_ANENABLE)) {
+ mii_reg |= BMCR_ANENABLE;
+ if (phywrite(priv, priv->pcsaddr, MII_BMCR, mii_reg))
+ goto failed_mdio;
+ }
+
+ /*
+ * Check the internal PHY status and warn user if the link between it
+ * and the external PHY is not obtained.
+ */
+ debug("axiemac: waiting for link status of the PCS/PMA PHY");
+ while (retry_cnt * 10 < PHY_ANEG_TIMEOUT) {
+ rc = phyread(priv, priv->pcsaddr, MII_BMSR, &mii_reg);
+ if ((mii_reg & BMSR_LSTATUS) && mii_reg != 0xffff && !rc) {
+ debug(".Done\n");
+ return 0;
+ }
+ if ((retry_cnt++ % 10) == 0)
+ debug(".");
+ mdelay(10);
+ }
+ debug("\n");
+ printf("axiemac: Warning, PCS/PMA PHY@%d is not ready, link is down\n",
+ priv->pcsaddr);
+ return 1;
+failed_mdio:
+ printf("axiemac: MDIO to the PCS/PMA PHY has failed\n");
+ return 1;
+}
+
/* Setting axi emac and phy to proper setting */
static int setup_phy(struct udevice *dev)
{
@@ -373,6 +412,11 @@ static int setup_phy(struct udevice *dev)
phydev->dev->name);
return 0;
}
+ if (priv->interface == PHY_INTERFACE_MODE_SGMII ||
+ priv->interface == PHY_INTERFACE_MODE_1000BASEX) {
+ if (pcs_pma_startup(priv))
+ return 0;
+ }
if (!phydev->link) {
printf("%s: No link.\n", phydev->dev->name);
return 0;