mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
axgbe: reset PHY RX data path on mailbox command timeout
This commit is contained in:
parent
2eb55efff8
commit
e131d9eb35
2 changed files with 43 additions and 1 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue