]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
net: xilinx_axi: check PCS/PMA PHY status in setup_phy
authorAndy Chiu <andy.chiu@sifive.com>
Tue, 1 Nov 2022 03:58:00 +0000 (11:58 +0800)
committerMichal Simek <michal.simek@amd.com>
Mon, 5 Dec 2022 07:55:54 +0000 (08:55 +0100)
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>
drivers/net/xilinx_axi_emac.c

index 5a4d8388125de037af42bc13848d59d300e2954f..3e9919993d06a891ea297e705731b7ad4020c9b7 100644 (file)
@@ -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;