mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-29 10:34:22 -04:00
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: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -1279,10 +1279,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
|
||||
@@ -1358,6 +1366,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
|
||||
@@ -1375,6 +1385,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
|
||||
|
||||
/* Bit setting and getting macros
|
||||
* The get macro will extract the current bit field value from within
|
||||
* the variable
|
||||
|
||||
@@ -1368,6 +1368,7 @@ static void xgbe_stop(struct xgbe_prv_data *pdata)
|
||||
return;
|
||||
|
||||
netif_tx_stop_all_queues(netdev);
|
||||
netif_carrier_off(pdata->netdev);
|
||||
|
||||
xgbe_stop_timers(pdata);
|
||||
flush_workqueue(pdata->dev_workqueue);
|
||||
|
||||
@@ -1345,7 +1345,7 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata)
|
||||
&an_restart);
|
||||
if (an_restart) {
|
||||
xgbe_phy_config_aneg(pdata);
|
||||
return;
|
||||
goto adjust_link;
|
||||
}
|
||||
|
||||
if (pdata->phy.link) {
|
||||
@@ -1396,7 +1396,6 @@ static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
|
||||
pdata->phy_if.phy_impl.stop(pdata);
|
||||
|
||||
pdata->phy.link = 0;
|
||||
netif_carrier_off(pdata->netdev);
|
||||
|
||||
xgbe_phy_adjust_link(pdata);
|
||||
}
|
||||
|
||||
@@ -922,6 +922,9 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
|
||||
if ((phy_id & 0xfffffff0) != 0x03625d10)
|
||||
return false;
|
||||
|
||||
/* Reset PHY - wait for self-clearing reset bit to clear */
|
||||
genphy_soft_reset(phy_data->phydev);
|
||||
|
||||
/* Disable RGMII mode */
|
||||
phy_write(phy_data->phydev, 0x18, 0x7007);
|
||||
reg = phy_read(phy_data->phydev, 0x18);
|
||||
@@ -1953,6 +1956,27 @@ static void 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 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,
|
||||
unsigned int cmd, unsigned int sub_cmd)
|
||||
{
|
||||
@@ -1960,9 +1984,11 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
|
||||
unsigned int wait;
|
||||
|
||||
/* 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,
|
||||
"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);
|
||||
@@ -1984,6 +2010,9 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
|
||||
|
||||
netif_dbg(pdata, link, pdata->netdev,
|
||||
"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)
|
||||
@@ -2584,6 +2613,14 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
|
||||
if (reg & MDIO_STAT1_LSTATUS)
|
||||
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 */
|
||||
if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) {
|
||||
phy_data->rrc_count = 0;
|
||||
|
||||
Reference in New Issue
Block a user