Skip to content

Commit 7501482

Browse files
committed
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 <[email protected]>
2 parents d8b2283 + 6e933a8 commit 7501482

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

drivers/net/ethernet/mediatek/mtk_eth_soc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,10 @@
542542
#define SGMII_SEND_AN_ERROR_EN BIT(11)
543543
#define SGMII_IF_MODE_MASK GENMASK(5, 1)
544544

545+
/* Register to reset SGMII design */
546+
#define SGMII_RESERVED_0 0x34
547+
#define SGMII_SW_RESET BIT(0)
548+
545549
/* Register to set SGMII speed, ANA RG_ Control Signals III*/
546550
#define SGMSYS_ANA_RG_CS3 0x2028
547551
#define RG_PHY_SPEED_MASK (BIT(2) | BIT(3))

drivers/net/ethernet/mediatek/mtk_sgmii.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
3838
const unsigned long *advertising,
3939
bool permit_pause_to_mac)
4040
{
41+
bool mode_changed = false, changed, use_an;
4142
struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
4243
unsigned int rgc3, sgm_mode, bmcr;
4344
int advertise, link_timer;
44-
bool changed, use_an;
4545

4646
advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
4747
advertising);
4848
if (advertise < 0)
4949
return advertise;
5050

51-
link_timer = phylink_get_link_timer_ns(interface);
52-
if (link_timer < 0)
53-
return link_timer;
54-
5551
/* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
5652
* we assume that fixes it's speed at bitrate = line rate (in
5753
* other words, 1000Mbps or 2500Mbps).
@@ -77,17 +73,24 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
7773
}
7874

7975
if (use_an) {
80-
/* FIXME: Do we need to set AN_RESTART here? */
81-
bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
76+
bmcr = SGMII_AN_ENABLE;
8277
} else {
8378
bmcr = 0;
8479
}
8580

8681
if (mpcs->interface != interface) {
82+
link_timer = phylink_get_link_timer_ns(interface);
83+
if (link_timer < 0)
84+
return link_timer;
85+
8786
/* PHYA power down */
8887
regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
8988
SGMII_PHYA_PWD, SGMII_PHYA_PWD);
9089

90+
/* Reset SGMII PCS state */
91+
regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
92+
SGMII_SW_RESET, SGMII_SW_RESET);
93+
9194
if (interface == PHY_INTERFACE_MODE_2500BASEX)
9295
rgc3 = RG_PHY_SPEED_3_125G;
9396
else
@@ -97,24 +100,25 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
97100
regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
98101
RG_PHY_SPEED_3_125G, rgc3);
99102

103+
/* Setup the link timer */
104+
regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
105+
100106
mpcs->interface = interface;
107+
mode_changed = true;
101108
}
102109

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

107-
/* Setup the link timer and QPHY power up inside SGMIISYS */
108-
regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
109-
110114
/* Update the sgmsys mode register */
111115
regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
112116
SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
113117
SGMII_IF_MODE_SGMII, sgm_mode);
114118

115119
/* Update the BMCR */
116120
regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
117-
SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
121+
SGMII_AN_ENABLE, bmcr);
118122

119123
/* Release PHYA power down state
120124
* 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,
128132
usleep_range(50, 100);
129133
regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
130134

131-
return changed;
135+
return changed || mode_changed;
132136
}
133137

134138
static void mtk_pcs_restart_an(struct phylink_pcs *pcs)

0 commit comments

Comments
 (0)