Commit 6e933a80 authored by Daniel Golle's avatar Daniel Golle Committed by David S. Miller
Browse files

net: ethernet: mtk_eth_soc: only write values if needed



Only restart auto-negotiation and write link timer if actually
necessary. This prevents losing the link in case of minor
changes.

Fixes: 7e538372 ("net: ethernet: mediatek: Re-add support SGMII")
Reviewed-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Tested-by: default avatarBjørn Mork <bjorn@mork.no>
Signed-off-by: default avatarDaniel Golle <daniel@makrotopia.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 611e2dab
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
			  const unsigned long *advertising,
			  bool permit_pause_to_mac)
{
	bool mode_changed = false, changed, use_an;
	struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
	unsigned int rgc3, sgm_mode, bmcr;
	int advertise, link_timer;
	bool changed, use_an;

	advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
							     advertising);
	if (advertise < 0)
		return advertise;

	link_timer = phylink_get_link_timer_ns(interface);
	if (link_timer < 0)
		return link_timer;

	/* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
	 * we assume that fixes it's speed at bitrate = line rate (in
	 * other words, 1000Mbps or 2500Mbps).
@@ -77,13 +73,16 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
	}

	if (use_an) {
		/* FIXME: Do we need to set AN_RESTART here? */
		bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
		bmcr = SGMII_AN_ENABLE;
	} else {
		bmcr = 0;
	}

	if (mpcs->interface != interface) {
		link_timer = phylink_get_link_timer_ns(interface);
		if (link_timer < 0)
			return link_timer;

		/* PHYA power down */
		regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
				   SGMII_PHYA_PWD, SGMII_PHYA_PWD);
@@ -101,16 +100,17 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
		regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
				   RG_PHY_SPEED_3_125G, rgc3);

		/* Setup the link timer */
		regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);

		mpcs->interface = interface;
		mode_changed = true;
	}

	/* Update the advertisement, noting whether it has changed */
	regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
				 SGMII_ADVERTISE, advertise, &changed);

	/* Setup the link timer and QPHY power up inside SGMIISYS */
	regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);

	/* Update the sgmsys mode register */
	regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
			   SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
@@ -118,7 +118,7 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,

	/* Update the BMCR */
	regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
			   SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
			   SGMII_AN_ENABLE, bmcr);

	/* Release PHYA power down state
	 * Only removing bit SGMII_PHYA_PWD isn't enough.
@@ -132,7 +132,7 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
	usleep_range(50, 100);
	regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);

	return changed;
	return changed || mode_changed;
}

static void mtk_pcs_restart_an(struct phylink_pcs *pcs)