0fabeea20c07aea1c0ed1c5659aea4d0f526409a
[openwrt/staging/stintel.git] /
1 From 6e933a804c7db8be64f367f33e63cd7dcc302ebb Mon Sep 17 00:00:00 2001
2 From: Daniel Golle <daniel@makrotopia.org>
3 Date: Tue, 14 Mar 2023 00:34:45 +0000
4 Subject: [PATCH 2/2] net: ethernet: mtk_eth_soc: only write values if needed
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Only restart auto-negotiation and write link timer if actually
10 necessary. This prevents losing the link in case of minor
11 changes.
12
13 Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
14 Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
15 Tested-by: Bjørn Mork <bjorn@mork.no>
16 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
17 Signed-off-by: David S. Miller <davem@davemloft.net>
18 ---
19 drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++++++++------------
20 1 file changed, 12 insertions(+), 12 deletions(-)
21
22 --- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
23 +++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
24 @@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink
25 const unsigned long *advertising,
26 bool permit_pause_to_mac)
27 {
28 + bool mode_changed = false, changed, use_an;
29 struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
30 unsigned int rgc3, sgm_mode, bmcr;
31 int advertise, link_timer;
32 - bool changed, use_an;
33
34 advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
35 advertising);
36 if (advertise < 0)
37 return advertise;
38
39 - link_timer = phylink_get_link_timer_ns(interface);
40 - if (link_timer < 0)
41 - return link_timer;
42 -
43 /* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
44 * we assume that fixes it's speed at bitrate = line rate (in
45 * other words, 1000Mbps or 2500Mbps).
46 @@ -77,13 +73,16 @@ static int mtk_pcs_config(struct phylink
47 }
48
49 if (use_an) {
50 - /* FIXME: Do we need to set AN_RESTART here? */
51 - bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
52 + bmcr = SGMII_AN_ENABLE;
53 } else {
54 bmcr = 0;
55 }
56
57 if (mpcs->interface != interface) {
58 + link_timer = phylink_get_link_timer_ns(interface);
59 + if (link_timer < 0)
60 + return link_timer;
61 +
62 /* PHYA power down */
63 regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
64 SGMII_PHYA_PWD, SGMII_PHYA_PWD);
65 @@ -101,16 +100,17 @@ static int mtk_pcs_config(struct phylink
66 regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
67 RG_PHY_SPEED_3_125G, rgc3);
68
69 + /* Setup the link timer */
70 + regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
71 +
72 mpcs->interface = interface;
73 + mode_changed = true;
74 }
75
76 /* Update the advertisement, noting whether it has changed */
77 regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
78 SGMII_ADVERTISE, advertise, &changed);
79
80 - /* Setup the link timer and QPHY power up inside SGMIISYS */
81 - regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
82 -
83 /* Update the sgmsys mode register */
84 regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
85 SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
86 @@ -118,7 +118,7 @@ static int mtk_pcs_config(struct phylink
87
88 /* Update the BMCR */
89 regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
90 - SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
91 + SGMII_AN_ENABLE, bmcr);
92
93 /* Release PHYA power down state
94 * Only removing bit SGMII_PHYA_PWD isn't enough.
95 @@ -132,7 +132,7 @@ static int mtk_pcs_config(struct phylink
96 usleep_range(50, 100);
97 regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
98
99 - return changed;
100 + return changed || mode_changed;
101 }
102
103 static void mtk_pcs_restart_an(struct phylink_pcs *pcs)