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

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
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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);
+1 −2
Original line number Diff line number Diff line
@@ -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);
}
+38 −1
Original line number Diff line number Diff line
@@ -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;