blob: 84579ac2c54fb3d8cffd3ac2105a973b22225cc5 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From: Landen Chao <landen.chao@mediatek.com>
2Date: Fri, 4 Sep 2020 22:21:57 +0800
3Subject: [PATCH] net: dsa: mt7530: Extend device data ready for adding a
4 new hardware
5
6Add a structure holding required operations for each device such as device
7initialization, PHY port read or write, a checker whether PHY interface is
8supported on a certain port, MAC port setup for either bus pad or a
9specific PHY interface.
10
11The patch is done for ready adding a new hardware MT7531, and keep the
12same setup logic of existing hardware.
13
14Signed-off-by: Landen Chao <landen.chao@mediatek.com>
15Signed-off-by: Sean Wang <sean.wang@mediatek.com>
16---
17
18--- a/drivers/net/dsa/mt7530.c
19+++ b/drivers/net/dsa/mt7530.c
20@@ -373,8 +373,9 @@ mt7530_fdb_write(struct mt7530_priv *pri
21 mt7530_write(priv, MT7530_ATA1 + (i * 4), reg[i]);
22 }
23
24+/* Setup TX circuit including relevant PAD and driving */
25 static int
26-mt7530_pad_clk_setup(struct dsa_switch *ds, int mode)
27+mt7530_pad_clk_setup(struct dsa_switch *ds, phy_interface_t interface)
28 {
29 struct mt7530_priv *priv = ds->priv;
30 u32 ncpo1, ssc_delta, trgint, i, xtal;
31@@ -388,7 +389,7 @@ mt7530_pad_clk_setup(struct dsa_switch *
32 return -EINVAL;
33 }
34
35- switch (mode) {
36+ switch (interface) {
37 case PHY_INTERFACE_MODE_RGMII:
38 trgint = 0;
39 /* PLL frequency: 125MHz */
40@@ -410,7 +411,8 @@ mt7530_pad_clk_setup(struct dsa_switch *
41 }
42 break;
43 default:
44- dev_err(priv->dev, "xMII mode %d not supported\n", mode);
45+ dev_err(priv->dev, "xMII interface %d not supported\n",
46+ interface);
47 return -EINVAL;
48 }
49
50@@ -1333,12 +1335,11 @@ mt7530_setup(struct dsa_switch *ds)
51 return 0;
52 }
53
54-static void mt7530_phylink_mac_config(struct dsa_switch *ds, int port,
55- unsigned int mode,
56- const struct phylink_link_state *state)
57+static bool
58+mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
59+ const struct phylink_link_state *state)
60 {
61 struct mt7530_priv *priv = ds->priv;
62- u32 mcr_cur, mcr_new;
63
64 switch (port) {
65 case 0: /* Internal phy */
66@@ -1347,33 +1348,114 @@ static void mt7530_phylink_mac_config(st
67 case 3:
68 case 4:
69 if (state->interface != PHY_INTERFACE_MODE_GMII)
70- return;
71+ goto unsupported;
72 break;
73 case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
74- if (priv->p5_interface == state->interface)
75- break;
76 if (!phy_interface_mode_is_rgmii(state->interface) &&
77 state->interface != PHY_INTERFACE_MODE_MII &&
78 state->interface != PHY_INTERFACE_MODE_GMII)
79- return;
80+ goto unsupported;
81+ break;
82+ case 6: /* 1st cpu port */
83+ if (state->interface != PHY_INTERFACE_MODE_RGMII &&
84+ state->interface != PHY_INTERFACE_MODE_TRGMII)
85+ goto unsupported;
86+ break;
87+ default:
88+ dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
89+ port);
90+ goto unsupported;
91+ }
92+
93+ return true;
94+
95+unsupported:
96+ return false;
97+}
98+
99+static bool
100+mt753x_phy_mode_supported(struct dsa_switch *ds, int port,
101+ const struct phylink_link_state *state)
102+{
103+ struct mt7530_priv *priv = ds->priv;
104+
105+ return priv->info->phy_mode_supported(ds, port, state);
106+}
107+
108+static int
109+mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
110+{
111+ struct mt7530_priv *priv = ds->priv;
112+
113+ return priv->info->pad_setup(ds, state->interface);
114+}
115+
116+static int
117+mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
118+ phy_interface_t interface)
119+{
120+ struct mt7530_priv *priv = ds->priv;
121+
122+ /* Only need to setup port5. */
123+ if (port != 5)
124+ return 0;
125+
126+ mt7530_setup_port5(priv->ds, interface);
127+
128+ return 0;
129+}
130+
131+static int
132+mt753x_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
133+ const struct phylink_link_state *state)
134+{
135+ struct mt7530_priv *priv = ds->priv;
136+
137+ return priv->info->mac_port_config(ds, port, mode, state->interface);
138+}
139+
140+static void
141+mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
142+ const struct phylink_link_state *state)
143+{
144+ struct mt7530_priv *priv = ds->priv;
145+ u32 mcr_cur, mcr_new;
146+
147+ if (!mt753x_phy_mode_supported(ds, port, state))
148+ goto unsupported;
149+
150+ switch (port) {
151+ case 0: /* Internal phy */
152+ case 1:
153+ case 2:
154+ case 3:
155+ case 4:
156+ if (state->interface != PHY_INTERFACE_MODE_GMII)
157+ goto unsupported;
158+ break;
159+ case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
160+ if (priv->p5_interface == state->interface)
161+ break;
162+
163+ if (mt753x_mac_config(ds, port, mode, state) < 0)
164+ goto unsupported;
165
166- mt7530_setup_port5(ds, state->interface);
167 break;
168 case 6: /* 1st cpu port */
169 if (priv->p6_interface == state->interface)
170 break;
171
172- if (state->interface != PHY_INTERFACE_MODE_RGMII &&
173- state->interface != PHY_INTERFACE_MODE_TRGMII)
174- return;
175+ mt753x_pad_setup(ds, state);
176
177- /* Setup TX circuit incluing relevant PAD and driving */
178- mt7530_pad_clk_setup(ds, state->interface);
179+ if (mt753x_mac_config(ds, port, mode, state) < 0)
180+ goto unsupported;
181
182 priv->p6_interface = state->interface;
183 break;
184 default:
185- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
186+unsupported:
187+ dev_err(ds->dev, "%s: unsupported %s port: %i\n",
188+ __func__, phy_modes(state->interface), port);
189 return;
190 }
191
192@@ -1441,61 +1523,44 @@ static void mt7530_phylink_mac_link_up(s
193 mt7530_set(priv, MT7530_PMCR_P(port), mcr);
194 }
195
196-static void mt7530_phylink_validate(struct dsa_switch *ds, int port,
197- unsigned long *supported,
198- struct phylink_link_state *state)
199+static void
200+mt7530_mac_port_validate(struct dsa_switch *ds, int port,
201+ unsigned long *supported)
202 {
203+ if (port == 5)
204+ phylink_set(supported, 1000baseX_Full);
205+}
206+
207+static void
208+mt753x_phylink_validate(struct dsa_switch *ds, int port,
209+ unsigned long *supported,
210+ struct phylink_link_state *state)
211+{
212+ struct mt7530_priv *priv = ds->priv;
213 __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
214
215- switch (port) {
216- case 0: /* Internal phy */
217- case 1:
218- case 2:
219- case 3:
220- case 4:
221- if (state->interface != PHY_INTERFACE_MODE_NA &&
222- state->interface != PHY_INTERFACE_MODE_GMII)
223- goto unsupported;
224- break;
225- case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
226- if (state->interface != PHY_INTERFACE_MODE_NA &&
227- !phy_interface_mode_is_rgmii(state->interface) &&
228- state->interface != PHY_INTERFACE_MODE_MII &&
229- state->interface != PHY_INTERFACE_MODE_GMII)
230- goto unsupported;
231- break;
232- case 6: /* 1st cpu port */
233- if (state->interface != PHY_INTERFACE_MODE_NA &&
234- state->interface != PHY_INTERFACE_MODE_RGMII &&
235- state->interface != PHY_INTERFACE_MODE_TRGMII)
236- goto unsupported;
237- break;
238- default:
239- dev_err(ds->dev, "%s: unsupported port: %i\n", __func__, port);
240-unsupported:
241+ if (state->interface != PHY_INTERFACE_MODE_NA &&
242+ !mt753x_phy_mode_supported(ds, port, state)) {
243 linkmode_zero(supported);
244 return;
245 }
246
247 phylink_set_port_modes(mask);
248- phylink_set(mask, Autoneg);
249
250- if (state->interface == PHY_INTERFACE_MODE_TRGMII) {
251- phylink_set(mask, 1000baseT_Full);
252- } else {
253+ if (state->interface != PHY_INTERFACE_MODE_TRGMII) {
254 phylink_set(mask, 10baseT_Half);
255 phylink_set(mask, 10baseT_Full);
256 phylink_set(mask, 100baseT_Half);
257 phylink_set(mask, 100baseT_Full);
258-
259- if (state->interface != PHY_INTERFACE_MODE_MII) {
260- /* This switch only supports 1G full-duplex. */
261- phylink_set(mask, 1000baseT_Full);
262- if (port == 5)
263- phylink_set(mask, 1000baseX_Full);
264- }
265+ phylink_set(mask, Autoneg);
266 }
267
268+ /* This switch only supports 1G full-duplex. */
269+ if (state->interface != PHY_INTERFACE_MODE_MII)
270+ phylink_set(mask, 1000baseT_Full);
271+
272+ priv->info->mac_port_validate(ds, port, mask);
273+
274 phylink_set(mask, Pause);
275 phylink_set(mask, Asym_Pause);
276
277@@ -1591,12 +1656,45 @@ static int mt7530_set_mac_eee(struct dsa
278 return 0;
279 }
280
281+static int
282+mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port,
283+ struct phylink_link_state *state)
284+{
285+ struct mt7530_priv *priv = ds->priv;
286+
287+ return priv->info->mac_port_get_state(ds, port, state);
288+}
289+
290+static int
291+mt753x_setup(struct dsa_switch *ds)
292+{
293+ struct mt7530_priv *priv = ds->priv;
294+
295+ return priv->info->sw_setup(ds);
296+}
297+
298+static int
299+mt753x_phy_read(struct dsa_switch *ds, int port, int regnum)
300+{
301+ struct mt7530_priv *priv = ds->priv;
302+
303+ return priv->info->phy_read(ds, port, regnum);
304+}
305+
306+static int
307+mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
308+{
309+ struct mt7530_priv *priv = ds->priv;
310+
311+ return priv->info->phy_write(ds, port, regnum, val);
312+}
313+
314 static const struct dsa_switch_ops mt7530_switch_ops = {
315 .get_tag_protocol = mtk_get_tag_protocol,
316- .setup = mt7530_setup,
317+ .setup = mt753x_setup,
318 .get_strings = mt7530_get_strings,
319- .phy_read = mt7530_phy_read,
320- .phy_write = mt7530_phy_write,
321+ .phy_read = mt753x_phy_read,
322+ .phy_write = mt753x_phy_write,
323 .get_ethtool_stats = mt7530_get_ethtool_stats,
324 .get_sset_count = mt7530_get_sset_count,
325 .port_enable = mt7530_port_enable,
326@@ -1613,18 +1711,43 @@ static const struct dsa_switch_ops mt753
327 .port_vlan_del = mt7530_port_vlan_del,
328 .port_mirror_add = mt7530_port_mirror_add,
329 .port_mirror_del = mt7530_port_mirror_del,
330- .phylink_validate = mt7530_phylink_validate,
331- .phylink_mac_link_state = mt7530_phylink_mac_link_state,
332- .phylink_mac_config = mt7530_phylink_mac_config,
333+ .phylink_validate = mt753x_phylink_validate,
334+ .phylink_mac_link_state = mt753x_phylink_mac_link_state,
335+ .phylink_mac_config = mt753x_phylink_mac_config,
336 .phylink_mac_link_down = mt7530_phylink_mac_link_down,
337 .phylink_mac_link_up = mt7530_phylink_mac_link_up,
338 .get_mac_eee = mt7530_get_mac_eee,
339 .set_mac_eee = mt7530_set_mac_eee,
340 };
341
342+static const struct mt753x_info mt753x_table[] = {
343+ [ID_MT7621] = {
344+ .id = ID_MT7621,
345+ .sw_setup = mt7530_setup,
346+ .phy_read = mt7530_phy_read,
347+ .phy_write = mt7530_phy_write,
348+ .pad_setup = mt7530_pad_clk_setup,
349+ .phy_mode_supported = mt7530_phy_mode_supported,
350+ .mac_port_validate = mt7530_mac_port_validate,
351+ .mac_port_get_state = mt7530_phylink_mac_link_state,
352+ .mac_port_config = mt7530_mac_config,
353+ },
354+ [ID_MT7530] = {
355+ .id = ID_MT7530,
356+ .sw_setup = mt7530_setup,
357+ .phy_read = mt7530_phy_read,
358+ .phy_write = mt7530_phy_write,
359+ .pad_setup = mt7530_pad_clk_setup,
360+ .phy_mode_supported = mt7530_phy_mode_supported,
361+ .mac_port_validate = mt7530_mac_port_validate,
362+ .mac_port_get_state = mt7530_phylink_mac_link_state,
363+ .mac_port_config = mt7530_mac_config,
364+ },
365+};
366+
367 static const struct of_device_id mt7530_of_match[] = {
368- { .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, },
369- { .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, },
370+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
371+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
372 { /* sentinel */ },
373 };
374 MODULE_DEVICE_TABLE(of, mt7530_of_match);
375@@ -1662,8 +1785,21 @@ mt7530_probe(struct mdio_device *mdiodev
376 /* Get the hardware identifier from the devicetree node.
377 * We will need it for some of the clock and regulator setup.
378 */
379- priv->id = (unsigned int)(unsigned long)
380- of_device_get_match_data(&mdiodev->dev);
381+ priv->info = of_device_get_match_data(&mdiodev->dev);
382+ if (!priv->info)
383+ return -EINVAL;
384+
385+ /* Sanity check if these required device operations are filled
386+ * properly.
387+ */
388+ if (!priv->info->sw_setup || !priv->info->pad_setup ||
389+ !priv->info->phy_read || !priv->info->phy_write ||
390+ !priv->info->phy_mode_supported ||
391+ !priv->info->mac_port_validate ||
392+ !priv->info->mac_port_get_state || !priv->info->mac_port_config)
393+ return -EINVAL;
394+
395+ priv->id = priv->info->id;
396
397 if (priv->id == ID_MT7530) {
398 priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
399--- a/drivers/net/dsa/mt7530.h
400+++ b/drivers/net/dsa/mt7530.h
401@@ -11,7 +11,7 @@
402 #define MT7530_NUM_FDB_RECORDS 2048
403 #define MT7530_ALL_MEMBERS 0xff
404
405-enum {
406+enum mt753x_id {
407 ID_MT7530 = 0,
408 ID_MT7621 = 1,
409 };
410@@ -451,6 +451,40 @@ static const char *p5_intf_modes(unsigne
411 }
412 }
413
414+/* struct mt753x_info - This is the main data structure for holding the specific
415+ * part for each supported device
416+ * @sw_setup: Holding the handler to a device initialization
417+ * @phy_read: Holding the way reading PHY port
418+ * @phy_write: Holding the way writing PHY port
419+ * @pad_setup: Holding the way setting up the bus pad for a certain
420+ * MAC port
421+ * @phy_mode_supported: Check if the PHY type is being supported on a certain
422+ * port
423+ * @mac_port_validate: Holding the way to set addition validate type for a
424+ * certan MAC port
425+ * @mac_port_get_state: Holding the way getting the MAC/PCS state for a certain
426+ * MAC port
427+ * @mac_port_config: Holding the way setting up the PHY attribute to a
428+ * certain MAC port
429+ */
430+struct mt753x_info {
431+ enum mt753x_id id;
432+
433+ int (*sw_setup)(struct dsa_switch *ds);
434+ int (*phy_read)(struct dsa_switch *ds, int port, int regnum);
435+ int (*phy_write)(struct dsa_switch *ds, int port, int regnum, u16 val);
436+ int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
437+ bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
438+ const struct phylink_link_state *state);
439+ void (*mac_port_validate)(struct dsa_switch *ds, int port,
440+ unsigned long *supported);
441+ int (*mac_port_get_state)(struct dsa_switch *ds, int port,
442+ struct phylink_link_state *state);
443+ int (*mac_port_config)(struct dsa_switch *ds, int port,
444+ unsigned int mode,
445+ phy_interface_t interface);
446+};
447+
448 /* struct mt7530_priv - This is the main data structure for holding the state
449 * of the driver
450 * @dev: The device pointer
451@@ -476,6 +510,7 @@ struct mt7530_priv {
452 struct regulator *core_pwr;
453 struct regulator *io_pwr;
454 struct gpio_desc *reset;
455+ const struct mt753x_info *info;
456 unsigned int id;
457 bool mcm;
458 phy_interface_t p6_interface;