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: 7e53837269
("net: ethernet: mediatek: Re-add support SGMII")
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Tested-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
611e2dabb4
Коммит
6e933a804c
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче