kernel: mt7530: add support for in-band managed link
[openwrt/openwrt.git] / target / linux / generic / pending-5.15 / 731-net-dsa-mt7530-add-support-for-in-band-link-status.patch
1 From 8e18c5fef75debfae3531fbd6901f3bf317d91ed Mon Sep 17 00:00:00 2001
2 From: Daniel Golle <daniel@makrotopia.org>
3 Date: Fri, 9 Sep 2022 04:28:43 +0100
4 Subject: [PATCH] net: dsa: mt7530: add support for in-band link status
5 To: linux-mediatek@lists.infradead.org,
6 netdev@vger.kernel.org
7 Cc: Russell King <linux@armlinux.org.uk>,
8 Sean Wang <sean.wang@mediatek.com>,
9 Landen Chao <Landen.Chao@mediatek.com>,
10 DENG Qingfang <dqfext@gmail.com>,
11 Andrew Lunn <andrew@lunn.ch>,
12 Vivien Didelot <vivien.didelot@gmail.com>,
13 Florian Fainelli <f.fainelli@gmail.com>,
14 Vladimir Oltean <olteanv@gmail.com>,
15 David S. Miller <davem@davemloft.net>,
16 Eric Dumazet <edumazet@google.com>,
17 Jakub Kicinski <kuba@kernel.org>,
18 Paolo Abeni <pabeni@redhat.com>,
19 Matthias Brugger <matthias.bgg@gmail.com>,
20 Philipp Zabel <p.zabel@pengutronix.de>
21
22 Read link status from SGMII PCS for in-band managed 2500Base-X and
23 1000Base-X connection on a MAC port of the MT7531. This is needed to
24 get the SFP cage working which is connected to SGMII interface of
25 port 5 of the MT7531 switch IC on the Bananapi BPi-R3 board.
26
27 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
28 ---
29 drivers/net/dsa/mt7530.c | 48 +++++++++++++++++++++++++++++-----------
30 1 file changed, 35 insertions(+), 13 deletions(-)
31
32 --- a/drivers/net/dsa/mt7530.c
33 +++ b/drivers/net/dsa/mt7530.c
34 @@ -2703,9 +2703,6 @@ mt7531_mac_config(struct dsa_switch *ds,
35 case PHY_INTERFACE_MODE_NA:
36 case PHY_INTERFACE_MODE_1000BASEX:
37 case PHY_INTERFACE_MODE_2500BASEX:
38 - if (phylink_autoneg_inband(mode))
39 - return -EINVAL;
40 -
41 return mt7531_sgmii_setup_mode_force(priv, port, interface);
42 default:
43 return -EINVAL;
44 @@ -2781,13 +2778,6 @@ unsupported:
45 return;
46 }
47
48 - if (phylink_autoneg_inband(mode) &&
49 - state->interface != PHY_INTERFACE_MODE_SGMII) {
50 - dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
51 - __func__);
52 - return;
53 - }
54 -
55 mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
56 mcr_new = mcr_cur;
57 mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
58 @@ -2924,6 +2914,9 @@ static void mt753x_phylink_get_caps(stru
59 config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
60 MAC_10 | MAC_100 | MAC_1000FD;
61
62 + if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port))
63 + config->mac_capabilities |= MAC_2500FD;
64 +
65 /* This driver does not make use of the speed, duplex, pause or the
66 * advertisement in its mac_config, so it is safe to mark this driver
67 * as non-legacy.
68 @@ -3019,16 +3012,43 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
69 return 0;
70 }
71
72 +static void
73 +mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
74 + struct phylink_link_state *state)
75 +{
76 + unsigned int val;
77 +
78 + val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
79 + state->link = !!(val & MT7531_SGMII_LINK_STATUS);
80 + if (!state->link)
81 + return;
82 +
83 + if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
84 + state->speed = SPEED_2500;
85 + else
86 + state->speed = SPEED_1000;
87 +
88 + state->duplex = DUPLEX_FULL;
89 + state->pause = 0;
90 +}
91 +
92 static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
93 struct phylink_link_state *state)
94 {
95 struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
96 int port = pcs_to_mt753x_pcs(pcs)->port;
97 + unsigned int val;
98
99 - if (state->interface == PHY_INTERFACE_MODE_SGMII)
100 + if (state->interface == PHY_INTERFACE_MODE_SGMII) {
101 mt7531_sgmii_pcs_get_state_an(priv, port, state);
102 - else
103 - state->link = false;
104 + return;
105 + } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
106 + (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
107 + mt7531_sgmii_pcs_get_state_inband(priv, port, state);
108 + return;
109 + }
110 +
111 + state->link = false;
112 }
113
114 static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
115 @@ -3069,6 +3089,8 @@ mt753x_setup(struct dsa_switch *ds)
116 priv->pcs[i].pcs.ops = priv->info->pcs_ops;
117 priv->pcs[i].priv = priv;
118 priv->pcs[i].port = i;
119 + if (mt753x_is_mac_port(i))
120 + priv->pcs[i].pcs.poll = 1;
121 }
122
123 ret = priv->info->sw_setup(ds);