axgbe: reset PHY RX data path on mailbox command timeout

This commit is contained in:
Stephan de Wit 2021-12-02 16:21:56 +00:00 committed by Franco Fichtner
parent 2eb55efff8
commit e131d9eb35
2 changed files with 43 additions and 1 deletions

View file

@ -1323,10 +1323,18 @@
#define MDIO_PMA_10GBR_FECCTRL 0x00ab
#endif
#ifndef MDIO_PMA_RX_CTRL1
#define MDIO_PMA_RX_CTRL1 0x8051
#endif
#ifndef MDIO_PCS_DIG_CTRL
#define MDIO_PCS_DIG_CTRL 0x8000
#endif
#ifndef MDIO_PCS_DIGITAL_STAT
#define MDIO_PCS_DIGITAL_STAT 0x8010
#endif
#ifndef MDIO_AN_XNP
#define MDIO_AN_XNP 0x0016
#endif
@ -1406,6 +1414,8 @@
#define XGBE_KR_TRAINING_ENABLE BIT(1)
#define XGBE_PCS_CL37_BP BIT(12)
#define XGBE_PCS_PSEQ_STATE_MASK 0x1c
#define XGBE_PCS_PSEQ_STATE_POWER_GOOD 0x10
#define XGBE_AN_CL37_INT_CMPLT BIT(0)
#define XGBE_AN_CL37_INT_MASK 0x01
@ -1423,6 +1433,10 @@
#define XGBE_PMA_CDR_TRACK_EN_OFF 0x00
#define XGBE_PMA_CDR_TRACK_EN_ON 0x01
#define XGBE_PMA_RX_RST_0_MASK BIT(4)
#define XGBE_PMA_RX_RST_0_RESET_ON 0x10
#define XGBE_PMA_RX_RST_0_RESET_OFF 0x00
#define XGBE_PMA_PLL_CTRL_MASK BIT(15)
#define XGBE_PMA_PLL_CTRL_ENABLE BIT(15)
#define XGBE_PMA_PLL_CTRL_DISABLE 0x0000

View file

@ -2131,6 +2131,29 @@ xgbe_phy_set_redrv_mode(struct xgbe_prv_data *pdata)
xgbe_phy_put_comm_ownership(pdata);
}
static void
xgbe_phy_rx_reset(struct xgbe_prv_data *pdata)
{
int reg;
reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PCS, MDIO_PCS_DIGITAL_STAT,
XGBE_PCS_PSEQ_STATE_MASK);
if (reg == XGBE_PCS_PSEQ_STATE_POWER_GOOD) {
/* Mailbox command timed out, reset of RX block is required.
* This can be done by asserting the reset bit and waiting
* for its completion.
*/
XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1,
XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_ON);
DELAY(20);
XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1,
XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_OFF);
DELAY(50);
axgbe_printf(0, "%s: firmware mailbox reset performed\n", __func__);
}
}
static void
xgbe_phy_pll_ctrl(struct xgbe_prv_data *pdata, bool enable)
{
@ -2151,8 +2174,10 @@ xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, unsigned int cmd,
xgbe_phy_pll_ctrl(pdata, false);
/* Log if a previous command did not complete */
if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) {
axgbe_error("firmware mailbox not ready for command\n");
xgbe_phy_rx_reset(pdata);
}
/* Construct the command */
XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, cmd);
@ -2176,6 +2201,9 @@ xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, unsigned int cmd,
axgbe_printf(3, "firmware mailbox command did not complete\n");
/* Reset on error */
xgbe_phy_rx_reset(pdata);
reenable_pll:
xgbe_phy_pll_ctrl(pdata, true);
}