Commit caa8d8bb authored by Ben Hutchings's avatar Ben Hutchings Committed by David S. Miller

sfc: Fix unreliable link detection in some loopback modes

Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6977dc63
...@@ -167,7 +167,7 @@ int mdio_clause45_check_mmds(struct efx_nic *efx, ...@@ -167,7 +167,7 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
{ {
int phy_id = efx->mii.phy_id; int phy_id = efx->mii.phy_id;
int status; u32 reg;
bool ok = true; bool ok = true;
int mmd = 0; int mmd = 0;
...@@ -179,12 +179,17 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) ...@@ -179,12 +179,17 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
return false; return false;
else if (efx_phy_mode_disabled(efx->phy_mode)) else if (efx_phy_mode_disabled(efx->phy_mode))
return false; return false;
else if (efx->loopback_mode == LOOPBACK_PHYXS) else if (efx->loopback_mode == LOOPBACK_PHYXS) {
mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS | mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
MDIO_MMDREG_DEVS_PCS | MDIO_MMDREG_DEVS_PCS |
MDIO_MMDREG_DEVS_PMAPMD | MDIO_MMDREG_DEVS_PMAPMD |
MDIO_MMDREG_DEVS_AN); MDIO_MMDREG_DEVS_AN);
else if (efx->loopback_mode == LOOPBACK_PCS) if (!mmd_mask) {
reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
MDIO_PHYXS_STATUS2);
return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
}
} else if (efx->loopback_mode == LOOPBACK_PCS)
mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS | mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
MDIO_MMDREG_DEVS_PMAPMD | MDIO_MMDREG_DEVS_PMAPMD |
MDIO_MMDREG_DEVS_AN); MDIO_MMDREG_DEVS_AN);
...@@ -196,12 +201,11 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask) ...@@ -196,12 +201,11 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
if (mmd_mask & 1) { if (mmd_mask & 1) {
/* Double reads because link state is latched, and a /* Double reads because link state is latched, and a
* read moves the current state into the register */ * read moves the current state into the register */
status = mdio_clause45_read(efx, phy_id, reg = mdio_clause45_read(efx, phy_id,
mmd, MDIO_MMDREG_STAT1); mmd, MDIO_MMDREG_STAT1);
status = mdio_clause45_read(efx, phy_id, reg = mdio_clause45_read(efx, phy_id,
mmd, MDIO_MMDREG_STAT1); mmd, MDIO_MMDREG_STAT1);
ok = ok && (reg & (1 << MDIO_MMDREG_STAT1_LINK_LBN));
ok = ok && (status & (1 << MDIO_MMDREG_STAT1_LINK_LBN));
} }
mmd_mask = (mmd_mask >> 1); mmd_mask = (mmd_mask >> 1);
mmd++; mmd++;
......
...@@ -133,6 +133,10 @@ ...@@ -133,6 +133,10 @@
#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0) #define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0)
#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1) #define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1)
/* PHY XGXS Status 2 */
#define MDIO_PHYXS_STATUS2 (8)
#define MDIO_PHYXS_STATUS2_RX_FAULT_LBN 10
/* PHY XGXS lane state */ /* PHY XGXS lane state */
#define MDIO_PHYXS_LANE_STATE (0x18) #define MDIO_PHYXS_LANE_STATE (0x18)
#define MDIO_PHYXS_LANE_ALIGNED_LBN (12) #define MDIO_PHYXS_LANE_ALIGNED_LBN (12)
......
...@@ -445,14 +445,13 @@ static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd) ...@@ -445,14 +445,13 @@ static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
int phy_id = efx->mii.phy_id; int phy_id = efx->mii.phy_id;
u32 reg; u32 reg;
if (efx->loopback_mode == LOOPBACK_GPHY) if (efx_phy_mode_disabled(efx->phy_mode))
return true;
else if (efx_phy_mode_disabled(efx->phy_mode))
return false; return false;
else if (efx->loopback_mode == LOOPBACK_GPHY)
return true;
else if (efx->loopback_mode) else if (efx->loopback_mode)
return mdio_clause45_links_ok(efx, return mdio_clause45_links_ok(efx,
MDIO_MMDREG_DEVS_PMAPMD | MDIO_MMDREG_DEVS_PMAPMD |
MDIO_MMDREG_DEVS_PCS |
MDIO_MMDREG_DEVS_PHYXS); MDIO_MMDREG_DEVS_PHYXS);
/* We must use the same definition of link state as LASI, /* We must use the same definition of link state as LASI,
...@@ -588,6 +587,10 @@ static void tenxpress_phy_poll(struct efx_nic *efx) ...@@ -588,6 +587,10 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
change = true; change = true;
} }
sfx7101_check_bad_lp(efx, link_ok); sfx7101_check_bad_lp(efx, link_ok);
} else if (efx->loopback_mode) {
bool link_ok = sft9001_link_ok(efx, NULL);
if (link_ok != efx->link_up)
change = true;
} else { } else {
u32 status = mdio_clause45_read(efx, efx->mii.phy_id, u32 status = mdio_clause45_read(efx, efx->mii.phy_id,
MDIO_MMD_PMAPMD, MDIO_MMD_PMAPMD,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment