Commit 17aff538 authored by David S. Miller's avatar David S. Miller

Merge branch 'amd-xgbe-fixes'

Shyam Sundar S K says:

====================
Bug fixes to amd-xgbe driver

General fixes on amd-xgbe driver are addressed in this series, mostly
on the mailbox communication failures and improving the link stability
of the amd-xgbe device.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 25c5a7e8 9eab3fdb
...@@ -1279,10 +1279,18 @@ ...@@ -1279,10 +1279,18 @@
#define MDIO_PMA_10GBR_FECCTRL 0x00ab #define MDIO_PMA_10GBR_FECCTRL 0x00ab
#endif #endif
#ifndef MDIO_PMA_RX_CTRL1
#define MDIO_PMA_RX_CTRL1 0x8051
#endif
#ifndef MDIO_PCS_DIG_CTRL #ifndef MDIO_PCS_DIG_CTRL
#define MDIO_PCS_DIG_CTRL 0x8000 #define MDIO_PCS_DIG_CTRL 0x8000
#endif #endif
#ifndef MDIO_PCS_DIGITAL_STAT
#define MDIO_PCS_DIGITAL_STAT 0x8010
#endif
#ifndef MDIO_AN_XNP #ifndef MDIO_AN_XNP
#define MDIO_AN_XNP 0x0016 #define MDIO_AN_XNP 0x0016
#endif #endif
...@@ -1358,6 +1366,8 @@ ...@@ -1358,6 +1366,8 @@
#define XGBE_KR_TRAINING_ENABLE BIT(1) #define XGBE_KR_TRAINING_ENABLE BIT(1)
#define XGBE_PCS_CL37_BP BIT(12) #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_CMPLT BIT(0)
#define XGBE_AN_CL37_INT_MASK 0x01 #define XGBE_AN_CL37_INT_MASK 0x01
...@@ -1375,6 +1385,10 @@ ...@@ -1375,6 +1385,10 @@
#define XGBE_PMA_CDR_TRACK_EN_OFF 0x00 #define XGBE_PMA_CDR_TRACK_EN_OFF 0x00
#define XGBE_PMA_CDR_TRACK_EN_ON 0x01 #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
/* Bit setting and getting macros /* Bit setting and getting macros
* The get macro will extract the current bit field value from within * The get macro will extract the current bit field value from within
* the variable * the variable
......
...@@ -1368,6 +1368,7 @@ static void xgbe_stop(struct xgbe_prv_data *pdata) ...@@ -1368,6 +1368,7 @@ static void xgbe_stop(struct xgbe_prv_data *pdata)
return; return;
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
netif_carrier_off(pdata->netdev);
xgbe_stop_timers(pdata); xgbe_stop_timers(pdata);
flush_workqueue(pdata->dev_workqueue); flush_workqueue(pdata->dev_workqueue);
......
...@@ -1345,7 +1345,7 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata) ...@@ -1345,7 +1345,7 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata)
&an_restart); &an_restart);
if (an_restart) { if (an_restart) {
xgbe_phy_config_aneg(pdata); xgbe_phy_config_aneg(pdata);
return; goto adjust_link;
} }
if (pdata->phy.link) { if (pdata->phy.link) {
...@@ -1396,7 +1396,6 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata) ...@@ -1396,7 +1396,6 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
pdata->phy_if.phy_impl.stop(pdata); pdata->phy_if.phy_impl.stop(pdata);
pdata->phy.link = 0; pdata->phy.link = 0;
netif_carrier_off(pdata->netdev);
xgbe_phy_adjust_link(pdata); xgbe_phy_adjust_link(pdata);
} }
......
...@@ -922,6 +922,9 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata) ...@@ -922,6 +922,9 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
if ((phy_id & 0xfffffff0) != 0x03625d10) if ((phy_id & 0xfffffff0) != 0x03625d10)
return false; return false;
/* Reset PHY - wait for self-clearing reset bit to clear */
genphy_soft_reset(phy_data->phydev);
/* Disable RGMII mode */ /* Disable RGMII mode */
phy_write(phy_data->phydev, 0x18, 0x7007); phy_write(phy_data->phydev, 0x18, 0x7007);
reg = phy_read(phy_data->phydev, 0x18); reg = phy_read(phy_data->phydev, 0x18);
...@@ -1953,6 +1956,27 @@ static void xgbe_phy_set_redrv_mode(struct xgbe_prv_data *pdata) ...@@ -1953,6 +1956,27 @@ static void xgbe_phy_set_redrv_mode(struct xgbe_prv_data *pdata)
xgbe_phy_put_comm_ownership(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 asseting the reset bit and wait for
* its compeletion.
*/
XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1,
XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_ON);
ndelay(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);
usleep_range(40, 50);
netif_err(pdata, link, pdata->netdev, "firmware mailbox reset performed\n");
}
}
static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
unsigned int cmd, unsigned int sub_cmd) unsigned int cmd, unsigned int sub_cmd)
{ {
...@@ -1960,9 +1984,11 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, ...@@ -1960,9 +1984,11 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
unsigned int wait; unsigned int wait;
/* Log if a previous command did not complete */ /* 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)) {
netif_dbg(pdata, link, pdata->netdev, netif_dbg(pdata, link, pdata->netdev,
"firmware mailbox not ready for command\n"); "firmware mailbox not ready for command\n");
xgbe_phy_rx_reset(pdata);
}
/* Construct the command */ /* Construct the command */
XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, cmd); XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, cmd);
...@@ -1984,6 +2010,9 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, ...@@ -1984,6 +2010,9 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
netif_dbg(pdata, link, pdata->netdev, netif_dbg(pdata, link, pdata->netdev,
"firmware mailbox command did not complete\n"); "firmware mailbox command did not complete\n");
/* Reset on error */
xgbe_phy_rx_reset(pdata);
} }
static void xgbe_phy_rrc(struct xgbe_prv_data *pdata) static void xgbe_phy_rrc(struct xgbe_prv_data *pdata)
...@@ -2584,6 +2613,14 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) ...@@ -2584,6 +2613,14 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
if (reg & MDIO_STAT1_LSTATUS) if (reg & MDIO_STAT1_LSTATUS)
return 1; return 1;
if (pdata->phy.autoneg == AUTONEG_ENABLE &&
phy_data->port_mode == XGBE_PORT_MODE_BACKPLANE) {
if (!test_bit(XGBE_LINK_INIT, &pdata->dev_state)) {
netif_carrier_off(pdata->netdev);
*an_restart = 1;
}
}
/* No link, attempt a receiver reset cycle */ /* No link, attempt a receiver reset cycle */
if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) { if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
phy_data->rrc_count = 0; phy_data->rrc_count = 0;
......
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