1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Mediatek MT7628 Embedded Switch (ESW) DSA driver
4 * Copyright (C) 2026 Joris Vaisvila <joey@tinyisr.com>
5 *
6 * Portions derived from OpenWRT esw_rt3050 driver:
7 * Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
8 * Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
9 * Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
10 * Copyright (C) 2016 Vittorio Gambaletta <openwrt@vittgam.net>
11 */
12
13 #include <linux/platform_device.h>
14 #include <linux/etherdevice.h>
15 #include <linux/netdevice.h>
16 #include <linux/dsa/8021q.h>
17 #include <linux/if_bridge.h>
18 #include <linux/module.h>
19 #include <linux/mdio.h>
20 #include <linux/of.h>
21 #include <linux/of_mdio.h>
22 #include <linux/of_net.h>
23 #include <linux/kernel.h>
24 #include <linux/regmap.h>
25 #include <linux/reset.h>
26 #include <net/dsa.h>
27
28 #define MT7628_ESW_REG_IMR 0x04
29 #define MT7628_ESW_REG_FCT0 0x08
30 #define MT7628_ESW_REG_PFC1 0x14
31 #define MT7628_ESW_REG_PVIDC(port) (0x40 + 4 * ((port) / 2))
32 #define MT7628_ESW_REG_VLANI(vlan) (0x50 + 4 * ((vlan) / 2))
33 #define MT7628_ESW_REG_VMSC(vlan) (0x70 + 4 * ((vlan) / 4))
34 #define MT7628_ESW_REG_VUB(vlan) (0x100 + 4 * ((vlan) / 4))
35 #define MT7628_ESW_REG_SOCPC 0x8c
36 #define MT7628_ESW_REG_POC0 0x90
37 #define MT7628_ESW_REG_POC2 0x98
38 #define MT7628_ESW_REG_SGC 0x9c
39 #define MT7628_ESW_REG_PCR0 0xc0
40 #define MT7628_ESW_REG_PCR1 0xc4
41 #define MT7628_ESW_REG_FPA2 0xc8
42 #define MT7628_ESW_REG_FCT2 0xcc
43 #define MT7628_ESW_REG_SGC2 0xe4
44
45 #define MT7628_ESW_FCT0_DROP_SET_TH GENMASK(7, 0)
46 #define MT7628_ESW_FCT0_DROP_RLS_TH GENMASK(15, 8)
47 #define MT7628_ESW_FCT0_FC_SET_TH GENMASK(23, 16)
48 #define MT7628_ESW_FCT0_FC_RLS_TH GENMASK(31, 24)
49
50 #define MT7628_ESW_PFC1_EN_VLAN GENMASK(22, 16)
51
52 #define MT7628_ESW_PVID_S 12
53 #define MT7628_ESW_PVID_M GENMASK(11, 0)
54 #define MT7628_ESW_PVID_SHIFT(port) \
55 (MT7628_ESW_PVID_S * ((port) % 2))
56 #define MT7628_ESW_PVID_MASK(port) \
57 (MT7628_ESW_PVID_M << MT7628_ESW_PVID_SHIFT(port))
58 #define MT7628_ESW_PVID_PREP(port, pvid) \
59 (((pvid) & MT7628_ESW_PVID_M) << MT7628_ESW_PVID_SHIFT(port))
60
61 #define MT7628_ESW_VID_S 12
62 #define MT7628_ESW_VID_M GENMASK(11, 0)
63 #define MT7628_ESW_VID_SHIFT(vlan) \
64 (MT7628_ESW_VID_S * ((vlan) % 2))
65 #define MT7628_ESW_VID_MASK(vlan) \
66 (MT7628_ESW_VID_M << MT7628_ESW_VID_SHIFT(vlan))
67 #define MT7628_ESW_VID_PREP(vlan, vid) \
68 (((vid) & MT7628_ESW_VID_M) << MT7628_ESW_VID_SHIFT(vlan))
69
70 #define MT7628_ESW_VMSC_S 8
71 #define MT7628_ESW_VMSC_M GENMASK(7, 0)
72 #define MT7628_ESW_VMSC_SHIFT(vlan) \
73 (MT7628_ESW_VMSC_S * ((vlan) % 4))
74 #define MT7628_ESW_VMSC_MASK(vlan) \
75 (MT7628_ESW_VMSC_M << MT7628_ESW_VMSC_SHIFT(vlan))
76 #define MT7628_ESW_VMSC_PREP(vlan, vmsc) \
77 (((vmsc) & MT7628_ESW_VMSC_M) << MT7628_ESW_VMSC_SHIFT(vlan))
78
79 #define MT7628_ESW_VUB_S 7
80 #define MT7628_ESW_VUB_M GENMASK(6, 0)
81 #define MT7628_ESW_VUB_SHIFT(vlan) \
82 (MT7628_ESW_VUB_S * ((vlan) % 4))
83 #define MT7628_ESW_VUB_MASK(vlan) \
84 (MT7628_ESW_VUB_M << MT7628_ESW_VUB_SHIFT(vlan))
85 #define MT7628_ESW_VUB_PREP(vlan, vub) \
86 (((vub) & MT7628_ESW_VUB_M) << MT7628_ESW_VUB_SHIFT(vlan))
87
88 #define MT7628_ESW_SOCPC_CRC_PADDING BIT(25)
89 #define MT7628_ESW_SOCPC_DISBC2CPU GENMASK(22, 16)
90 #define MT7628_ESW_SOCPC_DISMC2CPU GENMASK(14, 8)
91 #define MT7628_ESW_SOCPC_DISUN2CPU GENMASK(6, 0)
92
93 #define MT7628_ESW_POC0_PORT_DISABLE GENMASK(29, 23)
94
95 #define MT7628_ESW_POC2_PER_VLAN_UNTAG_EN BIT(15)
96
97 #define MT7628_ESW_SGC_AGING_INTERVAL GENMASK(3, 0)
98 #define MT7628_ESW_BC_STORM_PROT GENMASK(5, 4)
99 #define MT7628_ESW_PKT_MAX_LEN GENMASK(7, 6)
100 #define MT7628_ESW_DIS_PKT_ABORT BIT(8)
101 #define MT7628_ESW_ADDRESS_HASH_ALG GENMASK(10, 9)
102 #define MT7628_ESW_DISABLE_TX_BACKOFF BIT(11)
103 #define MT7628_ESW_BP_JAM_CNT GENMASK(15, 12)
104 #define MT7628_ESW_DISMIIPORT_WASTX GENMASK(17, 16)
105 #define MT7628_ESW_BP_MODE GENMASK(19, 18)
106 #define MT7628_ESW_BISH_DIS BIT(20)
107 #define MT7628_ESW_BISH_TH GENMASK(22, 21)
108 #define MT7628_ESW_LED_FLASH_TIME GENMASK(24, 23)
109 #define MT7628_ESW_RMC_RULE GENMASK(26, 25)
110 #define MT7628_ESW_IP_MULT_RULE GENMASK(28, 27)
111 #define MT7628_ESW_LEN_ERR_CHK BIT(29)
112 #define MT7628_ESW_BKOFF_ALG BIT(30)
113
114 #define MT7628_ESW_PCR0_WT_NWAY_DATA GENMASK(31, 16)
115 #define MT7628_ESW_PCR0_RD_PHY_CMD BIT(14)
116 #define MT7628_ESW_PCR0_WT_PHY_CMD BIT(13)
117 #define MT7628_ESW_PCR0_CPU_PHY_REG GENMASK(12, 8)
118 #define MT7628_ESW_PCR0_CPU_PHY_ADDR GENMASK(4, 0)
119
120 #define MT7628_ESW_PCR1_RD_DATA GENMASK(31, 16)
121 #define MT7628_ESW_PCR1_RD_DONE BIT(1)
122 #define MT7628_ESW_PCR1_WT_DONE BIT(0)
123
124 #define MT7628_ESW_FPA2_AP_EN BIT(29)
125 #define MT7628_ESW_FPA2_EXT_PHY_ADDR_BASE GENMASK(28, 24)
126 #define MT7628_ESW_FPA2_FORCE_RGMII_LINK1 BIT(13)
127 #define MT7628_ESW_FPA2_FORCE_RGMII_EN1 BIT(11)
128
129 #define MT7628_ESW_FCT2_MUST_DROP_RLS_TH GENMASK(17, 13)
130 #define MT7628_ESW_FCT2_MUST_DROP_SET_TH GENMASK(12, 8)
131 #define MT7628_ESW_FCT2_MC_PER_PORT_TH GENMASK(5, 0)
132
133 #define MT7628_ESW_SGC2_SPECIAL_TAG_EN BIT(23)
134 #define MT7628_ESW_SGC2_TX_CPU_TPID_BIT_MAP GENMASK(22, 16)
135 #define MT7628_ESW_SGC2_DOUBLE_TAG_EN GENMASK(6, 0)
136
137 #define MT7628_ESW_PORTS_NOCPU GENMASK(5, 0)
138 #define MT7628_ESW_PORTS_CPU BIT(6)
139 #define MT7628_ESW_PORTS_ALL GENMASK(6, 0)
140
141 #define MT7628_ESW_NUM_PORTS 7
142 #define MT7628_NUM_VLANS 16
143
144 static const struct regmap_config mt7628_esw_regmap_cfg = {
145 .name = "mt7628-esw",
146 .reg_bits = 32,
147 .val_bits = 32,
148 .reg_stride = 4,
149 .fast_io = true,
150 .reg_format_endian = REGMAP_ENDIAN_LITTLE,
151 .val_format_endian = REGMAP_ENDIAN_LITTLE,
152 };
153
154 struct mt7628_vlan {
155 bool active;
156 u8 members;
157 u8 untag;
158 u16 vid;
159 };
160
161 struct mt7628_esw {
162 struct reset_control *rst_ephy;
163 struct reset_control *rst_esw;
164 struct regmap *regmap;
165 struct dsa_switch *ds;
166 u16 tag_8021q_pvid[MT7628_ESW_NUM_PORTS];
167 struct mt7628_vlan vlans[MT7628_NUM_VLANS];
168 struct device *dev;
169 };
170
mt7628_mii_read(struct mii_bus * bus,int port,int regnum)171 static int mt7628_mii_read(struct mii_bus *bus, int port, int regnum)
172 {
173 struct mt7628_esw *esw = bus->priv;
174 int ret;
175 u32 val;
176
177 /*
178 * RD_DONE bit is read to clear. Read PCR1 once to acknowledge any
179 * stale completion indicator before starting a new transaction.
180 */
181 ret = regmap_read(esw->regmap, MT7628_ESW_REG_PCR1, &val);
182 if (ret)
183 goto out;
184
185 ret = regmap_write(esw->regmap, MT7628_ESW_REG_PCR0,
186 FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_REG,
187 regnum) |
188 FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_ADDR,
189 port) | MT7628_ESW_PCR0_RD_PHY_CMD);
190 if (ret)
191 goto out;
192
193 ret = regmap_read_poll_timeout(esw->regmap, MT7628_ESW_REG_PCR1, val,
194 (val & MT7628_ESW_PCR1_RD_DONE), 10,
195 5000);
196 if (ret)
197 goto out;
198
199 return FIELD_GET(MT7628_ESW_PCR1_RD_DATA, val);
200
201 out:
202 dev_err(&bus->dev, "read failed. MDIO timeout?\n");
203 return ret;
204 }
205
mt7628_mii_write(struct mii_bus * bus,int port,int regnum,u16 dat)206 static int mt7628_mii_write(struct mii_bus *bus, int port, int regnum, u16 dat)
207 {
208 struct mt7628_esw *esw = bus->priv;
209 u32 val;
210 int ret;
211
212 /*
213 * WT_DONE bit is read to clear. Read PCR1 once to acknowledge any
214 * stale completion indicator before starting a new transaction.
215 */
216 ret = regmap_read(esw->regmap, MT7628_ESW_REG_PCR1, &val);
217 if (ret)
218 goto out;
219
220 ret = regmap_write(esw->regmap, MT7628_ESW_REG_PCR0,
221 FIELD_PREP(MT7628_ESW_PCR0_WT_NWAY_DATA, dat) |
222 FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_REG,
223 regnum) |
224 FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_ADDR,
225 port) | MT7628_ESW_PCR0_WT_PHY_CMD);
226 if (ret)
227 goto out;
228
229 ret = regmap_read_poll_timeout(esw->regmap, MT7628_ESW_REG_PCR1, val,
230 (val & MT7628_ESW_PCR1_WT_DONE), 10,
231 5000);
232 if (ret)
233 goto out;
234
235 return 0;
236
237 out:
238 dev_err(&bus->dev, "write failed. MDIO timeout?\n");
239 return ret;
240 }
241
mt7628_setup_internal_mdio(struct dsa_switch * ds)242 static int mt7628_setup_internal_mdio(struct dsa_switch *ds)
243 {
244 struct mt7628_esw *esw = ds->priv;
245 struct device *dev = ds->dev;
246 struct mii_bus *bus;
247
248 bus = devm_mdiobus_alloc(dev);
249 if (!bus)
250 return -ENOMEM;
251
252 bus->name = "MT7628 internal MDIO bus";
253 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev));
254 bus->priv = esw;
255 bus->read = mt7628_mii_read;
256 bus->write = mt7628_mii_write;
257 bus->parent = dev;
258
259 ds->user_mii_bus = bus;
260 bus->phy_mask = ~ds->phys_mii_mask;
261
262 return devm_mdiobus_register(dev, bus);
263 }
264
mt7628_switch_init(struct dsa_switch * ds)265 static void mt7628_switch_init(struct dsa_switch *ds)
266 {
267 struct mt7628_esw *esw = ds->priv;
268
269 regmap_write(esw->regmap, MT7628_ESW_REG_FCT0,
270 FIELD_PREP(MT7628_ESW_FCT0_DROP_SET_TH, 0x50) |
271 FIELD_PREP(MT7628_ESW_FCT0_DROP_RLS_TH, 0x78) |
272 FIELD_PREP(MT7628_ESW_FCT0_FC_SET_TH, 0xa0) |
273 FIELD_PREP(MT7628_ESW_FCT0_FC_RLS_TH, 0xc8));
274
275 regmap_write(esw->regmap, MT7628_ESW_REG_FCT2,
276 FIELD_PREP(MT7628_ESW_FCT2_MC_PER_PORT_TH, 0xc) |
277 FIELD_PREP(MT7628_ESW_FCT2_MUST_DROP_SET_TH, 0x10) |
278 FIELD_PREP(MT7628_ESW_FCT2_MUST_DROP_RLS_TH, 0x12));
279
280 /*
281 * general switch configuration:
282 * 300s aging interval
283 * broadcast storm prevention disabled
284 * max packet length 1536 bytes
285 * disable collision 16 packet abort and late collision abort
286 * use xor48 for address hashing
287 * disable tx backoff
288 * 10 packet back pressure jam
289 * disable was_transmit
290 * jam until BP condition released
291 * 30ms LED flash
292 * rmc tb fault to all ports
293 * unmatched IGMP as broadcast
294 */
295 regmap_write(esw->regmap, MT7628_ESW_REG_SGC,
296 FIELD_PREP(MT7628_ESW_SGC_AGING_INTERVAL, 1) |
297 FIELD_PREP(MT7628_ESW_BC_STORM_PROT, 0) |
298 FIELD_PREP(MT7628_ESW_PKT_MAX_LEN, 0) |
299 MT7628_ESW_DIS_PKT_ABORT |
300 FIELD_PREP(MT7628_ESW_ADDRESS_HASH_ALG, 1) |
301 MT7628_ESW_DISABLE_TX_BACKOFF |
302 FIELD_PREP(MT7628_ESW_BP_JAM_CNT, 10) |
303 FIELD_PREP(MT7628_ESW_DISMIIPORT_WASTX, 0) |
304 FIELD_PREP(MT7628_ESW_BP_MODE, 0b10) |
305 FIELD_PREP(MT7628_ESW_LED_FLASH_TIME, 0) |
306 FIELD_PREP(MT7628_ESW_RMC_RULE, 0) |
307 FIELD_PREP(MT7628_ESW_IP_MULT_RULE, 0));
308
309 regmap_write(esw->regmap, MT7628_ESW_REG_SOCPC,
310 MT7628_ESW_SOCPC_CRC_PADDING |
311 FIELD_PREP(MT7628_ESW_SOCPC_DISUN2CPU,
312 MT7628_ESW_PORTS_CPU) |
313 FIELD_PREP(MT7628_ESW_SOCPC_DISMC2CPU,
314 MT7628_ESW_PORTS_CPU) |
315 FIELD_PREP(MT7628_ESW_SOCPC_DISBC2CPU,
316 MT7628_ESW_PORTS_CPU));
317
318 regmap_set_bits(esw->regmap, MT7628_ESW_REG_FPA2,
319 MT7628_ESW_FPA2_FORCE_RGMII_EN1 |
320 MT7628_ESW_FPA2_FORCE_RGMII_LINK1 |
321 MT7628_ESW_FPA2_AP_EN);
322
323 regmap_update_bits(esw->regmap, MT7628_ESW_REG_FPA2,
324 MT7628_ESW_FPA2_EXT_PHY_ADDR_BASE,
325 FIELD_PREP(MT7628_ESW_FPA2_EXT_PHY_ADDR_BASE, 31));
326
327 /* disable all interrupts */
328 regmap_write(esw->regmap, MT7628_ESW_REG_IMR, 0);
329
330 /* enable MT7628 DSA tag on CPU port */
331 regmap_write(esw->regmap, MT7628_ESW_REG_SGC2,
332 MT7628_ESW_SGC2_SPECIAL_TAG_EN |
333 FIELD_PREP(MT7628_ESW_SGC2_TX_CPU_TPID_BIT_MAP,
334 MT7628_ESW_PORTS_CPU));
335
336 /*
337 * Double tag feature allows switch to always append the port PVID VLAN tag
338 * regardless of if the incoming packet already has a VLAN tag.
339 * This is enabled to simulate VLAN unawareness.
340 */
341 regmap_set_bits(esw->regmap, MT7628_ESW_REG_SGC2,
342 FIELD_PREP(MT7628_ESW_SGC2_DOUBLE_TAG_EN,
343 MT7628_ESW_PORTS_NOCPU));
344
345 regmap_set_bits(esw->regmap, MT7628_ESW_REG_POC2,
346 MT7628_ESW_POC2_PER_VLAN_UNTAG_EN);
347
348 regmap_update_bits(esw->regmap, MT7628_ESW_REG_PFC1,
349 MT7628_ESW_PFC1_EN_VLAN,
350 FIELD_PREP(MT7628_ESW_PFC1_EN_VLAN,
351 MT7628_ESW_PORTS_ALL));
352 }
353
mt7628_esw_set_pvid(struct mt7628_esw * esw,unsigned int port,unsigned int pvid)354 static void mt7628_esw_set_pvid(struct mt7628_esw *esw, unsigned int port,
355 unsigned int pvid)
356 {
357 regmap_update_bits(esw->regmap, MT7628_ESW_REG_PVIDC(port),
358 MT7628_ESW_PVID_MASK(port),
359 MT7628_ESW_PVID_PREP(port, pvid));
360 }
361
mt7628_esw_set_vlan_id(struct mt7628_esw * esw,unsigned int vlan,unsigned int vid)362 static void mt7628_esw_set_vlan_id(struct mt7628_esw *esw, unsigned int vlan,
363 unsigned int vid)
364 {
365 regmap_update_bits(esw->regmap, MT7628_ESW_REG_VLANI(vlan),
366 MT7628_ESW_VID_MASK(vlan),
367 MT7628_ESW_VID_PREP(vlan, vid));
368 }
369
mt7628_esw_set_vmsc(struct mt7628_esw * esw,unsigned int vlan,unsigned int msc)370 static void mt7628_esw_set_vmsc(struct mt7628_esw *esw, unsigned int vlan,
371 unsigned int msc)
372 {
373 regmap_update_bits(esw->regmap, MT7628_ESW_REG_VMSC(vlan),
374 MT7628_ESW_VMSC_MASK(vlan),
375 MT7628_ESW_VMSC_PREP(vlan, msc));
376 }
377
mt7628_esw_set_vub(struct mt7628_esw * esw,unsigned int vlan,unsigned int vub)378 static void mt7628_esw_set_vub(struct mt7628_esw *esw, unsigned int vlan,
379 unsigned int vub)
380 {
381 regmap_update_bits(esw->regmap, MT7628_ESW_REG_VUB(vlan),
382 MT7628_ESW_VUB_MASK(vlan),
383 MT7628_ESW_VUB_PREP(vlan, vub));
384 }
385
mt7628_vlan_sync(struct dsa_switch * ds)386 static void mt7628_vlan_sync(struct dsa_switch *ds)
387 {
388 struct mt7628_esw *esw = ds->priv;
389 int i;
390
391 for (i = 0; i < MT7628_NUM_VLANS; i++) {
392 struct mt7628_vlan *vlan = &esw->vlans[i];
393
394 mt7628_esw_set_vmsc(esw, i, vlan->members);
395 mt7628_esw_set_vlan_id(esw, i, vlan->vid);
396 mt7628_esw_set_vub(esw, i, vlan->untag);
397 }
398
399 for (i = 0; i < ds->num_ports; i++)
400 mt7628_esw_set_pvid(esw, i, esw->tag_8021q_pvid[i]);
401 }
402
mt7628_setup(struct dsa_switch * ds)403 static int mt7628_setup(struct dsa_switch *ds)
404 {
405 struct mt7628_esw *esw = ds->priv;
406 int ret;
407
408 ret = reset_control_reset(esw->rst_esw);
409 if (ret)
410 return ret;
411 usleep_range(1000, 2000);
412
413 ret = reset_control_reset(esw->rst_ephy);
414 if (ret)
415 return ret;
416 usleep_range(1000, 2000);
417 /*
418 * all MMIO reads hang if esw is not out of reset
419 * ephy needs extra time to get out of reset or it ends up misconfigured
420 */
421
422 mt7628_switch_init(ds);
423
424 ret = mt7628_setup_internal_mdio(ds);
425 if (ret)
426 return ret;
427
428 rtnl_lock();
429 ret = dsa_tag_8021q_register(ds, htons(ETH_P_8021Q));
430 rtnl_unlock();
431
432 return ret;
433 }
434
mt7628_port_enable(struct dsa_switch * ds,int port,struct phy_device * phy)435 static int mt7628_port_enable(struct dsa_switch *ds, int port,
436 struct phy_device *phy)
437 {
438 struct mt7628_esw *esw = ds->priv;
439
440 /*
441 * All switch ports are disabled by esw reset and enabled here by DSA.
442 */
443 regmap_clear_bits(esw->regmap, MT7628_ESW_REG_POC0,
444 FIELD_PREP(MT7628_ESW_POC0_PORT_DISABLE, BIT(port)));
445 return 0;
446 }
447
mt7628_port_disable(struct dsa_switch * ds,int port)448 static void mt7628_port_disable(struct dsa_switch *ds, int port)
449 {
450 struct mt7628_esw *esw = ds->priv;
451
452 regmap_set_bits(esw->regmap, MT7628_ESW_REG_POC0,
453 FIELD_PREP(MT7628_ESW_POC0_PORT_DISABLE, BIT(port)));
454 }
455
456 static enum dsa_tag_protocol
mt7628_get_tag_proto(struct dsa_switch * ds,int port,enum dsa_tag_protocol mp)457 mt7628_get_tag_proto(struct dsa_switch *ds, int port, enum dsa_tag_protocol mp)
458 {
459 return DSA_TAG_PROTO_MT7628;
460 }
461
mt7628_phylink_get_caps(struct dsa_switch * ds,int port,struct phylink_config * config)462 static void mt7628_phylink_get_caps(struct dsa_switch *ds, int port,
463 struct phylink_config *config)
464 {
465 switch (port) {
466 case 6:
467 config->mac_capabilities |= MAC_1000;
468 fallthrough;
469 case 0 ... 4:
470 config->mac_capabilities |= MAC_100 | MAC_10;
471 __set_bit(PHY_INTERFACE_MODE_INTERNAL,
472 config->supported_interfaces);
473 break;
474 default:
475 break; /* port 5 does not exist on MT7628 */
476 }
477 }
478
mt7628_dsa_8021q_vlan_add(struct dsa_switch * ds,int port,u16 vid,u16 flags)479 static int mt7628_dsa_8021q_vlan_add(struct dsa_switch *ds, int port,
480 u16 vid, u16 flags)
481 {
482 struct mt7628_esw *esw = ds->priv;
483 struct mt7628_vlan *vlan = NULL;
484 int i;
485
486 for (i = 0; i < MT7628_NUM_VLANS; i++) {
487 struct mt7628_vlan *check_vlan = &esw->vlans[i];
488
489 if (!check_vlan->active && !vlan)
490 vlan = check_vlan;
491
492 if (check_vlan->active && check_vlan->vid == vid) {
493 vlan = check_vlan;
494 break;
495 }
496 }
497
498 if (!vlan)
499 return -ENOSPC;
500
501 vlan->vid = vid;
502 vlan->active = true;
503 vlan->members |= BIT(port);
504
505 if (flags & BRIDGE_VLAN_INFO_PVID)
506 esw->tag_8021q_pvid[port] = vid;
507
508 if (flags & BRIDGE_VLAN_INFO_UNTAGGED)
509 vlan->untag |= BIT(port);
510
511 mt7628_vlan_sync(ds);
512 return 0;
513 }
514
mt7628_dsa_8021q_vlan_del(struct dsa_switch * ds,int port,u16 vid)515 static int mt7628_dsa_8021q_vlan_del(struct dsa_switch *ds, int port, u16 vid)
516 {
517 struct mt7628_esw *esw = ds->priv;
518 struct mt7628_vlan *vlan = NULL;
519 int i;
520
521 for (i = 0; i < MT7628_NUM_VLANS; i++) {
522 struct mt7628_vlan *check_vlan = &esw->vlans[i];
523
524 if (!check_vlan->active || check_vlan->vid != vid)
525 continue;
526 vlan = check_vlan;
527 break;
528 }
529 if (!vlan)
530 return -ENOENT;
531
532 if (esw->tag_8021q_pvid[port] == vid)
533 esw->tag_8021q_pvid[port] = 0;
534
535 vlan->members &= ~BIT(port);
536 vlan->untag &= ~BIT(port);
537
538 if (!vlan->members) {
539 vlan->active = false;
540 vlan->vid = 0;
541 }
542
543 mt7628_vlan_sync(ds);
544 return 0;
545 }
546
mt7628_teardown(struct dsa_switch * ds)547 static void mt7628_teardown(struct dsa_switch *ds)
548 {
549 rtnl_lock();
550 dsa_tag_8021q_unregister(ds);
551 rtnl_unlock();
552 }
553
554 static const struct dsa_switch_ops mt7628_switch_ops = {
555 .get_tag_protocol = mt7628_get_tag_proto,
556 .setup = mt7628_setup,
557 .teardown = mt7628_teardown,
558 .port_enable = mt7628_port_enable,
559 .port_disable = mt7628_port_disable,
560 .phylink_get_caps = mt7628_phylink_get_caps,
561 .tag_8021q_vlan_add = mt7628_dsa_8021q_vlan_add,
562 .tag_8021q_vlan_del = mt7628_dsa_8021q_vlan_del,
563 };
564
mt7628_probe(struct platform_device * pdev)565 static int mt7628_probe(struct platform_device *pdev)
566 {
567 struct device *dev = &pdev->dev;
568 struct mt7628_esw *esw;
569 struct dsa_switch *ds;
570 void __iomem *base;
571
572 ds = devm_kzalloc(&pdev->dev, sizeof(*ds), GFP_KERNEL);
573 if (!ds)
574 return -ENOMEM;
575
576 esw = devm_kzalloc(&pdev->dev, sizeof(*esw), GFP_KERNEL);
577 if (!esw)
578 return -ENOMEM;
579
580 base = devm_platform_ioremap_resource(pdev, 0);
581 if (IS_ERR(base))
582 return PTR_ERR(base);
583
584 esw->regmap = devm_regmap_init_mmio(&pdev->dev, base,
585 &mt7628_esw_regmap_cfg);
586 if (IS_ERR(esw->regmap))
587 return PTR_ERR(esw->regmap);
588
589 esw->rst_ephy = devm_reset_control_get_exclusive(&pdev->dev, "ephy");
590 if (IS_ERR(esw->rst_ephy))
591 return dev_err_probe(dev, PTR_ERR(esw->rst_ephy),
592 "failed to get EPHY reset\n");
593
594 esw->rst_esw = devm_reset_control_get_exclusive(&pdev->dev, "esw");
595 if (IS_ERR(esw->rst_esw))
596 return dev_err_probe(dev, PTR_ERR(esw->rst_esw),
597 "failed to get ESW reset\n");
598
599 ds->dev = dev;
600 ds->num_ports = MT7628_ESW_NUM_PORTS;
601 ds->ops = &mt7628_switch_ops;
602 ds->priv = esw;
603 esw->ds = ds;
604 esw->dev = dev;
605 dev_set_drvdata(dev, esw);
606
607 return dsa_register_switch(ds);
608 }
609
mt7628_remove(struct platform_device * pdev)610 static void mt7628_remove(struct platform_device *pdev)
611 {
612 struct mt7628_esw *esw = platform_get_drvdata(pdev);
613
614 if (!esw)
615 return;
616
617 dsa_unregister_switch(esw->ds);
618 }
619
mt7628_shutdown(struct platform_device * pdev)620 static void mt7628_shutdown(struct platform_device *pdev)
621 {
622 struct mt7628_esw *esw = platform_get_drvdata(pdev);
623
624 if (!esw)
625 return;
626
627 dsa_switch_shutdown(esw->ds);
628 dev_set_drvdata(&pdev->dev, NULL);
629 }
630
631 static const struct of_device_id mt7628_of_match[] = {
632 { .compatible = "mediatek,mt7628-esw" },
633 {}
634 };
635
636 MODULE_DEVICE_TABLE(of, mt7628_of_match);
637
638 static struct platform_driver mt7628_driver = {
639 .driver = {
640 .name = "mt7628-esw",
641 .of_match_table = mt7628_of_match,
642 },
643 .probe = mt7628_probe,
644 .remove = mt7628_remove,
645 .shutdown = mt7628_shutdown,
646 };
647
648 module_platform_driver(mt7628_driver);
649
650 MODULE_AUTHOR("Joris Vaisvila <joey@tinyisr.com>");
651 MODULE_DESCRIPTION("Driver for Mediatek MT7628 embedded switch");
652 MODULE_LICENSE("GPL");
653