NVIDIA: SAUCE: net: phy: aqr113c: poll for TX ready at PHY system side

BugLink: https://bugs.launchpad.net/bugs/2072591

Issue: In case of Interface down and up, TX/RX
lane bringup failures are seen while configuring
speed settings.

Fix: Poll until PHY system interface gets ready
before configuring the interface settings.

http://nvbugs/3447132

Signed-off-by: Revanth Kumar Uppala <ruppala@nvidia.com>
Tested-by: Abhilash G <abhilashg@nvidia.com>
Reviewed-by: Abhilash G <abhilashg@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Acked-by: Jacob Martin <jacob.martin@canonical.com>
Acked-by: Noah Wager <noah.wager@canonical.com>
Signed-off-by: Noah Wager <noah.wager@canonical.com>
This commit is contained in:
Revanth Kumar Uppala
2022-08-18 06:38:08 +00:00
committed by Noah Wager
parent 52edf67725
commit 947c81e623
+16
View File
@@ -43,6 +43,7 @@
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI 7
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10
#define MDIO_PHYXS_VEND_IF_STATUS_TX_READY BIT(12)
#define MDIO_AN_VEND_PROV 0xc400
#define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15)
@@ -223,6 +224,7 @@ struct aqr107_priv {
int led_mode0;
int led_mode1;
int led_mode2;
int wol_status;
};
static int aqr107_get_sset_count(struct phy_device *phydev)
@@ -438,6 +440,7 @@ static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev)
int reg, val, ret;
int irq_status;
struct aqr107_priv *priv = phydev->priv;
reg = phy_read_mmd(phydev, MDIO_MMD_C22EXT, MDIO_C22EXT_GBE_PHY_SGMII_TX_ALARM1);
if ((reg & MDIO_C22EXT_SGMII0_MAGIC_PKT_FRAME_MASK) ==
MDIO_C22EXT_SGMII0_MAGIC_PKT_FRAME_MASK) {
@@ -458,6 +461,7 @@ static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev)
if (ret < 0)
return IRQ_NONE;
/* restart auto-negotiation */
priv->wol_status = 0;
return genphy_c45_restart_aneg(phydev);
}
@@ -556,6 +560,7 @@ static int aqr107_read_rate(struct phy_device *phydev)
static int aqr107_read_status(struct phy_device *phydev)
{
int val, ret;
struct aqr107_priv *priv = phydev->priv;
ret = aqr_read_status(phydev);
if (ret)
@@ -598,6 +603,14 @@ static int aqr107_read_status(struct phy_device *phydev)
break;
}
if (!priv->wol_status)
ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS,
val, (val & MDIO_PHYXS_VEND_IF_STATUS_TX_READY),
20000, 2000000, false);
if (ret) {
phydev_err(phydev, "PHY system interface is not yet ready\n");
return ret;
}
/* Read possibly downshifted rate from vendor register */
return aqr107_read_rate(phydev);
}
@@ -1053,6 +1066,7 @@ static int aqr113c_wol_settings(struct phy_device *phydev, bool enable)
{
u16 val;
int ret = 0;
struct aqr107_priv *priv = phydev->priv;
if (enable) {
/* Disables all advertised speeds except for the WoL
@@ -1128,6 +1142,7 @@ static int aqr113c_wol_settings(struct phy_device *phydev, bool enable)
/* restart auto-negotiation */
genphy_c45_restart_aneg(phydev);
priv->wol_status = 1;
} else {
/* Disable the WoL enable bit */
val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RSVD_VEND_PROV1);
@@ -1148,6 +1163,7 @@ static int aqr113c_wol_settings(struct phy_device *phydev, bool enable)
/* restart auto-negotiation */
genphy_c45_restart_aneg(phydev);
priv->wol_status = 0;
}
return ret;
}