mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-14 06:24:53 +08:00
Merge branch 'mtk_eth_soc-SGMII-fixes'
Daniel Golle says: ==================== net: ethernet: mtk_eth_soc: minor SGMII fixes This small series brings two minor fixes for the SGMII unit found in MediaTek's router SoCs. The first patch resets the PCS internal state machine on major configuration changes, just like it is also done in MediaTek's SDK. The second patch makes sure we only write values and restart AN if actually needed, thus preventing unnesseray loss of an existing link in some cases. Both patches have previously been submitted as part of the series "net: ethernet: mtk_eth_soc: various enhancements" which grew a bit too big and it has correctly been criticized that some of the patches should rather go as fixes to net-next. This new series tries to address this. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
75014826d0
@ -542,6 +542,10 @@
|
||||
#define SGMII_SEND_AN_ERROR_EN BIT(11)
|
||||
#define SGMII_IF_MODE_MASK GENMASK(5, 1)
|
||||
|
||||
/* Register to reset SGMII design */
|
||||
#define SGMII_RESERVED_0 0x34
|
||||
#define SGMII_SW_RESET BIT(0)
|
||||
|
||||
/* Register to set SGMII speed, ANA RG_ Control Signals III*/
|
||||
#define SGMSYS_ANA_RG_CS3 0x2028
|
||||
#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))
|
||||
|
@ -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,17 +73,24 @@ 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);
|
||||
|
||||
/* Reset SGMII PCS state */
|
||||
regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
|
||||
SGMII_SW_RESET, SGMII_SW_RESET);
|
||||
|
||||
if (interface == PHY_INTERFACE_MODE_2500BASEX)
|
||||
rgc3 = RG_PHY_SPEED_3_125G;
|
||||
else
|
||||
@ -97,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 |
|
||||
@ -114,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.
|
||||
@ -128,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)
|
||||
|
Loading…
Reference in New Issue
Block a user