1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Marvell 88e6xxx Ethernet switch single-chip support
4 *
5 * Copyright (c) 2008 Marvell Semiconductor
6 *
7 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
8 *
9 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
10 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
11 */
12
13 #include <linux/bitfield.h>
14 #include <linux/delay.h>
15 #include <linux/dsa/mv88e6xxx.h>
16 #include <linux/etherdevice.h>
17 #include <linux/ethtool.h>
18 #include <linux/if_bridge.h>
19 #include <linux/interrupt.h>
20 #include <linux/irq.h>
21 #include <linux/irqdomain.h>
22 #include <linux/jiffies.h>
23 #include <linux/list.h>
24 #include <linux/mdio.h>
25 #include <linux/module.h>
26 #include <linux/of.h>
27 #include <linux/of_irq.h>
28 #include <linux/of_mdio.h>
29 #include <linux/platform_data/mv88e6xxx.h>
30 #include <linux/property.h>
31 #include <linux/netdevice.h>
32 #include <linux/gpio/consumer.h>
33 #include <linux/phylink.h>
34 #include <net/dsa.h>
35
36 #include "chip.h"
37 #include "devlink.h"
38 #include "global1.h"
39 #include "global2.h"
40 #include "hwtstamp.h"
41 #include "phy.h"
42 #include "port.h"
43 #include "ptp.h"
44 #include "serdes.h"
45 #include "smi.h"
46 #include "tcam.h"
47 #include "tcflower.h"
48
assert_reg_lock(struct mv88e6xxx_chip * chip)49 static void assert_reg_lock(struct mv88e6xxx_chip *chip)
50 {
51 if (unlikely(!mutex_is_locked(&chip->reg_lock))) {
52 dev_err(chip->dev, "Switch registers lock not held!\n");
53 dump_stack();
54 }
55 }
56
mv88e6xxx_read(struct mv88e6xxx_chip * chip,int addr,int reg,u16 * val)57 int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val)
58 {
59 int err;
60
61 assert_reg_lock(chip);
62
63 err = mv88e6xxx_smi_read(chip, addr, reg, val);
64 if (err)
65 return err;
66
67 dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
68 addr, reg, *val);
69
70 return 0;
71 }
72
mv88e6xxx_write(struct mv88e6xxx_chip * chip,int addr,int reg,u16 val)73 int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
74 {
75 int err;
76
77 assert_reg_lock(chip);
78
79 err = mv88e6xxx_smi_write(chip, addr, reg, val);
80 if (err)
81 return err;
82
83 dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
84 addr, reg, val);
85
86 return 0;
87 }
88
mv88e6xxx_wait_mask(struct mv88e6xxx_chip * chip,int addr,int reg,u16 mask,u16 val)89 int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
90 u16 mask, u16 val)
91 {
92 const unsigned long timeout = jiffies + msecs_to_jiffies(50);
93 u16 data;
94 int err;
95 int i;
96
97 /* There's no bus specific operation to wait for a mask. Even
98 * if the initial poll takes longer than 50ms, always do at
99 * least one more attempt.
100 */
101 for (i = 0; time_before(jiffies, timeout) || (i < 2); i++) {
102 err = mv88e6xxx_read(chip, addr, reg, &data);
103 if (err)
104 return err;
105
106 if ((data & mask) == val)
107 return 0;
108
109 if (i < 2)
110 cpu_relax();
111 else
112 usleep_range(1000, 2000);
113 }
114
115 err = mv88e6xxx_read(chip, addr, reg, &data);
116 if (err)
117 return err;
118
119 if ((data & mask) == val)
120 return 0;
121
122 dev_err(chip->dev, "Timeout while waiting for switch\n");
123 return -ETIMEDOUT;
124 }
125
mv88e6xxx_wait_bit(struct mv88e6xxx_chip * chip,int addr,int reg,int bit,int val)126 int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
127 int bit, int val)
128 {
129 return mv88e6xxx_wait_mask(chip, addr, reg, BIT(bit),
130 val ? BIT(bit) : 0x0000);
131 }
132
mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip * chip)133 struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
134 {
135 struct mv88e6xxx_mdio_bus *mdio_bus;
136
137 mdio_bus = list_first_entry_or_null(&chip->mdios,
138 struct mv88e6xxx_mdio_bus, list);
139 if (!mdio_bus)
140 return NULL;
141
142 return mdio_bus->bus;
143 }
144
mv88e6xxx_g1_irq_mask(struct irq_data * d)145 static void mv88e6xxx_g1_irq_mask(struct irq_data *d)
146 {
147 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
148 unsigned int n = d->hwirq;
149
150 chip->g1_irq.masked |= (1 << n);
151 }
152
mv88e6xxx_g1_irq_unmask(struct irq_data * d)153 static void mv88e6xxx_g1_irq_unmask(struct irq_data *d)
154 {
155 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
156 unsigned int n = d->hwirq;
157
158 chip->g1_irq.masked &= ~(1 << n);
159 }
160
mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip * chip)161 static irqreturn_t mv88e6xxx_g1_irq_thread_work(struct mv88e6xxx_chip *chip)
162 {
163 unsigned int nhandled = 0;
164 unsigned int sub_irq;
165 unsigned int n;
166 u16 reg;
167 u16 ctl1;
168 int err;
169
170 mv88e6xxx_reg_lock(chip);
171 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®);
172 mv88e6xxx_reg_unlock(chip);
173
174 if (err)
175 goto out;
176
177 do {
178 for (n = 0; n < chip->g1_irq.nirqs; ++n) {
179 if (reg & (1 << n)) {
180 sub_irq = irq_find_mapping(chip->g1_irq.domain,
181 n);
182 handle_nested_irq(sub_irq);
183 ++nhandled;
184 }
185 }
186
187 mv88e6xxx_reg_lock(chip);
188 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &ctl1);
189 if (err)
190 goto unlock;
191 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®);
192 unlock:
193 mv88e6xxx_reg_unlock(chip);
194 if (err)
195 goto out;
196 ctl1 &= GENMASK(chip->g1_irq.nirqs, 0);
197 } while (reg & ctl1);
198
199 out:
200 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
201 }
202
mv88e6xxx_g1_irq_thread_fn(int irq,void * dev_id)203 static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
204 {
205 struct mv88e6xxx_chip *chip = dev_id;
206
207 return mv88e6xxx_g1_irq_thread_work(chip);
208 }
209
mv88e6xxx_g1_irq_bus_lock(struct irq_data * d)210 static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d)
211 {
212 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
213
214 mv88e6xxx_reg_lock(chip);
215 }
216
mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data * d)217 static void mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data *d)
218 {
219 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
220 u16 mask = GENMASK(chip->g1_irq.nirqs, 0);
221 u16 reg;
222 int err;
223
224 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, ®);
225 if (err)
226 goto out;
227
228 reg &= ~mask;
229 reg |= (~chip->g1_irq.masked & mask);
230
231 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, reg);
232 if (err)
233 goto out;
234
235 out:
236 mv88e6xxx_reg_unlock(chip);
237 }
238
239 static const struct irq_chip mv88e6xxx_g1_irq_chip = {
240 .name = "mv88e6xxx-g1",
241 .irq_mask = mv88e6xxx_g1_irq_mask,
242 .irq_unmask = mv88e6xxx_g1_irq_unmask,
243 .irq_bus_lock = mv88e6xxx_g1_irq_bus_lock,
244 .irq_bus_sync_unlock = mv88e6xxx_g1_irq_bus_sync_unlock,
245 };
246
mv88e6xxx_g1_irq_domain_map(struct irq_domain * d,unsigned int irq,irq_hw_number_t hwirq)247 static int mv88e6xxx_g1_irq_domain_map(struct irq_domain *d,
248 unsigned int irq,
249 irq_hw_number_t hwirq)
250 {
251 struct mv88e6xxx_chip *chip = d->host_data;
252
253 irq_set_chip_data(irq, d->host_data);
254 irq_set_chip_and_handler(irq, &chip->g1_irq.chip, handle_level_irq);
255 irq_set_noprobe(irq);
256
257 return 0;
258 }
259
260 static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = {
261 .map = mv88e6xxx_g1_irq_domain_map,
262 .xlate = irq_domain_xlate_twocell,
263 };
264
265 /* To be called with reg_lock held */
mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip * chip)266 static void mv88e6xxx_g1_irq_free_common(struct mv88e6xxx_chip *chip)
267 {
268 int irq, virq;
269 u16 mask;
270
271 mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
272 mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
273 mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
274
275 for (irq = 0; irq < chip->g1_irq.nirqs; irq++) {
276 virq = irq_find_mapping(chip->g1_irq.domain, irq);
277 irq_dispose_mapping(virq);
278 }
279
280 irq_domain_remove(chip->g1_irq.domain);
281 }
282
mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip * chip)283 static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
284 {
285 /*
286 * free_irq must be called without reg_lock taken because the irq
287 * handler takes this lock, too.
288 */
289 free_irq(chip->irq, chip);
290
291 mv88e6xxx_reg_lock(chip);
292 mv88e6xxx_g1_irq_free_common(chip);
293 mv88e6xxx_reg_unlock(chip);
294 }
295
mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip * chip)296 static int mv88e6xxx_g1_irq_setup_common(struct mv88e6xxx_chip *chip)
297 {
298 int err, irq, virq;
299 u16 reg, mask;
300
301 chip->g1_irq.nirqs = chip->info->g1_irqs;
302 chip->g1_irq.domain = irq_domain_create_simple(
303 NULL, chip->g1_irq.nirqs, 0,
304 &mv88e6xxx_g1_irq_domain_ops, chip);
305 if (!chip->g1_irq.domain)
306 return -ENOMEM;
307
308 for (irq = 0; irq < chip->g1_irq.nirqs; irq++)
309 irq_create_mapping(chip->g1_irq.domain, irq);
310
311 chip->g1_irq.chip = mv88e6xxx_g1_irq_chip;
312 chip->g1_irq.masked = ~0;
313
314 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
315 if (err)
316 goto out_mapping;
317
318 mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
319
320 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
321 if (err)
322 goto out_disable;
323
324 /* Reading the interrupt status clears (most of) them */
325 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, ®);
326 if (err)
327 goto out_disable;
328
329 return 0;
330
331 out_disable:
332 mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
333 mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
334
335 out_mapping:
336 for (irq = 0; irq < 16; irq++) {
337 virq = irq_find_mapping(chip->g1_irq.domain, irq);
338 irq_dispose_mapping(virq);
339 }
340
341 irq_domain_remove(chip->g1_irq.domain);
342
343 return err;
344 }
345
mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip * chip)346 static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
347 {
348 static struct lock_class_key lock_key;
349 static struct lock_class_key request_key;
350 int err;
351
352 err = mv88e6xxx_g1_irq_setup_common(chip);
353 if (err)
354 return err;
355
356 /* These lock classes tells lockdep that global 1 irqs are in
357 * a different category than their parent GPIO, so it won't
358 * report false recursion.
359 */
360 irq_set_lockdep_class(chip->irq, &lock_key, &request_key);
361
362 snprintf(chip->irq_name, sizeof(chip->irq_name),
363 "mv88e6xxx-%s", dev_name(chip->dev));
364
365 mv88e6xxx_reg_unlock(chip);
366 err = request_threaded_irq(chip->irq, NULL,
367 mv88e6xxx_g1_irq_thread_fn,
368 IRQF_ONESHOT | IRQF_SHARED,
369 chip->irq_name, chip);
370 mv88e6xxx_reg_lock(chip);
371 if (err)
372 mv88e6xxx_g1_irq_free_common(chip);
373
374 return err;
375 }
376
mv88e6xxx_irq_poll(struct kthread_work * work)377 static void mv88e6xxx_irq_poll(struct kthread_work *work)
378 {
379 struct mv88e6xxx_chip *chip = container_of(work,
380 struct mv88e6xxx_chip,
381 irq_poll_work.work);
382 mv88e6xxx_g1_irq_thread_work(chip);
383
384 kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
385 msecs_to_jiffies(100));
386 }
387
mv88e6xxx_irq_poll_setup(struct mv88e6xxx_chip * chip)388 static int mv88e6xxx_irq_poll_setup(struct mv88e6xxx_chip *chip)
389 {
390 int err;
391
392 err = mv88e6xxx_g1_irq_setup_common(chip);
393 if (err)
394 return err;
395
396 kthread_init_delayed_work(&chip->irq_poll_work,
397 mv88e6xxx_irq_poll);
398
399 chip->kworker = kthread_run_worker(0, "%s", dev_name(chip->dev));
400 if (IS_ERR(chip->kworker))
401 return PTR_ERR(chip->kworker);
402
403 kthread_queue_delayed_work(chip->kworker, &chip->irq_poll_work,
404 msecs_to_jiffies(100));
405
406 return 0;
407 }
408
mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip * chip)409 static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip)
410 {
411 kthread_cancel_delayed_work_sync(&chip->irq_poll_work);
412 kthread_destroy_worker(chip->kworker);
413
414 mv88e6xxx_reg_lock(chip);
415 mv88e6xxx_g1_irq_free_common(chip);
416 mv88e6xxx_reg_unlock(chip);
417 }
418
mv88e6xxx_port_config_interface(struct mv88e6xxx_chip * chip,int port,phy_interface_t interface)419 static int mv88e6xxx_port_config_interface(struct mv88e6xxx_chip *chip,
420 int port, phy_interface_t interface)
421 {
422 int err;
423
424 if (chip->info->ops->port_set_rgmii_delay) {
425 err = chip->info->ops->port_set_rgmii_delay(chip, port,
426 interface);
427 if (err && err != -EOPNOTSUPP)
428 return err;
429 }
430
431 if (chip->info->ops->port_set_cmode) {
432 err = chip->info->ops->port_set_cmode(chip, port,
433 interface);
434 if (err && err != -EOPNOTSUPP)
435 return err;
436 }
437
438 return 0;
439 }
440
mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip * chip,int port,int link,int speed,int duplex,int pause,phy_interface_t mode)441 static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
442 int link, int speed, int duplex, int pause,
443 phy_interface_t mode)
444 {
445 int err;
446
447 if (!chip->info->ops->port_set_link)
448 return 0;
449
450 /* Port's MAC control must not be changed unless the link is down */
451 err = chip->info->ops->port_set_link(chip, port, LINK_FORCED_DOWN);
452 if (err)
453 return err;
454
455 if (chip->info->ops->port_set_speed_duplex) {
456 err = chip->info->ops->port_set_speed_duplex(chip, port,
457 speed, duplex);
458 if (err && err != -EOPNOTSUPP)
459 goto restore_link;
460 }
461
462 if (chip->info->ops->port_set_pause) {
463 err = chip->info->ops->port_set_pause(chip, port, pause);
464 if (err)
465 goto restore_link;
466 }
467
468 err = mv88e6xxx_port_config_interface(chip, port, mode);
469 restore_link:
470 if (chip->info->ops->port_set_link(chip, port, link))
471 dev_err(chip->dev, "p%d: failed to restore MAC's link\n", port);
472
473 return err;
474 }
475
mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip * chip,int port)476 static int mv88e6xxx_phy_is_internal(struct mv88e6xxx_chip *chip, int port)
477 {
478 return port >= chip->info->internal_phys_offset &&
479 port < chip->info->num_internal_phys +
480 chip->info->internal_phys_offset;
481 }
482
mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip * chip,int port)483 static int mv88e6xxx_port_ppu_updates(struct mv88e6xxx_chip *chip, int port)
484 {
485 u16 reg;
486 int err;
487
488 /* The 88e6250 family does not have the PHY detect bit. Instead,
489 * report whether the port is internal.
490 */
491 if (chip->info->family == MV88E6XXX_FAMILY_6250)
492 return mv88e6xxx_phy_is_internal(chip, port);
493
494 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
495 if (err) {
496 dev_err(chip->dev,
497 "p%d: %s: failed to read port status\n",
498 port, __func__);
499 return err;
500 }
501
502 return !!(reg & MV88E6XXX_PORT_STS_PHY_DETECT);
503 }
504
505 static const u8 mv88e6185_phy_interface_modes[] = {
506 [MV88E6185_PORT_STS_CMODE_GMII_FD] = PHY_INTERFACE_MODE_GMII,
507 [MV88E6185_PORT_STS_CMODE_MII_100_FD_PS] = PHY_INTERFACE_MODE_MII,
508 [MV88E6185_PORT_STS_CMODE_MII_100] = PHY_INTERFACE_MODE_MII,
509 [MV88E6185_PORT_STS_CMODE_MII_10] = PHY_INTERFACE_MODE_MII,
510 [MV88E6185_PORT_STS_CMODE_SERDES] = PHY_INTERFACE_MODE_1000BASEX,
511 [MV88E6185_PORT_STS_CMODE_1000BASE_X] = PHY_INTERFACE_MODE_1000BASEX,
512 [MV88E6185_PORT_STS_CMODE_PHY] = PHY_INTERFACE_MODE_SGMII,
513 };
514
mv88e6095_phylink_get_caps(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)515 static void mv88e6095_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
516 struct phylink_config *config)
517 {
518 u8 cmode = chip->ports[port].cmode;
519
520 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
521
522 if (mv88e6xxx_phy_is_internal(chip, port)) {
523 __set_bit(PHY_INTERFACE_MODE_MII, config->supported_interfaces);
524 } else {
525 if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
526 mv88e6185_phy_interface_modes[cmode])
527 __set_bit(mv88e6185_phy_interface_modes[cmode],
528 config->supported_interfaces);
529
530 config->mac_capabilities |= MAC_1000FD;
531 }
532 }
533
mv88e6185_phylink_get_caps(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)534 static void mv88e6185_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
535 struct phylink_config *config)
536 {
537 u8 cmode = chip->ports[port].cmode;
538
539 if (cmode < ARRAY_SIZE(mv88e6185_phy_interface_modes) &&
540 mv88e6185_phy_interface_modes[cmode])
541 __set_bit(mv88e6185_phy_interface_modes[cmode],
542 config->supported_interfaces);
543
544 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
545 MAC_1000FD;
546 }
547
548 static const u8 mv88e6xxx_phy_interface_modes[] = {
549 [MV88E6XXX_PORT_STS_CMODE_MII_PHY] = PHY_INTERFACE_MODE_REVMII,
550 [MV88E6XXX_PORT_STS_CMODE_MII] = PHY_INTERFACE_MODE_MII,
551 [MV88E6XXX_PORT_STS_CMODE_GMII] = PHY_INTERFACE_MODE_GMII,
552 [MV88E6XXX_PORT_STS_CMODE_RMII_PHY] = PHY_INTERFACE_MODE_REVRMII,
553 [MV88E6XXX_PORT_STS_CMODE_RMII] = PHY_INTERFACE_MODE_RMII,
554 [MV88E6XXX_PORT_STS_CMODE_100BASEX] = PHY_INTERFACE_MODE_100BASEX,
555 [MV88E6XXX_PORT_STS_CMODE_1000BASEX] = PHY_INTERFACE_MODE_1000BASEX,
556 [MV88E6XXX_PORT_STS_CMODE_SGMII] = PHY_INTERFACE_MODE_SGMII,
557 /* higher interface modes are not needed here, since ports supporting
558 * them are writable, and so the supported interfaces are filled in the
559 * corresponding .phylink_set_interfaces() implementation below
560 */
561 };
562
mv88e6xxx_translate_cmode(u8 cmode,unsigned long * supported)563 static void mv88e6xxx_translate_cmode(u8 cmode, unsigned long *supported)
564 {
565 if (cmode < ARRAY_SIZE(mv88e6xxx_phy_interface_modes) &&
566 mv88e6xxx_phy_interface_modes[cmode])
567 __set_bit(mv88e6xxx_phy_interface_modes[cmode], supported);
568 else if (cmode == MV88E6XXX_PORT_STS_CMODE_RGMII)
569 phy_interface_set_rgmii(supported);
570 }
571
572 static void
mv88e6250_setup_supported_interfaces(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)573 mv88e6250_setup_supported_interfaces(struct mv88e6xxx_chip *chip, int port,
574 struct phylink_config *config)
575 {
576 unsigned long *supported = config->supported_interfaces;
577 int err;
578 u16 reg;
579
580 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
581 if (err) {
582 dev_err(chip->dev, "p%d: failed to read port status\n", port);
583 return;
584 }
585
586 switch (reg & MV88E6250_PORT_STS_PORTMODE_MASK) {
587 case MV88E6250_PORT_STS_PORTMODE_MII_10_HALF_PHY:
588 case MV88E6250_PORT_STS_PORTMODE_MII_100_HALF_PHY:
589 case MV88E6250_PORT_STS_PORTMODE_MII_10_FULL_PHY:
590 case MV88E6250_PORT_STS_PORTMODE_MII_100_FULL_PHY:
591 __set_bit(PHY_INTERFACE_MODE_REVMII, supported);
592 break;
593
594 case MV88E6250_PORT_STS_PORTMODE_MII_HALF:
595 case MV88E6250_PORT_STS_PORTMODE_MII_FULL:
596 __set_bit(PHY_INTERFACE_MODE_MII, supported);
597 break;
598
599 case MV88E6250_PORT_STS_PORTMODE_MII_DUAL_100_RMII_FULL_PHY:
600 case MV88E6250_PORT_STS_PORTMODE_MII_200_RMII_FULL_PHY:
601 case MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_HALF_PHY:
602 case MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_FULL_PHY:
603 __set_bit(PHY_INTERFACE_MODE_REVRMII, supported);
604 break;
605
606 case MV88E6250_PORT_STS_PORTMODE_MII_DUAL_100_RMII_FULL:
607 case MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_FULL:
608 __set_bit(PHY_INTERFACE_MODE_RMII, supported);
609 break;
610
611 case MV88E6250_PORT_STS_PORTMODE_MII_100_RGMII:
612 __set_bit(PHY_INTERFACE_MODE_RGMII, supported);
613 break;
614
615 default:
616 dev_err(chip->dev,
617 "p%d: invalid port mode in status register: %04x\n",
618 port, reg);
619 }
620 }
621
mv88e6250_phylink_get_caps(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)622 static void mv88e6250_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
623 struct phylink_config *config)
624 {
625 if (!mv88e6xxx_phy_is_internal(chip, port))
626 mv88e6250_setup_supported_interfaces(chip, port, config);
627
628 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
629 }
630
mv88e6351_phylink_get_caps(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)631 static void mv88e6351_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
632 struct phylink_config *config)
633 {
634 unsigned long *supported = config->supported_interfaces;
635
636 /* Translate the default cmode */
637 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
638
639 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
640 MAC_1000FD;
641 }
642
mv88e63xx_get_port_serdes_cmode(struct mv88e6xxx_chip * chip,int port)643 static int mv88e63xx_get_port_serdes_cmode(struct mv88e6xxx_chip *chip, int port)
644 {
645 u16 reg, val;
646 int err;
647
648 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
649 if (err)
650 return err;
651
652 /* If PHY_DETECT is zero, then we are not in auto-media mode */
653 if (!(reg & MV88E6XXX_PORT_STS_PHY_DETECT))
654 return 0xf;
655
656 val = reg & ~MV88E6XXX_PORT_STS_PHY_DETECT;
657 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, val);
658 if (err)
659 return err;
660
661 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &val);
662 if (err)
663 return err;
664
665 /* Restore PHY_DETECT value */
666 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
667 if (err)
668 return err;
669
670 return val & MV88E6XXX_PORT_STS_CMODE_MASK;
671 }
672
mv88e6352_phylink_get_caps(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)673 static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
674 struct phylink_config *config)
675 {
676 unsigned long *supported = config->supported_interfaces;
677 int err, cmode;
678
679 /* Translate the default cmode */
680 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
681
682 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
683 MAC_1000FD;
684
685 /* Port 4 supports automedia if the serdes is associated with it. */
686 if (port == 4) {
687 err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
688 if (err <= 0)
689 return;
690
691 cmode = mv88e63xx_get_port_serdes_cmode(chip, port);
692 if (cmode < 0)
693 dev_err(chip->dev, "p%d: failed to read serdes cmode\n",
694 port);
695 else
696 mv88e6xxx_translate_cmode(cmode, supported);
697 }
698 }
699
mv88e632x_phylink_get_caps(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)700 static void mv88e632x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
701 struct phylink_config *config)
702 {
703 unsigned long *supported = config->supported_interfaces;
704 int cmode;
705
706 /* Translate the default cmode */
707 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
708
709 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
710 MAC_1000FD;
711
712 /* Port 0/1 are serdes only ports */
713 if (port == 0 || port == 1) {
714 cmode = mv88e63xx_get_port_serdes_cmode(chip, port);
715 if (cmode < 0)
716 dev_err(chip->dev, "p%d: failed to read serdes cmode\n",
717 port);
718 else
719 mv88e6xxx_translate_cmode(cmode, supported);
720 }
721 }
722
mv88e6341_phylink_get_caps(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)723 static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
724 struct phylink_config *config)
725 {
726 unsigned long *supported = config->supported_interfaces;
727
728 /* Translate the default cmode */
729 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
730
731 /* No ethtool bits for 200Mbps */
732 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
733 MAC_1000FD;
734
735 /* The C_Mode field is programmable on port 5 */
736 if (port == 5) {
737 __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
738 __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
739 __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
740
741 config->mac_capabilities |= MAC_2500FD;
742 }
743 }
744
mv88e6390_phylink_get_caps(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)745 static void mv88e6390_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
746 struct phylink_config *config)
747 {
748 unsigned long *supported = config->supported_interfaces;
749
750 /* Translate the default cmode */
751 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
752
753 /* No ethtool bits for 200Mbps */
754 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
755 MAC_1000FD;
756
757 /* The C_Mode field is programmable on ports 9 and 10 */
758 if (port == 9 || port == 10) {
759 __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
760 __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
761 __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
762
763 config->mac_capabilities |= MAC_2500FD;
764 }
765 }
766
mv88e6390x_phylink_get_caps(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)767 static void mv88e6390x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
768 struct phylink_config *config)
769 {
770 unsigned long *supported = config->supported_interfaces;
771
772 mv88e6390_phylink_get_caps(chip, port, config);
773
774 /* For the 6x90X, ports 2-7 can be in automedia mode.
775 * (Note that 6x90 doesn't support RXAUI nor XAUI).
776 *
777 * Port 2 can also support 1000BASE-X in automedia mode if port 9 is
778 * configured for 1000BASE-X, SGMII or 2500BASE-X.
779 * Port 3-4 can also support 1000BASE-X in automedia mode if port 9 is
780 * configured for RXAUI, 1000BASE-X, SGMII or 2500BASE-X.
781 *
782 * Port 5 can also support 1000BASE-X in automedia mode if port 10 is
783 * configured for 1000BASE-X, SGMII or 2500BASE-X.
784 * Port 6-7 can also support 1000BASE-X in automedia mode if port 10 is
785 * configured for RXAUI, 1000BASE-X, SGMII or 2500BASE-X.
786 *
787 * For now, be permissive (as the old code was) and allow 1000BASE-X
788 * on ports 2..7.
789 */
790 if (port >= 2 && port <= 7)
791 __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
792
793 /* The C_Mode field can also be programmed for 10G speeds */
794 if (port == 9 || port == 10) {
795 __set_bit(PHY_INTERFACE_MODE_XAUI, supported);
796 __set_bit(PHY_INTERFACE_MODE_RXAUI, supported);
797
798 config->mac_capabilities |= MAC_10000FD;
799 }
800 }
801
mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip * chip,int port,struct phylink_config * config)802 static void mv88e6393x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
803 struct phylink_config *config)
804 {
805 unsigned long *supported = config->supported_interfaces;
806 bool is_6191x =
807 chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6191X;
808 bool is_6361 =
809 chip->info->prod_num == MV88E6XXX_PORT_SWITCH_ID_PROD_6361;
810
811 mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
812
813 config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
814 MAC_1000FD;
815
816 /* The C_Mode field can be programmed for ports 0, 9 and 10 */
817 if (port == 0 || port == 9 || port == 10) {
818 __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
819 __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
820
821 /* 6191X supports >1G modes only on port 10 */
822 if (!is_6191x || port == 10) {
823 __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
824 config->mac_capabilities |= MAC_2500FD;
825
826 /* 6361 only supports up to 2500BaseX */
827 if (!is_6361) {
828 __set_bit(PHY_INTERFACE_MODE_5GBASER, supported);
829 __set_bit(PHY_INTERFACE_MODE_10GBASER, supported);
830 __set_bit(PHY_INTERFACE_MODE_USXGMII, supported);
831 config->mac_capabilities |= MAC_5000FD |
832 MAC_10000FD;
833 }
834 }
835 }
836
837 if (port == 0) {
838 __set_bit(PHY_INTERFACE_MODE_RMII, supported);
839 __set_bit(PHY_INTERFACE_MODE_RGMII, supported);
840 __set_bit(PHY_INTERFACE_MODE_RGMII_ID, supported);
841 __set_bit(PHY_INTERFACE_MODE_RGMII_RXID, supported);
842 __set_bit(PHY_INTERFACE_MODE_RGMII_TXID, supported);
843 }
844 }
845
mv88e6xxx_get_caps(struct dsa_switch * ds,int port,struct phylink_config * config)846 static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
847 struct phylink_config *config)
848 {
849 struct mv88e6xxx_chip *chip = ds->priv;
850
851 mv88e6xxx_reg_lock(chip);
852 chip->info->ops->phylink_get_caps(chip, port, config);
853 mv88e6xxx_reg_unlock(chip);
854
855 if (mv88e6xxx_phy_is_internal(chip, port)) {
856 __set_bit(PHY_INTERFACE_MODE_INTERNAL,
857 config->supported_interfaces);
858 /* Internal ports with no phy-mode need GMII for PHYLIB */
859 __set_bit(PHY_INTERFACE_MODE_GMII,
860 config->supported_interfaces);
861 }
862 }
863
864 static struct phylink_pcs *
mv88e6xxx_mac_select_pcs(struct phylink_config * config,phy_interface_t interface)865 mv88e6xxx_mac_select_pcs(struct phylink_config *config,
866 phy_interface_t interface)
867 {
868 struct dsa_port *dp = dsa_phylink_to_port(config);
869 struct mv88e6xxx_chip *chip = dp->ds->priv;
870 struct phylink_pcs *pcs = NULL;
871
872 if (chip->info->ops->pcs_ops)
873 pcs = chip->info->ops->pcs_ops->pcs_select(chip, dp->index,
874 interface);
875
876 return pcs;
877 }
878
mv88e6xxx_mac_prepare(struct phylink_config * config,unsigned int mode,phy_interface_t interface)879 static int mv88e6xxx_mac_prepare(struct phylink_config *config,
880 unsigned int mode, phy_interface_t interface)
881 {
882 struct dsa_port *dp = dsa_phylink_to_port(config);
883 struct mv88e6xxx_chip *chip = dp->ds->priv;
884 int port = dp->index;
885 int err = 0;
886
887 /* In inband mode, the link may come up at any time while the link
888 * is not forced down. Force the link down while we reconfigure the
889 * interface mode.
890 */
891 if (mode == MLO_AN_INBAND &&
892 chip->ports[port].interface != interface &&
893 chip->info->ops->port_set_link) {
894 mv88e6xxx_reg_lock(chip);
895 err = chip->info->ops->port_set_link(chip, port,
896 LINK_FORCED_DOWN);
897 mv88e6xxx_reg_unlock(chip);
898 }
899
900 return err;
901 }
902
mv88e6xxx_mac_config(struct phylink_config * config,unsigned int mode,const struct phylink_link_state * state)903 static void mv88e6xxx_mac_config(struct phylink_config *config,
904 unsigned int mode,
905 const struct phylink_link_state *state)
906 {
907 struct dsa_port *dp = dsa_phylink_to_port(config);
908 struct mv88e6xxx_chip *chip = dp->ds->priv;
909 int port = dp->index;
910 int err = 0;
911
912 mv88e6xxx_reg_lock(chip);
913
914 if (mode != MLO_AN_PHY || !mv88e6xxx_phy_is_internal(chip, port)) {
915 err = mv88e6xxx_port_config_interface(chip, port,
916 state->interface);
917 if (err && err != -EOPNOTSUPP)
918 goto err_unlock;
919 }
920
921 err_unlock:
922 mv88e6xxx_reg_unlock(chip);
923
924 if (err && err != -EOPNOTSUPP)
925 dev_err(chip->dev, "p%d: failed to configure MAC/PCS\n", port);
926 }
927
mv88e6xxx_mac_finish(struct phylink_config * config,unsigned int mode,phy_interface_t interface)928 static int mv88e6xxx_mac_finish(struct phylink_config *config,
929 unsigned int mode, phy_interface_t interface)
930 {
931 struct dsa_port *dp = dsa_phylink_to_port(config);
932 struct mv88e6xxx_chip *chip = dp->ds->priv;
933 int port = dp->index;
934 int err = 0;
935
936 /* Undo the forced down state above after completing configuration
937 * irrespective of its state on entry, which allows the link to come
938 * up in the in-band case where there is no separate SERDES. Also
939 * ensure that the link can come up if the PPU is in use and we are
940 * in PHY mode (we treat the PPU as an effective in-band mechanism.)
941 */
942 mv88e6xxx_reg_lock(chip);
943
944 if (chip->info->ops->port_set_link &&
945 ((mode == MLO_AN_INBAND &&
946 chip->ports[port].interface != interface) ||
947 (mode == MLO_AN_PHY && mv88e6xxx_port_ppu_updates(chip, port))))
948 err = chip->info->ops->port_set_link(chip, port, LINK_UNFORCED);
949
950 mv88e6xxx_reg_unlock(chip);
951
952 chip->ports[port].interface = interface;
953
954 return err;
955 }
956
mv88e6xxx_mac_link_down(struct phylink_config * config,unsigned int mode,phy_interface_t interface)957 static void mv88e6xxx_mac_link_down(struct phylink_config *config,
958 unsigned int mode,
959 phy_interface_t interface)
960 {
961 struct dsa_port *dp = dsa_phylink_to_port(config);
962 struct mv88e6xxx_chip *chip = dp->ds->priv;
963 const struct mv88e6xxx_ops *ops;
964 int port = dp->index;
965 int err = 0;
966
967 ops = chip->info->ops;
968
969 mv88e6xxx_reg_lock(chip);
970 /* Force the link down if we know the port may not be automatically
971 * updated by the switch or if we are using fixed-link mode.
972 */
973 if ((!mv88e6xxx_port_ppu_updates(chip, port) ||
974 mode == MLO_AN_FIXED) && ops->port_sync_link)
975 err = ops->port_sync_link(chip, port, mode, false);
976
977 if (!err && ops->port_set_speed_duplex)
978 err = ops->port_set_speed_duplex(chip, port, SPEED_UNFORCED,
979 DUPLEX_UNFORCED);
980 mv88e6xxx_reg_unlock(chip);
981
982 if (err)
983 dev_err(chip->dev,
984 "p%d: failed to force MAC link down\n", port);
985 }
986
mv88e6xxx_mac_link_up(struct phylink_config * config,struct phy_device * phydev,unsigned int mode,phy_interface_t interface,int speed,int duplex,bool tx_pause,bool rx_pause)987 static void mv88e6xxx_mac_link_up(struct phylink_config *config,
988 struct phy_device *phydev,
989 unsigned int mode, phy_interface_t interface,
990 int speed, int duplex,
991 bool tx_pause, bool rx_pause)
992 {
993 struct dsa_port *dp = dsa_phylink_to_port(config);
994 struct mv88e6xxx_chip *chip = dp->ds->priv;
995 const struct mv88e6xxx_ops *ops;
996 int port = dp->index;
997 int err = 0;
998
999 ops = chip->info->ops;
1000
1001 mv88e6xxx_reg_lock(chip);
1002 /* Configure and force the link up if we know that the port may not
1003 * automatically updated by the switch or if we are using fixed-link
1004 * mode.
1005 */
1006 if (!mv88e6xxx_port_ppu_updates(chip, port) ||
1007 mode == MLO_AN_FIXED) {
1008 if (ops->port_set_speed_duplex) {
1009 err = ops->port_set_speed_duplex(chip, port,
1010 speed, duplex);
1011 if (err && err != -EOPNOTSUPP)
1012 goto error;
1013 }
1014
1015 if (ops->port_sync_link)
1016 err = ops->port_sync_link(chip, port, mode, true);
1017 }
1018 error:
1019 mv88e6xxx_reg_unlock(chip);
1020
1021 if (err && err != -EOPNOTSUPP)
1022 dev_err(chip->dev,
1023 "p%d: failed to configure MAC link up\n", port);
1024 }
1025
mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip * chip,int port)1026 static int mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
1027 {
1028 int err;
1029
1030 if (!chip->info->ops->stats_snapshot)
1031 return -EOPNOTSUPP;
1032
1033 mv88e6xxx_reg_lock(chip);
1034 err = chip->info->ops->stats_snapshot(chip, port);
1035 mv88e6xxx_reg_unlock(chip);
1036
1037 return err;
1038 }
1039
1040 #define MV88E6XXX_HW_STAT_MAPPER(_fn) \
1041 _fn(in_good_octets, 8, 0x00, STATS_TYPE_BANK0), \
1042 _fn(in_bad_octets, 4, 0x02, STATS_TYPE_BANK0), \
1043 _fn(in_unicast, 4, 0x04, STATS_TYPE_BANK0), \
1044 _fn(in_broadcasts, 4, 0x06, STATS_TYPE_BANK0), \
1045 _fn(in_multicasts, 4, 0x07, STATS_TYPE_BANK0), \
1046 _fn(in_pause, 4, 0x16, STATS_TYPE_BANK0), \
1047 _fn(in_undersize, 4, 0x18, STATS_TYPE_BANK0), \
1048 _fn(in_fragments, 4, 0x19, STATS_TYPE_BANK0), \
1049 _fn(in_oversize, 4, 0x1a, STATS_TYPE_BANK0), \
1050 _fn(in_jabber, 4, 0x1b, STATS_TYPE_BANK0), \
1051 _fn(in_rx_error, 4, 0x1c, STATS_TYPE_BANK0), \
1052 _fn(in_fcs_error, 4, 0x1d, STATS_TYPE_BANK0), \
1053 _fn(out_octets, 8, 0x0e, STATS_TYPE_BANK0), \
1054 _fn(out_unicast, 4, 0x10, STATS_TYPE_BANK0), \
1055 _fn(out_broadcasts, 4, 0x13, STATS_TYPE_BANK0), \
1056 _fn(out_multicasts, 4, 0x12, STATS_TYPE_BANK0), \
1057 _fn(out_pause, 4, 0x15, STATS_TYPE_BANK0), \
1058 _fn(excessive, 4, 0x11, STATS_TYPE_BANK0), \
1059 _fn(collisions, 4, 0x1e, STATS_TYPE_BANK0), \
1060 _fn(deferred, 4, 0x05, STATS_TYPE_BANK0), \
1061 _fn(single, 4, 0x14, STATS_TYPE_BANK0), \
1062 _fn(multiple, 4, 0x17, STATS_TYPE_BANK0), \
1063 _fn(out_fcs_error, 4, 0x03, STATS_TYPE_BANK0), \
1064 _fn(late, 4, 0x1f, STATS_TYPE_BANK0), \
1065 _fn(hist_64bytes, 4, 0x08, STATS_TYPE_BANK0), \
1066 _fn(hist_65_127bytes, 4, 0x09, STATS_TYPE_BANK0), \
1067 _fn(hist_128_255bytes, 4, 0x0a, STATS_TYPE_BANK0), \
1068 _fn(hist_256_511bytes, 4, 0x0b, STATS_TYPE_BANK0), \
1069 _fn(hist_512_1023bytes, 4, 0x0c, STATS_TYPE_BANK0), \
1070 _fn(hist_1024_max_bytes, 4, 0x0d, STATS_TYPE_BANK0), \
1071 _fn(sw_in_discards, 4, 0x10, STATS_TYPE_PORT), \
1072 _fn(sw_in_filtered, 2, 0x12, STATS_TYPE_PORT), \
1073 _fn(sw_out_filtered, 2, 0x13, STATS_TYPE_PORT), \
1074 _fn(in_discards, 4, 0x00, STATS_TYPE_BANK1), \
1075 _fn(in_filtered, 4, 0x01, STATS_TYPE_BANK1), \
1076 _fn(in_accepted, 4, 0x02, STATS_TYPE_BANK1), \
1077 _fn(in_bad_accepted, 4, 0x03, STATS_TYPE_BANK1), \
1078 _fn(in_good_avb_class_a, 4, 0x04, STATS_TYPE_BANK1), \
1079 _fn(in_good_avb_class_b, 4, 0x05, STATS_TYPE_BANK1), \
1080 _fn(in_bad_avb_class_a, 4, 0x06, STATS_TYPE_BANK1), \
1081 _fn(in_bad_avb_class_b, 4, 0x07, STATS_TYPE_BANK1), \
1082 _fn(tcam_counter_0, 4, 0x08, STATS_TYPE_BANK1), \
1083 _fn(tcam_counter_1, 4, 0x09, STATS_TYPE_BANK1), \
1084 _fn(tcam_counter_2, 4, 0x0a, STATS_TYPE_BANK1), \
1085 _fn(tcam_counter_3, 4, 0x0b, STATS_TYPE_BANK1), \
1086 _fn(in_da_unknown, 4, 0x0e, STATS_TYPE_BANK1), \
1087 _fn(in_management, 4, 0x0f, STATS_TYPE_BANK1), \
1088 _fn(out_queue_0, 4, 0x10, STATS_TYPE_BANK1), \
1089 _fn(out_queue_1, 4, 0x11, STATS_TYPE_BANK1), \
1090 _fn(out_queue_2, 4, 0x12, STATS_TYPE_BANK1), \
1091 _fn(out_queue_3, 4, 0x13, STATS_TYPE_BANK1), \
1092 _fn(out_queue_4, 4, 0x14, STATS_TYPE_BANK1), \
1093 _fn(out_queue_5, 4, 0x15, STATS_TYPE_BANK1), \
1094 _fn(out_queue_6, 4, 0x16, STATS_TYPE_BANK1), \
1095 _fn(out_queue_7, 4, 0x17, STATS_TYPE_BANK1), \
1096 _fn(out_cut_through, 4, 0x18, STATS_TYPE_BANK1), \
1097 _fn(out_octets_a, 4, 0x1a, STATS_TYPE_BANK1), \
1098 _fn(out_octets_b, 4, 0x1b, STATS_TYPE_BANK1), \
1099 _fn(out_management, 4, 0x1f, STATS_TYPE_BANK1), \
1100 /* */
1101
1102 #define MV88E6XXX_HW_STAT_ENTRY(_string, _size, _reg, _type) \
1103 { #_string, _size, _reg, _type }
1104 static const struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
1105 MV88E6XXX_HW_STAT_MAPPER(MV88E6XXX_HW_STAT_ENTRY)
1106 };
1107
1108 #define MV88E6XXX_HW_STAT_ENUM(_string, _size, _reg, _type) \
1109 MV88E6XXX_HW_STAT_ID_ ## _string
1110 enum mv88e6xxx_hw_stat_id {
1111 MV88E6XXX_HW_STAT_MAPPER(MV88E6XXX_HW_STAT_ENUM)
1112 };
1113
_mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip * chip,const struct mv88e6xxx_hw_stat * s,int port,u16 bank1_select,u16 histogram)1114 static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
1115 const struct mv88e6xxx_hw_stat *s,
1116 int port, u16 bank1_select,
1117 u16 histogram)
1118 {
1119 u32 low;
1120 u32 high = 0;
1121 u16 reg = 0;
1122 int err;
1123 u64 value;
1124
1125 switch (s->type) {
1126 case STATS_TYPE_PORT:
1127 err = mv88e6xxx_port_read(chip, port, s->reg, ®);
1128 if (err)
1129 return U64_MAX;
1130
1131 low = reg;
1132 if (s->size == 4) {
1133 err = mv88e6xxx_port_read(chip, port, s->reg + 1, ®);
1134 if (err)
1135 return U64_MAX;
1136 low |= ((u32)reg) << 16;
1137 }
1138 break;
1139 case STATS_TYPE_BANK1:
1140 reg = bank1_select;
1141 fallthrough;
1142 case STATS_TYPE_BANK0:
1143 reg |= s->reg | histogram;
1144 mv88e6xxx_g1_stats_read(chip, reg, &low);
1145 if (s->size == 8)
1146 mv88e6xxx_g1_stats_read(chip, reg + 1, &high);
1147 break;
1148 default:
1149 return U64_MAX;
1150 }
1151 value = (((u64)high) << 32) | low;
1152 return value;
1153 }
1154
mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip * chip,uint8_t ** data,int types)1155 static void mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
1156 uint8_t **data, int types)
1157 {
1158 const struct mv88e6xxx_hw_stat *stat;
1159 int i;
1160
1161 for (i = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
1162 stat = &mv88e6xxx_hw_stats[i];
1163 if (stat->type & types)
1164 ethtool_puts(data, stat->string);
1165 }
1166 }
1167
mv88e6095_stats_get_strings(struct mv88e6xxx_chip * chip,uint8_t ** data)1168 static void mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip,
1169 uint8_t **data)
1170 {
1171 mv88e6xxx_stats_get_strings(chip, data,
1172 STATS_TYPE_BANK0 | STATS_TYPE_PORT);
1173 }
1174
mv88e6250_stats_get_strings(struct mv88e6xxx_chip * chip,uint8_t ** data)1175 static void mv88e6250_stats_get_strings(struct mv88e6xxx_chip *chip,
1176 uint8_t **data)
1177 {
1178 mv88e6xxx_stats_get_strings(chip, data, STATS_TYPE_BANK0);
1179 }
1180
mv88e6320_stats_get_strings(struct mv88e6xxx_chip * chip,uint8_t ** data)1181 static void mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
1182 uint8_t **data)
1183 {
1184 mv88e6xxx_stats_get_strings(chip, data,
1185 STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
1186 }
1187
1188 static const uint8_t *mv88e6xxx_atu_vtu_stats_strings[] = {
1189 "atu_member_violation",
1190 "atu_miss_violation",
1191 "atu_full_violation",
1192 "vtu_member_violation",
1193 "vtu_miss_violation",
1194 };
1195
mv88e6xxx_atu_vtu_get_strings(uint8_t ** data)1196 static void mv88e6xxx_atu_vtu_get_strings(uint8_t **data)
1197 {
1198 unsigned int i;
1199
1200 for (i = 0; i < ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings); i++)
1201 ethtool_puts(data, mv88e6xxx_atu_vtu_stats_strings[i]);
1202 }
1203
mv88e6xxx_get_strings(struct dsa_switch * ds,int port,u32 stringset,uint8_t * data)1204 static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
1205 u32 stringset, uint8_t *data)
1206 {
1207 struct mv88e6xxx_chip *chip = ds->priv;
1208
1209 if (stringset != ETH_SS_STATS)
1210 return;
1211
1212 mv88e6xxx_reg_lock(chip);
1213
1214 if (chip->info->ops->stats_get_strings)
1215 chip->info->ops->stats_get_strings(chip, &data);
1216
1217 if (chip->info->ops->serdes_get_strings)
1218 chip->info->ops->serdes_get_strings(chip, port, &data);
1219
1220 mv88e6xxx_atu_vtu_get_strings(&data);
1221
1222 mv88e6xxx_reg_unlock(chip);
1223 }
1224
mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip * chip,int types)1225 static int mv88e6xxx_stats_get_sset_count(struct mv88e6xxx_chip *chip,
1226 int types)
1227 {
1228 const struct mv88e6xxx_hw_stat *stat;
1229 int i, j;
1230
1231 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
1232 stat = &mv88e6xxx_hw_stats[i];
1233 if (stat->type & types)
1234 j++;
1235 }
1236 return j;
1237 }
1238
mv88e6095_stats_get_sset_count(struct mv88e6xxx_chip * chip)1239 static int mv88e6095_stats_get_sset_count(struct mv88e6xxx_chip *chip)
1240 {
1241 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
1242 STATS_TYPE_PORT);
1243 }
1244
mv88e6250_stats_get_sset_count(struct mv88e6xxx_chip * chip)1245 static int mv88e6250_stats_get_sset_count(struct mv88e6xxx_chip *chip)
1246 {
1247 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0);
1248 }
1249
mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip * chip)1250 static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip)
1251 {
1252 return mv88e6xxx_stats_get_sset_count(chip, STATS_TYPE_BANK0 |
1253 STATS_TYPE_BANK1);
1254 }
1255
mv88e6xxx_get_sset_count(struct dsa_switch * ds,int port,int sset)1256 static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port, int sset)
1257 {
1258 struct mv88e6xxx_chip *chip = ds->priv;
1259 int serdes_count = 0;
1260 int count = 0;
1261
1262 if (sset != ETH_SS_STATS)
1263 return 0;
1264
1265 mv88e6xxx_reg_lock(chip);
1266 if (chip->info->ops->stats_get_sset_count)
1267 count = chip->info->ops->stats_get_sset_count(chip);
1268 if (count < 0)
1269 goto out;
1270
1271 if (chip->info->ops->serdes_get_sset_count)
1272 serdes_count = chip->info->ops->serdes_get_sset_count(chip,
1273 port);
1274 if (serdes_count < 0) {
1275 count = serdes_count;
1276 goto out;
1277 }
1278 count += serdes_count;
1279 count += ARRAY_SIZE(mv88e6xxx_atu_vtu_stats_strings);
1280
1281 out:
1282 mv88e6xxx_reg_unlock(chip);
1283
1284 return count;
1285 }
1286
mv88e6095_stats_get_stat(struct mv88e6xxx_chip * chip,int port,const struct mv88e6xxx_hw_stat * stat,uint64_t * data)1287 static size_t mv88e6095_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
1288 const struct mv88e6xxx_hw_stat *stat,
1289 uint64_t *data)
1290 {
1291 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 0,
1292 MV88E6XXX_G1_STATS_OP_HIST_RX);
1293 return 1;
1294 }
1295
mv88e6250_stats_get_stat(struct mv88e6xxx_chip * chip,int port,const struct mv88e6xxx_hw_stat * stat,uint64_t * data)1296 static size_t mv88e6250_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
1297 const struct mv88e6xxx_hw_stat *stat,
1298 uint64_t *data)
1299 {
1300 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port, 0,
1301 MV88E6XXX_G1_STATS_OP_HIST_RX);
1302 return 1;
1303 }
1304
mv88e6320_stats_get_stat(struct mv88e6xxx_chip * chip,int port,const struct mv88e6xxx_hw_stat * stat,uint64_t * data)1305 static size_t mv88e6320_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
1306 const struct mv88e6xxx_hw_stat *stat,
1307 uint64_t *data)
1308 {
1309 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
1310 MV88E6XXX_G1_STATS_OP_BANK_1_BIT_9,
1311 MV88E6XXX_G1_STATS_OP_HIST_RX);
1312 return 1;
1313 }
1314
mv88e6390_stats_get_stat(struct mv88e6xxx_chip * chip,int port,const struct mv88e6xxx_hw_stat * stat,uint64_t * data)1315 static size_t mv88e6390_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
1316 const struct mv88e6xxx_hw_stat *stat,
1317 uint64_t *data)
1318 {
1319 *data = _mv88e6xxx_get_ethtool_stat(chip, stat, port,
1320 MV88E6XXX_G1_STATS_OP_BANK_1_BIT_10,
1321 0);
1322 return 1;
1323 }
1324
mv88e6xxx_stats_get_stat(struct mv88e6xxx_chip * chip,int port,const struct mv88e6xxx_hw_stat * stat,uint64_t * data)1325 static size_t mv88e6xxx_stats_get_stat(struct mv88e6xxx_chip *chip, int port,
1326 const struct mv88e6xxx_hw_stat *stat,
1327 uint64_t *data)
1328 {
1329 int ret = 0;
1330
1331 if (!(stat->type & chip->info->stats_type))
1332 return 0;
1333
1334 if (chip->info->ops->stats_get_stat) {
1335 mv88e6xxx_reg_lock(chip);
1336 ret = chip->info->ops->stats_get_stat(chip, port, stat, data);
1337 mv88e6xxx_reg_unlock(chip);
1338 }
1339
1340 return ret;
1341 }
1342
mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip * chip,int port,uint64_t * data)1343 static size_t mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
1344 uint64_t *data)
1345 {
1346 const struct mv88e6xxx_hw_stat *stat;
1347 size_t i, j;
1348
1349 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
1350 stat = &mv88e6xxx_hw_stats[i];
1351 j += mv88e6xxx_stats_get_stat(chip, port, stat, &data[j]);
1352 }
1353 return j;
1354 }
1355
mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip * chip,int port,uint64_t * data)1356 static void mv88e6xxx_atu_vtu_get_stats(struct mv88e6xxx_chip *chip, int port,
1357 uint64_t *data)
1358 {
1359 *data++ = chip->ports[port].atu_member_violation;
1360 *data++ = chip->ports[port].atu_miss_violation;
1361 *data++ = chip->ports[port].atu_full_violation;
1362 *data++ = chip->ports[port].vtu_member_violation;
1363 *data++ = chip->ports[port].vtu_miss_violation;
1364 }
1365
mv88e6xxx_get_stats(struct mv88e6xxx_chip * chip,int port,uint64_t * data)1366 static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
1367 uint64_t *data)
1368 {
1369 size_t count;
1370
1371 count = mv88e6xxx_stats_get_stats(chip, port, data);
1372
1373 mv88e6xxx_reg_lock(chip);
1374 if (chip->info->ops->serdes_get_stats) {
1375 data += count;
1376 count = chip->info->ops->serdes_get_stats(chip, port, data);
1377 }
1378 data += count;
1379 mv88e6xxx_atu_vtu_get_stats(chip, port, data);
1380 mv88e6xxx_reg_unlock(chip);
1381 }
1382
mv88e6xxx_get_ethtool_stats(struct dsa_switch * ds,int port,uint64_t * data)1383 static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
1384 uint64_t *data)
1385 {
1386 struct mv88e6xxx_chip *chip = ds->priv;
1387 int ret;
1388
1389 ret = mv88e6xxx_stats_snapshot(chip, port);
1390 if (ret < 0)
1391 return;
1392
1393 mv88e6xxx_get_stats(chip, port, data);
1394 }
1395
mv88e6xxx_get_eth_mac_stats(struct dsa_switch * ds,int port,struct ethtool_eth_mac_stats * mac_stats)1396 static void mv88e6xxx_get_eth_mac_stats(struct dsa_switch *ds, int port,
1397 struct ethtool_eth_mac_stats *mac_stats)
1398 {
1399 struct mv88e6xxx_chip *chip = ds->priv;
1400 int ret;
1401
1402 ret = mv88e6xxx_stats_snapshot(chip, port);
1403 if (ret < 0)
1404 return;
1405
1406 #define MV88E6XXX_ETH_MAC_STAT_MAP(_id, _member) \
1407 mv88e6xxx_stats_get_stat(chip, port, \
1408 &mv88e6xxx_hw_stats[MV88E6XXX_HW_STAT_ID_ ## _id], \
1409 &mac_stats->stats._member)
1410
1411 MV88E6XXX_ETH_MAC_STAT_MAP(out_unicast, FramesTransmittedOK);
1412 MV88E6XXX_ETH_MAC_STAT_MAP(single, SingleCollisionFrames);
1413 MV88E6XXX_ETH_MAC_STAT_MAP(multiple, MultipleCollisionFrames);
1414 MV88E6XXX_ETH_MAC_STAT_MAP(in_unicast, FramesReceivedOK);
1415 MV88E6XXX_ETH_MAC_STAT_MAP(in_fcs_error, FrameCheckSequenceErrors);
1416 MV88E6XXX_ETH_MAC_STAT_MAP(out_octets, OctetsTransmittedOK);
1417 MV88E6XXX_ETH_MAC_STAT_MAP(deferred, FramesWithDeferredXmissions);
1418 MV88E6XXX_ETH_MAC_STAT_MAP(late, LateCollisions);
1419 MV88E6XXX_ETH_MAC_STAT_MAP(in_good_octets, OctetsReceivedOK);
1420 MV88E6XXX_ETH_MAC_STAT_MAP(out_multicasts, MulticastFramesXmittedOK);
1421 MV88E6XXX_ETH_MAC_STAT_MAP(out_broadcasts, BroadcastFramesXmittedOK);
1422 MV88E6XXX_ETH_MAC_STAT_MAP(excessive, FramesWithExcessiveDeferral);
1423 MV88E6XXX_ETH_MAC_STAT_MAP(in_multicasts, MulticastFramesReceivedOK);
1424 MV88E6XXX_ETH_MAC_STAT_MAP(in_broadcasts, BroadcastFramesReceivedOK);
1425
1426 #undef MV88E6XXX_ETH_MAC_STAT_MAP
1427
1428 mac_stats->stats.FramesTransmittedOK += mac_stats->stats.MulticastFramesXmittedOK;
1429 mac_stats->stats.FramesTransmittedOK += mac_stats->stats.BroadcastFramesXmittedOK;
1430 mac_stats->stats.FramesReceivedOK += mac_stats->stats.MulticastFramesReceivedOK;
1431 mac_stats->stats.FramesReceivedOK += mac_stats->stats.BroadcastFramesReceivedOK;
1432 }
1433
mv88e6xxx_get_rmon_stats(struct dsa_switch * ds,int port,struct ethtool_rmon_stats * rmon_stats,const struct ethtool_rmon_hist_range ** ranges)1434 static void mv88e6xxx_get_rmon_stats(struct dsa_switch *ds, int port,
1435 struct ethtool_rmon_stats *rmon_stats,
1436 const struct ethtool_rmon_hist_range **ranges)
1437 {
1438 static const struct ethtool_rmon_hist_range rmon_ranges[] = {
1439 { 64, 64 },
1440 { 65, 127 },
1441 { 128, 255 },
1442 { 256, 511 },
1443 { 512, 1023 },
1444 { 1024, 65535 },
1445 {}
1446 };
1447 struct mv88e6xxx_chip *chip = ds->priv;
1448 int ret;
1449
1450 ret = mv88e6xxx_stats_snapshot(chip, port);
1451 if (ret < 0)
1452 return;
1453
1454 #define MV88E6XXX_RMON_STAT_MAP(_id, _member) \
1455 mv88e6xxx_stats_get_stat(chip, port, \
1456 &mv88e6xxx_hw_stats[MV88E6XXX_HW_STAT_ID_ ## _id], \
1457 &rmon_stats->stats._member)
1458
1459 MV88E6XXX_RMON_STAT_MAP(in_undersize, undersize_pkts);
1460 MV88E6XXX_RMON_STAT_MAP(in_oversize, oversize_pkts);
1461 MV88E6XXX_RMON_STAT_MAP(in_fragments, fragments);
1462 MV88E6XXX_RMON_STAT_MAP(in_jabber, jabbers);
1463 MV88E6XXX_RMON_STAT_MAP(hist_64bytes, hist[0]);
1464 MV88E6XXX_RMON_STAT_MAP(hist_65_127bytes, hist[1]);
1465 MV88E6XXX_RMON_STAT_MAP(hist_128_255bytes, hist[2]);
1466 MV88E6XXX_RMON_STAT_MAP(hist_256_511bytes, hist[3]);
1467 MV88E6XXX_RMON_STAT_MAP(hist_512_1023bytes, hist[4]);
1468 MV88E6XXX_RMON_STAT_MAP(hist_1024_max_bytes, hist[5]);
1469
1470 #undef MV88E6XXX_RMON_STAT_MAP
1471
1472 *ranges = rmon_ranges;
1473 }
1474
mv88e6xxx_get_regs_len(struct dsa_switch * ds,int port)1475 static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
1476 {
1477 struct mv88e6xxx_chip *chip = ds->priv;
1478 int len;
1479
1480 len = 32 * sizeof(u16);
1481 if (chip->info->ops->serdes_get_regs_len)
1482 len += chip->info->ops->serdes_get_regs_len(chip, port);
1483
1484 return len;
1485 }
1486
mv88e6xxx_get_regs(struct dsa_switch * ds,int port,struct ethtool_regs * regs,void * _p)1487 static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
1488 struct ethtool_regs *regs, void *_p)
1489 {
1490 struct mv88e6xxx_chip *chip = ds->priv;
1491 int err;
1492 u16 reg;
1493 u16 *p = _p;
1494 int i;
1495
1496 regs->version = chip->info->prod_num;
1497
1498 memset(p, 0xff, 32 * sizeof(u16));
1499
1500 mv88e6xxx_reg_lock(chip);
1501
1502 for (i = 0; i < 32; i++) {
1503
1504 err = mv88e6xxx_port_read(chip, port, i, ®);
1505 if (!err)
1506 p[i] = reg;
1507 }
1508
1509 if (chip->info->ops->serdes_get_regs)
1510 chip->info->ops->serdes_get_regs(chip, port, &p[i]);
1511
1512 mv88e6xxx_reg_unlock(chip);
1513 }
1514
mv88e6xxx_set_mac_eee(struct dsa_switch * ds,int port,struct ethtool_keee * e)1515 static int mv88e6xxx_set_mac_eee(struct dsa_switch *ds, int port,
1516 struct ethtool_keee *e)
1517 {
1518 /* Nothing to do on the port's MAC */
1519 return 0;
1520 }
1521
1522 /* Mask of the local ports allowed to receive frames from a given fabric port */
mv88e6xxx_port_vlan(struct mv88e6xxx_chip * chip,int dev,int port)1523 static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port)
1524 {
1525 struct dsa_switch *ds = chip->ds;
1526 struct dsa_switch_tree *dst = ds->dst;
1527 struct dsa_port *dp, *other_dp;
1528 bool found = false;
1529 u16 pvlan;
1530
1531 /* dev is a physical switch */
1532 if (dev <= dst->last_switch) {
1533 list_for_each_entry(dp, &dst->ports, list) {
1534 if (dp->ds->index == dev && dp->index == port) {
1535 /* dp might be a DSA link or a user port, so it
1536 * might or might not have a bridge.
1537 * Use the "found" variable for both cases.
1538 */
1539 found = true;
1540 break;
1541 }
1542 }
1543 /* dev is a virtual bridge */
1544 } else {
1545 list_for_each_entry(dp, &dst->ports, list) {
1546 unsigned int bridge_num = dsa_port_bridge_num_get(dp);
1547
1548 if (!bridge_num)
1549 continue;
1550
1551 if (bridge_num + dst->last_switch != dev)
1552 continue;
1553
1554 found = true;
1555 break;
1556 }
1557 }
1558
1559 /* Prevent frames from unknown switch or virtual bridge */
1560 if (!found)
1561 return 0;
1562
1563 /* Frames from DSA links and CPU ports can egress any local port */
1564 if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA)
1565 return mv88e6xxx_port_mask(chip);
1566
1567 pvlan = 0;
1568
1569 /* Frames from standalone user ports can only egress on the
1570 * upstream port.
1571 */
1572 if (!dsa_port_bridge_dev_get(dp))
1573 return BIT(dsa_switch_upstream_port(ds));
1574
1575 /* Frames from bridged user ports can egress any local DSA
1576 * links and CPU ports, as well as any local member of their
1577 * bridge group.
1578 */
1579 dsa_switch_for_each_port(other_dp, ds)
1580 if (other_dp->type == DSA_PORT_TYPE_CPU ||
1581 other_dp->type == DSA_PORT_TYPE_DSA ||
1582 dsa_port_bridge_same(dp, other_dp))
1583 pvlan |= BIT(other_dp->index);
1584
1585 return pvlan;
1586 }
1587
mv88e6xxx_port_vlan_map(struct mv88e6xxx_chip * chip,int port)1588 static int mv88e6xxx_port_vlan_map(struct mv88e6xxx_chip *chip, int port)
1589 {
1590 u16 output_ports = mv88e6xxx_port_vlan(chip, chip->ds->index, port);
1591
1592 /* prevent frames from going back out of the port they came in on */
1593 output_ports &= ~BIT(port);
1594
1595 return mv88e6xxx_port_set_vlan_map(chip, port, output_ports);
1596 }
1597
mv88e6xxx_port_stp_state_set(struct dsa_switch * ds,int port,u8 state)1598 static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
1599 u8 state)
1600 {
1601 struct mv88e6xxx_chip *chip = ds->priv;
1602 int err;
1603
1604 mv88e6xxx_reg_lock(chip);
1605 err = mv88e6xxx_port_set_state(chip, port, state);
1606 mv88e6xxx_reg_unlock(chip);
1607
1608 if (err)
1609 dev_err(ds->dev, "p%d: failed to update state\n", port);
1610 }
1611
mv88e6xxx_pri_setup(struct mv88e6xxx_chip * chip)1612 static int mv88e6xxx_pri_setup(struct mv88e6xxx_chip *chip)
1613 {
1614 int err;
1615
1616 if (chip->info->ops->ieee_pri_map) {
1617 err = chip->info->ops->ieee_pri_map(chip);
1618 if (err)
1619 return err;
1620 }
1621
1622 if (chip->info->ops->ip_pri_map) {
1623 err = chip->info->ops->ip_pri_map(chip);
1624 if (err)
1625 return err;
1626 }
1627
1628 return 0;
1629 }
1630
mv88e6xxx_devmap_setup(struct mv88e6xxx_chip * chip)1631 static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip)
1632 {
1633 struct dsa_switch *ds = chip->ds;
1634 int target, port;
1635 int err;
1636
1637 if (!chip->info->global2_addr)
1638 return 0;
1639
1640 /* Initialize the routing port to the 32 possible target devices */
1641 for (target = 0; target < 32; target++) {
1642 port = dsa_routing_port(ds, target);
1643 if (port == ds->num_ports)
1644 port = 0x1f;
1645
1646 err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
1647 if (err)
1648 return err;
1649 }
1650
1651 if (chip->info->ops->set_cascade_port) {
1652 port = MV88E6XXX_CASCADE_PORT_MULTIPLE;
1653 err = chip->info->ops->set_cascade_port(chip, port);
1654 if (err)
1655 return err;
1656 }
1657
1658 err = mv88e6xxx_g1_set_device_number(chip, chip->ds->index);
1659 if (err)
1660 return err;
1661
1662 return 0;
1663 }
1664
mv88e6xxx_trunk_setup(struct mv88e6xxx_chip * chip)1665 static int mv88e6xxx_trunk_setup(struct mv88e6xxx_chip *chip)
1666 {
1667 /* Clear all trunk masks and mapping */
1668 if (chip->info->global2_addr)
1669 return mv88e6xxx_g2_trunk_clear(chip);
1670
1671 return 0;
1672 }
1673
mv88e6xxx_rmu_setup(struct mv88e6xxx_chip * chip)1674 static int mv88e6xxx_rmu_setup(struct mv88e6xxx_chip *chip)
1675 {
1676 if (chip->info->ops->rmu_disable)
1677 return chip->info->ops->rmu_disable(chip);
1678
1679 return 0;
1680 }
1681
mv88e6xxx_pot_setup(struct mv88e6xxx_chip * chip)1682 static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip)
1683 {
1684 if (chip->info->ops->pot_clear)
1685 return chip->info->ops->pot_clear(chip);
1686
1687 return 0;
1688 }
1689
mv88e6xxx_rsvd2cpu_setup(struct mv88e6xxx_chip * chip)1690 static int mv88e6xxx_rsvd2cpu_setup(struct mv88e6xxx_chip *chip)
1691 {
1692 if (chip->info->ops->mgmt_rsvd2cpu)
1693 return chip->info->ops->mgmt_rsvd2cpu(chip);
1694
1695 return 0;
1696 }
1697
mv88e6xxx_atu_setup(struct mv88e6xxx_chip * chip)1698 static int mv88e6xxx_atu_setup(struct mv88e6xxx_chip *chip)
1699 {
1700 int err;
1701
1702 err = mv88e6xxx_g1_atu_flush(chip, 0, true);
1703 if (err)
1704 return err;
1705
1706 /* The chips that have a "learn2all" bit in Global1, ATU
1707 * Control are precisely those whose port registers have a
1708 * Message Port bit in Port Control 1 and hence implement
1709 * ->port_setup_message_port.
1710 */
1711 if (chip->info->ops->port_setup_message_port) {
1712 err = mv88e6xxx_g1_atu_set_learn2all(chip, true);
1713 if (err)
1714 return err;
1715 }
1716
1717 return mv88e6xxx_g1_atu_set_age_time(chip, 300000);
1718 }
1719
mv88e6xxx_irl_setup(struct mv88e6xxx_chip * chip)1720 static int mv88e6xxx_irl_setup(struct mv88e6xxx_chip *chip)
1721 {
1722 int port;
1723 int err;
1724
1725 if (!chip->info->ops->irl_init_all)
1726 return 0;
1727
1728 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
1729 /* Disable ingress rate limiting by resetting all per port
1730 * ingress rate limit resources to their initial state.
1731 */
1732 err = chip->info->ops->irl_init_all(chip, port);
1733 if (err)
1734 return err;
1735 }
1736
1737 return 0;
1738 }
1739
mv88e6xxx_mac_setup(struct mv88e6xxx_chip * chip)1740 static int mv88e6xxx_mac_setup(struct mv88e6xxx_chip *chip)
1741 {
1742 if (chip->info->ops->set_switch_mac) {
1743 u8 addr[ETH_ALEN];
1744
1745 eth_random_addr(addr);
1746
1747 return chip->info->ops->set_switch_mac(chip, addr);
1748 }
1749
1750 return 0;
1751 }
1752
mv88e6xxx_pvt_map(struct mv88e6xxx_chip * chip,int dev,int port)1753 static int mv88e6xxx_pvt_map(struct mv88e6xxx_chip *chip, int dev, int port)
1754 {
1755 struct dsa_switch_tree *dst = chip->ds->dst;
1756 struct dsa_switch *ds;
1757 struct dsa_port *dp;
1758 u16 pvlan = 0;
1759
1760 if (!mv88e6xxx_has_pvt(chip))
1761 return 0;
1762
1763 /* Skip the local source device, which uses in-chip port VLAN */
1764 if (dev != chip->ds->index) {
1765 pvlan = mv88e6xxx_port_vlan(chip, dev, port);
1766
1767 ds = dsa_switch_find(dst->index, dev);
1768 dp = ds ? dsa_to_port(ds, port) : NULL;
1769 if (dp && dp->lag) {
1770 /* As the PVT is used to limit flooding of
1771 * FORWARD frames, which use the LAG ID as the
1772 * source port, we must translate dev/port to
1773 * the special "LAG device" in the PVT, using
1774 * the LAG ID (one-based) as the port number
1775 * (zero-based).
1776 */
1777 dev = MV88E6XXX_G2_PVT_ADDR_DEV_TRUNK;
1778 port = dsa_port_lag_id_get(dp) - 1;
1779 }
1780 }
1781
1782 return mv88e6xxx_g2_pvt_write(chip, dev, port, pvlan);
1783 }
1784
mv88e6xxx_pvt_setup(struct mv88e6xxx_chip * chip)1785 static int mv88e6xxx_pvt_setup(struct mv88e6xxx_chip *chip)
1786 {
1787 int dev, port;
1788 int err;
1789
1790 if (!mv88e6xxx_has_pvt(chip))
1791 return 0;
1792
1793 /* Clear 5 Bit Port for usage with Marvell Link Street devices:
1794 * use 4 bits for the Src_Port/Src_Trunk and 5 bits for the Src_Dev.
1795 */
1796 err = mv88e6xxx_g2_misc_4_bit_port(chip);
1797 if (err)
1798 return err;
1799
1800 for (dev = 0; dev < MV88E6XXX_MAX_PVT_SWITCHES; ++dev) {
1801 for (port = 0; port < MV88E6XXX_MAX_PVT_PORTS; ++port) {
1802 err = mv88e6xxx_pvt_map(chip, dev, port);
1803 if (err)
1804 return err;
1805 }
1806 }
1807
1808 return 0;
1809 }
1810
mv88e6xxx_port_fast_age_fid(struct mv88e6xxx_chip * chip,int port,u16 fid)1811 static int mv88e6xxx_port_fast_age_fid(struct mv88e6xxx_chip *chip, int port,
1812 u16 fid)
1813 {
1814 if (dsa_to_port(chip->ds, port)->lag)
1815 /* Hardware is incapable of fast-aging a LAG through a
1816 * regular ATU move operation. Until we have something
1817 * more fancy in place this is a no-op.
1818 */
1819 return -EOPNOTSUPP;
1820
1821 return mv88e6xxx_g1_atu_remove(chip, fid, port, false);
1822 }
1823
mv88e6xxx_port_fast_age(struct dsa_switch * ds,int port)1824 static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port)
1825 {
1826 struct mv88e6xxx_chip *chip = ds->priv;
1827 int err;
1828
1829 mv88e6xxx_reg_lock(chip);
1830 err = mv88e6xxx_port_fast_age_fid(chip, port, 0);
1831 mv88e6xxx_reg_unlock(chip);
1832
1833 if (err)
1834 dev_err(chip->ds->dev, "p%d: failed to flush ATU: %d\n",
1835 port, err);
1836 }
1837
mv88e6xxx_vtu_setup(struct mv88e6xxx_chip * chip)1838 static int mv88e6xxx_vtu_setup(struct mv88e6xxx_chip *chip)
1839 {
1840 if (!mv88e6xxx_max_vid(chip))
1841 return 0;
1842
1843 return mv88e6xxx_g1_vtu_flush(chip);
1844 }
1845
mv88e6xxx_vtu_get(struct mv88e6xxx_chip * chip,u16 vid,struct mv88e6xxx_vtu_entry * entry)1846 static int mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
1847 struct mv88e6xxx_vtu_entry *entry)
1848 {
1849 int err;
1850
1851 if (!chip->info->ops->vtu_getnext)
1852 return -EOPNOTSUPP;
1853
1854 memset(entry, 0, sizeof(*entry));
1855
1856 entry->vid = vid ? vid - 1 : mv88e6xxx_max_vid(chip);
1857 entry->valid = false;
1858
1859 err = chip->info->ops->vtu_getnext(chip, entry);
1860
1861 if (entry->vid != vid)
1862 entry->valid = false;
1863
1864 return err;
1865 }
1866
mv88e6xxx_vtu_walk(struct mv88e6xxx_chip * chip,int (* cb)(struct mv88e6xxx_chip * chip,const struct mv88e6xxx_vtu_entry * entry,void * priv),void * priv)1867 int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
1868 int (*cb)(struct mv88e6xxx_chip *chip,
1869 const struct mv88e6xxx_vtu_entry *entry,
1870 void *priv),
1871 void *priv)
1872 {
1873 struct mv88e6xxx_vtu_entry entry = {
1874 .vid = mv88e6xxx_max_vid(chip),
1875 .valid = false,
1876 };
1877 int err;
1878
1879 if (!chip->info->ops->vtu_getnext)
1880 return -EOPNOTSUPP;
1881
1882 do {
1883 err = chip->info->ops->vtu_getnext(chip, &entry);
1884 if (err)
1885 return err;
1886
1887 if (!entry.valid)
1888 break;
1889
1890 err = cb(chip, &entry, priv);
1891 if (err)
1892 return err;
1893 } while (entry.vid < mv88e6xxx_max_vid(chip));
1894
1895 return 0;
1896 }
1897
mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip * chip,struct mv88e6xxx_vtu_entry * entry)1898 static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
1899 struct mv88e6xxx_vtu_entry *entry)
1900 {
1901 if (!chip->info->ops->vtu_loadpurge)
1902 return -EOPNOTSUPP;
1903
1904 return chip->info->ops->vtu_loadpurge(chip, entry);
1905 }
1906
mv88e6xxx_atu_new(struct mv88e6xxx_chip * chip,u16 * fid)1907 static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
1908 {
1909 *fid = find_first_zero_bit(chip->fid_bitmap, MV88E6XXX_N_FID);
1910 if (unlikely(*fid >= mv88e6xxx_num_databases(chip)))
1911 return -ENOSPC;
1912
1913 /* Clear the database */
1914 return mv88e6xxx_g1_atu_flush(chip, *fid, true);
1915 }
1916
mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip * chip,struct mv88e6xxx_stu_entry * entry)1917 static int mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip,
1918 struct mv88e6xxx_stu_entry *entry)
1919 {
1920 if (!chip->info->ops->stu_loadpurge)
1921 return -EOPNOTSUPP;
1922
1923 return chip->info->ops->stu_loadpurge(chip, entry);
1924 }
1925
mv88e6xxx_stu_setup(struct mv88e6xxx_chip * chip)1926 static int mv88e6xxx_stu_setup(struct mv88e6xxx_chip *chip)
1927 {
1928 struct mv88e6xxx_stu_entry stu = {
1929 .valid = true,
1930 .sid = 0
1931 };
1932
1933 if (!mv88e6xxx_has_stu(chip))
1934 return 0;
1935
1936 /* Make sure that SID 0 is always valid. This is used by VTU
1937 * entries that do not make use of the STU, e.g. when creating
1938 * a VLAN upper on a port that is also part of a VLAN
1939 * filtering bridge.
1940 */
1941 return mv88e6xxx_stu_loadpurge(chip, &stu);
1942 }
1943
mv88e6xxx_sid_get(struct mv88e6xxx_chip * chip,u8 * sid)1944 static int mv88e6xxx_sid_get(struct mv88e6xxx_chip *chip, u8 *sid)
1945 {
1946 DECLARE_BITMAP(busy, MV88E6XXX_N_SID) = { 0 };
1947 struct mv88e6xxx_mst *mst;
1948
1949 __set_bit(0, busy);
1950
1951 list_for_each_entry(mst, &chip->msts, node)
1952 __set_bit(mst->stu.sid, busy);
1953
1954 *sid = find_first_zero_bit(busy, MV88E6XXX_N_SID);
1955
1956 return (*sid >= mv88e6xxx_max_sid(chip)) ? -ENOSPC : 0;
1957 }
1958
mv88e6xxx_mst_put(struct mv88e6xxx_chip * chip,u8 sid)1959 static int mv88e6xxx_mst_put(struct mv88e6xxx_chip *chip, u8 sid)
1960 {
1961 struct mv88e6xxx_mst *mst, *tmp;
1962 int err;
1963
1964 /* If the SID is zero, it is for a VLAN mapped to the default MSTI,
1965 * and mv88e6xxx_stu_setup() made sure it is always present, and thus,
1966 * should not be removed here.
1967 *
1968 * If the chip lacks STU support, numerically the "sid" variable will
1969 * happen to also be zero, but we don't want to rely on that fact, so
1970 * we explicitly test that first. In that case, there is also nothing
1971 * to do here.
1972 */
1973 if (!mv88e6xxx_has_stu(chip) || !sid)
1974 return 0;
1975
1976 list_for_each_entry_safe(mst, tmp, &chip->msts, node) {
1977 if (mst->stu.sid != sid)
1978 continue;
1979
1980 if (!refcount_dec_and_test(&mst->refcnt))
1981 return 0;
1982
1983 mst->stu.valid = false;
1984 err = mv88e6xxx_stu_loadpurge(chip, &mst->stu);
1985 if (err) {
1986 refcount_set(&mst->refcnt, 1);
1987 return err;
1988 }
1989
1990 list_del(&mst->node);
1991 kfree(mst);
1992 return 0;
1993 }
1994
1995 return -ENOENT;
1996 }
1997
mv88e6xxx_mst_get(struct mv88e6xxx_chip * chip,struct net_device * br,u16 msti,u8 * sid)1998 static int mv88e6xxx_mst_get(struct mv88e6xxx_chip *chip, struct net_device *br,
1999 u16 msti, u8 *sid)
2000 {
2001 struct mv88e6xxx_mst *mst;
2002 int err, i;
2003
2004 if (!mv88e6xxx_has_stu(chip)) {
2005 err = -EOPNOTSUPP;
2006 goto err;
2007 }
2008
2009 if (!msti) {
2010 *sid = 0;
2011 return 0;
2012 }
2013
2014 list_for_each_entry(mst, &chip->msts, node) {
2015 if (mst->br == br && mst->msti == msti) {
2016 refcount_inc(&mst->refcnt);
2017 *sid = mst->stu.sid;
2018 return 0;
2019 }
2020 }
2021
2022 err = mv88e6xxx_sid_get(chip, sid);
2023 if (err)
2024 goto err;
2025
2026 mst = kzalloc_obj(*mst);
2027 if (!mst) {
2028 err = -ENOMEM;
2029 goto err;
2030 }
2031
2032 INIT_LIST_HEAD(&mst->node);
2033 refcount_set(&mst->refcnt, 1);
2034 mst->br = br;
2035 mst->msti = msti;
2036 mst->stu.valid = true;
2037 mst->stu.sid = *sid;
2038
2039 /* The bridge starts out all ports in the disabled state. But
2040 * a STU state of disabled means to go by the port-global
2041 * state. So we set all user port's initial state to blocking,
2042 * to match the bridge's behavior.
2043 */
2044 for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
2045 mst->stu.state[i] = dsa_is_user_port(chip->ds, i) ?
2046 MV88E6XXX_PORT_CTL0_STATE_BLOCKING :
2047 MV88E6XXX_PORT_CTL0_STATE_DISABLED;
2048
2049 err = mv88e6xxx_stu_loadpurge(chip, &mst->stu);
2050 if (err)
2051 goto err_free;
2052
2053 list_add_tail(&mst->node, &chip->msts);
2054 return 0;
2055
2056 err_free:
2057 kfree(mst);
2058 err:
2059 return err;
2060 }
2061
mv88e6xxx_port_mst_state_set(struct dsa_switch * ds,int port,const struct switchdev_mst_state * st)2062 static int mv88e6xxx_port_mst_state_set(struct dsa_switch *ds, int port,
2063 const struct switchdev_mst_state *st)
2064 {
2065 struct dsa_port *dp = dsa_to_port(ds, port);
2066 struct mv88e6xxx_chip *chip = ds->priv;
2067 struct mv88e6xxx_mst *mst;
2068 u8 state;
2069 int err;
2070
2071 if (!mv88e6xxx_has_stu(chip))
2072 return -EOPNOTSUPP;
2073
2074 switch (st->state) {
2075 case BR_STATE_DISABLED:
2076 case BR_STATE_BLOCKING:
2077 case BR_STATE_LISTENING:
2078 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
2079 break;
2080 case BR_STATE_LEARNING:
2081 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
2082 break;
2083 case BR_STATE_FORWARDING:
2084 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
2085 break;
2086 default:
2087 return -EINVAL;
2088 }
2089
2090 list_for_each_entry(mst, &chip->msts, node) {
2091 if (mst->br == dsa_port_bridge_dev_get(dp) &&
2092 mst->msti == st->msti) {
2093 if (mst->stu.state[port] == state)
2094 return 0;
2095
2096 mst->stu.state[port] = state;
2097 mv88e6xxx_reg_lock(chip);
2098 err = mv88e6xxx_stu_loadpurge(chip, &mst->stu);
2099 mv88e6xxx_reg_unlock(chip);
2100 return err;
2101 }
2102 }
2103
2104 return -ENOENT;
2105 }
2106
mv88e6xxx_port_check_hw_vlan(struct dsa_switch * ds,int port,u16 vid)2107 static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
2108 u16 vid)
2109 {
2110 struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
2111 struct mv88e6xxx_chip *chip = ds->priv;
2112 struct mv88e6xxx_vtu_entry vlan;
2113 int err;
2114
2115 /* DSA and CPU ports have to be members of multiple vlans */
2116 if (dsa_port_is_dsa(dp) || dsa_port_is_cpu(dp))
2117 return 0;
2118
2119 err = mv88e6xxx_vtu_get(chip, vid, &vlan);
2120 if (err)
2121 return err;
2122
2123 if (!vlan.valid)
2124 return 0;
2125
2126 dsa_switch_for_each_user_port(other_dp, ds) {
2127 struct net_device *other_br;
2128
2129 if (vlan.member[other_dp->index] ==
2130 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
2131 continue;
2132
2133 if (dsa_port_bridge_same(dp, other_dp))
2134 break; /* same bridge, check next VLAN */
2135
2136 other_br = dsa_port_bridge_dev_get(other_dp);
2137 if (!other_br)
2138 continue;
2139
2140 dev_err(ds->dev, "p%d: hw VLAN %d already used by port %d in %s\n",
2141 port, vlan.vid, other_dp->index, netdev_name(other_br));
2142 return -EOPNOTSUPP;
2143 }
2144
2145 return 0;
2146 }
2147
mv88e6xxx_port_commit_pvid(struct mv88e6xxx_chip * chip,int port)2148 static int mv88e6xxx_port_commit_pvid(struct mv88e6xxx_chip *chip, int port)
2149 {
2150 struct dsa_port *dp = dsa_to_port(chip->ds, port);
2151 struct net_device *br = dsa_port_bridge_dev_get(dp);
2152 struct mv88e6xxx_port *p = &chip->ports[port];
2153 u16 pvid = MV88E6XXX_VID_STANDALONE;
2154 bool drop_untagged = false;
2155 int err;
2156
2157 if (br) {
2158 if (br_vlan_enabled(br)) {
2159 pvid = p->bridge_pvid.vid;
2160 drop_untagged = !p->bridge_pvid.valid;
2161 } else {
2162 pvid = MV88E6XXX_VID_BRIDGED;
2163 }
2164 }
2165
2166 err = mv88e6xxx_port_set_pvid(chip, port, pvid);
2167 if (err)
2168 return err;
2169
2170 return mv88e6xxx_port_drop_untagged(chip, port, drop_untagged);
2171 }
2172
mv88e6xxx_port_vlan_filtering(struct dsa_switch * ds,int port,bool vlan_filtering,struct netlink_ext_ack * extack)2173 static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
2174 bool vlan_filtering,
2175 struct netlink_ext_ack *extack)
2176 {
2177 struct mv88e6xxx_chip *chip = ds->priv;
2178 u16 mode = vlan_filtering ? MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE :
2179 MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED;
2180 int err;
2181
2182 if (!mv88e6xxx_max_vid(chip))
2183 return -EOPNOTSUPP;
2184
2185 mv88e6xxx_reg_lock(chip);
2186
2187 err = mv88e6xxx_port_set_8021q_mode(chip, port, mode);
2188 if (err)
2189 goto unlock;
2190
2191 err = mv88e6xxx_port_commit_pvid(chip, port);
2192 if (err)
2193 goto unlock;
2194
2195 unlock:
2196 mv88e6xxx_reg_unlock(chip);
2197
2198 return err;
2199 }
2200
2201 static int
mv88e6xxx_port_vlan_prepare(struct dsa_switch * ds,int port,const struct switchdev_obj_port_vlan * vlan)2202 mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
2203 const struct switchdev_obj_port_vlan *vlan)
2204 {
2205 struct mv88e6xxx_chip *chip = ds->priv;
2206 int err;
2207
2208 if (!mv88e6xxx_max_vid(chip))
2209 return -EOPNOTSUPP;
2210
2211 /* If the requested port doesn't belong to the same bridge as the VLAN
2212 * members, do not support it (yet) and fallback to software VLAN.
2213 */
2214 mv88e6xxx_reg_lock(chip);
2215 err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid);
2216 mv88e6xxx_reg_unlock(chip);
2217
2218 return err;
2219 }
2220
mv88e6xxx_port_db_get(struct mv88e6xxx_chip * chip,const unsigned char * addr,u16 vid,u16 * fid,struct mv88e6xxx_atu_entry * entry)2221 static int mv88e6xxx_port_db_get(struct mv88e6xxx_chip *chip,
2222 const unsigned char *addr, u16 vid,
2223 u16 *fid, struct mv88e6xxx_atu_entry *entry)
2224 {
2225 struct mv88e6xxx_vtu_entry vlan;
2226 int err;
2227
2228 /* Ports have two private address databases: one for when the port is
2229 * standalone and one for when the port is under a bridge and the
2230 * 802.1Q mode is disabled. When the port is standalone, DSA wants its
2231 * address database to remain 100% empty, so we never load an ATU entry
2232 * into a standalone port's database. Therefore, translate the null
2233 * VLAN ID into the port's database used for VLAN-unaware bridging.
2234 */
2235 if (vid == 0) {
2236 *fid = MV88E6XXX_FID_BRIDGED;
2237 } else {
2238 err = mv88e6xxx_vtu_get(chip, vid, &vlan);
2239 if (err)
2240 return err;
2241
2242 /* switchdev expects -EOPNOTSUPP to honor software VLANs */
2243 if (!vlan.valid)
2244 return -EOPNOTSUPP;
2245
2246 *fid = vlan.fid;
2247 }
2248
2249 entry->state = 0;
2250 ether_addr_copy(entry->mac, addr);
2251 eth_addr_dec(entry->mac);
2252
2253 return mv88e6xxx_g1_atu_getnext(chip, *fid, entry);
2254 }
2255
mv88e6xxx_port_db_find(struct mv88e6xxx_chip * chip,const unsigned char * addr,u16 vid)2256 static bool mv88e6xxx_port_db_find(struct mv88e6xxx_chip *chip,
2257 const unsigned char *addr, u16 vid)
2258 {
2259 struct mv88e6xxx_atu_entry entry;
2260 u16 fid;
2261 int err;
2262
2263 err = mv88e6xxx_port_db_get(chip, addr, vid, &fid, &entry);
2264 if (err)
2265 return false;
2266
2267 return entry.state && ether_addr_equal(entry.mac, addr);
2268 }
2269
mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip * chip,int port,const unsigned char * addr,u16 vid,u8 state)2270 static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
2271 const unsigned char *addr, u16 vid,
2272 u8 state)
2273 {
2274 struct mv88e6xxx_atu_entry entry;
2275 u16 fid;
2276 int err;
2277
2278 err = mv88e6xxx_port_db_get(chip, addr, vid, &fid, &entry);
2279 if (err)
2280 return err;
2281
2282 /* Initialize a fresh ATU entry if it isn't found */
2283 if (!entry.state || !ether_addr_equal(entry.mac, addr)) {
2284 memset(&entry, 0, sizeof(entry));
2285 ether_addr_copy(entry.mac, addr);
2286 }
2287
2288 /* Purge the ATU entry only if no port is using it anymore */
2289 if (!state) {
2290 entry.portvec &= ~BIT(port);
2291 if (!entry.portvec)
2292 entry.state = 0;
2293 } else {
2294 if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
2295 entry.portvec = BIT(port);
2296 else
2297 entry.portvec |= BIT(port);
2298
2299 entry.state = state;
2300 }
2301
2302 return mv88e6xxx_g1_atu_loadpurge(chip, fid, &entry);
2303 }
2304
mv88e6xxx_policy_apply(struct mv88e6xxx_chip * chip,int port,const struct mv88e6xxx_policy * policy)2305 static int mv88e6xxx_policy_apply(struct mv88e6xxx_chip *chip, int port,
2306 const struct mv88e6xxx_policy *policy)
2307 {
2308 enum mv88e6xxx_policy_mapping mapping = policy->mapping;
2309 enum mv88e6xxx_policy_action action = policy->action;
2310 const u8 *addr = policy->addr;
2311 u16 vid = policy->vid;
2312 u8 state;
2313 int err;
2314 int id;
2315
2316 if (!chip->info->ops->port_set_policy)
2317 return -EOPNOTSUPP;
2318
2319 switch (mapping) {
2320 case MV88E6XXX_POLICY_MAPPING_DA:
2321 case MV88E6XXX_POLICY_MAPPING_SA:
2322 if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
2323 state = 0; /* Dissociate the port and address */
2324 else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
2325 is_multicast_ether_addr(addr))
2326 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC_POLICY;
2327 else if (action == MV88E6XXX_POLICY_ACTION_DISCARD &&
2328 is_unicast_ether_addr(addr))
2329 state = MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC_POLICY;
2330 else
2331 return -EOPNOTSUPP;
2332
2333 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
2334 state);
2335 if (err)
2336 return err;
2337 break;
2338 default:
2339 return -EOPNOTSUPP;
2340 }
2341
2342 /* Skip the port's policy clearing if the mapping is still in use */
2343 if (action == MV88E6XXX_POLICY_ACTION_NORMAL)
2344 idr_for_each_entry(&chip->policies, policy, id)
2345 if (policy->port == port &&
2346 policy->mapping == mapping &&
2347 policy->action != action)
2348 return 0;
2349
2350 return chip->info->ops->port_set_policy(chip, port, mapping, action);
2351 }
2352
mv88e6xxx_policy_insert(struct mv88e6xxx_chip * chip,int port,struct ethtool_rx_flow_spec * fs)2353 static int mv88e6xxx_policy_insert(struct mv88e6xxx_chip *chip, int port,
2354 struct ethtool_rx_flow_spec *fs)
2355 {
2356 struct ethhdr *mac_entry = &fs->h_u.ether_spec;
2357 struct ethhdr *mac_mask = &fs->m_u.ether_spec;
2358 enum mv88e6xxx_policy_mapping mapping;
2359 enum mv88e6xxx_policy_action action;
2360 struct mv88e6xxx_policy *policy;
2361 u16 vid = 0;
2362 u8 *addr;
2363 int err;
2364 int id;
2365
2366 if (fs->location != RX_CLS_LOC_ANY)
2367 return -EINVAL;
2368
2369 if (fs->ring_cookie == RX_CLS_FLOW_DISC)
2370 action = MV88E6XXX_POLICY_ACTION_DISCARD;
2371 else
2372 return -EOPNOTSUPP;
2373
2374 switch (fs->flow_type & ~FLOW_EXT) {
2375 case ETHER_FLOW:
2376 if (!is_zero_ether_addr(mac_mask->h_dest) &&
2377 is_zero_ether_addr(mac_mask->h_source)) {
2378 mapping = MV88E6XXX_POLICY_MAPPING_DA;
2379 addr = mac_entry->h_dest;
2380 } else if (is_zero_ether_addr(mac_mask->h_dest) &&
2381 !is_zero_ether_addr(mac_mask->h_source)) {
2382 mapping = MV88E6XXX_POLICY_MAPPING_SA;
2383 addr = mac_entry->h_source;
2384 } else {
2385 /* Cannot support DA and SA mapping in the same rule */
2386 return -EOPNOTSUPP;
2387 }
2388 break;
2389 default:
2390 return -EOPNOTSUPP;
2391 }
2392
2393 if ((fs->flow_type & FLOW_EXT) && fs->m_ext.vlan_tci) {
2394 if (fs->m_ext.vlan_tci != htons(0xffff))
2395 return -EOPNOTSUPP;
2396 vid = be16_to_cpu(fs->h_ext.vlan_tci) & VLAN_VID_MASK;
2397 }
2398
2399 idr_for_each_entry(&chip->policies, policy, id) {
2400 if (policy->port == port && policy->mapping == mapping &&
2401 policy->action == action && policy->vid == vid &&
2402 ether_addr_equal(policy->addr, addr))
2403 return -EEXIST;
2404 }
2405
2406 policy = devm_kzalloc(chip->dev, sizeof(*policy), GFP_KERNEL);
2407 if (!policy)
2408 return -ENOMEM;
2409
2410 fs->location = 0;
2411 err = idr_alloc_u32(&chip->policies, policy, &fs->location, 0xffffffff,
2412 GFP_KERNEL);
2413 if (err) {
2414 devm_kfree(chip->dev, policy);
2415 return err;
2416 }
2417
2418 memcpy(&policy->fs, fs, sizeof(*fs));
2419 ether_addr_copy(policy->addr, addr);
2420 policy->mapping = mapping;
2421 policy->action = action;
2422 policy->port = port;
2423 policy->vid = vid;
2424
2425 err = mv88e6xxx_policy_apply(chip, port, policy);
2426 if (err) {
2427 idr_remove(&chip->policies, fs->location);
2428 devm_kfree(chip->dev, policy);
2429 return err;
2430 }
2431
2432 return 0;
2433 }
2434
mv88e6xxx_get_rxnfc(struct dsa_switch * ds,int port,struct ethtool_rxnfc * rxnfc,u32 * rule_locs)2435 static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port,
2436 struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
2437 {
2438 struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
2439 struct mv88e6xxx_chip *chip = ds->priv;
2440 struct mv88e6xxx_policy *policy;
2441 u32 cnt = 0;
2442 int err;
2443 int id;
2444
2445 mv88e6xxx_reg_lock(chip);
2446
2447 switch (rxnfc->cmd) {
2448 case ETHTOOL_GRXCLSRLCNT:
2449 rxnfc->data = 0;
2450 rxnfc->data |= RX_CLS_LOC_SPECIAL;
2451 rxnfc->rule_cnt = 0;
2452 idr_for_each_entry(&chip->policies, policy, id)
2453 if (policy->port == port)
2454 rxnfc->rule_cnt++;
2455 err = 0;
2456 break;
2457 case ETHTOOL_GRXCLSRULE:
2458 err = -ENOENT;
2459 policy = idr_find(&chip->policies, fs->location);
2460 if (policy) {
2461 memcpy(fs, &policy->fs, sizeof(*fs));
2462 err = 0;
2463 }
2464 break;
2465 case ETHTOOL_GRXCLSRLALL:
2466 rxnfc->data = 0;
2467 err = 0;
2468 idr_for_each_entry(&chip->policies, policy, id) {
2469 if (policy->port != port)
2470 continue;
2471 if (cnt == rxnfc->rule_cnt) {
2472 err = -EMSGSIZE;
2473 break;
2474 }
2475 rule_locs[cnt++] = id;
2476 }
2477 if (!err)
2478 rxnfc->rule_cnt = cnt;
2479 break;
2480 default:
2481 err = -EOPNOTSUPP;
2482 break;
2483 }
2484
2485 mv88e6xxx_reg_unlock(chip);
2486
2487 return err;
2488 }
2489
mv88e6xxx_set_rxnfc(struct dsa_switch * ds,int port,struct ethtool_rxnfc * rxnfc)2490 static int mv88e6xxx_set_rxnfc(struct dsa_switch *ds, int port,
2491 struct ethtool_rxnfc *rxnfc)
2492 {
2493 struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
2494 struct mv88e6xxx_chip *chip = ds->priv;
2495 struct mv88e6xxx_policy *policy;
2496 int err;
2497
2498 mv88e6xxx_reg_lock(chip);
2499
2500 switch (rxnfc->cmd) {
2501 case ETHTOOL_SRXCLSRLINS:
2502 err = mv88e6xxx_policy_insert(chip, port, fs);
2503 break;
2504 case ETHTOOL_SRXCLSRLDEL:
2505 err = -ENOENT;
2506 policy = idr_remove(&chip->policies, fs->location);
2507 if (policy) {
2508 policy->action = MV88E6XXX_POLICY_ACTION_NORMAL;
2509 err = mv88e6xxx_policy_apply(chip, port, policy);
2510 devm_kfree(chip->dev, policy);
2511 }
2512 break;
2513 default:
2514 err = -EOPNOTSUPP;
2515 break;
2516 }
2517
2518 mv88e6xxx_reg_unlock(chip);
2519
2520 return err;
2521 }
2522
mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip * chip,int port,u16 vid)2523 static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
2524 u16 vid)
2525 {
2526 u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
2527 u8 broadcast[ETH_ALEN];
2528
2529 eth_broadcast_addr(broadcast);
2530
2531 return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state);
2532 }
2533
mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip * chip,u16 vid)2534 static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
2535 {
2536 int port;
2537 int err;
2538
2539 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
2540 struct dsa_port *dp = dsa_to_port(chip->ds, port);
2541 struct net_device *brport;
2542
2543 if (dsa_is_unused_port(chip->ds, port))
2544 continue;
2545
2546 brport = dsa_port_to_bridge_port(dp);
2547 if (brport && !br_port_flag_is_set(brport, BR_BCAST_FLOOD))
2548 /* Skip bridged user ports where broadcast
2549 * flooding is disabled.
2550 */
2551 continue;
2552
2553 err = mv88e6xxx_port_add_broadcast(chip, port, vid);
2554 if (err)
2555 return err;
2556 }
2557
2558 return 0;
2559 }
2560
2561 struct mv88e6xxx_port_broadcast_sync_ctx {
2562 int port;
2563 bool flood;
2564 };
2565
2566 static int
mv88e6xxx_port_broadcast_sync_vlan(struct mv88e6xxx_chip * chip,const struct mv88e6xxx_vtu_entry * vlan,void * _ctx)2567 mv88e6xxx_port_broadcast_sync_vlan(struct mv88e6xxx_chip *chip,
2568 const struct mv88e6xxx_vtu_entry *vlan,
2569 void *_ctx)
2570 {
2571 struct mv88e6xxx_port_broadcast_sync_ctx *ctx = _ctx;
2572 u8 broadcast[ETH_ALEN];
2573 u8 state;
2574
2575 if (ctx->flood)
2576 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
2577 else
2578 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_UNUSED;
2579
2580 eth_broadcast_addr(broadcast);
2581
2582 return mv88e6xxx_port_db_load_purge(chip, ctx->port, broadcast,
2583 vlan->vid, state);
2584 }
2585
mv88e6xxx_port_broadcast_sync(struct mv88e6xxx_chip * chip,int port,bool flood)2586 static int mv88e6xxx_port_broadcast_sync(struct mv88e6xxx_chip *chip, int port,
2587 bool flood)
2588 {
2589 struct mv88e6xxx_port_broadcast_sync_ctx ctx = {
2590 .port = port,
2591 .flood = flood,
2592 };
2593 struct mv88e6xxx_vtu_entry vid0 = {
2594 .vid = 0,
2595 };
2596 int err;
2597
2598 /* Update the port's private database... */
2599 err = mv88e6xxx_port_broadcast_sync_vlan(chip, &vid0, &ctx);
2600 if (err)
2601 return err;
2602
2603 /* ...and the database for all VLANs. */
2604 return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_broadcast_sync_vlan,
2605 &ctx);
2606 }
2607
mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip * chip,int port,u16 vid,u8 member,bool warn)2608 static int mv88e6xxx_port_vlan_join(struct mv88e6xxx_chip *chip, int port,
2609 u16 vid, u8 member, bool warn)
2610 {
2611 const u8 non_member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
2612 struct mv88e6xxx_vtu_entry vlan;
2613 int i, err;
2614
2615 err = mv88e6xxx_vtu_get(chip, vid, &vlan);
2616 if (err)
2617 return err;
2618
2619 if (!vlan.valid) {
2620 memset(&vlan, 0, sizeof(vlan));
2621
2622 if (vid == MV88E6XXX_VID_STANDALONE)
2623 vlan.policy = true;
2624
2625 err = mv88e6xxx_atu_new(chip, &vlan.fid);
2626 if (err)
2627 return err;
2628
2629 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
2630 if (i == port)
2631 vlan.member[i] = member;
2632 else
2633 vlan.member[i] = non_member;
2634
2635 vlan.vid = vid;
2636 vlan.valid = true;
2637
2638 err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
2639 if (err)
2640 return err;
2641
2642 err = mv88e6xxx_broadcast_setup(chip, vlan.vid);
2643 if (err)
2644 return err;
2645 } else if (vlan.member[port] != member) {
2646 vlan.member[port] = member;
2647
2648 err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
2649 if (err)
2650 return err;
2651 } else if (warn) {
2652 dev_info(chip->dev, "p%d: already a member of VLAN %d\n",
2653 port, vid);
2654 }
2655
2656 /* Record FID used in SW FID map */
2657 bitmap_set(chip->fid_bitmap, vlan.fid, 1);
2658
2659 return 0;
2660 }
2661
mv88e6xxx_port_vlan_add(struct dsa_switch * ds,int port,const struct switchdev_obj_port_vlan * vlan,struct netlink_ext_ack * extack)2662 static int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
2663 const struct switchdev_obj_port_vlan *vlan,
2664 struct netlink_ext_ack *extack)
2665 {
2666 struct mv88e6xxx_chip *chip = ds->priv;
2667 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
2668 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
2669 struct mv88e6xxx_port *p = &chip->ports[port];
2670 bool warn;
2671 u8 member;
2672 int err;
2673
2674 if (!vlan->vid)
2675 return 0;
2676
2677 err = mv88e6xxx_port_vlan_prepare(ds, port, vlan);
2678 if (err)
2679 return err;
2680
2681 if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
2682 member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED;
2683 else if (untagged)
2684 member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNTAGGED;
2685 else
2686 member = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_TAGGED;
2687
2688 /* net/dsa/user.c will call dsa_port_vlan_add() for the affected port
2689 * and then the CPU port. Do not warn for duplicates for the CPU port.
2690 */
2691 warn = !dsa_is_cpu_port(ds, port) && !dsa_is_dsa_port(ds, port);
2692
2693 mv88e6xxx_reg_lock(chip);
2694
2695 err = mv88e6xxx_port_vlan_join(chip, port, vlan->vid, member, warn);
2696 if (err) {
2697 dev_err(ds->dev, "p%d: failed to add VLAN %d%c\n", port,
2698 vlan->vid, untagged ? 'u' : 't');
2699 goto out;
2700 }
2701
2702 if (pvid) {
2703 p->bridge_pvid.vid = vlan->vid;
2704 p->bridge_pvid.valid = true;
2705
2706 err = mv88e6xxx_port_commit_pvid(chip, port);
2707 if (err)
2708 goto out;
2709 } else if (vlan->vid && p->bridge_pvid.vid == vlan->vid) {
2710 /* The old pvid was reinstalled as a non-pvid VLAN */
2711 p->bridge_pvid.valid = false;
2712
2713 err = mv88e6xxx_port_commit_pvid(chip, port);
2714 if (err)
2715 goto out;
2716 }
2717
2718 out:
2719 mv88e6xxx_reg_unlock(chip);
2720
2721 return err;
2722 }
2723
mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip * chip,int port,u16 vid)2724 static int mv88e6xxx_port_vlan_leave(struct mv88e6xxx_chip *chip,
2725 int port, u16 vid)
2726 {
2727 struct mv88e6xxx_vtu_entry vlan;
2728 int i, err;
2729
2730 if (!vid)
2731 return 0;
2732
2733 err = mv88e6xxx_vtu_get(chip, vid, &vlan);
2734 if (err)
2735 return err;
2736
2737 /* If the VLAN doesn't exist in hardware or the port isn't a member,
2738 * tell switchdev that this VLAN is likely handled in software.
2739 */
2740 if (!vlan.valid ||
2741 vlan.member[port] == MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER)
2742 return -EOPNOTSUPP;
2743
2744 vlan.member[port] = MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER;
2745
2746 /* keep the VLAN unless all ports are excluded */
2747 vlan.valid = false;
2748 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
2749 if (vlan.member[i] !=
2750 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
2751 vlan.valid = true;
2752 break;
2753 }
2754 }
2755
2756 err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
2757 if (err)
2758 return err;
2759
2760 if (!vlan.valid) {
2761 err = mv88e6xxx_mst_put(chip, vlan.sid);
2762 if (err)
2763 return err;
2764
2765 /* Record FID freed in SW FID map */
2766 bitmap_clear(chip->fid_bitmap, vlan.fid, 1);
2767 }
2768
2769 return mv88e6xxx_g1_atu_remove(chip, vlan.fid, port, false);
2770 }
2771
mv88e6xxx_port_vlan_del(struct dsa_switch * ds,int port,const struct switchdev_obj_port_vlan * vlan)2772 static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
2773 const struct switchdev_obj_port_vlan *vlan)
2774 {
2775 struct mv88e6xxx_chip *chip = ds->priv;
2776 struct mv88e6xxx_port *p = &chip->ports[port];
2777 int err = 0;
2778 u16 pvid;
2779
2780 if (!mv88e6xxx_max_vid(chip))
2781 return -EOPNOTSUPP;
2782
2783 /* The ATU removal procedure needs the FID to be mapped in the VTU,
2784 * but FDB deletion runs concurrently with VLAN deletion. Flush the DSA
2785 * switchdev workqueue to ensure that all FDB entries are deleted
2786 * before we remove the VLAN.
2787 */
2788 dsa_flush_workqueue();
2789
2790 mv88e6xxx_reg_lock(chip);
2791
2792 err = mv88e6xxx_port_get_pvid(chip, port, &pvid);
2793 if (err)
2794 goto unlock;
2795
2796 err = mv88e6xxx_port_vlan_leave(chip, port, vlan->vid);
2797 if (err)
2798 goto unlock;
2799
2800 if (vlan->vid == pvid) {
2801 p->bridge_pvid.valid = false;
2802
2803 err = mv88e6xxx_port_commit_pvid(chip, port);
2804 if (err)
2805 goto unlock;
2806 }
2807
2808 unlock:
2809 mv88e6xxx_reg_unlock(chip);
2810
2811 return err;
2812 }
2813
mv88e6xxx_port_vlan_fast_age(struct dsa_switch * ds,int port,u16 vid)2814 static int mv88e6xxx_port_vlan_fast_age(struct dsa_switch *ds, int port, u16 vid)
2815 {
2816 struct mv88e6xxx_chip *chip = ds->priv;
2817 struct mv88e6xxx_vtu_entry vlan;
2818 int err;
2819
2820 mv88e6xxx_reg_lock(chip);
2821
2822 err = mv88e6xxx_vtu_get(chip, vid, &vlan);
2823 if (err)
2824 goto unlock;
2825
2826 err = mv88e6xxx_port_fast_age_fid(chip, port, vlan.fid);
2827
2828 unlock:
2829 mv88e6xxx_reg_unlock(chip);
2830
2831 return err;
2832 }
2833
mv88e6xxx_vlan_msti_set(struct dsa_switch * ds,struct dsa_bridge bridge,const struct switchdev_vlan_msti * msti)2834 static int mv88e6xxx_vlan_msti_set(struct dsa_switch *ds,
2835 struct dsa_bridge bridge,
2836 const struct switchdev_vlan_msti *msti)
2837 {
2838 struct mv88e6xxx_chip *chip = ds->priv;
2839 struct mv88e6xxx_vtu_entry vlan;
2840 u8 old_sid, new_sid;
2841 int err;
2842
2843 if (!mv88e6xxx_has_stu(chip))
2844 return -EOPNOTSUPP;
2845
2846 mv88e6xxx_reg_lock(chip);
2847
2848 err = mv88e6xxx_vtu_get(chip, msti->vid, &vlan);
2849 if (err)
2850 goto unlock;
2851
2852 if (!vlan.valid) {
2853 err = -EINVAL;
2854 goto unlock;
2855 }
2856
2857 old_sid = vlan.sid;
2858
2859 err = mv88e6xxx_mst_get(chip, bridge.dev, msti->msti, &new_sid);
2860 if (err)
2861 goto unlock;
2862
2863 if (new_sid != old_sid) {
2864 vlan.sid = new_sid;
2865
2866 err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
2867 if (err) {
2868 mv88e6xxx_mst_put(chip, new_sid);
2869 goto unlock;
2870 }
2871 }
2872
2873 err = mv88e6xxx_mst_put(chip, old_sid);
2874
2875 unlock:
2876 mv88e6xxx_reg_unlock(chip);
2877 return err;
2878 }
2879
mv88e6xxx_port_fdb_add(struct dsa_switch * ds,int port,const unsigned char * addr,u16 vid,struct dsa_db db)2880 static int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
2881 const unsigned char *addr, u16 vid,
2882 struct dsa_db db)
2883 {
2884 struct mv88e6xxx_chip *chip = ds->priv;
2885 int err;
2886
2887 mv88e6xxx_reg_lock(chip);
2888 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
2889 MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
2890 if (err)
2891 goto out;
2892
2893 if (!mv88e6xxx_port_db_find(chip, addr, vid))
2894 err = -ENOSPC;
2895
2896 out:
2897 mv88e6xxx_reg_unlock(chip);
2898
2899 return err;
2900 }
2901
mv88e6xxx_port_fdb_del(struct dsa_switch * ds,int port,const unsigned char * addr,u16 vid,struct dsa_db db)2902 static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
2903 const unsigned char *addr, u16 vid,
2904 struct dsa_db db)
2905 {
2906 struct mv88e6xxx_chip *chip = ds->priv;
2907 int err;
2908
2909 mv88e6xxx_reg_lock(chip);
2910 err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 0);
2911 mv88e6xxx_reg_unlock(chip);
2912
2913 return err;
2914 }
2915
mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip * chip,u16 fid,u16 vid,int port,dsa_fdb_dump_cb_t * cb,void * data)2916 static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
2917 u16 fid, u16 vid, int port,
2918 dsa_fdb_dump_cb_t *cb, void *data)
2919 {
2920 struct mv88e6xxx_atu_entry addr;
2921 bool is_static;
2922 int err;
2923
2924 addr.state = 0;
2925 eth_broadcast_addr(addr.mac);
2926
2927 do {
2928 err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
2929 if (err)
2930 return err;
2931
2932 if (!addr.state)
2933 break;
2934
2935 if (addr.trunk || (addr.portvec & BIT(port)) == 0)
2936 continue;
2937
2938 if (!is_unicast_ether_addr(addr.mac))
2939 continue;
2940
2941 is_static = (addr.state ==
2942 MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
2943 err = cb(addr.mac, vid, is_static, data);
2944 if (err)
2945 return err;
2946 } while (!is_broadcast_ether_addr(addr.mac));
2947
2948 return err;
2949 }
2950
2951 struct mv88e6xxx_port_db_dump_vlan_ctx {
2952 int port;
2953 dsa_fdb_dump_cb_t *cb;
2954 void *data;
2955 };
2956
mv88e6xxx_port_db_dump_vlan(struct mv88e6xxx_chip * chip,const struct mv88e6xxx_vtu_entry * entry,void * _data)2957 static int mv88e6xxx_port_db_dump_vlan(struct mv88e6xxx_chip *chip,
2958 const struct mv88e6xxx_vtu_entry *entry,
2959 void *_data)
2960 {
2961 struct mv88e6xxx_port_db_dump_vlan_ctx *ctx = _data;
2962
2963 return mv88e6xxx_port_db_dump_fid(chip, entry->fid, entry->vid,
2964 ctx->port, ctx->cb, ctx->data);
2965 }
2966
mv88e6xxx_port_db_dump(struct mv88e6xxx_chip * chip,int port,dsa_fdb_dump_cb_t * cb,void * data)2967 static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
2968 dsa_fdb_dump_cb_t *cb, void *data)
2969 {
2970 struct mv88e6xxx_port_db_dump_vlan_ctx ctx = {
2971 .port = port,
2972 .cb = cb,
2973 .data = data,
2974 };
2975 u16 fid;
2976 int err;
2977
2978 /* Dump port's default Filtering Information Database (VLAN ID 0) */
2979 err = mv88e6xxx_port_get_fid(chip, port, &fid);
2980 if (err)
2981 return err;
2982
2983 err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data);
2984 if (err)
2985 return err;
2986
2987 return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_db_dump_vlan, &ctx);
2988 }
2989
mv88e6xxx_port_fdb_dump(struct dsa_switch * ds,int port,dsa_fdb_dump_cb_t * cb,void * data)2990 static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
2991 dsa_fdb_dump_cb_t *cb, void *data)
2992 {
2993 struct mv88e6xxx_chip *chip = ds->priv;
2994 int err;
2995
2996 mv88e6xxx_reg_lock(chip);
2997 err = mv88e6xxx_port_db_dump(chip, port, cb, data);
2998 mv88e6xxx_reg_unlock(chip);
2999
3000 return err;
3001 }
3002
mv88e6xxx_bridge_map(struct mv88e6xxx_chip * chip,struct dsa_bridge bridge)3003 static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
3004 struct dsa_bridge bridge)
3005 {
3006 struct dsa_switch *ds = chip->ds;
3007 struct dsa_switch_tree *dst = ds->dst;
3008 struct dsa_port *dp;
3009 int err;
3010
3011 list_for_each_entry(dp, &dst->ports, list) {
3012 if (dsa_port_offloads_bridge(dp, &bridge)) {
3013 if (dp->ds == ds) {
3014 /* This is a local bridge group member,
3015 * remap its Port VLAN Map.
3016 */
3017 err = mv88e6xxx_port_vlan_map(chip, dp->index);
3018 if (err)
3019 return err;
3020 } else {
3021 /* This is an external bridge group member,
3022 * remap its cross-chip Port VLAN Table entry.
3023 */
3024 err = mv88e6xxx_pvt_map(chip, dp->ds->index,
3025 dp->index);
3026 if (err)
3027 return err;
3028 }
3029 }
3030 }
3031
3032 return 0;
3033 }
3034
3035 /* Treat the software bridge as a virtual single-port switch behind the
3036 * CPU and map in the PVT. First dst->last_switch elements are taken by
3037 * physical switches, so start from beyond that range.
3038 */
mv88e6xxx_map_virtual_bridge_to_pvt(struct dsa_switch * ds,unsigned int bridge_num)3039 static int mv88e6xxx_map_virtual_bridge_to_pvt(struct dsa_switch *ds,
3040 unsigned int bridge_num)
3041 {
3042 u8 dev = bridge_num + ds->dst->last_switch;
3043 struct mv88e6xxx_chip *chip = ds->priv;
3044
3045 return mv88e6xxx_pvt_map(chip, dev, 0);
3046 }
3047
mv88e6xxx_port_bridge_join(struct dsa_switch * ds,int port,struct dsa_bridge bridge,bool * tx_fwd_offload,struct netlink_ext_ack * extack)3048 static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
3049 struct dsa_bridge bridge,
3050 bool *tx_fwd_offload,
3051 struct netlink_ext_ack *extack)
3052 {
3053 struct mv88e6xxx_chip *chip = ds->priv;
3054 int err;
3055
3056 mv88e6xxx_reg_lock(chip);
3057
3058 err = mv88e6xxx_bridge_map(chip, bridge);
3059 if (err)
3060 goto unlock;
3061
3062 err = mv88e6xxx_port_set_map_da(chip, port, true);
3063 if (err)
3064 goto unlock;
3065
3066 err = mv88e6xxx_port_commit_pvid(chip, port);
3067 if (err)
3068 goto unlock;
3069
3070 if (mv88e6xxx_has_pvt(chip)) {
3071 err = mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num);
3072 if (err)
3073 goto unlock;
3074
3075 *tx_fwd_offload = true;
3076 }
3077
3078 unlock:
3079 mv88e6xxx_reg_unlock(chip);
3080
3081 return err;
3082 }
3083
mv88e6xxx_port_bridge_leave(struct dsa_switch * ds,int port,struct dsa_bridge bridge)3084 static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port,
3085 struct dsa_bridge bridge)
3086 {
3087 struct mv88e6xxx_chip *chip = ds->priv;
3088 int err;
3089
3090 mv88e6xxx_reg_lock(chip);
3091
3092 if (bridge.tx_fwd_offload &&
3093 mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num))
3094 dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n");
3095
3096 if (mv88e6xxx_bridge_map(chip, bridge) ||
3097 mv88e6xxx_port_vlan_map(chip, port))
3098 dev_err(ds->dev, "failed to remap in-chip Port VLAN\n");
3099
3100 err = mv88e6xxx_port_set_map_da(chip, port, false);
3101 if (err)
3102 dev_err(ds->dev,
3103 "port %d failed to restore map-DA: %pe\n",
3104 port, ERR_PTR(err));
3105
3106 err = mv88e6xxx_port_commit_pvid(chip, port);
3107 if (err)
3108 dev_err(ds->dev,
3109 "port %d failed to restore standalone pvid: %pe\n",
3110 port, ERR_PTR(err));
3111
3112 mv88e6xxx_reg_unlock(chip);
3113 }
3114
mv88e6xxx_crosschip_bridge_join(struct dsa_switch * ds,int tree_index,int sw_index,int port,struct dsa_bridge bridge,struct netlink_ext_ack * extack)3115 static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds,
3116 int tree_index, int sw_index,
3117 int port, struct dsa_bridge bridge,
3118 struct netlink_ext_ack *extack)
3119 {
3120 struct mv88e6xxx_chip *chip = ds->priv;
3121 int err;
3122
3123 if (tree_index != ds->dst->index)
3124 return 0;
3125
3126 mv88e6xxx_reg_lock(chip);
3127 err = mv88e6xxx_pvt_map(chip, sw_index, port);
3128 err = err ? : mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num);
3129 mv88e6xxx_reg_unlock(chip);
3130
3131 return err;
3132 }
3133
mv88e6xxx_crosschip_bridge_leave(struct dsa_switch * ds,int tree_index,int sw_index,int port,struct dsa_bridge bridge)3134 static void mv88e6xxx_crosschip_bridge_leave(struct dsa_switch *ds,
3135 int tree_index, int sw_index,
3136 int port, struct dsa_bridge bridge)
3137 {
3138 struct mv88e6xxx_chip *chip = ds->priv;
3139
3140 if (tree_index != ds->dst->index)
3141 return;
3142
3143 mv88e6xxx_reg_lock(chip);
3144 if (mv88e6xxx_pvt_map(chip, sw_index, port) ||
3145 mv88e6xxx_map_virtual_bridge_to_pvt(ds, bridge.num))
3146 dev_err(ds->dev, "failed to remap cross-chip Port VLAN\n");
3147 mv88e6xxx_reg_unlock(chip);
3148 }
3149
mv88e6xxx_software_reset(struct mv88e6xxx_chip * chip)3150 static int mv88e6xxx_software_reset(struct mv88e6xxx_chip *chip)
3151 {
3152 if (chip->info->ops->reset)
3153 return chip->info->ops->reset(chip);
3154
3155 return 0;
3156 }
3157
mv88e6xxx_hardware_reset(struct mv88e6xxx_chip * chip)3158 static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
3159 {
3160 struct gpio_desc *gpiod = chip->reset;
3161 int err;
3162
3163 /* If there is a GPIO connected to the reset pin, toggle it */
3164 if (gpiod) {
3165 /* If the switch has just been reset and not yet completed
3166 * loading EEPROM, the reset may interrupt the I2C transaction
3167 * mid-byte, causing the first EEPROM read after the reset
3168 * from the wrong location resulting in the switch booting
3169 * to wrong mode and inoperable.
3170 * For this reason, switch families with EEPROM support
3171 * generally wait for EEPROM loads to complete as their pre-
3172 * and post-reset handlers.
3173 */
3174 if (chip->info->ops->hardware_reset_pre) {
3175 err = chip->info->ops->hardware_reset_pre(chip);
3176 if (err)
3177 dev_err(chip->dev, "pre-reset error: %d\n", err);
3178 }
3179
3180 gpiod_set_value_cansleep(gpiod, 1);
3181 usleep_range(10000, 20000);
3182 gpiod_set_value_cansleep(gpiod, 0);
3183 usleep_range(10000, 20000);
3184
3185 if (chip->info->ops->hardware_reset_post) {
3186 err = chip->info->ops->hardware_reset_post(chip);
3187 if (err)
3188 dev_err(chip->dev, "post-reset error: %d\n", err);
3189 }
3190 }
3191 }
3192
mv88e6xxx_disable_ports(struct mv88e6xxx_chip * chip)3193 static int mv88e6xxx_disable_ports(struct mv88e6xxx_chip *chip)
3194 {
3195 int i, err;
3196
3197 /* Set all ports to the Disabled state */
3198 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
3199 err = mv88e6xxx_port_set_state(chip, i, BR_STATE_DISABLED);
3200 if (err)
3201 return err;
3202 }
3203
3204 /* Wait for transmit queues to drain,
3205 * i.e. 2ms for a maximum frame to be transmitted at 10 Mbps.
3206 */
3207 usleep_range(2000, 4000);
3208
3209 return 0;
3210 }
3211
mv88e6xxx_switch_reset(struct mv88e6xxx_chip * chip)3212 static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
3213 {
3214 int err;
3215
3216 err = mv88e6xxx_disable_ports(chip);
3217 if (err)
3218 return err;
3219
3220 mv88e6xxx_hardware_reset(chip);
3221
3222 return mv88e6xxx_software_reset(chip);
3223 }
3224
mv88e6xxx_set_port_mode(struct mv88e6xxx_chip * chip,int port,enum mv88e6xxx_frame_mode frame,enum mv88e6xxx_egress_mode egress,u16 etype)3225 static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port,
3226 enum mv88e6xxx_frame_mode frame,
3227 enum mv88e6xxx_egress_mode egress, u16 etype)
3228 {
3229 int err;
3230
3231 if (!chip->info->ops->port_set_frame_mode)
3232 return -EOPNOTSUPP;
3233
3234 err = mv88e6xxx_port_set_egress_mode(chip, port, egress);
3235 if (err)
3236 return err;
3237
3238 err = chip->info->ops->port_set_frame_mode(chip, port, frame);
3239 if (err)
3240 return err;
3241
3242 if (chip->info->ops->port_set_ether_type)
3243 return chip->info->ops->port_set_ether_type(chip, port, etype);
3244
3245 return 0;
3246 }
3247
mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip * chip,int port)3248 static int mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip *chip, int port)
3249 {
3250 return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_NORMAL,
3251 MV88E6XXX_EGRESS_MODE_UNMODIFIED,
3252 MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
3253 }
3254
mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip * chip,int port)3255 static int mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip *chip, int port)
3256 {
3257 return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_DSA,
3258 MV88E6XXX_EGRESS_MODE_UNMODIFIED,
3259 MV88E6XXX_PORT_ETH_TYPE_DEFAULT);
3260 }
3261
mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip * chip,int port)3262 static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port)
3263 {
3264 return mv88e6xxx_set_port_mode(chip, port,
3265 MV88E6XXX_FRAME_MODE_ETHERTYPE,
3266 MV88E6XXX_EGRESS_MODE_ETHERTYPE,
3267 ETH_P_EDSA);
3268 }
3269
mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip * chip,int port)3270 static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
3271 {
3272 if (dsa_is_dsa_port(chip->ds, port))
3273 return mv88e6xxx_set_port_mode_dsa(chip, port);
3274
3275 if (dsa_is_user_port(chip->ds, port))
3276 return mv88e6xxx_set_port_mode_normal(chip, port);
3277
3278 /* Setup CPU port mode depending on its supported tag format */
3279 if (chip->tag_protocol == DSA_TAG_PROTO_DSA)
3280 return mv88e6xxx_set_port_mode_dsa(chip, port);
3281
3282 if (chip->tag_protocol == DSA_TAG_PROTO_EDSA)
3283 return mv88e6xxx_set_port_mode_edsa(chip, port);
3284
3285 return -EINVAL;
3286 }
3287
mv88e6xxx_setup_message_port(struct mv88e6xxx_chip * chip,int port)3288 static int mv88e6xxx_setup_message_port(struct mv88e6xxx_chip *chip, int port)
3289 {
3290 bool message = dsa_is_dsa_port(chip->ds, port);
3291
3292 return mv88e6xxx_port_set_message_port(chip, port, message);
3293 }
3294
mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip * chip,int port)3295 static int mv88e6xxx_setup_egress_floods(struct mv88e6xxx_chip *chip, int port)
3296 {
3297 int err;
3298
3299 if (chip->info->ops->port_set_ucast_flood) {
3300 err = chip->info->ops->port_set_ucast_flood(chip, port, true);
3301 if (err)
3302 return err;
3303 }
3304 if (chip->info->ops->port_set_mcast_flood) {
3305 err = chip->info->ops->port_set_mcast_flood(chip, port, true);
3306 if (err)
3307 return err;
3308 }
3309
3310 return 0;
3311 }
3312
mv88e6xxx_set_egress_port(struct mv88e6xxx_chip * chip,enum mv88e6xxx_egress_direction direction,int port)3313 static int mv88e6xxx_set_egress_port(struct mv88e6xxx_chip *chip,
3314 enum mv88e6xxx_egress_direction direction,
3315 int port)
3316 {
3317 int err;
3318
3319 if (!chip->info->ops->set_egress_port)
3320 return -EOPNOTSUPP;
3321
3322 err = chip->info->ops->set_egress_port(chip, direction, port);
3323 if (err)
3324 return err;
3325
3326 if (direction == MV88E6XXX_EGRESS_DIR_INGRESS)
3327 chip->ingress_dest_port = port;
3328 else
3329 chip->egress_dest_port = port;
3330
3331 return 0;
3332 }
3333
mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip * chip,int port)3334 static int mv88e6xxx_setup_upstream_port(struct mv88e6xxx_chip *chip, int port)
3335 {
3336 struct dsa_switch *ds = chip->ds;
3337 int upstream_port;
3338 int err;
3339
3340 upstream_port = dsa_upstream_port(ds, port);
3341 if (chip->info->ops->port_set_upstream_port) {
3342 err = chip->info->ops->port_set_upstream_port(chip, port,
3343 upstream_port);
3344 if (err)
3345 return err;
3346 }
3347
3348 if (port == upstream_port) {
3349 if (chip->info->ops->set_cpu_port) {
3350 err = chip->info->ops->set_cpu_port(chip,
3351 upstream_port);
3352 if (err)
3353 return err;
3354 }
3355
3356 err = mv88e6xxx_set_egress_port(chip,
3357 MV88E6XXX_EGRESS_DIR_INGRESS,
3358 upstream_port);
3359 if (err && err != -EOPNOTSUPP)
3360 return err;
3361
3362 err = mv88e6xxx_set_egress_port(chip,
3363 MV88E6XXX_EGRESS_DIR_EGRESS,
3364 upstream_port);
3365 if (err && err != -EOPNOTSUPP)
3366 return err;
3367 }
3368
3369 return 0;
3370 }
3371
mv88e6xxx_setup_port(struct mv88e6xxx_chip * chip,int port)3372 static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
3373 {
3374 struct fwnode_handle *ports_fwnode;
3375 struct fwnode_handle *port_fwnode;
3376 struct dsa_switch *ds = chip->ds;
3377 struct mv88e6xxx_port *p;
3378 int err;
3379 u16 reg;
3380 u32 val;
3381
3382 p = &chip->ports[port];
3383 p->chip = chip;
3384 p->port = port;
3385
3386 /* Look up corresponding fwnode if any */
3387 ports_fwnode = device_get_named_child_node(chip->dev, "ethernet-ports");
3388 if (!ports_fwnode)
3389 ports_fwnode = device_get_named_child_node(chip->dev, "ports");
3390 if (ports_fwnode) {
3391 fwnode_for_each_child_node(ports_fwnode, port_fwnode) {
3392 if (fwnode_property_read_u32(port_fwnode, "reg", &val))
3393 continue;
3394 if (val == port) {
3395 p->fwnode = port_fwnode;
3396 p->fiber = fwnode_property_present(port_fwnode, "sfp");
3397 break;
3398 }
3399 }
3400 fwnode_handle_put(ports_fwnode);
3401 } else {
3402 dev_dbg(chip->dev, "no ethernet ports node defined for the device\n");
3403 }
3404
3405 if (chip->info->ops->port_setup_leds) {
3406 err = chip->info->ops->port_setup_leds(chip, port);
3407 if (err && err != -EOPNOTSUPP)
3408 return err;
3409 }
3410
3411 err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
3412 SPEED_UNFORCED, DUPLEX_UNFORCED,
3413 PAUSE_ON, PHY_INTERFACE_MODE_NA);
3414 if (err)
3415 return err;
3416
3417 /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
3418 * disable Header mode, enable IGMP/MLD snooping, disable VLAN
3419 * tunneling, determine priority by looking at 802.1p and IP
3420 * priority fields (IP prio has precedence), and set STP state
3421 * to Forwarding.
3422 *
3423 * If this is the CPU link, use DSA or EDSA tagging depending
3424 * on which tagging mode was configured.
3425 *
3426 * If this is a link to another switch, use DSA tagging mode.
3427 *
3428 * If this is the upstream port for this switch, enable
3429 * forwarding of unknown unicasts and multicasts.
3430 */
3431 reg = MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP |
3432 MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
3433 /* Forward any IPv4 IGMP or IPv6 MLD frames received
3434 * by a USER port to the CPU port to allow snooping.
3435 */
3436 if (dsa_is_user_port(ds, port))
3437 reg |= MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP;
3438
3439 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
3440 if (err)
3441 return err;
3442
3443 err = mv88e6xxx_setup_port_mode(chip, port);
3444 if (err)
3445 return err;
3446
3447 err = mv88e6xxx_setup_egress_floods(chip, port);
3448 if (err)
3449 return err;
3450
3451 /* Port Control 2: don't force a good FCS, set the MTU size to
3452 * 10222 bytes, disable 802.1q tags checking, don't discard
3453 * tagged or untagged frames on this port, skip destination
3454 * address lookup on user ports, disable ARP mirroring and don't
3455 * send a copy of all transmitted/received frames on this port
3456 * to the CPU.
3457 */
3458 err = mv88e6xxx_port_set_map_da(chip, port, !dsa_is_user_port(ds, port));
3459 if (err)
3460 return err;
3461
3462 err = mv88e6xxx_setup_upstream_port(chip, port);
3463 if (err)
3464 return err;
3465
3466 /* On chips that support it, set all downstream DSA ports'
3467 * VLAN policy to TRAP. In combination with loading
3468 * MV88E6XXX_VID_STANDALONE as a policy entry in the VTU, this
3469 * provides a better isolation barrier between standalone
3470 * ports, as the ATU is bypassed on any intermediate switches
3471 * between the incoming port and the CPU.
3472 */
3473 if (dsa_is_downstream_port(ds, port) &&
3474 chip->info->ops->port_set_policy) {
3475 err = chip->info->ops->port_set_policy(chip, port,
3476 MV88E6XXX_POLICY_MAPPING_VTU,
3477 MV88E6XXX_POLICY_ACTION_TRAP);
3478 if (err)
3479 return err;
3480 }
3481
3482 /* User ports start out in standalone mode and 802.1Q is
3483 * therefore disabled. On DSA ports, all valid VIDs are always
3484 * loaded in the VTU - therefore, enable 802.1Q in order to take
3485 * advantage of VLAN policy on chips that supports it.
3486 */
3487 err = mv88e6xxx_port_set_8021q_mode(chip, port,
3488 dsa_is_user_port(ds, port) ?
3489 MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED :
3490 MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE);
3491 if (err)
3492 return err;
3493
3494 /* Bind MV88E6XXX_VID_STANDALONE to MV88E6XXX_FID_STANDALONE by
3495 * virtue of the fact that mv88e6xxx_atu_new() will pick it as
3496 * the first free FID. This will be used as the private PVID for
3497 * unbridged ports. Shared (DSA and CPU) ports must also be
3498 * members of this VID, in order to trap all frames assigned to
3499 * it to the CPU.
3500 */
3501 err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_STANDALONE,
3502 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED,
3503 false);
3504 if (err)
3505 return err;
3506
3507 /* Associate MV88E6XXX_VID_BRIDGED with MV88E6XXX_FID_BRIDGED in the
3508 * ATU by virtue of the fact that mv88e6xxx_atu_new() will pick it as
3509 * the first free FID after MV88E6XXX_FID_STANDALONE. This will be used
3510 * as the private PVID on ports under a VLAN-unaware bridge.
3511 * Shared (DSA and CPU) ports must also be members of it, to translate
3512 * the VID from the DSA tag into MV88E6XXX_FID_BRIDGED, instead of
3513 * relying on their port default FID.
3514 */
3515 err = mv88e6xxx_port_vlan_join(chip, port, MV88E6XXX_VID_BRIDGED,
3516 MV88E6XXX_G1_VTU_DATA_MEMBER_TAG_UNMODIFIED,
3517 false);
3518 if (err)
3519 return err;
3520
3521 if (chip->info->ops->port_set_jumbo_size) {
3522 err = chip->info->ops->port_set_jumbo_size(chip, port, 10218);
3523 if (err)
3524 return err;
3525 }
3526
3527 /* Port Association Vector: disable automatic address learning
3528 * on all user ports since they start out in standalone
3529 * mode. When joining a bridge, learning will be configured to
3530 * match the bridge port settings. Enable learning on all
3531 * DSA/CPU ports. NOTE: FROM_CPU frames always bypass the
3532 * learning process.
3533 *
3534 * Disable HoldAt1, IntOnAgeOut, LockedPort, IgnoreWrongData,
3535 * and RefreshLocked. I.e. setup standard automatic learning.
3536 */
3537 if (dsa_is_user_port(ds, port))
3538 reg = 0;
3539 else
3540 reg = 1 << port;
3541
3542 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
3543 reg);
3544 if (err)
3545 return err;
3546
3547 /* Egress rate control 2: disable egress rate control. */
3548 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL2,
3549 0x0000);
3550 if (err)
3551 return err;
3552
3553 if (chip->info->ops->port_pause_limit) {
3554 err = chip->info->ops->port_pause_limit(chip, port, 0, 0);
3555 if (err)
3556 return err;
3557 }
3558
3559 if (chip->info->ops->port_disable_learn_limit) {
3560 err = chip->info->ops->port_disable_learn_limit(chip, port);
3561 if (err)
3562 return err;
3563 }
3564
3565 if (chip->info->ops->port_disable_pri_override) {
3566 err = chip->info->ops->port_disable_pri_override(chip, port);
3567 if (err)
3568 return err;
3569 }
3570 if (chip->info->ops->port_enable_tcam) {
3571 err = chip->info->ops->port_enable_tcam(chip, port);
3572 if (err)
3573 return err;
3574 }
3575
3576 if (chip->info->ops->port_tag_remap) {
3577 err = chip->info->ops->port_tag_remap(chip, port);
3578 if (err)
3579 return err;
3580 }
3581
3582 if (chip->info->ops->port_egress_rate_limiting) {
3583 err = chip->info->ops->port_egress_rate_limiting(chip, port);
3584 if (err)
3585 return err;
3586 }
3587
3588 if (chip->info->ops->port_setup_message_port) {
3589 err = chip->info->ops->port_setup_message_port(chip, port);
3590 if (err)
3591 return err;
3592 }
3593
3594 /* Port based VLAN map: give each port the same default address
3595 * database, and allow bidirectional communication between the
3596 * CPU and DSA port(s), and the other ports.
3597 */
3598 err = mv88e6xxx_port_set_fid(chip, port, MV88E6XXX_FID_STANDALONE);
3599 if (err)
3600 return err;
3601
3602 err = mv88e6xxx_port_vlan_map(chip, port);
3603 if (err)
3604 return err;
3605
3606 /* Default VLAN ID and priority: don't set a default VLAN
3607 * ID, and set the default packet priority to zero.
3608 */
3609 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN, 0);
3610 }
3611
mv88e6xxx_get_max_mtu(struct dsa_switch * ds,int port)3612 static int mv88e6xxx_get_max_mtu(struct dsa_switch *ds, int port)
3613 {
3614 struct mv88e6xxx_chip *chip = ds->priv;
3615
3616 if (chip->info->ops->port_set_jumbo_size)
3617 return 10240 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
3618 else if (chip->info->ops->set_max_frame_size)
3619 return 1632 - VLAN_ETH_HLEN - EDSA_HLEN - ETH_FCS_LEN;
3620 return ETH_DATA_LEN;
3621 }
3622
mv88e6xxx_change_mtu(struct dsa_switch * ds,int port,int new_mtu)3623 static int mv88e6xxx_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
3624 {
3625 struct mv88e6xxx_chip *chip = ds->priv;
3626 int ret = 0;
3627
3628 /* For families where we don't know how to alter the MTU,
3629 * just accept any value up to ETH_DATA_LEN
3630 */
3631 if (!chip->info->ops->port_set_jumbo_size &&
3632 !chip->info->ops->set_max_frame_size) {
3633 if (new_mtu > ETH_DATA_LEN)
3634 return -EINVAL;
3635
3636 return 0;
3637 }
3638
3639 if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
3640 new_mtu += EDSA_HLEN;
3641
3642 mv88e6xxx_reg_lock(chip);
3643 if (chip->info->ops->port_set_jumbo_size)
3644 ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
3645 else if (chip->info->ops->set_max_frame_size &&
3646 dsa_is_cpu_port(ds, port))
3647 ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
3648 mv88e6xxx_reg_unlock(chip);
3649
3650 return ret;
3651 }
3652
mv88e6xxx_set_ageing_time(struct dsa_switch * ds,unsigned int ageing_time)3653 static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
3654 unsigned int ageing_time)
3655 {
3656 struct mv88e6xxx_chip *chip = ds->priv;
3657 int err;
3658
3659 mv88e6xxx_reg_lock(chip);
3660 err = mv88e6xxx_g1_atu_set_age_time(chip, ageing_time);
3661 mv88e6xxx_reg_unlock(chip);
3662
3663 return err;
3664 }
3665
mv88e6xxx_stats_setup(struct mv88e6xxx_chip * chip)3666 static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip)
3667 {
3668 int err;
3669
3670 /* Initialize the statistics unit */
3671 if (chip->info->ops->stats_set_histogram) {
3672 err = chip->info->ops->stats_set_histogram(chip);
3673 if (err)
3674 return err;
3675 }
3676
3677 return mv88e6xxx_g1_stats_clear(chip);
3678 }
3679
mv88e6320_setup_errata(struct mv88e6xxx_chip * chip)3680 static int mv88e6320_setup_errata(struct mv88e6xxx_chip *chip)
3681 {
3682 u16 dummy;
3683 int err;
3684
3685 /* Workaround for erratum
3686 * 3.3 RGMII timing may be out of spec when transmit delay is enabled
3687 */
3688 err = mv88e6xxx_port_hidden_write(chip, 0, 0xf, 0x7, 0xe000);
3689 if (err)
3690 return err;
3691
3692 return mv88e6xxx_port_hidden_read(chip, 0, 0xf, 0x7, &dummy);
3693 }
3694
3695 /* Check if the errata has already been applied. */
mv88e6390_setup_errata_applied(struct mv88e6xxx_chip * chip)3696 static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
3697 {
3698 int port;
3699 int err;
3700 u16 val;
3701
3702 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
3703 err = mv88e6xxx_port_hidden_read(chip, 0xf, port, 0, &val);
3704 if (err) {
3705 dev_err(chip->dev,
3706 "Error reading hidden register: %d\n", err);
3707 return false;
3708 }
3709 if (val != 0x01c0)
3710 return false;
3711 }
3712
3713 return true;
3714 }
3715
3716 /* The 6390 copper ports have an errata which require poking magic
3717 * values into undocumented hidden registers and then performing a
3718 * software reset.
3719 */
mv88e6390_setup_errata(struct mv88e6xxx_chip * chip)3720 static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip)
3721 {
3722 int port;
3723 int err;
3724
3725 if (mv88e6390_setup_errata_applied(chip))
3726 return 0;
3727
3728 /* Set the ports into blocking mode */
3729 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
3730 err = mv88e6xxx_port_set_state(chip, port, BR_STATE_DISABLED);
3731 if (err)
3732 return err;
3733 }
3734
3735 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
3736 err = mv88e6xxx_port_hidden_write(chip, 0xf, port, 0, 0x01c0);
3737 if (err)
3738 return err;
3739 }
3740
3741 return mv88e6xxx_software_reset(chip);
3742 }
3743
3744 /* For MV88E6XXX_FAMILY_6352, perform reset on G1 control.
3745 * Also, read and cache G2 scratch register.
3746 */
mv88e6352_reset(struct mv88e6xxx_chip * chip)3747 static int mv88e6352_reset(struct mv88e6xxx_chip *chip)
3748 {
3749 int err;
3750
3751 err = mv88e6352_g1_reset(chip);
3752 if (err)
3753 return err;
3754
3755 return mv88e6352_g2_cache_global_scratch_config3(chip);
3756 }
3757
3758 /* prod_id for switch families which do not have a PHY model number */
3759 static const u16 family_prod_id_table[] = {
3760 [MV88E6XXX_FAMILY_6341] = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
3761 [MV88E6XXX_FAMILY_6390] = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
3762 [MV88E6XXX_FAMILY_6393] = MV88E6XXX_PORT_SWITCH_ID_PROD_6393X,
3763 };
3764
mv88e6xxx_mdio_read(struct mii_bus * bus,int phy,int reg)3765 static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
3766 {
3767 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
3768 struct mv88e6xxx_chip *chip = mdio_bus->chip;
3769 u16 prod_id;
3770 u16 val;
3771 int err;
3772
3773 if (!chip->info->ops->phy_read)
3774 return -EOPNOTSUPP;
3775
3776 mv88e6xxx_reg_lock(chip);
3777 err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
3778 mv88e6xxx_reg_unlock(chip);
3779
3780 /* Some internal PHYs don't have a model number. */
3781 if (reg == MII_PHYSID2 && !(val & 0x3f0) &&
3782 chip->info->family < ARRAY_SIZE(family_prod_id_table)) {
3783 prod_id = family_prod_id_table[chip->info->family];
3784 if (prod_id)
3785 val |= prod_id >> 4;
3786 }
3787
3788 return err ? err : val;
3789 }
3790
mv88e6xxx_mdio_read_c45(struct mii_bus * bus,int phy,int devad,int reg)3791 static int mv88e6xxx_mdio_read_c45(struct mii_bus *bus, int phy, int devad,
3792 int reg)
3793 {
3794 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
3795 struct mv88e6xxx_chip *chip = mdio_bus->chip;
3796 u16 val;
3797 int err;
3798
3799 if (!chip->info->ops->phy_read_c45)
3800 return -ENODEV;
3801
3802 mv88e6xxx_reg_lock(chip);
3803 err = chip->info->ops->phy_read_c45(chip, bus, phy, devad, reg, &val);
3804 mv88e6xxx_reg_unlock(chip);
3805
3806 return err ? err : val;
3807 }
3808
mv88e6xxx_mdio_write(struct mii_bus * bus,int phy,int reg,u16 val)3809 static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
3810 {
3811 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
3812 struct mv88e6xxx_chip *chip = mdio_bus->chip;
3813 int err;
3814
3815 if (!chip->info->ops->phy_write)
3816 return -EOPNOTSUPP;
3817
3818 mv88e6xxx_reg_lock(chip);
3819 err = chip->info->ops->phy_write(chip, bus, phy, reg, val);
3820 mv88e6xxx_reg_unlock(chip);
3821
3822 return err;
3823 }
3824
mv88e6xxx_mdio_write_c45(struct mii_bus * bus,int phy,int devad,int reg,u16 val)3825 static int mv88e6xxx_mdio_write_c45(struct mii_bus *bus, int phy, int devad,
3826 int reg, u16 val)
3827 {
3828 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
3829 struct mv88e6xxx_chip *chip = mdio_bus->chip;
3830 int err;
3831
3832 if (!chip->info->ops->phy_write_c45)
3833 return -EOPNOTSUPP;
3834
3835 mv88e6xxx_reg_lock(chip);
3836 err = chip->info->ops->phy_write_c45(chip, bus, phy, devad, reg, val);
3837 mv88e6xxx_reg_unlock(chip);
3838
3839 return err;
3840 }
3841
mv88e6xxx_mdio_register(struct mv88e6xxx_chip * chip,struct device_node * np,bool external)3842 static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
3843 struct device_node *np,
3844 bool external)
3845 {
3846 static int index;
3847 struct mv88e6xxx_mdio_bus *mdio_bus;
3848 struct mii_bus *bus;
3849 int err;
3850
3851 if (external) {
3852 mv88e6xxx_reg_lock(chip);
3853 if (chip->info->family == MV88E6XXX_FAMILY_6393)
3854 err = mv88e6393x_g2_scratch_gpio_set_smi(chip, true);
3855 else
3856 err = mv88e6390_g2_scratch_gpio_set_smi(chip, true);
3857 mv88e6xxx_reg_unlock(chip);
3858
3859 if (err)
3860 return err;
3861 }
3862
3863 bus = mdiobus_alloc_size(sizeof(*mdio_bus));
3864 if (!bus)
3865 return -ENOMEM;
3866
3867 mdio_bus = bus->priv;
3868 mdio_bus->bus = bus;
3869 mdio_bus->chip = chip;
3870 INIT_LIST_HEAD(&mdio_bus->list);
3871 mdio_bus->external = external;
3872
3873 if (np) {
3874 bus->name = np->full_name;
3875 snprintf(bus->id, MII_BUS_ID_SIZE, "%pOF", np);
3876 } else {
3877 bus->name = "mv88e6xxx SMI";
3878 snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
3879 }
3880
3881 bus->read = mv88e6xxx_mdio_read;
3882 bus->write = mv88e6xxx_mdio_write;
3883 bus->read_c45 = mv88e6xxx_mdio_read_c45;
3884 bus->write_c45 = mv88e6xxx_mdio_write_c45;
3885 bus->parent = chip->dev;
3886 bus->phy_mask = ~GENMASK(chip->info->phy_base_addr +
3887 mv88e6xxx_num_ports(chip) - 1,
3888 chip->info->phy_base_addr);
3889
3890 if (!external) {
3891 err = mv88e6xxx_g2_irq_mdio_setup(chip, bus);
3892 if (err)
3893 goto out;
3894 }
3895
3896 err = of_mdiobus_register(bus, np);
3897 if (err) {
3898 dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
3899 mv88e6xxx_g2_irq_mdio_free(chip, bus);
3900 goto out;
3901 }
3902
3903 if (external)
3904 list_add_tail(&mdio_bus->list, &chip->mdios);
3905 else
3906 list_add(&mdio_bus->list, &chip->mdios);
3907
3908 return 0;
3909
3910 out:
3911 mdiobus_free(bus);
3912 return err;
3913 }
3914
mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip * chip)3915 static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
3916
3917 {
3918 struct mv88e6xxx_mdio_bus *mdio_bus, *p;
3919 struct mii_bus *bus;
3920
3921 list_for_each_entry_safe(mdio_bus, p, &chip->mdios, list) {
3922 bus = mdio_bus->bus;
3923
3924 if (!mdio_bus->external)
3925 mv88e6xxx_g2_irq_mdio_free(chip, bus);
3926
3927 mdiobus_unregister(bus);
3928 mdiobus_free(bus);
3929 }
3930 }
3931
mv88e6xxx_mdios_register(struct mv88e6xxx_chip * chip)3932 static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip)
3933 {
3934 struct device_node *np = chip->dev->of_node;
3935 struct device_node *child;
3936 int err;
3937
3938 /* Always register one mdio bus for the internal/default mdio
3939 * bus. This maybe represented in the device tree, but is
3940 * optional.
3941 */
3942 child = of_get_child_by_name(np, "mdio");
3943 err = mv88e6xxx_mdio_register(chip, child, false);
3944 of_node_put(child);
3945 if (err)
3946 return err;
3947
3948 /* Walk the device tree, and see if there are any other nodes
3949 * which say they are compatible with the external mdio
3950 * bus.
3951 */
3952 for_each_available_child_of_node(np, child) {
3953 if (of_device_is_compatible(
3954 child, "marvell,mv88e6xxx-mdio-external")) {
3955 err = mv88e6xxx_mdio_register(chip, child, true);
3956 if (err) {
3957 mv88e6xxx_mdios_unregister(chip);
3958 of_node_put(child);
3959 return err;
3960 }
3961 }
3962 }
3963
3964 return 0;
3965 }
3966
mv88e6xxx_tcam_setup(struct mv88e6xxx_chip * chip)3967 static int mv88e6xxx_tcam_setup(struct mv88e6xxx_chip *chip)
3968 {
3969 if (!mv88e6xxx_has_tcam(chip))
3970 return 0;
3971
3972 return chip->info->ops->tcam_ops->flush_tcam(chip);
3973 }
3974
mv88e6xxx_teardown(struct dsa_switch * ds)3975 static void mv88e6xxx_teardown(struct dsa_switch *ds)
3976 {
3977 struct mv88e6xxx_chip *chip = ds->priv;
3978
3979 mv88e6xxx_teardown_devlink_params(ds);
3980 dsa_devlink_resources_unregister(ds);
3981 mv88e6xxx_teardown_devlink_regions_global(ds);
3982 mv88e6xxx_hwtstamp_free(chip);
3983 mv88e6xxx_ptp_free(chip);
3984 mv88e6xxx_flower_teardown(chip);
3985 mv88e6xxx_mdios_unregister(chip);
3986 }
3987
mv88e6xxx_setup(struct dsa_switch * ds)3988 static int mv88e6xxx_setup(struct dsa_switch *ds)
3989 {
3990 struct mv88e6xxx_chip *chip = ds->priv;
3991 u8 cmode;
3992 int err;
3993 int i;
3994
3995 err = mv88e6xxx_mdios_register(chip);
3996 if (err)
3997 return err;
3998
3999 chip->ds = ds;
4000 ds->user_mii_bus = mv88e6xxx_default_mdio_bus(chip);
4001
4002 /* Since virtual bridges are mapped in the PVT, the number we support
4003 * depends on the physical switch topology. We need to let DSA figure
4004 * that out and therefore we cannot set this at dsa_register_switch()
4005 * time.
4006 */
4007 if (mv88e6xxx_has_pvt(chip))
4008 ds->max_num_bridges = MV88E6XXX_MAX_PVT_SWITCHES -
4009 ds->dst->last_switch - 1;
4010
4011 mv88e6xxx_reg_lock(chip);
4012
4013 if (chip->info->ops->setup_errata) {
4014 err = chip->info->ops->setup_errata(chip);
4015 if (err)
4016 goto unlock;
4017 }
4018
4019 /* Cache the cmode of each port. */
4020 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
4021 if (chip->info->ops->port_get_cmode) {
4022 err = chip->info->ops->port_get_cmode(chip, i, &cmode);
4023 if (err)
4024 goto unlock;
4025
4026 chip->ports[i].cmode = cmode;
4027 }
4028 }
4029
4030 err = mv88e6xxx_vtu_setup(chip);
4031 if (err)
4032 goto unlock;
4033
4034 /* Must be called after mv88e6xxx_vtu_setup (which flushes the
4035 * VTU, thereby also flushing the STU).
4036 */
4037 err = mv88e6xxx_stu_setup(chip);
4038 if (err)
4039 goto unlock;
4040
4041 /* Setup Switch Port Registers */
4042 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
4043 if (dsa_is_unused_port(ds, i))
4044 continue;
4045
4046 /* Prevent the use of an invalid port. */
4047 if (mv88e6xxx_is_invalid_port(chip, i)) {
4048 dev_err(chip->dev, "port %d is invalid\n", i);
4049 err = -EINVAL;
4050 goto unlock;
4051 }
4052
4053 err = mv88e6xxx_setup_port(chip, i);
4054 if (err)
4055 goto unlock;
4056 }
4057
4058 err = mv88e6xxx_irl_setup(chip);
4059 if (err)
4060 goto unlock;
4061
4062 err = mv88e6xxx_mac_setup(chip);
4063 if (err)
4064 goto unlock;
4065
4066 err = mv88e6xxx_phy_setup(chip);
4067 if (err)
4068 goto unlock;
4069
4070 err = mv88e6xxx_pvt_setup(chip);
4071 if (err)
4072 goto unlock;
4073
4074 err = mv88e6xxx_atu_setup(chip);
4075 if (err)
4076 goto unlock;
4077
4078 err = mv88e6xxx_broadcast_setup(chip, 0);
4079 if (err)
4080 goto unlock;
4081
4082 err = mv88e6xxx_pot_setup(chip);
4083 if (err)
4084 goto unlock;
4085
4086 err = mv88e6xxx_rmu_setup(chip);
4087 if (err)
4088 goto unlock;
4089
4090 err = mv88e6xxx_rsvd2cpu_setup(chip);
4091 if (err)
4092 goto unlock;
4093
4094 err = mv88e6xxx_trunk_setup(chip);
4095 if (err)
4096 goto unlock;
4097
4098 err = mv88e6xxx_devmap_setup(chip);
4099 if (err)
4100 goto unlock;
4101
4102 err = mv88e6xxx_pri_setup(chip);
4103 if (err)
4104 goto unlock;
4105
4106 /* Setup PTP Hardware Clock and timestamping */
4107 if (chip->info->ptp_support) {
4108 err = mv88e6xxx_ptp_setup(chip);
4109 if (err)
4110 goto unlock;
4111
4112 err = mv88e6xxx_hwtstamp_setup(chip);
4113 if (err)
4114 goto unlock;
4115 }
4116
4117 err = mv88e6xxx_stats_setup(chip);
4118 if (err)
4119 goto unlock;
4120
4121 err = mv88e6xxx_tcam_setup(chip);
4122 if (err)
4123 goto unlock;
4124
4125 unlock:
4126 mv88e6xxx_reg_unlock(chip);
4127
4128 if (err)
4129 goto out_hwtstamp;
4130
4131 /* Have to be called without holding the register lock, since
4132 * they take the devlink lock, and we later take the locks in
4133 * the reverse order when getting/setting parameters or
4134 * resource occupancy.
4135 */
4136 err = mv88e6xxx_setup_devlink_resources(ds);
4137 if (err)
4138 goto out_hwtstamp;
4139
4140 err = mv88e6xxx_setup_devlink_params(ds);
4141 if (err)
4142 goto out_resources;
4143
4144 err = mv88e6xxx_setup_devlink_regions_global(ds);
4145 if (err)
4146 goto out_params;
4147
4148 return 0;
4149
4150 out_params:
4151 mv88e6xxx_teardown_devlink_params(ds);
4152 out_resources:
4153 dsa_devlink_resources_unregister(ds);
4154 out_hwtstamp:
4155 mv88e6xxx_hwtstamp_free(chip);
4156 mv88e6xxx_ptp_free(chip);
4157 mv88e6xxx_mdios_unregister(chip);
4158
4159 return err;
4160 }
4161
mv88e6xxx_port_setup(struct dsa_switch * ds,int port)4162 static int mv88e6xxx_port_setup(struct dsa_switch *ds, int port)
4163 {
4164 struct mv88e6xxx_chip *chip = ds->priv;
4165 int err;
4166
4167 if (chip->info->ops->pcs_ops &&
4168 chip->info->ops->pcs_ops->pcs_init) {
4169 err = chip->info->ops->pcs_ops->pcs_init(chip, port);
4170 if (err)
4171 return err;
4172 }
4173
4174 return mv88e6xxx_setup_devlink_regions_port(ds, port);
4175 }
4176
mv88e6xxx_port_teardown(struct dsa_switch * ds,int port)4177 static void mv88e6xxx_port_teardown(struct dsa_switch *ds, int port)
4178 {
4179 struct mv88e6xxx_chip *chip = ds->priv;
4180
4181 mv88e6xxx_teardown_devlink_regions_port(ds, port);
4182
4183 if (chip->info->ops->pcs_ops &&
4184 chip->info->ops->pcs_ops->pcs_teardown)
4185 chip->info->ops->pcs_ops->pcs_teardown(chip, port);
4186 }
4187
mv88e6xxx_get_eeprom_len(struct dsa_switch * ds)4188 static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
4189 {
4190 struct mv88e6xxx_chip *chip = ds->priv;
4191
4192 return chip->eeprom_len;
4193 }
4194
mv88e6xxx_get_eeprom(struct dsa_switch * ds,struct ethtool_eeprom * eeprom,u8 * data)4195 static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
4196 struct ethtool_eeprom *eeprom, u8 *data)
4197 {
4198 struct mv88e6xxx_chip *chip = ds->priv;
4199 int err;
4200
4201 if (!chip->info->ops->get_eeprom)
4202 return -EOPNOTSUPP;
4203
4204 mv88e6xxx_reg_lock(chip);
4205 err = chip->info->ops->get_eeprom(chip, eeprom, data);
4206 mv88e6xxx_reg_unlock(chip);
4207
4208 if (err)
4209 return err;
4210
4211 eeprom->magic = 0xc3ec4951;
4212
4213 return 0;
4214 }
4215
mv88e6xxx_set_eeprom(struct dsa_switch * ds,struct ethtool_eeprom * eeprom,u8 * data)4216 static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
4217 struct ethtool_eeprom *eeprom, u8 *data)
4218 {
4219 struct mv88e6xxx_chip *chip = ds->priv;
4220 int err;
4221
4222 if (!chip->info->ops->set_eeprom)
4223 return -EOPNOTSUPP;
4224
4225 if (eeprom->magic != 0xc3ec4951)
4226 return -EINVAL;
4227
4228 mv88e6xxx_reg_lock(chip);
4229 err = chip->info->ops->set_eeprom(chip, eeprom, data);
4230 mv88e6xxx_reg_unlock(chip);
4231
4232 return err;
4233 }
4234
4235 static const struct mv88e6xxx_ops mv88e6085_ops = {
4236 /* MV88E6XXX_FAMILY_6097 */
4237 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4238 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4239 .irl_init_all = mv88e6352_g2_irl_init_all,
4240 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
4241 .phy_read = mv88e6185_phy_ppu_read,
4242 .phy_write = mv88e6185_phy_ppu_write,
4243 .port_set_link = mv88e6xxx_port_set_link,
4244 .port_sync_link = mv88e6xxx_port_sync_link,
4245 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4246 .port_tag_remap = mv88e6095_port_tag_remap,
4247 .port_set_policy = mv88e6352_port_set_policy,
4248 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4249 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4250 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4251 .port_set_ether_type = mv88e6351_port_set_ether_type,
4252 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4253 .port_pause_limit = mv88e6097_port_pause_limit,
4254 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4255 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4256 .port_get_cmode = mv88e6185_port_get_cmode,
4257 .port_setup_message_port = mv88e6xxx_setup_message_port,
4258 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4259 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4260 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4261 .stats_get_strings = mv88e6095_stats_get_strings,
4262 .stats_get_stat = mv88e6095_stats_get_stat,
4263 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4264 .set_egress_port = mv88e6095_g1_set_egress_port,
4265 .watchdog_ops = &mv88e6097_watchdog_ops,
4266 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4267 .pot_clear = mv88e6xxx_g2_pot_clear,
4268 .ppu_enable = mv88e6185_g1_ppu_enable,
4269 .ppu_disable = mv88e6185_g1_ppu_disable,
4270 .reset = mv88e6185_g1_reset,
4271 .rmu_disable = mv88e6085_g1_rmu_disable,
4272 .vtu_getnext = mv88e6352_g1_vtu_getnext,
4273 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4274 .stu_getnext = mv88e6352_g1_stu_getnext,
4275 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4276 .phylink_get_caps = mv88e6185_phylink_get_caps,
4277 .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4278 };
4279
4280 static const struct mv88e6xxx_ops mv88e6095_ops = {
4281 /* MV88E6XXX_FAMILY_6095 */
4282 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4283 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4284 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
4285 .phy_read = mv88e6185_phy_ppu_read,
4286 .phy_write = mv88e6185_phy_ppu_write,
4287 .port_set_link = mv88e6xxx_port_set_link,
4288 .port_sync_link = mv88e6185_port_sync_link,
4289 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4290 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
4291 .port_set_ucast_flood = mv88e6185_port_set_forward_unknown,
4292 .port_set_mcast_flood = mv88e6185_port_set_default_forward,
4293 .port_set_upstream_port = mv88e6095_port_set_upstream_port,
4294 .port_get_cmode = mv88e6185_port_get_cmode,
4295 .port_setup_message_port = mv88e6xxx_setup_message_port,
4296 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4297 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4298 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4299 .stats_get_strings = mv88e6095_stats_get_strings,
4300 .stats_get_stat = mv88e6095_stats_get_stat,
4301 .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
4302 .ppu_enable = mv88e6185_g1_ppu_enable,
4303 .ppu_disable = mv88e6185_g1_ppu_disable,
4304 .reset = mv88e6185_g1_reset,
4305 .vtu_getnext = mv88e6185_g1_vtu_getnext,
4306 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
4307 .phylink_get_caps = mv88e6095_phylink_get_caps,
4308 .pcs_ops = &mv88e6185_pcs_ops,
4309 .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4310 };
4311
4312 static const struct mv88e6xxx_ops mv88e6097_ops = {
4313 /* MV88E6XXX_FAMILY_6097 */
4314 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4315 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4316 .irl_init_all = mv88e6352_g2_irl_init_all,
4317 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4318 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4319 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4320 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4321 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4322 .port_set_link = mv88e6xxx_port_set_link,
4323 .port_sync_link = mv88e6185_port_sync_link,
4324 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4325 .port_tag_remap = mv88e6095_port_tag_remap,
4326 .port_set_policy = mv88e6352_port_set_policy,
4327 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4328 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4329 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4330 .port_set_ether_type = mv88e6351_port_set_ether_type,
4331 .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
4332 .port_pause_limit = mv88e6097_port_pause_limit,
4333 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4334 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4335 .port_get_cmode = mv88e6185_port_get_cmode,
4336 .port_setup_message_port = mv88e6xxx_setup_message_port,
4337 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4338 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4339 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4340 .stats_get_strings = mv88e6095_stats_get_strings,
4341 .stats_get_stat = mv88e6095_stats_get_stat,
4342 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4343 .set_egress_port = mv88e6095_g1_set_egress_port,
4344 .watchdog_ops = &mv88e6097_watchdog_ops,
4345 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4346 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4347 .pot_clear = mv88e6xxx_g2_pot_clear,
4348 .reset = mv88e6352_g1_reset,
4349 .rmu_disable = mv88e6085_g1_rmu_disable,
4350 .vtu_getnext = mv88e6352_g1_vtu_getnext,
4351 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4352 .phylink_get_caps = mv88e6095_phylink_get_caps,
4353 .pcs_ops = &mv88e6185_pcs_ops,
4354 .stu_getnext = mv88e6352_g1_stu_getnext,
4355 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4356 .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4357 };
4358
4359 static const struct mv88e6xxx_ops mv88e6123_ops = {
4360 /* MV88E6XXX_FAMILY_6165 */
4361 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4362 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4363 .irl_init_all = mv88e6352_g2_irl_init_all,
4364 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4365 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4366 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4367 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4368 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4369 .port_set_link = mv88e6xxx_port_set_link,
4370 .port_sync_link = mv88e6xxx_port_sync_link,
4371 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4372 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
4373 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4374 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4375 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4376 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4377 .port_get_cmode = mv88e6185_port_get_cmode,
4378 .port_setup_message_port = mv88e6xxx_setup_message_port,
4379 .stats_snapshot = mv88e6320_g1_stats_snapshot,
4380 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4381 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4382 .stats_get_strings = mv88e6095_stats_get_strings,
4383 .stats_get_stat = mv88e6095_stats_get_stat,
4384 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4385 .set_egress_port = mv88e6095_g1_set_egress_port,
4386 .watchdog_ops = &mv88e6097_watchdog_ops,
4387 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4388 .pot_clear = mv88e6xxx_g2_pot_clear,
4389 .reset = mv88e6352_g1_reset,
4390 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4391 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4392 .vtu_getnext = mv88e6352_g1_vtu_getnext,
4393 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4394 .stu_getnext = mv88e6352_g1_stu_getnext,
4395 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4396 .phylink_get_caps = mv88e6185_phylink_get_caps,
4397 .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4398 };
4399
4400 static const struct mv88e6xxx_ops mv88e6131_ops = {
4401 /* MV88E6XXX_FAMILY_6185 */
4402 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4403 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4404 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
4405 .phy_read = mv88e6185_phy_ppu_read,
4406 .phy_write = mv88e6185_phy_ppu_write,
4407 .port_set_link = mv88e6xxx_port_set_link,
4408 .port_sync_link = mv88e6xxx_port_sync_link,
4409 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4410 .port_tag_remap = mv88e6095_port_tag_remap,
4411 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4412 .port_set_ucast_flood = mv88e6185_port_set_forward_unknown,
4413 .port_set_mcast_flood = mv88e6185_port_set_default_forward,
4414 .port_set_ether_type = mv88e6351_port_set_ether_type,
4415 .port_set_upstream_port = mv88e6095_port_set_upstream_port,
4416 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4417 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4418 .port_pause_limit = mv88e6097_port_pause_limit,
4419 .port_set_pause = mv88e6185_port_set_pause,
4420 .port_get_cmode = mv88e6185_port_get_cmode,
4421 .port_setup_message_port = mv88e6xxx_setup_message_port,
4422 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4423 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4424 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4425 .stats_get_strings = mv88e6095_stats_get_strings,
4426 .stats_get_stat = mv88e6095_stats_get_stat,
4427 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4428 .set_egress_port = mv88e6095_g1_set_egress_port,
4429 .watchdog_ops = &mv88e6097_watchdog_ops,
4430 .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
4431 .ppu_enable = mv88e6185_g1_ppu_enable,
4432 .set_cascade_port = mv88e6185_g1_set_cascade_port,
4433 .ppu_disable = mv88e6185_g1_ppu_disable,
4434 .reset = mv88e6185_g1_reset,
4435 .vtu_getnext = mv88e6185_g1_vtu_getnext,
4436 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
4437 .phylink_get_caps = mv88e6185_phylink_get_caps,
4438 };
4439
4440 static const struct mv88e6xxx_ops mv88e6141_ops = {
4441 /* MV88E6XXX_FAMILY_6341 */
4442 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4443 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4444 .irl_init_all = mv88e6352_g2_irl_init_all,
4445 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
4446 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
4447 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4448 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4449 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4450 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4451 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4452 .port_set_link = mv88e6xxx_port_set_link,
4453 .port_sync_link = mv88e6xxx_port_sync_link,
4454 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4455 .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
4456 .port_tag_remap = mv88e6095_port_tag_remap,
4457 .port_set_policy = mv88e6352_port_set_policy,
4458 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4459 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4460 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4461 .port_set_ether_type = mv88e6351_port_set_ether_type,
4462 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4463 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4464 .port_pause_limit = mv88e6097_port_pause_limit,
4465 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4466 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4467 .port_get_cmode = mv88e6352_port_get_cmode,
4468 .port_set_cmode = mv88e6341_port_set_cmode,
4469 .port_setup_message_port = mv88e6xxx_setup_message_port,
4470 .stats_snapshot = mv88e6390_g1_stats_snapshot,
4471 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4472 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
4473 .stats_get_strings = mv88e6320_stats_get_strings,
4474 .stats_get_stat = mv88e6390_stats_get_stat,
4475 .set_cpu_port = mv88e6390_g1_set_cpu_port,
4476 .set_egress_port = mv88e6390_g1_set_egress_port,
4477 .watchdog_ops = &mv88e6390_watchdog_ops,
4478 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4479 .pot_clear = mv88e6xxx_g2_pot_clear,
4480 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
4481 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
4482 .reset = mv88e6352_g1_reset,
4483 .rmu_disable = mv88e6390_g1_rmu_disable,
4484 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4485 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4486 .vtu_getnext = mv88e6352_g1_vtu_getnext,
4487 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4488 .stu_getnext = mv88e6352_g1_stu_getnext,
4489 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4490 .serdes_get_lane = mv88e6341_serdes_get_lane,
4491 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4492 .gpio_ops = &mv88e6352_gpio_ops,
4493 .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
4494 .serdes_get_strings = mv88e6390_serdes_get_strings,
4495 .serdes_get_stats = mv88e6390_serdes_get_stats,
4496 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4497 .serdes_get_regs = mv88e6390_serdes_get_regs,
4498 .phylink_get_caps = mv88e6341_phylink_get_caps,
4499 .pcs_ops = &mv88e6390_pcs_ops,
4500 };
4501
4502 static const struct mv88e6xxx_ops mv88e6161_ops = {
4503 /* MV88E6XXX_FAMILY_6165 */
4504 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4505 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4506 .irl_init_all = mv88e6352_g2_irl_init_all,
4507 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4508 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4509 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4510 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4511 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4512 .port_set_link = mv88e6xxx_port_set_link,
4513 .port_sync_link = mv88e6xxx_port_sync_link,
4514 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4515 .port_tag_remap = mv88e6095_port_tag_remap,
4516 .port_set_policy = mv88e6352_port_set_policy,
4517 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4518 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4519 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4520 .port_set_ether_type = mv88e6351_port_set_ether_type,
4521 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4522 .port_pause_limit = mv88e6097_port_pause_limit,
4523 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4524 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4525 .port_get_cmode = mv88e6185_port_get_cmode,
4526 .port_setup_message_port = mv88e6xxx_setup_message_port,
4527 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4528 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4529 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4530 .stats_get_strings = mv88e6095_stats_get_strings,
4531 .stats_get_stat = mv88e6095_stats_get_stat,
4532 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4533 .set_egress_port = mv88e6095_g1_set_egress_port,
4534 .watchdog_ops = &mv88e6097_watchdog_ops,
4535 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4536 .pot_clear = mv88e6xxx_g2_pot_clear,
4537 .reset = mv88e6352_g1_reset,
4538 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4539 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4540 .vtu_getnext = mv88e6352_g1_vtu_getnext,
4541 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4542 .stu_getnext = mv88e6352_g1_stu_getnext,
4543 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4544 .avb_ops = &mv88e6165_avb_ops,
4545 .ptp_ops = &mv88e6165_ptp_ops,
4546 .phylink_get_caps = mv88e6185_phylink_get_caps,
4547 .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4548 };
4549
4550 static const struct mv88e6xxx_ops mv88e6165_ops = {
4551 /* MV88E6XXX_FAMILY_6165 */
4552 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4553 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4554 .irl_init_all = mv88e6352_g2_irl_init_all,
4555 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4556 .phy_read = mv88e6165_phy_read,
4557 .phy_write = mv88e6165_phy_write,
4558 .port_set_link = mv88e6xxx_port_set_link,
4559 .port_sync_link = mv88e6xxx_port_sync_link,
4560 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4561 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4562 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4563 .port_get_cmode = mv88e6185_port_get_cmode,
4564 .port_setup_message_port = mv88e6xxx_setup_message_port,
4565 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4566 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4567 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4568 .stats_get_strings = mv88e6095_stats_get_strings,
4569 .stats_get_stat = mv88e6095_stats_get_stat,
4570 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4571 .set_egress_port = mv88e6095_g1_set_egress_port,
4572 .watchdog_ops = &mv88e6097_watchdog_ops,
4573 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4574 .pot_clear = mv88e6xxx_g2_pot_clear,
4575 .reset = mv88e6352_g1_reset,
4576 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4577 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4578 .vtu_getnext = mv88e6352_g1_vtu_getnext,
4579 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4580 .stu_getnext = mv88e6352_g1_stu_getnext,
4581 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4582 .avb_ops = &mv88e6165_avb_ops,
4583 .ptp_ops = &mv88e6165_ptp_ops,
4584 .phylink_get_caps = mv88e6185_phylink_get_caps,
4585 };
4586
4587 static const struct mv88e6xxx_ops mv88e6171_ops = {
4588 /* MV88E6XXX_FAMILY_6351 */
4589 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4590 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4591 .irl_init_all = mv88e6352_g2_irl_init_all,
4592 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4593 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4594 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4595 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4596 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4597 .port_set_link = mv88e6xxx_port_set_link,
4598 .port_sync_link = mv88e6xxx_port_sync_link,
4599 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4600 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4601 .port_tag_remap = mv88e6095_port_tag_remap,
4602 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4603 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4604 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4605 .port_set_ether_type = mv88e6351_port_set_ether_type,
4606 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4607 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4608 .port_pause_limit = mv88e6097_port_pause_limit,
4609 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4610 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4611 .port_get_cmode = mv88e6352_port_get_cmode,
4612 .port_setup_message_port = mv88e6xxx_setup_message_port,
4613 .stats_snapshot = mv88e6320_g1_stats_snapshot,
4614 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4615 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4616 .stats_get_strings = mv88e6095_stats_get_strings,
4617 .stats_get_stat = mv88e6095_stats_get_stat,
4618 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4619 .set_egress_port = mv88e6095_g1_set_egress_port,
4620 .watchdog_ops = &mv88e6097_watchdog_ops,
4621 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4622 .pot_clear = mv88e6xxx_g2_pot_clear,
4623 .reset = mv88e6352_g1_reset,
4624 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4625 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4626 .vtu_getnext = mv88e6352_g1_vtu_getnext,
4627 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4628 .stu_getnext = mv88e6352_g1_stu_getnext,
4629 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4630 .phylink_get_caps = mv88e6351_phylink_get_caps,
4631 };
4632
4633 static const struct mv88e6xxx_ops mv88e6172_ops = {
4634 /* MV88E6XXX_FAMILY_6352 */
4635 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4636 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4637 .irl_init_all = mv88e6352_g2_irl_init_all,
4638 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
4639 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
4640 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4641 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4642 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4643 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4644 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4645 .port_set_link = mv88e6xxx_port_set_link,
4646 .port_sync_link = mv88e6xxx_port_sync_link,
4647 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4648 .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
4649 .port_tag_remap = mv88e6095_port_tag_remap,
4650 .port_set_policy = mv88e6352_port_set_policy,
4651 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4652 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4653 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4654 .port_set_ether_type = mv88e6351_port_set_ether_type,
4655 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4656 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4657 .port_pause_limit = mv88e6097_port_pause_limit,
4658 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4659 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4660 .port_get_cmode = mv88e6352_port_get_cmode,
4661 .port_setup_leds = mv88e6xxx_port_setup_leds,
4662 .port_setup_message_port = mv88e6xxx_setup_message_port,
4663 .stats_snapshot = mv88e6320_g1_stats_snapshot,
4664 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4665 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4666 .stats_get_strings = mv88e6095_stats_get_strings,
4667 .stats_get_stat = mv88e6095_stats_get_stat,
4668 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4669 .set_egress_port = mv88e6095_g1_set_egress_port,
4670 .watchdog_ops = &mv88e6097_watchdog_ops,
4671 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4672 .pot_clear = mv88e6xxx_g2_pot_clear,
4673 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
4674 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
4675 .reset = mv88e6352_reset,
4676 .rmu_disable = mv88e6352_g1_rmu_disable,
4677 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4678 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4679 .vtu_getnext = mv88e6352_g1_vtu_getnext,
4680 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4681 .stu_getnext = mv88e6352_g1_stu_getnext,
4682 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4683 .serdes_get_lane = mv88e6352_serdes_get_lane,
4684 .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
4685 .serdes_get_regs = mv88e6352_serdes_get_regs,
4686 .gpio_ops = &mv88e6352_gpio_ops,
4687 .phylink_get_caps = mv88e6352_phylink_get_caps,
4688 .pcs_ops = &mv88e6352_pcs_ops,
4689 };
4690
4691 static const struct mv88e6xxx_ops mv88e6175_ops = {
4692 /* MV88E6XXX_FAMILY_6351 */
4693 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4694 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4695 .irl_init_all = mv88e6352_g2_irl_init_all,
4696 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4697 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4698 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4699 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4700 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4701 .port_set_link = mv88e6xxx_port_set_link,
4702 .port_sync_link = mv88e6xxx_port_sync_link,
4703 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4704 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4705 .port_tag_remap = mv88e6095_port_tag_remap,
4706 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4707 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4708 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4709 .port_set_ether_type = mv88e6351_port_set_ether_type,
4710 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4711 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4712 .port_pause_limit = mv88e6097_port_pause_limit,
4713 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4714 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4715 .port_get_cmode = mv88e6352_port_get_cmode,
4716 .port_setup_message_port = mv88e6xxx_setup_message_port,
4717 .stats_snapshot = mv88e6320_g1_stats_snapshot,
4718 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4719 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4720 .stats_get_strings = mv88e6095_stats_get_strings,
4721 .stats_get_stat = mv88e6095_stats_get_stat,
4722 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4723 .set_egress_port = mv88e6095_g1_set_egress_port,
4724 .watchdog_ops = &mv88e6097_watchdog_ops,
4725 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4726 .pot_clear = mv88e6xxx_g2_pot_clear,
4727 .reset = mv88e6352_g1_reset,
4728 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4729 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4730 .vtu_getnext = mv88e6352_g1_vtu_getnext,
4731 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4732 .stu_getnext = mv88e6352_g1_stu_getnext,
4733 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4734 .phylink_get_caps = mv88e6351_phylink_get_caps,
4735 };
4736
4737 static const struct mv88e6xxx_ops mv88e6176_ops = {
4738 /* MV88E6XXX_FAMILY_6352 */
4739 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4740 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4741 .irl_init_all = mv88e6352_g2_irl_init_all,
4742 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
4743 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
4744 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4745 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4746 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4747 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4748 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4749 .port_set_link = mv88e6xxx_port_set_link,
4750 .port_sync_link = mv88e6xxx_port_sync_link,
4751 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
4752 .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
4753 .port_tag_remap = mv88e6095_port_tag_remap,
4754 .port_set_policy = mv88e6352_port_set_policy,
4755 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4756 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4757 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4758 .port_set_ether_type = mv88e6351_port_set_ether_type,
4759 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4760 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
4761 .port_pause_limit = mv88e6097_port_pause_limit,
4762 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4763 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4764 .port_get_cmode = mv88e6352_port_get_cmode,
4765 .port_setup_leds = mv88e6xxx_port_setup_leds,
4766 .port_setup_message_port = mv88e6xxx_setup_message_port,
4767 .stats_snapshot = mv88e6320_g1_stats_snapshot,
4768 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4769 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4770 .stats_get_strings = mv88e6095_stats_get_strings,
4771 .stats_get_stat = mv88e6095_stats_get_stat,
4772 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4773 .set_egress_port = mv88e6095_g1_set_egress_port,
4774 .watchdog_ops = &mv88e6097_watchdog_ops,
4775 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
4776 .pot_clear = mv88e6xxx_g2_pot_clear,
4777 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
4778 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
4779 .reset = mv88e6352_reset,
4780 .rmu_disable = mv88e6352_g1_rmu_disable,
4781 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4782 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4783 .vtu_getnext = mv88e6352_g1_vtu_getnext,
4784 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
4785 .stu_getnext = mv88e6352_g1_stu_getnext,
4786 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
4787 .serdes_get_lane = mv88e6352_serdes_get_lane,
4788 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
4789 .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
4790 .serdes_get_regs = mv88e6352_serdes_get_regs,
4791 .gpio_ops = &mv88e6352_gpio_ops,
4792 .phylink_get_caps = mv88e6352_phylink_get_caps,
4793 .pcs_ops = &mv88e6352_pcs_ops,
4794 };
4795
4796 static const struct mv88e6xxx_ops mv88e6185_ops = {
4797 /* MV88E6XXX_FAMILY_6185 */
4798 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
4799 .ip_pri_map = mv88e6085_g1_ip_pri_map,
4800 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
4801 .phy_read = mv88e6185_phy_ppu_read,
4802 .phy_write = mv88e6185_phy_ppu_write,
4803 .port_set_link = mv88e6xxx_port_set_link,
4804 .port_sync_link = mv88e6185_port_sync_link,
4805 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
4806 .port_set_frame_mode = mv88e6085_port_set_frame_mode,
4807 .port_set_ucast_flood = mv88e6185_port_set_forward_unknown,
4808 .port_set_mcast_flood = mv88e6185_port_set_default_forward,
4809 .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
4810 .port_set_upstream_port = mv88e6095_port_set_upstream_port,
4811 .port_set_pause = mv88e6185_port_set_pause,
4812 .port_get_cmode = mv88e6185_port_get_cmode,
4813 .port_setup_message_port = mv88e6xxx_setup_message_port,
4814 .stats_snapshot = mv88e6xxx_g1_stats_snapshot,
4815 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
4816 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
4817 .stats_get_strings = mv88e6095_stats_get_strings,
4818 .stats_get_stat = mv88e6095_stats_get_stat,
4819 .set_cpu_port = mv88e6095_g1_set_cpu_port,
4820 .set_egress_port = mv88e6095_g1_set_egress_port,
4821 .watchdog_ops = &mv88e6097_watchdog_ops,
4822 .mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
4823 .set_cascade_port = mv88e6185_g1_set_cascade_port,
4824 .ppu_enable = mv88e6185_g1_ppu_enable,
4825 .ppu_disable = mv88e6185_g1_ppu_disable,
4826 .reset = mv88e6185_g1_reset,
4827 .vtu_getnext = mv88e6185_g1_vtu_getnext,
4828 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
4829 .phylink_get_caps = mv88e6185_phylink_get_caps,
4830 .pcs_ops = &mv88e6185_pcs_ops,
4831 .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
4832 };
4833
4834 static const struct mv88e6xxx_ops mv88e6190_ops = {
4835 /* MV88E6XXX_FAMILY_6390 */
4836 .setup_errata = mv88e6390_setup_errata,
4837 .irl_init_all = mv88e6390_g2_irl_init_all,
4838 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
4839 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
4840 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4841 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4842 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4843 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4844 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4845 .port_set_link = mv88e6xxx_port_set_link,
4846 .port_sync_link = mv88e6xxx_port_sync_link,
4847 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4848 .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4849 .port_tag_remap = mv88e6390_port_tag_remap,
4850 .port_set_policy = mv88e6352_port_set_policy,
4851 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4852 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4853 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4854 .port_set_ether_type = mv88e6351_port_set_ether_type,
4855 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4856 .port_pause_limit = mv88e6390_port_pause_limit,
4857 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4858 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4859 .port_get_cmode = mv88e6352_port_get_cmode,
4860 .port_set_cmode = mv88e6390_port_set_cmode,
4861 .port_setup_message_port = mv88e6xxx_setup_message_port,
4862 .stats_snapshot = mv88e6390_g1_stats_snapshot,
4863 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4864 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
4865 .stats_get_strings = mv88e6320_stats_get_strings,
4866 .stats_get_stat = mv88e6390_stats_get_stat,
4867 .set_cpu_port = mv88e6390_g1_set_cpu_port,
4868 .set_egress_port = mv88e6390_g1_set_egress_port,
4869 .watchdog_ops = &mv88e6390_watchdog_ops,
4870 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4871 .pot_clear = mv88e6xxx_g2_pot_clear,
4872 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
4873 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
4874 .reset = mv88e6352_g1_reset,
4875 .rmu_disable = mv88e6390_g1_rmu_disable,
4876 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4877 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4878 .vtu_getnext = mv88e6390_g1_vtu_getnext,
4879 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
4880 .stu_getnext = mv88e6390_g1_stu_getnext,
4881 .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
4882 .serdes_get_lane = mv88e6390_serdes_get_lane,
4883 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4884 .serdes_get_strings = mv88e6390_serdes_get_strings,
4885 .serdes_get_stats = mv88e6390_serdes_get_stats,
4886 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4887 .serdes_get_regs = mv88e6390_serdes_get_regs,
4888 .gpio_ops = &mv88e6352_gpio_ops,
4889 .phylink_get_caps = mv88e6390_phylink_get_caps,
4890 .pcs_ops = &mv88e6390_pcs_ops,
4891 };
4892
4893 static const struct mv88e6xxx_ops mv88e6190x_ops = {
4894 /* MV88E6XXX_FAMILY_6390 */
4895 .setup_errata = mv88e6390_setup_errata,
4896 .irl_init_all = mv88e6390_g2_irl_init_all,
4897 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
4898 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
4899 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4900 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4901 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4902 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4903 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4904 .port_set_link = mv88e6xxx_port_set_link,
4905 .port_sync_link = mv88e6xxx_port_sync_link,
4906 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4907 .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
4908 .port_tag_remap = mv88e6390_port_tag_remap,
4909 .port_set_policy = mv88e6352_port_set_policy,
4910 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4911 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4912 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4913 .port_set_ether_type = mv88e6351_port_set_ether_type,
4914 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
4915 .port_pause_limit = mv88e6390_port_pause_limit,
4916 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4917 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4918 .port_get_cmode = mv88e6352_port_get_cmode,
4919 .port_set_cmode = mv88e6390x_port_set_cmode,
4920 .port_setup_message_port = mv88e6xxx_setup_message_port,
4921 .stats_snapshot = mv88e6390_g1_stats_snapshot,
4922 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4923 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
4924 .stats_get_strings = mv88e6320_stats_get_strings,
4925 .stats_get_stat = mv88e6390_stats_get_stat,
4926 .set_cpu_port = mv88e6390_g1_set_cpu_port,
4927 .set_egress_port = mv88e6390_g1_set_egress_port,
4928 .watchdog_ops = &mv88e6390_watchdog_ops,
4929 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4930 .pot_clear = mv88e6xxx_g2_pot_clear,
4931 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
4932 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
4933 .reset = mv88e6352_g1_reset,
4934 .rmu_disable = mv88e6390_g1_rmu_disable,
4935 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4936 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4937 .vtu_getnext = mv88e6390_g1_vtu_getnext,
4938 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
4939 .stu_getnext = mv88e6390_g1_stu_getnext,
4940 .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
4941 .serdes_get_lane = mv88e6390x_serdes_get_lane,
4942 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
4943 .serdes_get_strings = mv88e6390_serdes_get_strings,
4944 .serdes_get_stats = mv88e6390_serdes_get_stats,
4945 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
4946 .serdes_get_regs = mv88e6390_serdes_get_regs,
4947 .gpio_ops = &mv88e6352_gpio_ops,
4948 .phylink_get_caps = mv88e6390x_phylink_get_caps,
4949 .pcs_ops = &mv88e6390_pcs_ops,
4950 };
4951
4952 static const struct mv88e6xxx_ops mv88e6191_ops = {
4953 /* MV88E6XXX_FAMILY_6390 */
4954 .setup_errata = mv88e6390_setup_errata,
4955 .irl_init_all = mv88e6390_g2_irl_init_all,
4956 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
4957 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
4958 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
4959 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
4960 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
4961 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
4962 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
4963 .port_set_link = mv88e6xxx_port_set_link,
4964 .port_sync_link = mv88e6xxx_port_sync_link,
4965 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
4966 .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
4967 .port_tag_remap = mv88e6390_port_tag_remap,
4968 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
4969 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
4970 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
4971 .port_set_ether_type = mv88e6351_port_set_ether_type,
4972 .port_pause_limit = mv88e6390_port_pause_limit,
4973 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
4974 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
4975 .port_get_cmode = mv88e6352_port_get_cmode,
4976 .port_set_cmode = mv88e6390_port_set_cmode,
4977 .port_setup_message_port = mv88e6xxx_setup_message_port,
4978 .stats_snapshot = mv88e6390_g1_stats_snapshot,
4979 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
4980 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
4981 .stats_get_strings = mv88e6320_stats_get_strings,
4982 .stats_get_stat = mv88e6390_stats_get_stat,
4983 .set_cpu_port = mv88e6390_g1_set_cpu_port,
4984 .set_egress_port = mv88e6390_g1_set_egress_port,
4985 .watchdog_ops = &mv88e6390_watchdog_ops,
4986 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
4987 .pot_clear = mv88e6xxx_g2_pot_clear,
4988 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
4989 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
4990 .reset = mv88e6352_g1_reset,
4991 .rmu_disable = mv88e6390_g1_rmu_disable,
4992 .atu_get_hash = mv88e6165_g1_atu_get_hash,
4993 .atu_set_hash = mv88e6165_g1_atu_set_hash,
4994 .vtu_getnext = mv88e6390_g1_vtu_getnext,
4995 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
4996 .stu_getnext = mv88e6390_g1_stu_getnext,
4997 .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
4998 .serdes_get_lane = mv88e6390_serdes_get_lane,
4999 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5000 .serdes_get_strings = mv88e6390_serdes_get_strings,
5001 .serdes_get_stats = mv88e6390_serdes_get_stats,
5002 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
5003 .serdes_get_regs = mv88e6390_serdes_get_regs,
5004 .avb_ops = &mv88e6390_avb_ops,
5005 .ptp_ops = &mv88e6352_ptp_ops,
5006 .phylink_get_caps = mv88e6390_phylink_get_caps,
5007 .pcs_ops = &mv88e6390_pcs_ops,
5008 };
5009
5010 static const struct mv88e6xxx_ops mv88e6240_ops = {
5011 /* MV88E6XXX_FAMILY_6352 */
5012 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5013 .ip_pri_map = mv88e6085_g1_ip_pri_map,
5014 .irl_init_all = mv88e6352_g2_irl_init_all,
5015 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
5016 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
5017 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5018 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5019 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5020 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5021 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5022 .port_set_link = mv88e6xxx_port_set_link,
5023 .port_sync_link = mv88e6xxx_port_sync_link,
5024 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
5025 .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
5026 .port_tag_remap = mv88e6095_port_tag_remap,
5027 .port_set_policy = mv88e6352_port_set_policy,
5028 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5029 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5030 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5031 .port_set_ether_type = mv88e6351_port_set_ether_type,
5032 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5033 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5034 .port_pause_limit = mv88e6097_port_pause_limit,
5035 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5036 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5037 .port_get_cmode = mv88e6352_port_get_cmode,
5038 .port_setup_leds = mv88e6xxx_port_setup_leds,
5039 .port_setup_message_port = mv88e6xxx_setup_message_port,
5040 .stats_snapshot = mv88e6320_g1_stats_snapshot,
5041 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5042 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
5043 .stats_get_strings = mv88e6095_stats_get_strings,
5044 .stats_get_stat = mv88e6095_stats_get_stat,
5045 .set_cpu_port = mv88e6095_g1_set_cpu_port,
5046 .set_egress_port = mv88e6095_g1_set_egress_port,
5047 .watchdog_ops = &mv88e6097_watchdog_ops,
5048 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5049 .pot_clear = mv88e6xxx_g2_pot_clear,
5050 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
5051 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
5052 .reset = mv88e6352_reset,
5053 .rmu_disable = mv88e6352_g1_rmu_disable,
5054 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5055 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5056 .vtu_getnext = mv88e6352_g1_vtu_getnext,
5057 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5058 .stu_getnext = mv88e6352_g1_stu_getnext,
5059 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5060 .serdes_get_lane = mv88e6352_serdes_get_lane,
5061 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
5062 .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
5063 .serdes_get_regs = mv88e6352_serdes_get_regs,
5064 .gpio_ops = &mv88e6352_gpio_ops,
5065 .avb_ops = &mv88e6352_avb_ops,
5066 .ptp_ops = &mv88e6352_ptp_ops,
5067 .phylink_get_caps = mv88e6352_phylink_get_caps,
5068 .pcs_ops = &mv88e6352_pcs_ops,
5069 };
5070
5071 static const struct mv88e6xxx_ops mv88e6250_ops = {
5072 /* MV88E6XXX_FAMILY_6250 */
5073 .ieee_pri_map = mv88e6250_g1_ieee_pri_map,
5074 .ip_pri_map = mv88e6085_g1_ip_pri_map,
5075 .irl_init_all = mv88e6352_g2_irl_init_all,
5076 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
5077 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
5078 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5079 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5080 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5081 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5082 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5083 .port_set_link = mv88e6xxx_port_set_link,
5084 .port_sync_link = mv88e6xxx_port_sync_link,
5085 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
5086 .port_set_speed_duplex = mv88e6250_port_set_speed_duplex,
5087 .port_tag_remap = mv88e6095_port_tag_remap,
5088 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5089 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5090 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5091 .port_set_ether_type = mv88e6351_port_set_ether_type,
5092 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5093 .port_pause_limit = mv88e6097_port_pause_limit,
5094 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5095 .stats_snapshot = mv88e6320_g1_stats_snapshot,
5096 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5097 .stats_get_sset_count = mv88e6250_stats_get_sset_count,
5098 .stats_get_strings = mv88e6250_stats_get_strings,
5099 .stats_get_stat = mv88e6250_stats_get_stat,
5100 .set_cpu_port = mv88e6095_g1_set_cpu_port,
5101 .set_egress_port = mv88e6095_g1_set_egress_port,
5102 .watchdog_ops = &mv88e6250_watchdog_ops,
5103 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5104 .pot_clear = mv88e6xxx_g2_pot_clear,
5105 .hardware_reset_pre = mv88e6250_g1_wait_eeprom_done_prereset,
5106 .hardware_reset_post = mv88e6xxx_g1_wait_eeprom_done,
5107 .reset = mv88e6250_g1_reset,
5108 .vtu_getnext = mv88e6185_g1_vtu_getnext,
5109 .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
5110 .avb_ops = &mv88e6352_avb_ops,
5111 .ptp_ops = &mv88e6352_ptp_ops,
5112 .phylink_get_caps = mv88e6250_phylink_get_caps,
5113 .set_max_frame_size = mv88e6185_g1_set_max_frame_size,
5114 };
5115
5116 static const struct mv88e6xxx_ops mv88e6290_ops = {
5117 /* MV88E6XXX_FAMILY_6390 */
5118 .setup_errata = mv88e6390_setup_errata,
5119 .irl_init_all = mv88e6390_g2_irl_init_all,
5120 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
5121 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
5122 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5123 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5124 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5125 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5126 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5127 .port_set_link = mv88e6xxx_port_set_link,
5128 .port_sync_link = mv88e6xxx_port_sync_link,
5129 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
5130 .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
5131 .port_tag_remap = mv88e6390_port_tag_remap,
5132 .port_set_policy = mv88e6352_port_set_policy,
5133 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5134 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5135 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5136 .port_set_ether_type = mv88e6351_port_set_ether_type,
5137 .port_pause_limit = mv88e6390_port_pause_limit,
5138 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5139 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5140 .port_get_cmode = mv88e6352_port_get_cmode,
5141 .port_set_cmode = mv88e6390_port_set_cmode,
5142 .port_setup_message_port = mv88e6xxx_setup_message_port,
5143 .stats_snapshot = mv88e6390_g1_stats_snapshot,
5144 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
5145 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5146 .stats_get_strings = mv88e6320_stats_get_strings,
5147 .stats_get_stat = mv88e6390_stats_get_stat,
5148 .set_cpu_port = mv88e6390_g1_set_cpu_port,
5149 .set_egress_port = mv88e6390_g1_set_egress_port,
5150 .watchdog_ops = &mv88e6390_watchdog_ops,
5151 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
5152 .pot_clear = mv88e6xxx_g2_pot_clear,
5153 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
5154 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
5155 .reset = mv88e6352_g1_reset,
5156 .rmu_disable = mv88e6390_g1_rmu_disable,
5157 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5158 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5159 .vtu_getnext = mv88e6390_g1_vtu_getnext,
5160 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
5161 .stu_getnext = mv88e6390_g1_stu_getnext,
5162 .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
5163 .serdes_get_lane = mv88e6390_serdes_get_lane,
5164 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5165 .serdes_get_strings = mv88e6390_serdes_get_strings,
5166 .serdes_get_stats = mv88e6390_serdes_get_stats,
5167 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
5168 .serdes_get_regs = mv88e6390_serdes_get_regs,
5169 .gpio_ops = &mv88e6352_gpio_ops,
5170 .avb_ops = &mv88e6390_avb_ops,
5171 .ptp_ops = &mv88e6390_ptp_ops,
5172 .phylink_get_caps = mv88e6390_phylink_get_caps,
5173 .pcs_ops = &mv88e6390_pcs_ops,
5174 .tcam_ops = &mv88e6390_tcam_ops,
5175 };
5176
5177 static const struct mv88e6xxx_ops mv88e6320_ops = {
5178 /* MV88E6XXX_FAMILY_6320 */
5179 .setup_errata = mv88e6320_setup_errata,
5180 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5181 .ip_pri_map = mv88e6085_g1_ip_pri_map,
5182 .irl_init_all = mv88e6352_g2_irl_init_all,
5183 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
5184 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
5185 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5186 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5187 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5188 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5189 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5190 .port_set_link = mv88e6xxx_port_set_link,
5191 .port_sync_link = mv88e6xxx_port_sync_link,
5192 .port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,
5193 .port_set_speed_duplex = mv88e6320_port_set_speed_duplex,
5194 .port_tag_remap = mv88e6095_port_tag_remap,
5195 .port_set_policy = mv88e6352_port_set_policy,
5196 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5197 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5198 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5199 .port_set_ether_type = mv88e6351_port_set_ether_type,
5200 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5201 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5202 .port_pause_limit = mv88e6097_port_pause_limit,
5203 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5204 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5205 .port_get_cmode = mv88e6352_port_get_cmode,
5206 .port_setup_message_port = mv88e6xxx_setup_message_port,
5207 .stats_snapshot = mv88e6320_g1_stats_snapshot,
5208 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5209 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5210 .stats_get_strings = mv88e6320_stats_get_strings,
5211 .stats_get_stat = mv88e6320_stats_get_stat,
5212 .set_cpu_port = mv88e6095_g1_set_cpu_port,
5213 .set_egress_port = mv88e6095_g1_set_egress_port,
5214 .watchdog_ops = &mv88e6390_watchdog_ops,
5215 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5216 .pot_clear = mv88e6xxx_g2_pot_clear,
5217 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
5218 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
5219 .reset = mv88e6352_g1_reset,
5220 .rmu_disable = mv88e6352_g1_rmu_disable,
5221 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5222 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5223 .vtu_getnext = mv88e6352_g1_vtu_getnext,
5224 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5225 .stu_getnext = mv88e6352_g1_stu_getnext,
5226 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5227 .gpio_ops = &mv88e6352_gpio_ops,
5228 .avb_ops = &mv88e6352_avb_ops,
5229 .ptp_ops = &mv88e6352_ptp_ops,
5230 .phylink_get_caps = mv88e632x_phylink_get_caps,
5231 };
5232
5233 static const struct mv88e6xxx_ops mv88e6321_ops = {
5234 /* MV88E6XXX_FAMILY_6320 */
5235 .setup_errata = mv88e6320_setup_errata,
5236 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5237 .ip_pri_map = mv88e6085_g1_ip_pri_map,
5238 .irl_init_all = mv88e6352_g2_irl_init_all,
5239 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
5240 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
5241 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5242 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5243 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5244 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5245 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5246 .port_set_link = mv88e6xxx_port_set_link,
5247 .port_sync_link = mv88e6xxx_port_sync_link,
5248 .port_set_rgmii_delay = mv88e6320_port_set_rgmii_delay,
5249 .port_set_speed_duplex = mv88e6320_port_set_speed_duplex,
5250 .port_tag_remap = mv88e6095_port_tag_remap,
5251 .port_set_policy = mv88e6352_port_set_policy,
5252 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5253 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5254 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5255 .port_set_ether_type = mv88e6351_port_set_ether_type,
5256 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5257 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5258 .port_pause_limit = mv88e6097_port_pause_limit,
5259 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5260 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5261 .port_get_cmode = mv88e6352_port_get_cmode,
5262 .port_setup_message_port = mv88e6xxx_setup_message_port,
5263 .stats_snapshot = mv88e6320_g1_stats_snapshot,
5264 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5265 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5266 .stats_get_strings = mv88e6320_stats_get_strings,
5267 .stats_get_stat = mv88e6320_stats_get_stat,
5268 .set_cpu_port = mv88e6095_g1_set_cpu_port,
5269 .set_egress_port = mv88e6095_g1_set_egress_port,
5270 .watchdog_ops = &mv88e6390_watchdog_ops,
5271 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5272 .pot_clear = mv88e6xxx_g2_pot_clear,
5273 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
5274 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
5275 .reset = mv88e6352_g1_reset,
5276 .rmu_disable = mv88e6352_g1_rmu_disable,
5277 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5278 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5279 .vtu_getnext = mv88e6352_g1_vtu_getnext,
5280 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5281 .stu_getnext = mv88e6352_g1_stu_getnext,
5282 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5283 .serdes_get_lane = mv88e6321_serdes_get_lane,
5284 .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
5285 .serdes_get_regs = mv88e6352_serdes_get_regs,
5286 .gpio_ops = &mv88e6352_gpio_ops,
5287 .avb_ops = &mv88e6352_avb_ops,
5288 .ptp_ops = &mv88e6352_ptp_ops,
5289 .phylink_get_caps = mv88e632x_phylink_get_caps,
5290 .pcs_ops = &mv88e6352_pcs_ops,
5291 };
5292
5293 static const struct mv88e6xxx_ops mv88e6341_ops = {
5294 /* MV88E6XXX_FAMILY_6341 */
5295 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5296 .ip_pri_map = mv88e6085_g1_ip_pri_map,
5297 .irl_init_all = mv88e6352_g2_irl_init_all,
5298 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
5299 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
5300 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5301 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5302 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5303 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5304 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5305 .port_set_link = mv88e6xxx_port_set_link,
5306 .port_sync_link = mv88e6xxx_port_sync_link,
5307 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
5308 .port_set_speed_duplex = mv88e6341_port_set_speed_duplex,
5309 .port_tag_remap = mv88e6095_port_tag_remap,
5310 .port_set_policy = mv88e6352_port_set_policy,
5311 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5312 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5313 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5314 .port_set_ether_type = mv88e6351_port_set_ether_type,
5315 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5316 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5317 .port_pause_limit = mv88e6097_port_pause_limit,
5318 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5319 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5320 .port_get_cmode = mv88e6352_port_get_cmode,
5321 .port_set_cmode = mv88e6341_port_set_cmode,
5322 .port_setup_message_port = mv88e6xxx_setup_message_port,
5323 .stats_snapshot = mv88e6390_g1_stats_snapshot,
5324 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
5325 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5326 .stats_get_strings = mv88e6320_stats_get_strings,
5327 .stats_get_stat = mv88e6390_stats_get_stat,
5328 .set_cpu_port = mv88e6390_g1_set_cpu_port,
5329 .set_egress_port = mv88e6390_g1_set_egress_port,
5330 .watchdog_ops = &mv88e6390_watchdog_ops,
5331 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
5332 .pot_clear = mv88e6xxx_g2_pot_clear,
5333 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
5334 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
5335 .reset = mv88e6352_g1_reset,
5336 .rmu_disable = mv88e6390_g1_rmu_disable,
5337 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5338 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5339 .vtu_getnext = mv88e6352_g1_vtu_getnext,
5340 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5341 .stu_getnext = mv88e6352_g1_stu_getnext,
5342 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5343 .serdes_get_lane = mv88e6341_serdes_get_lane,
5344 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5345 .gpio_ops = &mv88e6352_gpio_ops,
5346 .avb_ops = &mv88e6390_avb_ops,
5347 .ptp_ops = &mv88e6352_ptp_ops,
5348 .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
5349 .serdes_get_strings = mv88e6390_serdes_get_strings,
5350 .serdes_get_stats = mv88e6390_serdes_get_stats,
5351 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
5352 .serdes_get_regs = mv88e6390_serdes_get_regs,
5353 .phylink_get_caps = mv88e6341_phylink_get_caps,
5354 .pcs_ops = &mv88e6390_pcs_ops,
5355 };
5356
5357 static const struct mv88e6xxx_ops mv88e6350_ops = {
5358 /* MV88E6XXX_FAMILY_6351 */
5359 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5360 .ip_pri_map = mv88e6085_g1_ip_pri_map,
5361 .irl_init_all = mv88e6352_g2_irl_init_all,
5362 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5363 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5364 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5365 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5366 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5367 .port_set_link = mv88e6xxx_port_set_link,
5368 .port_sync_link = mv88e6xxx_port_sync_link,
5369 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
5370 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
5371 .port_tag_remap = mv88e6095_port_tag_remap,
5372 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5373 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5374 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5375 .port_set_ether_type = mv88e6351_port_set_ether_type,
5376 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5377 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5378 .port_pause_limit = mv88e6097_port_pause_limit,
5379 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5380 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5381 .port_get_cmode = mv88e6352_port_get_cmode,
5382 .port_setup_message_port = mv88e6xxx_setup_message_port,
5383 .stats_snapshot = mv88e6320_g1_stats_snapshot,
5384 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5385 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
5386 .stats_get_strings = mv88e6095_stats_get_strings,
5387 .stats_get_stat = mv88e6095_stats_get_stat,
5388 .set_cpu_port = mv88e6095_g1_set_cpu_port,
5389 .set_egress_port = mv88e6095_g1_set_egress_port,
5390 .watchdog_ops = &mv88e6097_watchdog_ops,
5391 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5392 .pot_clear = mv88e6xxx_g2_pot_clear,
5393 .reset = mv88e6352_g1_reset,
5394 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5395 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5396 .vtu_getnext = mv88e6352_g1_vtu_getnext,
5397 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5398 .stu_getnext = mv88e6352_g1_stu_getnext,
5399 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5400 .phylink_get_caps = mv88e6351_phylink_get_caps,
5401 };
5402
5403 static const struct mv88e6xxx_ops mv88e6351_ops = {
5404 /* MV88E6XXX_FAMILY_6351 */
5405 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5406 .ip_pri_map = mv88e6085_g1_ip_pri_map,
5407 .irl_init_all = mv88e6352_g2_irl_init_all,
5408 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5409 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5410 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5411 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5412 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5413 .port_set_link = mv88e6xxx_port_set_link,
5414 .port_sync_link = mv88e6xxx_port_sync_link,
5415 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
5416 .port_set_speed_duplex = mv88e6185_port_set_speed_duplex,
5417 .port_tag_remap = mv88e6095_port_tag_remap,
5418 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5419 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5420 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5421 .port_set_ether_type = mv88e6351_port_set_ether_type,
5422 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5423 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5424 .port_pause_limit = mv88e6097_port_pause_limit,
5425 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5426 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5427 .port_get_cmode = mv88e6352_port_get_cmode,
5428 .port_setup_message_port = mv88e6xxx_setup_message_port,
5429 .stats_snapshot = mv88e6320_g1_stats_snapshot,
5430 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5431 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
5432 .stats_get_strings = mv88e6095_stats_get_strings,
5433 .stats_get_stat = mv88e6095_stats_get_stat,
5434 .set_cpu_port = mv88e6095_g1_set_cpu_port,
5435 .set_egress_port = mv88e6095_g1_set_egress_port,
5436 .watchdog_ops = &mv88e6097_watchdog_ops,
5437 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5438 .pot_clear = mv88e6xxx_g2_pot_clear,
5439 .reset = mv88e6352_g1_reset,
5440 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5441 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5442 .vtu_getnext = mv88e6352_g1_vtu_getnext,
5443 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5444 .stu_getnext = mv88e6352_g1_stu_getnext,
5445 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5446 .avb_ops = &mv88e6352_avb_ops,
5447 .ptp_ops = &mv88e6352_ptp_ops,
5448 .phylink_get_caps = mv88e6351_phylink_get_caps,
5449 };
5450
5451 static const struct mv88e6xxx_ops mv88e6352_ops = {
5452 /* MV88E6XXX_FAMILY_6352 */
5453 .ieee_pri_map = mv88e6085_g1_ieee_pri_map,
5454 .ip_pri_map = mv88e6085_g1_ip_pri_map,
5455 .irl_init_all = mv88e6352_g2_irl_init_all,
5456 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
5457 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
5458 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5459 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5460 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5461 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5462 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5463 .port_set_link = mv88e6xxx_port_set_link,
5464 .port_sync_link = mv88e6xxx_port_sync_link,
5465 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
5466 .port_set_speed_duplex = mv88e6352_port_set_speed_duplex,
5467 .port_tag_remap = mv88e6095_port_tag_remap,
5468 .port_set_policy = mv88e6352_port_set_policy,
5469 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5470 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5471 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5472 .port_set_ether_type = mv88e6351_port_set_ether_type,
5473 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5474 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5475 .port_pause_limit = mv88e6097_port_pause_limit,
5476 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5477 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5478 .port_get_cmode = mv88e6352_port_get_cmode,
5479 .port_setup_leds = mv88e6xxx_port_setup_leds,
5480 .port_setup_message_port = mv88e6xxx_setup_message_port,
5481 .stats_snapshot = mv88e6320_g1_stats_snapshot,
5482 .stats_set_histogram = mv88e6095_g1_stats_set_histogram,
5483 .stats_get_sset_count = mv88e6095_stats_get_sset_count,
5484 .stats_get_strings = mv88e6095_stats_get_strings,
5485 .stats_get_stat = mv88e6095_stats_get_stat,
5486 .set_cpu_port = mv88e6095_g1_set_cpu_port,
5487 .set_egress_port = mv88e6095_g1_set_egress_port,
5488 .watchdog_ops = &mv88e6097_watchdog_ops,
5489 .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
5490 .pot_clear = mv88e6xxx_g2_pot_clear,
5491 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
5492 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
5493 .reset = mv88e6352_reset,
5494 .rmu_disable = mv88e6352_g1_rmu_disable,
5495 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5496 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5497 .vtu_getnext = mv88e6352_g1_vtu_getnext,
5498 .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
5499 .stu_getnext = mv88e6352_g1_stu_getnext,
5500 .stu_loadpurge = mv88e6352_g1_stu_loadpurge,
5501 .serdes_irq_mapping = mv88e6352_serdes_irq_mapping,
5502 .gpio_ops = &mv88e6352_gpio_ops,
5503 .avb_ops = &mv88e6352_avb_ops,
5504 .ptp_ops = &mv88e6352_ptp_ops,
5505 .serdes_get_lane = mv88e6352_serdes_get_lane,
5506 .serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
5507 .serdes_get_strings = mv88e6352_serdes_get_strings,
5508 .serdes_get_stats = mv88e6352_serdes_get_stats,
5509 .serdes_get_regs_len = mv88e6352_serdes_get_regs_len,
5510 .serdes_get_regs = mv88e6352_serdes_get_regs,
5511 .phylink_get_caps = mv88e6352_phylink_get_caps,
5512 .pcs_ops = &mv88e6352_pcs_ops,
5513 };
5514
5515 static const struct mv88e6xxx_ops mv88e6390_ops = {
5516 /* MV88E6XXX_FAMILY_6390 */
5517 .setup_errata = mv88e6390_setup_errata,
5518 .irl_init_all = mv88e6390_g2_irl_init_all,
5519 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
5520 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
5521 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5522 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5523 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5524 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5525 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5526 .port_set_link = mv88e6xxx_port_set_link,
5527 .port_sync_link = mv88e6xxx_port_sync_link,
5528 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
5529 .port_set_speed_duplex = mv88e6390_port_set_speed_duplex,
5530 .port_tag_remap = mv88e6390_port_tag_remap,
5531 .port_set_policy = mv88e6352_port_set_policy,
5532 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5533 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5534 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5535 .port_set_ether_type = mv88e6351_port_set_ether_type,
5536 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5537 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5538 .port_pause_limit = mv88e6390_port_pause_limit,
5539 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5540 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5541 .port_get_cmode = mv88e6352_port_get_cmode,
5542 .port_set_cmode = mv88e6390_port_set_cmode,
5543 .port_setup_message_port = mv88e6xxx_setup_message_port,
5544 .stats_snapshot = mv88e6390_g1_stats_snapshot,
5545 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
5546 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5547 .stats_get_strings = mv88e6320_stats_get_strings,
5548 .stats_get_stat = mv88e6390_stats_get_stat,
5549 .set_cpu_port = mv88e6390_g1_set_cpu_port,
5550 .set_egress_port = mv88e6390_g1_set_egress_port,
5551 .watchdog_ops = &mv88e6390_watchdog_ops,
5552 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
5553 .pot_clear = mv88e6xxx_g2_pot_clear,
5554 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
5555 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
5556 .reset = mv88e6352_g1_reset,
5557 .rmu_disable = mv88e6390_g1_rmu_disable,
5558 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5559 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5560 .vtu_getnext = mv88e6390_g1_vtu_getnext,
5561 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
5562 .stu_getnext = mv88e6390_g1_stu_getnext,
5563 .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
5564 .serdes_get_lane = mv88e6390_serdes_get_lane,
5565 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5566 .gpio_ops = &mv88e6352_gpio_ops,
5567 .avb_ops = &mv88e6390_avb_ops,
5568 .ptp_ops = &mv88e6390_ptp_ops,
5569 .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
5570 .serdes_get_strings = mv88e6390_serdes_get_strings,
5571 .serdes_get_stats = mv88e6390_serdes_get_stats,
5572 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
5573 .serdes_get_regs = mv88e6390_serdes_get_regs,
5574 .phylink_get_caps = mv88e6390_phylink_get_caps,
5575 .pcs_ops = &mv88e6390_pcs_ops,
5576 .tcam_ops = &mv88e6390_tcam_ops,
5577 };
5578
5579 static const struct mv88e6xxx_ops mv88e6390x_ops = {
5580 /* MV88E6XXX_FAMILY_6390 */
5581 .setup_errata = mv88e6390_setup_errata,
5582 .irl_init_all = mv88e6390_g2_irl_init_all,
5583 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
5584 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
5585 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5586 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5587 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5588 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5589 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5590 .port_set_link = mv88e6xxx_port_set_link,
5591 .port_sync_link = mv88e6xxx_port_sync_link,
5592 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
5593 .port_set_speed_duplex = mv88e6390x_port_set_speed_duplex,
5594 .port_tag_remap = mv88e6390_port_tag_remap,
5595 .port_set_policy = mv88e6352_port_set_policy,
5596 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5597 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5598 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5599 .port_set_ether_type = mv88e6351_port_set_ether_type,
5600 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5601 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5602 .port_pause_limit = mv88e6390_port_pause_limit,
5603 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5604 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5605 .port_get_cmode = mv88e6352_port_get_cmode,
5606 .port_set_cmode = mv88e6390x_port_set_cmode,
5607 .port_setup_message_port = mv88e6xxx_setup_message_port,
5608 .stats_snapshot = mv88e6390_g1_stats_snapshot,
5609 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
5610 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5611 .stats_get_strings = mv88e6320_stats_get_strings,
5612 .stats_get_stat = mv88e6390_stats_get_stat,
5613 .set_cpu_port = mv88e6390_g1_set_cpu_port,
5614 .set_egress_port = mv88e6390_g1_set_egress_port,
5615 .watchdog_ops = &mv88e6390_watchdog_ops,
5616 .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
5617 .pot_clear = mv88e6xxx_g2_pot_clear,
5618 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
5619 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
5620 .reset = mv88e6352_g1_reset,
5621 .rmu_disable = mv88e6390_g1_rmu_disable,
5622 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5623 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5624 .vtu_getnext = mv88e6390_g1_vtu_getnext,
5625 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
5626 .stu_getnext = mv88e6390_g1_stu_getnext,
5627 .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
5628 .serdes_get_lane = mv88e6390x_serdes_get_lane,
5629 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5630 .serdes_get_sset_count = mv88e6390_serdes_get_sset_count,
5631 .serdes_get_strings = mv88e6390_serdes_get_strings,
5632 .serdes_get_stats = mv88e6390_serdes_get_stats,
5633 .serdes_get_regs_len = mv88e6390_serdes_get_regs_len,
5634 .serdes_get_regs = mv88e6390_serdes_get_regs,
5635 .gpio_ops = &mv88e6352_gpio_ops,
5636 .avb_ops = &mv88e6390_avb_ops,
5637 .ptp_ops = &mv88e6390_ptp_ops,
5638 .phylink_get_caps = mv88e6390x_phylink_get_caps,
5639 .pcs_ops = &mv88e6390_pcs_ops,
5640 };
5641
5642 static const struct mv88e6xxx_ops mv88e6393x_ops = {
5643 /* MV88E6XXX_FAMILY_6393 */
5644 .irl_init_all = mv88e6390_g2_irl_init_all,
5645 .get_eeprom = mv88e6xxx_g2_get_eeprom8,
5646 .set_eeprom = mv88e6xxx_g2_set_eeprom8,
5647 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
5648 .phy_read = mv88e6xxx_g2_smi_phy_read_c22,
5649 .phy_write = mv88e6xxx_g2_smi_phy_write_c22,
5650 .phy_read_c45 = mv88e6xxx_g2_smi_phy_read_c45,
5651 .phy_write_c45 = mv88e6xxx_g2_smi_phy_write_c45,
5652 .port_set_link = mv88e6xxx_port_set_link,
5653 .port_sync_link = mv88e6xxx_port_sync_link,
5654 .port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
5655 .port_set_speed_duplex = mv88e6393x_port_set_speed_duplex,
5656 .port_tag_remap = mv88e6390_port_tag_remap,
5657 .port_set_policy = mv88e6393x_port_set_policy,
5658 .port_set_frame_mode = mv88e6351_port_set_frame_mode,
5659 .port_set_ucast_flood = mv88e6352_port_set_ucast_flood,
5660 .port_set_mcast_flood = mv88e6352_port_set_mcast_flood,
5661 .port_set_ether_type = mv88e6393x_port_set_ether_type,
5662 .port_set_jumbo_size = mv88e6165_port_set_jumbo_size,
5663 .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
5664 .port_pause_limit = mv88e6390_port_pause_limit,
5665 .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
5666 .port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
5667 .port_get_cmode = mv88e6352_port_get_cmode,
5668 .port_set_cmode = mv88e6393x_port_set_cmode,
5669 .port_setup_message_port = mv88e6xxx_setup_message_port,
5670 .port_set_upstream_port = mv88e6393x_port_set_upstream_port,
5671 .port_enable_tcam = mv88e6xxx_port_enable_tcam,
5672 .stats_snapshot = mv88e6390_g1_stats_snapshot,
5673 .stats_set_histogram = mv88e6390_g1_stats_set_histogram,
5674 .stats_get_sset_count = mv88e6320_stats_get_sset_count,
5675 .stats_get_strings = mv88e6320_stats_get_strings,
5676 .stats_get_stat = mv88e6390_stats_get_stat,
5677 /* .set_cpu_port is missing because this family does not support a global
5678 * CPU port, only per port CPU port which is set via
5679 * .port_set_upstream_port method.
5680 */
5681 .set_egress_port = mv88e6393x_set_egress_port,
5682 .watchdog_ops = &mv88e6393x_watchdog_ops,
5683 .mgmt_rsvd2cpu = mv88e6393x_port_mgmt_rsvd2cpu,
5684 .pot_clear = mv88e6xxx_g2_pot_clear,
5685 .hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
5686 .hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
5687 .reset = mv88e6352_g1_reset,
5688 .rmu_disable = mv88e6390_g1_rmu_disable,
5689 .atu_get_hash = mv88e6165_g1_atu_get_hash,
5690 .atu_set_hash = mv88e6165_g1_atu_set_hash,
5691 .vtu_getnext = mv88e6390_g1_vtu_getnext,
5692 .vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
5693 .stu_getnext = mv88e6390_g1_stu_getnext,
5694 .stu_loadpurge = mv88e6390_g1_stu_loadpurge,
5695 .serdes_get_lane = mv88e6393x_serdes_get_lane,
5696 .serdes_irq_mapping = mv88e6390_serdes_irq_mapping,
5697 /* TODO: serdes stats */
5698 .gpio_ops = &mv88e6352_gpio_ops,
5699 .avb_ops = &mv88e6390_avb_ops,
5700 .ptp_ops = &mv88e6352_ptp_ops,
5701 .phylink_get_caps = mv88e6393x_phylink_get_caps,
5702 .pcs_ops = &mv88e6393x_pcs_ops,
5703 .tcam_ops = &mv88e6393_tcam_ops,
5704 };
5705
5706 static const struct mv88e6xxx_info mv88e6xxx_table[] = {
5707 [MV88E6020] = {
5708 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6020,
5709 .family = MV88E6XXX_FAMILY_6250,
5710 .name = "Marvell 88E6020",
5711 .num_databases = 64,
5712 /* Ports 2-4 are not routed to pins
5713 * => usable ports 0, 1, 5, 6
5714 */
5715 .num_ports = 7,
5716 .num_internal_phys = 2,
5717 .invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
5718 .max_vid = 4095,
5719 .port_base_addr = 0x8,
5720 .phy_base_addr = 0x0,
5721 .global1_addr = 0xf,
5722 .global2_addr = 0x7,
5723 .age_time_coeff = 15000,
5724 .g1_irqs = 9,
5725 .g2_irqs = 5,
5726 .stats_type = STATS_TYPE_BANK0,
5727 .atu_move_port_mask = 0xf,
5728 .dual_chip = true,
5729 .ops = &mv88e6250_ops,
5730 },
5731
5732 [MV88E6071] = {
5733 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6071,
5734 .family = MV88E6XXX_FAMILY_6250,
5735 .name = "Marvell 88E6071",
5736 .num_databases = 64,
5737 .num_ports = 7,
5738 .num_internal_phys = 5,
5739 .max_vid = 4095,
5740 .port_base_addr = 0x08,
5741 .phy_base_addr = 0x00,
5742 .global1_addr = 0x0f,
5743 .global2_addr = 0x07,
5744 .age_time_coeff = 15000,
5745 .g1_irqs = 9,
5746 .g2_irqs = 5,
5747 .stats_type = STATS_TYPE_BANK0,
5748 .atu_move_port_mask = 0xf,
5749 .dual_chip = true,
5750 .ops = &mv88e6250_ops,
5751 },
5752
5753 [MV88E6085] = {
5754 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6085,
5755 .family = MV88E6XXX_FAMILY_6097,
5756 .name = "Marvell 88E6085",
5757 .num_databases = 4096,
5758 .num_macs = 8192,
5759 .num_ports = 10,
5760 .num_internal_phys = 5,
5761 .max_vid = 4095,
5762 .max_sid = 63,
5763 .port_base_addr = 0x10,
5764 .phy_base_addr = 0x0,
5765 .global1_addr = 0x1b,
5766 .global2_addr = 0x1c,
5767 .age_time_coeff = 15000,
5768 .g1_irqs = 8,
5769 .g2_irqs = 10,
5770 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
5771 .atu_move_port_mask = 0xf,
5772 .pvt = true,
5773 .multi_chip = true,
5774 .ops = &mv88e6085_ops,
5775 },
5776
5777 [MV88E6095] = {
5778 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6095,
5779 .family = MV88E6XXX_FAMILY_6095,
5780 .name = "Marvell 88E6095/88E6095F",
5781 .num_databases = 256,
5782 .num_macs = 8192,
5783 .num_ports = 11,
5784 .num_internal_phys = 0,
5785 .max_vid = 4095,
5786 .port_base_addr = 0x10,
5787 .phy_base_addr = 0x0,
5788 .global1_addr = 0x1b,
5789 .global2_addr = 0x1c,
5790 .age_time_coeff = 15000,
5791 .g1_irqs = 8,
5792 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
5793 .atu_move_port_mask = 0xf,
5794 .multi_chip = true,
5795 .ops = &mv88e6095_ops,
5796 },
5797
5798 [MV88E6097] = {
5799 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6097,
5800 .family = MV88E6XXX_FAMILY_6097,
5801 .name = "Marvell 88E6097/88E6097F",
5802 .num_databases = 4096,
5803 .num_macs = 8192,
5804 .num_ports = 11,
5805 .num_internal_phys = 8,
5806 .max_vid = 4095,
5807 .max_sid = 63,
5808 .port_base_addr = 0x10,
5809 .phy_base_addr = 0x0,
5810 .global1_addr = 0x1b,
5811 .global2_addr = 0x1c,
5812 .age_time_coeff = 15000,
5813 .g1_irqs = 8,
5814 .g2_irqs = 10,
5815 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
5816 .atu_move_port_mask = 0xf,
5817 .pvt = true,
5818 .multi_chip = true,
5819 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5820 .ops = &mv88e6097_ops,
5821 },
5822
5823 [MV88E6123] = {
5824 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6123,
5825 .family = MV88E6XXX_FAMILY_6165,
5826 .name = "Marvell 88E6123",
5827 .num_databases = 4096,
5828 .num_macs = 1024,
5829 .num_ports = 3,
5830 .num_internal_phys = 5,
5831 .max_vid = 4095,
5832 .max_sid = 63,
5833 .port_base_addr = 0x10,
5834 .phy_base_addr = 0x0,
5835 .global1_addr = 0x1b,
5836 .global2_addr = 0x1c,
5837 .age_time_coeff = 15000,
5838 .g1_irqs = 9,
5839 .g2_irqs = 10,
5840 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
5841 .atu_move_port_mask = 0xf,
5842 .pvt = true,
5843 .multi_chip = true,
5844 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5845 .ops = &mv88e6123_ops,
5846 },
5847
5848 [MV88E6131] = {
5849 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6131,
5850 .family = MV88E6XXX_FAMILY_6185,
5851 .name = "Marvell 88E6131",
5852 .num_databases = 256,
5853 .num_macs = 8192,
5854 .num_ports = 8,
5855 .num_internal_phys = 0,
5856 .max_vid = 4095,
5857 .port_base_addr = 0x10,
5858 .phy_base_addr = 0x0,
5859 .global1_addr = 0x1b,
5860 .global2_addr = 0x1c,
5861 .age_time_coeff = 15000,
5862 .g1_irqs = 9,
5863 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
5864 .atu_move_port_mask = 0xf,
5865 .multi_chip = true,
5866 .ops = &mv88e6131_ops,
5867 },
5868
5869 [MV88E6141] = {
5870 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
5871 .family = MV88E6XXX_FAMILY_6341,
5872 .name = "Marvell 88E6141",
5873 .num_databases = 256,
5874 .num_macs = 2048,
5875 .num_ports = 6,
5876 .num_internal_phys = 5,
5877 .num_gpio = 11,
5878 .max_vid = 4095,
5879 .max_sid = 63,
5880 .port_base_addr = 0x10,
5881 .phy_base_addr = 0x10,
5882 .global1_addr = 0x1b,
5883 .global2_addr = 0x1c,
5884 .age_time_coeff = 3750,
5885 .atu_move_port_mask = 0xf,
5886 .g1_irqs = 9,
5887 .g2_irqs = 10,
5888 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
5889 .pvt = true,
5890 .multi_chip = true,
5891 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5892 .ops = &mv88e6141_ops,
5893 },
5894
5895 [MV88E6161] = {
5896 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6161,
5897 .family = MV88E6XXX_FAMILY_6165,
5898 .name = "Marvell 88E6161",
5899 .num_databases = 4096,
5900 .num_macs = 1024,
5901 .num_ports = 6,
5902 .num_internal_phys = 5,
5903 .max_vid = 4095,
5904 .max_sid = 63,
5905 .port_base_addr = 0x10,
5906 .phy_base_addr = 0x0,
5907 .global1_addr = 0x1b,
5908 .global2_addr = 0x1c,
5909 .age_time_coeff = 15000,
5910 .g1_irqs = 9,
5911 .g2_irqs = 10,
5912 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
5913 .atu_move_port_mask = 0xf,
5914 .pvt = true,
5915 .multi_chip = true,
5916 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5917 .ptp_support = true,
5918 .ops = &mv88e6161_ops,
5919 },
5920
5921 [MV88E6165] = {
5922 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6165,
5923 .family = MV88E6XXX_FAMILY_6165,
5924 .name = "Marvell 88E6165",
5925 .num_databases = 4096,
5926 .num_macs = 8192,
5927 .num_ports = 6,
5928 .num_internal_phys = 0,
5929 .max_vid = 4095,
5930 .max_sid = 63,
5931 .port_base_addr = 0x10,
5932 .phy_base_addr = 0x0,
5933 .global1_addr = 0x1b,
5934 .global2_addr = 0x1c,
5935 .age_time_coeff = 15000,
5936 .g1_irqs = 9,
5937 .g2_irqs = 10,
5938 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
5939 .atu_move_port_mask = 0xf,
5940 .pvt = true,
5941 .multi_chip = true,
5942 .ptp_support = true,
5943 .ops = &mv88e6165_ops,
5944 },
5945
5946 [MV88E6171] = {
5947 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6171,
5948 .family = MV88E6XXX_FAMILY_6351,
5949 .name = "Marvell 88E6171",
5950 .num_databases = 4096,
5951 .num_macs = 8192,
5952 .num_ports = 7,
5953 .num_internal_phys = 5,
5954 .max_vid = 4095,
5955 .max_sid = 63,
5956 .port_base_addr = 0x10,
5957 .phy_base_addr = 0x0,
5958 .global1_addr = 0x1b,
5959 .global2_addr = 0x1c,
5960 .age_time_coeff = 15000,
5961 .g1_irqs = 9,
5962 .g2_irqs = 10,
5963 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
5964 .atu_move_port_mask = 0xf,
5965 .pvt = true,
5966 .multi_chip = true,
5967 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5968 .ops = &mv88e6171_ops,
5969 },
5970
5971 [MV88E6172] = {
5972 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6172,
5973 .family = MV88E6XXX_FAMILY_6352,
5974 .name = "Marvell 88E6172",
5975 .num_databases = 4096,
5976 .num_macs = 8192,
5977 .num_ports = 7,
5978 .num_internal_phys = 5,
5979 .num_gpio = 15,
5980 .max_vid = 4095,
5981 .max_sid = 63,
5982 .port_base_addr = 0x10,
5983 .phy_base_addr = 0x0,
5984 .global1_addr = 0x1b,
5985 .global2_addr = 0x1c,
5986 .age_time_coeff = 15000,
5987 .g1_irqs = 9,
5988 .g2_irqs = 10,
5989 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
5990 .atu_move_port_mask = 0xf,
5991 .pvt = true,
5992 .multi_chip = true,
5993 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
5994 .ops = &mv88e6172_ops,
5995 },
5996
5997 [MV88E6175] = {
5998 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6175,
5999 .family = MV88E6XXX_FAMILY_6351,
6000 .name = "Marvell 88E6175",
6001 .num_databases = 4096,
6002 .num_macs = 8192,
6003 .num_ports = 7,
6004 .num_internal_phys = 5,
6005 .max_vid = 4095,
6006 .max_sid = 63,
6007 .port_base_addr = 0x10,
6008 .phy_base_addr = 0x0,
6009 .global1_addr = 0x1b,
6010 .global2_addr = 0x1c,
6011 .age_time_coeff = 15000,
6012 .g1_irqs = 9,
6013 .g2_irqs = 10,
6014 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
6015 .atu_move_port_mask = 0xf,
6016 .pvt = true,
6017 .multi_chip = true,
6018 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6019 .ops = &mv88e6175_ops,
6020 },
6021
6022 [MV88E6176] = {
6023 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6176,
6024 .family = MV88E6XXX_FAMILY_6352,
6025 .name = "Marvell 88E6176",
6026 .num_databases = 4096,
6027 .num_macs = 8192,
6028 .num_ports = 7,
6029 .num_internal_phys = 5,
6030 .num_gpio = 15,
6031 .max_vid = 4095,
6032 .max_sid = 63,
6033 .port_base_addr = 0x10,
6034 .phy_base_addr = 0x0,
6035 .global1_addr = 0x1b,
6036 .global2_addr = 0x1c,
6037 .age_time_coeff = 15000,
6038 .g1_irqs = 9,
6039 .g2_irqs = 10,
6040 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
6041 .atu_move_port_mask = 0xf,
6042 .pvt = true,
6043 .multi_chip = true,
6044 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6045 .ops = &mv88e6176_ops,
6046 },
6047
6048 [MV88E6185] = {
6049 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6185,
6050 .family = MV88E6XXX_FAMILY_6185,
6051 .name = "Marvell 88E6185",
6052 .num_databases = 256,
6053 .num_macs = 8192,
6054 .num_ports = 10,
6055 .num_internal_phys = 0,
6056 .max_vid = 4095,
6057 .port_base_addr = 0x10,
6058 .phy_base_addr = 0x0,
6059 .global1_addr = 0x1b,
6060 .global2_addr = 0x1c,
6061 .age_time_coeff = 15000,
6062 .g1_irqs = 8,
6063 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
6064 .atu_move_port_mask = 0xf,
6065 .multi_chip = true,
6066 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6067 .ops = &mv88e6185_ops,
6068 },
6069
6070 [MV88E6190] = {
6071 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190,
6072 .family = MV88E6XXX_FAMILY_6390,
6073 .name = "Marvell 88E6190",
6074 .num_databases = 4096,
6075 .num_macs = 16384,
6076 .num_ports = 11, /* 10 + Z80 */
6077 .num_internal_phys = 9,
6078 .num_gpio = 16,
6079 .max_vid = 8191,
6080 .max_sid = 63,
6081 .port_base_addr = 0x0,
6082 .phy_base_addr = 0x0,
6083 .global1_addr = 0x1b,
6084 .global2_addr = 0x1c,
6085 .age_time_coeff = 3750,
6086 .g1_irqs = 9,
6087 .g2_irqs = 14,
6088 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6089 .pvt = true,
6090 .multi_chip = true,
6091 .atu_move_port_mask = 0x1f,
6092 .ops = &mv88e6190_ops,
6093 },
6094
6095 [MV88E6190X] = {
6096 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6190X,
6097 .family = MV88E6XXX_FAMILY_6390,
6098 .name = "Marvell 88E6190X",
6099 .num_databases = 4096,
6100 .num_macs = 16384,
6101 .num_ports = 11, /* 10 + Z80 */
6102 .num_internal_phys = 9,
6103 .num_gpio = 16,
6104 .max_vid = 8191,
6105 .max_sid = 63,
6106 .port_base_addr = 0x0,
6107 .phy_base_addr = 0x0,
6108 .global1_addr = 0x1b,
6109 .global2_addr = 0x1c,
6110 .age_time_coeff = 3750,
6111 .g1_irqs = 9,
6112 .g2_irqs = 14,
6113 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6114 .atu_move_port_mask = 0x1f,
6115 .pvt = true,
6116 .multi_chip = true,
6117 .ops = &mv88e6190x_ops,
6118 },
6119
6120 [MV88E6191] = {
6121 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191,
6122 .family = MV88E6XXX_FAMILY_6390,
6123 .name = "Marvell 88E6191",
6124 .num_databases = 4096,
6125 .num_macs = 16384,
6126 .num_ports = 11, /* 10 + Z80 */
6127 .num_internal_phys = 9,
6128 .max_vid = 8191,
6129 .max_sid = 63,
6130 .port_base_addr = 0x0,
6131 .phy_base_addr = 0x0,
6132 .global1_addr = 0x1b,
6133 .global2_addr = 0x1c,
6134 .age_time_coeff = 3750,
6135 .g1_irqs = 9,
6136 .g2_irqs = 14,
6137 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6138 .atu_move_port_mask = 0x1f,
6139 .pvt = true,
6140 .multi_chip = true,
6141 .ptp_support = true,
6142 .ops = &mv88e6191_ops,
6143 },
6144
6145 [MV88E6191X] = {
6146 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6191X,
6147 .family = MV88E6XXX_FAMILY_6393,
6148 .name = "Marvell 88E6191X",
6149 .num_databases = 4096,
6150 .num_ports = 11, /* 10 + Z80 */
6151 .num_internal_phys = 8,
6152 .internal_phys_offset = 1,
6153 .max_vid = 8191,
6154 .max_sid = 63,
6155 .port_base_addr = 0x0,
6156 .phy_base_addr = 0x0,
6157 .global1_addr = 0x1b,
6158 .global2_addr = 0x1c,
6159 .age_time_coeff = 3750,
6160 .g1_irqs = 10,
6161 .g2_irqs = 14,
6162 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6163 .atu_move_port_mask = 0x1f,
6164 .pvt = true,
6165 .multi_chip = true,
6166 .ptp_support = true,
6167 .ops = &mv88e6393x_ops,
6168 },
6169
6170 [MV88E6193X] = {
6171 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6193X,
6172 .family = MV88E6XXX_FAMILY_6393,
6173 .name = "Marvell 88E6193X",
6174 .num_databases = 4096,
6175 .num_ports = 11, /* 10 + Z80 */
6176 .num_internal_phys = 8,
6177 .num_tcam_entries = 256,
6178 .internal_phys_offset = 1,
6179 .max_vid = 8191,
6180 .max_sid = 63,
6181 .port_base_addr = 0x0,
6182 .phy_base_addr = 0x0,
6183 .global1_addr = 0x1b,
6184 .global2_addr = 0x1c,
6185 .tcam_addr = 0x1f,
6186 .age_time_coeff = 3750,
6187 .g1_irqs = 10,
6188 .g2_irqs = 14,
6189 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6190 .atu_move_port_mask = 0x1f,
6191 .pvt = true,
6192 .multi_chip = true,
6193 .ptp_support = true,
6194 .ops = &mv88e6393x_ops,
6195 },
6196
6197 [MV88E6220] = {
6198 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6220,
6199 .family = MV88E6XXX_FAMILY_6250,
6200 .name = "Marvell 88E6220",
6201 .num_databases = 64,
6202
6203 /* Ports 2-4 are not routed to pins
6204 * => usable ports 0, 1, 5, 6
6205 */
6206 .num_ports = 7,
6207 .num_internal_phys = 2,
6208 .invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
6209 .max_vid = 4095,
6210 .port_base_addr = 0x08,
6211 .phy_base_addr = 0x00,
6212 .global1_addr = 0x0f,
6213 .global2_addr = 0x07,
6214 .age_time_coeff = 15000,
6215 .g1_irqs = 9,
6216 .g2_irqs = 10,
6217 .stats_type = STATS_TYPE_BANK0,
6218 .atu_move_port_mask = 0xf,
6219 .dual_chip = true,
6220 .ptp_support = true,
6221 .ops = &mv88e6250_ops,
6222 },
6223
6224 [MV88E6240] = {
6225 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240,
6226 .family = MV88E6XXX_FAMILY_6352,
6227 .name = "Marvell 88E6240",
6228 .num_databases = 4096,
6229 .num_macs = 8192,
6230 .num_ports = 7,
6231 .num_internal_phys = 5,
6232 .num_gpio = 15,
6233 .max_vid = 4095,
6234 .max_sid = 63,
6235 .port_base_addr = 0x10,
6236 .phy_base_addr = 0x0,
6237 .global1_addr = 0x1b,
6238 .global2_addr = 0x1c,
6239 .age_time_coeff = 15000,
6240 .g1_irqs = 9,
6241 .g2_irqs = 10,
6242 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
6243 .atu_move_port_mask = 0xf,
6244 .pvt = true,
6245 .multi_chip = true,
6246 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6247 .ptp_support = true,
6248 .ops = &mv88e6240_ops,
6249 },
6250
6251 [MV88E6250] = {
6252 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250,
6253 .family = MV88E6XXX_FAMILY_6250,
6254 .name = "Marvell 88E6250",
6255 .num_databases = 64,
6256 .num_ports = 7,
6257 .num_internal_phys = 5,
6258 .max_vid = 4095,
6259 .port_base_addr = 0x08,
6260 .phy_base_addr = 0x00,
6261 .global1_addr = 0x0f,
6262 .global2_addr = 0x07,
6263 .age_time_coeff = 15000,
6264 .g1_irqs = 9,
6265 .g2_irqs = 10,
6266 .stats_type = STATS_TYPE_BANK0,
6267 .atu_move_port_mask = 0xf,
6268 .dual_chip = true,
6269 .ptp_support = true,
6270 .ops = &mv88e6250_ops,
6271 },
6272
6273 [MV88E6290] = {
6274 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6290,
6275 .family = MV88E6XXX_FAMILY_6390,
6276 .name = "Marvell 88E6290",
6277 .num_databases = 4096,
6278 .num_ports = 11, /* 10 + Z80 */
6279 .num_internal_phys = 9,
6280 .num_gpio = 16,
6281 .num_tcam_entries = 256,
6282 .max_vid = 8191,
6283 .max_sid = 63,
6284 .port_base_addr = 0x0,
6285 .phy_base_addr = 0x0,
6286 .global1_addr = 0x1b,
6287 .global2_addr = 0x1c,
6288 .tcam_addr = 0x1f,
6289 .age_time_coeff = 3750,
6290 .g1_irqs = 9,
6291 .g2_irqs = 14,
6292 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6293 .atu_move_port_mask = 0x1f,
6294 .pvt = true,
6295 .multi_chip = true,
6296 .ptp_support = true,
6297 .ops = &mv88e6290_ops,
6298 },
6299
6300 [MV88E6320] = {
6301 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6320,
6302 .family = MV88E6XXX_FAMILY_6320,
6303 .name = "Marvell 88E6320",
6304 .num_databases = 4096,
6305 .num_macs = 8192,
6306 .num_ports = 7,
6307 .num_internal_phys = 2,
6308 .internal_phys_offset = 3,
6309 .num_gpio = 15,
6310 .max_vid = 4095,
6311 .max_sid = 63,
6312 .port_base_addr = 0x10,
6313 .phy_base_addr = 0x0,
6314 .global1_addr = 0x1b,
6315 .global2_addr = 0x1c,
6316 .age_time_coeff = 15000,
6317 .g1_irqs = 9,
6318 .g2_irqs = 10,
6319 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6320 .atu_move_port_mask = 0xf,
6321 .pvt = true,
6322 .multi_chip = true,
6323 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6324 .ptp_support = true,
6325 .ops = &mv88e6320_ops,
6326 },
6327
6328 [MV88E6321] = {
6329 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6321,
6330 .family = MV88E6XXX_FAMILY_6320,
6331 .name = "Marvell 88E6321",
6332 .num_databases = 4096,
6333 .num_macs = 8192,
6334 .num_ports = 7,
6335 .num_internal_phys = 2,
6336 .internal_phys_offset = 3,
6337 .num_gpio = 15,
6338 .max_vid = 4095,
6339 .max_sid = 63,
6340 .port_base_addr = 0x10,
6341 .phy_base_addr = 0x0,
6342 .global1_addr = 0x1b,
6343 .global2_addr = 0x1c,
6344 .age_time_coeff = 15000,
6345 .g1_irqs = 9,
6346 .g2_irqs = 10,
6347 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6348 .atu_move_port_mask = 0xf,
6349 .pvt = true,
6350 .multi_chip = true,
6351 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6352 .ptp_support = true,
6353 .ops = &mv88e6321_ops,
6354 },
6355
6356 [MV88E6341] = {
6357 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
6358 .family = MV88E6XXX_FAMILY_6341,
6359 .name = "Marvell 88E6341",
6360 .num_databases = 256,
6361 .num_macs = 2048,
6362 .num_internal_phys = 5,
6363 .num_ports = 6,
6364 .num_gpio = 11,
6365 .max_vid = 4095,
6366 .max_sid = 63,
6367 .port_base_addr = 0x10,
6368 .phy_base_addr = 0x10,
6369 .global1_addr = 0x1b,
6370 .global2_addr = 0x1c,
6371 .age_time_coeff = 3750,
6372 .atu_move_port_mask = 0xf,
6373 .g1_irqs = 9,
6374 .g2_irqs = 10,
6375 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6376 .pvt = true,
6377 .multi_chip = true,
6378 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6379 .ptp_support = true,
6380 .ops = &mv88e6341_ops,
6381 },
6382
6383 [MV88E6350] = {
6384 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6350,
6385 .family = MV88E6XXX_FAMILY_6351,
6386 .name = "Marvell 88E6350",
6387 .num_databases = 4096,
6388 .num_macs = 8192,
6389 .num_ports = 7,
6390 .num_internal_phys = 5,
6391 .max_vid = 4095,
6392 .max_sid = 63,
6393 .port_base_addr = 0x10,
6394 .phy_base_addr = 0x0,
6395 .global1_addr = 0x1b,
6396 .global2_addr = 0x1c,
6397 .age_time_coeff = 15000,
6398 .g1_irqs = 9,
6399 .g2_irqs = 10,
6400 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
6401 .atu_move_port_mask = 0xf,
6402 .pvt = true,
6403 .multi_chip = true,
6404 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6405 .ops = &mv88e6350_ops,
6406 },
6407
6408 [MV88E6351] = {
6409 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6351,
6410 .family = MV88E6XXX_FAMILY_6351,
6411 .name = "Marvell 88E6351",
6412 .num_databases = 4096,
6413 .num_macs = 8192,
6414 .num_ports = 7,
6415 .num_internal_phys = 5,
6416 .max_vid = 4095,
6417 .max_sid = 63,
6418 .port_base_addr = 0x10,
6419 .phy_base_addr = 0x0,
6420 .global1_addr = 0x1b,
6421 .global2_addr = 0x1c,
6422 .age_time_coeff = 15000,
6423 .g1_irqs = 9,
6424 .g2_irqs = 10,
6425 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
6426 .atu_move_port_mask = 0xf,
6427 .pvt = true,
6428 .multi_chip = true,
6429 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6430 .ops = &mv88e6351_ops,
6431 },
6432
6433 [MV88E6352] = {
6434 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6352,
6435 .family = MV88E6XXX_FAMILY_6352,
6436 .name = "Marvell 88E6352",
6437 .num_databases = 4096,
6438 .num_macs = 8192,
6439 .num_ports = 7,
6440 .num_internal_phys = 5,
6441 .num_gpio = 15,
6442 .max_vid = 4095,
6443 .max_sid = 63,
6444 .port_base_addr = 0x10,
6445 .phy_base_addr = 0x0,
6446 .global1_addr = 0x1b,
6447 .global2_addr = 0x1c,
6448 .age_time_coeff = 15000,
6449 .g1_irqs = 9,
6450 .g2_irqs = 10,
6451 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_PORT,
6452 .atu_move_port_mask = 0xf,
6453 .pvt = true,
6454 .multi_chip = true,
6455 .edsa_support = MV88E6XXX_EDSA_SUPPORTED,
6456 .ptp_support = true,
6457 .ops = &mv88e6352_ops,
6458 },
6459 [MV88E6361] = {
6460 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6361,
6461 .family = MV88E6XXX_FAMILY_6393,
6462 .name = "Marvell 88E6361",
6463 .num_databases = 4096,
6464 .num_macs = 16384,
6465 .num_ports = 11,
6466 /* Ports 1, 2 and 8 are not routed */
6467 .invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
6468 .num_internal_phys = 5,
6469 .internal_phys_offset = 3,
6470 .max_vid = 8191,
6471 .max_sid = 63,
6472 .port_base_addr = 0x0,
6473 .phy_base_addr = 0x0,
6474 .global1_addr = 0x1b,
6475 .global2_addr = 0x1c,
6476 .age_time_coeff = 3750,
6477 .g1_irqs = 10,
6478 .g2_irqs = 14,
6479 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6480 .atu_move_port_mask = 0x1f,
6481 .pvt = true,
6482 .multi_chip = true,
6483 .ptp_support = true,
6484 .ops = &mv88e6393x_ops,
6485 },
6486 [MV88E6390] = {
6487 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
6488 .family = MV88E6XXX_FAMILY_6390,
6489 .name = "Marvell 88E6390",
6490 .num_databases = 4096,
6491 .num_macs = 16384,
6492 .num_ports = 11, /* 10 + Z80 */
6493 .num_internal_phys = 9,
6494 .num_gpio = 16,
6495 .num_tcam_entries = 256,
6496 .max_vid = 8191,
6497 .max_sid = 63,
6498 .port_base_addr = 0x0,
6499 .phy_base_addr = 0x0,
6500 .global1_addr = 0x1b,
6501 .global2_addr = 0x1c,
6502 .tcam_addr = 0x1f,
6503 .age_time_coeff = 3750,
6504 .g1_irqs = 9,
6505 .g2_irqs = 14,
6506 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6507 .atu_move_port_mask = 0x1f,
6508 .pvt = true,
6509 .multi_chip = true,
6510 .edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED,
6511 .ptp_support = true,
6512 .ops = &mv88e6390_ops,
6513 },
6514 [MV88E6390X] = {
6515 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6390X,
6516 .family = MV88E6XXX_FAMILY_6390,
6517 .name = "Marvell 88E6390X",
6518 .num_databases = 4096,
6519 .num_macs = 16384,
6520 .num_ports = 11, /* 10 + Z80 */
6521 .num_internal_phys = 9,
6522 .num_gpio = 16,
6523 .max_vid = 8191,
6524 .max_sid = 63,
6525 .port_base_addr = 0x0,
6526 .phy_base_addr = 0x0,
6527 .global1_addr = 0x1b,
6528 .global2_addr = 0x1c,
6529 .age_time_coeff = 3750,
6530 .g1_irqs = 9,
6531 .g2_irqs = 14,
6532 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6533 .atu_move_port_mask = 0x1f,
6534 .pvt = true,
6535 .multi_chip = true,
6536 .edsa_support = MV88E6XXX_EDSA_UNDOCUMENTED,
6537 .ptp_support = true,
6538 .ops = &mv88e6390x_ops,
6539 },
6540
6541 [MV88E6393X] = {
6542 .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6393X,
6543 .family = MV88E6XXX_FAMILY_6393,
6544 .name = "Marvell 88E6393X",
6545 .num_databases = 4096,
6546 .num_ports = 11, /* 10 + Z80 */
6547 .num_internal_phys = 8,
6548 .num_tcam_entries = 256,
6549 .internal_phys_offset = 1,
6550 .max_vid = 8191,
6551 .max_sid = 63,
6552 .port_base_addr = 0x0,
6553 .phy_base_addr = 0x0,
6554 .global1_addr = 0x1b,
6555 .global2_addr = 0x1c,
6556 .tcam_addr = 0x1f,
6557 .age_time_coeff = 3750,
6558 .g1_irqs = 10,
6559 .g2_irqs = 14,
6560 .stats_type = STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
6561 .atu_move_port_mask = 0x1f,
6562 .pvt = true,
6563 .multi_chip = true,
6564 .ptp_support = true,
6565 .ops = &mv88e6393x_ops,
6566 },
6567 };
6568
mv88e6xxx_lookup_info(unsigned int prod_num)6569 static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
6570 {
6571 int i;
6572
6573 for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
6574 if (mv88e6xxx_table[i].prod_num == prod_num)
6575 return &mv88e6xxx_table[i];
6576
6577 return NULL;
6578 }
6579
mv88e6xxx_detect(struct mv88e6xxx_chip * chip)6580 static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
6581 {
6582 const struct mv88e6xxx_info *info;
6583 unsigned int prod_num, rev;
6584 u16 id;
6585 int err;
6586
6587 mv88e6xxx_reg_lock(chip);
6588 err = mv88e6xxx_port_read(chip, 0, MV88E6XXX_PORT_SWITCH_ID, &id);
6589 mv88e6xxx_reg_unlock(chip);
6590 if (err)
6591 return err;
6592
6593 prod_num = id & MV88E6XXX_PORT_SWITCH_ID_PROD_MASK;
6594 rev = id & MV88E6XXX_PORT_SWITCH_ID_REV_MASK;
6595
6596 info = mv88e6xxx_lookup_info(prod_num);
6597 if (!info)
6598 return -ENODEV;
6599
6600 /* Update the compatible info with the probed one */
6601 chip->info = info;
6602
6603 dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
6604 chip->info->prod_num, chip->info->name, rev);
6605
6606 return 0;
6607 }
6608
mv88e6xxx_single_chip_detect(struct mv88e6xxx_chip * chip,struct mdio_device * mdiodev)6609 static int mv88e6xxx_single_chip_detect(struct mv88e6xxx_chip *chip,
6610 struct mdio_device *mdiodev)
6611 {
6612 int err;
6613
6614 /* dual_chip takes precedence over single/multi-chip modes */
6615 if (chip->info->dual_chip)
6616 return -EINVAL;
6617
6618 /* If the mdio addr is 16 indicating the first port address of a switch
6619 * (e.g. mv88e6*41) in single chip addressing mode the device may be
6620 * configured in single chip addressing mode. Setup the smi access as
6621 * single chip addressing mode and attempt to detect the model of the
6622 * switch, if this fails the device is not configured in single chip
6623 * addressing mode.
6624 */
6625 if (mdiodev->addr != 16)
6626 return -EINVAL;
6627
6628 err = mv88e6xxx_smi_init(chip, mdiodev->bus, 0);
6629 if (err)
6630 return err;
6631
6632 return mv88e6xxx_detect(chip);
6633 }
6634
mv88e6xxx_alloc_chip(struct device * dev)6635 static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
6636 {
6637 struct mv88e6xxx_chip *chip;
6638
6639 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
6640 if (!chip)
6641 return NULL;
6642
6643 chip->dev = dev;
6644
6645 mutex_init(&chip->reg_lock);
6646 INIT_LIST_HEAD(&chip->mdios);
6647 idr_init(&chip->policies);
6648 INIT_LIST_HEAD(&chip->msts);
6649 INIT_LIST_HEAD(&chip->tcam.entries);
6650
6651 return chip;
6652 }
6653
mv88e6xxx_get_tag_protocol(struct dsa_switch * ds,int port,enum dsa_tag_protocol m)6654 static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
6655 int port,
6656 enum dsa_tag_protocol m)
6657 {
6658 struct mv88e6xxx_chip *chip = ds->priv;
6659
6660 return chip->tag_protocol;
6661 }
6662
mv88e6xxx_change_tag_protocol(struct dsa_switch * ds,enum dsa_tag_protocol proto)6663 static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds,
6664 enum dsa_tag_protocol proto)
6665 {
6666 struct mv88e6xxx_chip *chip = ds->priv;
6667 enum dsa_tag_protocol old_protocol;
6668 struct dsa_port *cpu_dp;
6669 int err;
6670
6671 switch (proto) {
6672 case DSA_TAG_PROTO_EDSA:
6673 switch (chip->info->edsa_support) {
6674 case MV88E6XXX_EDSA_UNSUPPORTED:
6675 return -EPROTONOSUPPORT;
6676 case MV88E6XXX_EDSA_UNDOCUMENTED:
6677 dev_warn(chip->dev, "Relying on undocumented EDSA tagging behavior\n");
6678 fallthrough;
6679 case MV88E6XXX_EDSA_SUPPORTED:
6680 break;
6681 }
6682 break;
6683 case DSA_TAG_PROTO_DSA:
6684 break;
6685 default:
6686 return -EPROTONOSUPPORT;
6687 }
6688
6689 old_protocol = chip->tag_protocol;
6690 chip->tag_protocol = proto;
6691
6692 mv88e6xxx_reg_lock(chip);
6693 dsa_switch_for_each_cpu_port(cpu_dp, ds) {
6694 err = mv88e6xxx_setup_port_mode(chip, cpu_dp->index);
6695 if (err) {
6696 mv88e6xxx_reg_unlock(chip);
6697 goto unwind;
6698 }
6699 }
6700 mv88e6xxx_reg_unlock(chip);
6701
6702 return 0;
6703
6704 unwind:
6705 chip->tag_protocol = old_protocol;
6706
6707 mv88e6xxx_reg_lock(chip);
6708 dsa_switch_for_each_cpu_port_continue_reverse(cpu_dp, ds)
6709 mv88e6xxx_setup_port_mode(chip, cpu_dp->index);
6710 mv88e6xxx_reg_unlock(chip);
6711
6712 return err;
6713 }
6714
mv88e6xxx_port_mdb_add(struct dsa_switch * ds,int port,const struct switchdev_obj_port_mdb * mdb,struct dsa_db db)6715 static int mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
6716 const struct switchdev_obj_port_mdb *mdb,
6717 struct dsa_db db)
6718 {
6719 struct mv88e6xxx_chip *chip = ds->priv;
6720 int err;
6721
6722 mv88e6xxx_reg_lock(chip);
6723 err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
6724 MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC);
6725 if (err)
6726 goto out;
6727
6728 if (!mv88e6xxx_port_db_find(chip, mdb->addr, mdb->vid))
6729 err = -ENOSPC;
6730
6731 out:
6732 mv88e6xxx_reg_unlock(chip);
6733
6734 return err;
6735 }
6736
mv88e6xxx_port_mdb_del(struct dsa_switch * ds,int port,const struct switchdev_obj_port_mdb * mdb,struct dsa_db db)6737 static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
6738 const struct switchdev_obj_port_mdb *mdb,
6739 struct dsa_db db)
6740 {
6741 struct mv88e6xxx_chip *chip = ds->priv;
6742 int err;
6743
6744 mv88e6xxx_reg_lock(chip);
6745 err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid, 0);
6746 mv88e6xxx_reg_unlock(chip);
6747
6748 return err;
6749 }
6750
mv88e6xxx_port_mirror_add(struct dsa_switch * ds,int port,struct dsa_mall_mirror_tc_entry * mirror,bool ingress,struct netlink_ext_ack * extack)6751 static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int port,
6752 struct dsa_mall_mirror_tc_entry *mirror,
6753 bool ingress,
6754 struct netlink_ext_ack *extack)
6755 {
6756 enum mv88e6xxx_egress_direction direction = ingress ?
6757 MV88E6XXX_EGRESS_DIR_INGRESS :
6758 MV88E6XXX_EGRESS_DIR_EGRESS;
6759 struct mv88e6xxx_chip *chip = ds->priv;
6760 bool other_mirrors = false;
6761 int i;
6762 int err;
6763
6764 mutex_lock(&chip->reg_lock);
6765 if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) !=
6766 mirror->to_local_port) {
6767 for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
6768 other_mirrors |= ingress ?
6769 chip->ports[i].mirror_ingress :
6770 chip->ports[i].mirror_egress;
6771
6772 /* Can't change egress port when other mirror is active */
6773 if (other_mirrors) {
6774 err = -EBUSY;
6775 goto out;
6776 }
6777
6778 err = mv88e6xxx_set_egress_port(chip, direction,
6779 mirror->to_local_port);
6780 if (err)
6781 goto out;
6782 }
6783
6784 err = mv88e6xxx_port_set_mirror(chip, port, direction, true);
6785 out:
6786 mutex_unlock(&chip->reg_lock);
6787
6788 return err;
6789 }
6790
mv88e6xxx_port_mirror_del(struct dsa_switch * ds,int port,struct dsa_mall_mirror_tc_entry * mirror)6791 static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int port,
6792 struct dsa_mall_mirror_tc_entry *mirror)
6793 {
6794 enum mv88e6xxx_egress_direction direction = mirror->ingress ?
6795 MV88E6XXX_EGRESS_DIR_INGRESS :
6796 MV88E6XXX_EGRESS_DIR_EGRESS;
6797 struct mv88e6xxx_chip *chip = ds->priv;
6798 bool other_mirrors = false;
6799 int i;
6800
6801 mutex_lock(&chip->reg_lock);
6802 if (mv88e6xxx_port_set_mirror(chip, port, direction, false))
6803 dev_err(ds->dev, "p%d: failed to disable mirroring\n", port);
6804
6805 for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
6806 other_mirrors |= mirror->ingress ?
6807 chip->ports[i].mirror_ingress :
6808 chip->ports[i].mirror_egress;
6809
6810 /* Reset egress port when no other mirror is active */
6811 if (!other_mirrors) {
6812 if (mv88e6xxx_set_egress_port(chip, direction,
6813 dsa_upstream_port(ds, port)))
6814 dev_err(ds->dev, "failed to set egress port\n");
6815 }
6816
6817 mutex_unlock(&chip->reg_lock);
6818 }
6819
mv88e6xxx_port_pre_bridge_flags(struct dsa_switch * ds,int port,struct switchdev_brport_flags flags,struct netlink_ext_ack * extack)6820 static int mv88e6xxx_port_pre_bridge_flags(struct dsa_switch *ds, int port,
6821 struct switchdev_brport_flags flags,
6822 struct netlink_ext_ack *extack)
6823 {
6824 struct mv88e6xxx_chip *chip = ds->priv;
6825 const struct mv88e6xxx_ops *ops;
6826
6827 if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
6828 BR_BCAST_FLOOD | BR_PORT_LOCKED | BR_PORT_MAB))
6829 return -EINVAL;
6830
6831 ops = chip->info->ops;
6832
6833 if ((flags.mask & BR_FLOOD) && !ops->port_set_ucast_flood)
6834 return -EINVAL;
6835
6836 if ((flags.mask & BR_MCAST_FLOOD) && !ops->port_set_mcast_flood)
6837 return -EINVAL;
6838
6839 return 0;
6840 }
6841
mv88e6xxx_port_bridge_flags(struct dsa_switch * ds,int port,struct switchdev_brport_flags flags,struct netlink_ext_ack * extack)6842 static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port,
6843 struct switchdev_brport_flags flags,
6844 struct netlink_ext_ack *extack)
6845 {
6846 struct mv88e6xxx_chip *chip = ds->priv;
6847 int err = 0;
6848
6849 mv88e6xxx_reg_lock(chip);
6850
6851 if (flags.mask & BR_LEARNING) {
6852 bool learning = !!(flags.val & BR_LEARNING);
6853 u16 pav = learning ? (1 << port) : 0;
6854
6855 err = mv88e6xxx_port_set_assoc_vector(chip, port, pav);
6856 if (err)
6857 goto out;
6858 }
6859
6860 if (flags.mask & BR_FLOOD) {
6861 bool unicast = !!(flags.val & BR_FLOOD);
6862
6863 err = chip->info->ops->port_set_ucast_flood(chip, port,
6864 unicast);
6865 if (err)
6866 goto out;
6867 }
6868
6869 if (flags.mask & BR_MCAST_FLOOD) {
6870 bool multicast = !!(flags.val & BR_MCAST_FLOOD);
6871
6872 err = chip->info->ops->port_set_mcast_flood(chip, port,
6873 multicast);
6874 if (err)
6875 goto out;
6876 }
6877
6878 if (flags.mask & BR_BCAST_FLOOD) {
6879 bool broadcast = !!(flags.val & BR_BCAST_FLOOD);
6880
6881 err = mv88e6xxx_port_broadcast_sync(chip, port, broadcast);
6882 if (err)
6883 goto out;
6884 }
6885
6886 if (flags.mask & BR_PORT_MAB) {
6887 bool mab = !!(flags.val & BR_PORT_MAB);
6888
6889 mv88e6xxx_port_set_mab(chip, port, mab);
6890 }
6891
6892 if (flags.mask & BR_PORT_LOCKED) {
6893 bool locked = !!(flags.val & BR_PORT_LOCKED);
6894
6895 err = mv88e6xxx_port_set_lock(chip, port, locked);
6896 if (err)
6897 goto out;
6898 }
6899 out:
6900 mv88e6xxx_reg_unlock(chip);
6901
6902 return err;
6903 }
6904
mv88e6xxx_lag_can_offload(struct dsa_switch * ds,struct dsa_lag lag,struct netdev_lag_upper_info * info,struct netlink_ext_ack * extack)6905 static bool mv88e6xxx_lag_can_offload(struct dsa_switch *ds,
6906 struct dsa_lag lag,
6907 struct netdev_lag_upper_info *info,
6908 struct netlink_ext_ack *extack)
6909 {
6910 struct mv88e6xxx_chip *chip = ds->priv;
6911 struct dsa_port *dp;
6912 int members = 0;
6913
6914 if (!mv88e6xxx_has_lag(chip)) {
6915 NL_SET_ERR_MSG_MOD(extack, "Chip does not support LAG offload");
6916 return false;
6917 }
6918
6919 if (!lag.id)
6920 return false;
6921
6922 dsa_lag_foreach_port(dp, ds->dst, &lag)
6923 /* Includes the port joining the LAG */
6924 members++;
6925
6926 if (members > 8) {
6927 NL_SET_ERR_MSG_MOD(extack,
6928 "Cannot offload more than 8 LAG ports");
6929 return false;
6930 }
6931
6932 /* We could potentially relax this to include active
6933 * backup in the future.
6934 */
6935 if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
6936 NL_SET_ERR_MSG_MOD(extack,
6937 "Can only offload LAG using hash TX type");
6938 return false;
6939 }
6940
6941 /* Ideally we would also validate that the hash type matches
6942 * the hardware. Alas, this is always set to unknown on team
6943 * interfaces.
6944 */
6945 return true;
6946 }
6947
mv88e6xxx_lag_sync_map(struct dsa_switch * ds,struct dsa_lag lag)6948 static int mv88e6xxx_lag_sync_map(struct dsa_switch *ds, struct dsa_lag lag)
6949 {
6950 struct mv88e6xxx_chip *chip = ds->priv;
6951 struct dsa_port *dp;
6952 u16 map = 0;
6953 int id;
6954
6955 /* DSA LAG IDs are one-based, hardware is zero-based */
6956 id = lag.id - 1;
6957
6958 /* Build the map of all ports to distribute flows destined for
6959 * this LAG. This can be either a local user port, or a DSA
6960 * port if the LAG port is on a remote chip.
6961 */
6962 dsa_lag_foreach_port(dp, ds->dst, &lag)
6963 map |= BIT(dsa_towards_port(ds, dp->ds->index, dp->index));
6964
6965 return mv88e6xxx_g2_trunk_mapping_write(chip, id, map);
6966 }
6967
6968 static const u8 mv88e6xxx_lag_mask_table[8][8] = {
6969 /* Row number corresponds to the number of active members in a
6970 * LAG. Each column states which of the eight hash buckets are
6971 * mapped to the column:th port in the LAG.
6972 *
6973 * Example: In a LAG with three active ports, the second port
6974 * ([2][1]) would be selected for traffic mapped to buckets
6975 * 3,4,5 (0x38).
6976 */
6977 { 0xff, 0, 0, 0, 0, 0, 0, 0 },
6978 { 0x0f, 0xf0, 0, 0, 0, 0, 0, 0 },
6979 { 0x07, 0x38, 0xc0, 0, 0, 0, 0, 0 },
6980 { 0x03, 0x0c, 0x30, 0xc0, 0, 0, 0, 0 },
6981 { 0x03, 0x0c, 0x30, 0x40, 0x80, 0, 0, 0 },
6982 { 0x03, 0x0c, 0x10, 0x20, 0x40, 0x80, 0, 0 },
6983 { 0x03, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0 },
6984 { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
6985 };
6986
mv88e6xxx_lag_set_port_mask(u16 * mask,int port,int num_tx,int nth)6987 static void mv88e6xxx_lag_set_port_mask(u16 *mask, int port,
6988 int num_tx, int nth)
6989 {
6990 u8 active = 0;
6991 int i;
6992
6993 num_tx = num_tx <= 8 ? num_tx : 8;
6994 if (nth < num_tx)
6995 active = mv88e6xxx_lag_mask_table[num_tx - 1][nth];
6996
6997 for (i = 0; i < 8; i++) {
6998 if (BIT(i) & active)
6999 mask[i] |= BIT(port);
7000 }
7001 }
7002
mv88e6xxx_lag_sync_masks(struct dsa_switch * ds)7003 static int mv88e6xxx_lag_sync_masks(struct dsa_switch *ds)
7004 {
7005 struct mv88e6xxx_chip *chip = ds->priv;
7006 unsigned int id, num_tx;
7007 struct dsa_port *dp;
7008 struct dsa_lag *lag;
7009 int i, err, nth;
7010 u16 mask[8];
7011 u16 ivec;
7012
7013 /* Assume no port is a member of any LAG. */
7014 ivec = BIT(mv88e6xxx_num_ports(chip)) - 1;
7015
7016 /* Disable all masks for ports that _are_ members of a LAG. */
7017 dsa_switch_for_each_port(dp, ds) {
7018 if (!dp->lag)
7019 continue;
7020
7021 ivec &= ~BIT(dp->index);
7022 }
7023
7024 for (i = 0; i < 8; i++)
7025 mask[i] = ivec;
7026
7027 /* Enable the correct subset of masks for all LAG ports that
7028 * are in the Tx set.
7029 */
7030 dsa_lags_foreach_id(id, ds->dst) {
7031 lag = dsa_lag_by_id(ds->dst, id);
7032 if (!lag)
7033 continue;
7034
7035 num_tx = 0;
7036 dsa_lag_foreach_port(dp, ds->dst, lag) {
7037 if (dp->lag_tx_enabled)
7038 num_tx++;
7039 }
7040
7041 if (!num_tx)
7042 continue;
7043
7044 nth = 0;
7045 dsa_lag_foreach_port(dp, ds->dst, lag) {
7046 if (!dp->lag_tx_enabled)
7047 continue;
7048
7049 if (dp->ds == ds)
7050 mv88e6xxx_lag_set_port_mask(mask, dp->index,
7051 num_tx, nth);
7052
7053 nth++;
7054 }
7055 }
7056
7057 for (i = 0; i < 8; i++) {
7058 err = mv88e6xxx_g2_trunk_mask_write(chip, i, true, mask[i]);
7059 if (err)
7060 return err;
7061 }
7062
7063 return 0;
7064 }
7065
mv88e6xxx_lag_sync_masks_map(struct dsa_switch * ds,struct dsa_lag lag)7066 static int mv88e6xxx_lag_sync_masks_map(struct dsa_switch *ds,
7067 struct dsa_lag lag)
7068 {
7069 int err;
7070
7071 err = mv88e6xxx_lag_sync_masks(ds);
7072
7073 if (!err)
7074 err = mv88e6xxx_lag_sync_map(ds, lag);
7075
7076 return err;
7077 }
7078
mv88e6xxx_port_lag_change(struct dsa_switch * ds,int port)7079 static int mv88e6xxx_port_lag_change(struct dsa_switch *ds, int port)
7080 {
7081 struct mv88e6xxx_chip *chip = ds->priv;
7082 int err;
7083
7084 mv88e6xxx_reg_lock(chip);
7085 err = mv88e6xxx_lag_sync_masks(ds);
7086 mv88e6xxx_reg_unlock(chip);
7087 return err;
7088 }
7089
mv88e6xxx_port_lag_join(struct dsa_switch * ds,int port,struct dsa_lag lag,struct netdev_lag_upper_info * info,struct netlink_ext_ack * extack)7090 static int mv88e6xxx_port_lag_join(struct dsa_switch *ds, int port,
7091 struct dsa_lag lag,
7092 struct netdev_lag_upper_info *info,
7093 struct netlink_ext_ack *extack)
7094 {
7095 struct mv88e6xxx_chip *chip = ds->priv;
7096 int err, id;
7097
7098 if (!mv88e6xxx_lag_can_offload(ds, lag, info, extack))
7099 return -EOPNOTSUPP;
7100
7101 /* DSA LAG IDs are one-based */
7102 id = lag.id - 1;
7103
7104 mv88e6xxx_reg_lock(chip);
7105
7106 err = mv88e6xxx_port_set_trunk(chip, port, true, id);
7107 if (err)
7108 goto err_unlock;
7109
7110 err = mv88e6xxx_lag_sync_masks_map(ds, lag);
7111 if (err)
7112 goto err_clear_trunk;
7113
7114 mv88e6xxx_reg_unlock(chip);
7115 return 0;
7116
7117 err_clear_trunk:
7118 mv88e6xxx_port_set_trunk(chip, port, false, 0);
7119 err_unlock:
7120 mv88e6xxx_reg_unlock(chip);
7121 return err;
7122 }
7123
mv88e6xxx_port_lag_leave(struct dsa_switch * ds,int port,struct dsa_lag lag)7124 static int mv88e6xxx_port_lag_leave(struct dsa_switch *ds, int port,
7125 struct dsa_lag lag)
7126 {
7127 struct mv88e6xxx_chip *chip = ds->priv;
7128 int err_sync, err_trunk;
7129
7130 mv88e6xxx_reg_lock(chip);
7131 err_sync = mv88e6xxx_lag_sync_masks_map(ds, lag);
7132 err_trunk = mv88e6xxx_port_set_trunk(chip, port, false, 0);
7133 mv88e6xxx_reg_unlock(chip);
7134 return err_sync ? : err_trunk;
7135 }
7136
mv88e6xxx_crosschip_lag_change(struct dsa_switch * ds,int sw_index,int port)7137 static int mv88e6xxx_crosschip_lag_change(struct dsa_switch *ds, int sw_index,
7138 int port)
7139 {
7140 struct mv88e6xxx_chip *chip = ds->priv;
7141 int err;
7142
7143 mv88e6xxx_reg_lock(chip);
7144 err = mv88e6xxx_lag_sync_masks(ds);
7145 mv88e6xxx_reg_unlock(chip);
7146 return err;
7147 }
7148
mv88e6xxx_crosschip_lag_join(struct dsa_switch * ds,int sw_index,int port,struct dsa_lag lag,struct netdev_lag_upper_info * info,struct netlink_ext_ack * extack)7149 static int mv88e6xxx_crosschip_lag_join(struct dsa_switch *ds, int sw_index,
7150 int port, struct dsa_lag lag,
7151 struct netdev_lag_upper_info *info,
7152 struct netlink_ext_ack *extack)
7153 {
7154 struct mv88e6xxx_chip *chip = ds->priv;
7155 int err;
7156
7157 if (!mv88e6xxx_lag_can_offload(ds, lag, info, extack))
7158 return -EOPNOTSUPP;
7159
7160 mv88e6xxx_reg_lock(chip);
7161
7162 err = mv88e6xxx_lag_sync_masks_map(ds, lag);
7163 if (err)
7164 goto unlock;
7165
7166 err = mv88e6xxx_pvt_map(chip, sw_index, port);
7167
7168 unlock:
7169 mv88e6xxx_reg_unlock(chip);
7170 return err;
7171 }
7172
mv88e6xxx_crosschip_lag_leave(struct dsa_switch * ds,int sw_index,int port,struct dsa_lag lag)7173 static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index,
7174 int port, struct dsa_lag lag)
7175 {
7176 struct mv88e6xxx_chip *chip = ds->priv;
7177 int err_sync, err_pvt;
7178
7179 mv88e6xxx_reg_lock(chip);
7180 err_sync = mv88e6xxx_lag_sync_masks_map(ds, lag);
7181 err_pvt = mv88e6xxx_pvt_map(chip, sw_index, port);
7182 mv88e6xxx_reg_unlock(chip);
7183 return err_sync ? : err_pvt;
7184 }
7185
7186 static const struct phylink_mac_ops mv88e6xxx_phylink_mac_ops = {
7187 .mac_select_pcs = mv88e6xxx_mac_select_pcs,
7188 .mac_prepare = mv88e6xxx_mac_prepare,
7189 .mac_config = mv88e6xxx_mac_config,
7190 .mac_finish = mv88e6xxx_mac_finish,
7191 .mac_link_down = mv88e6xxx_mac_link_down,
7192 .mac_link_up = mv88e6xxx_mac_link_up,
7193 };
7194
7195 static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
7196 .get_tag_protocol = mv88e6xxx_get_tag_protocol,
7197 .change_tag_protocol = mv88e6xxx_change_tag_protocol,
7198 .setup = mv88e6xxx_setup,
7199 .teardown = mv88e6xxx_teardown,
7200 .port_setup = mv88e6xxx_port_setup,
7201 .port_teardown = mv88e6xxx_port_teardown,
7202 .phylink_get_caps = mv88e6xxx_get_caps,
7203 .get_strings = mv88e6xxx_get_strings,
7204 .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
7205 .get_eth_mac_stats = mv88e6xxx_get_eth_mac_stats,
7206 .get_rmon_stats = mv88e6xxx_get_rmon_stats,
7207 .get_sset_count = mv88e6xxx_get_sset_count,
7208 .port_max_mtu = mv88e6xxx_get_max_mtu,
7209 .port_change_mtu = mv88e6xxx_change_mtu,
7210 .support_eee = dsa_supports_eee,
7211 .set_mac_eee = mv88e6xxx_set_mac_eee,
7212 .get_eeprom_len = mv88e6xxx_get_eeprom_len,
7213 .get_eeprom = mv88e6xxx_get_eeprom,
7214 .set_eeprom = mv88e6xxx_set_eeprom,
7215 .get_regs_len = mv88e6xxx_get_regs_len,
7216 .get_regs = mv88e6xxx_get_regs,
7217 .get_rxnfc = mv88e6xxx_get_rxnfc,
7218 .set_rxnfc = mv88e6xxx_set_rxnfc,
7219 .set_ageing_time = mv88e6xxx_set_ageing_time,
7220 .port_bridge_join = mv88e6xxx_port_bridge_join,
7221 .port_bridge_leave = mv88e6xxx_port_bridge_leave,
7222 .port_pre_bridge_flags = mv88e6xxx_port_pre_bridge_flags,
7223 .port_bridge_flags = mv88e6xxx_port_bridge_flags,
7224 .port_stp_state_set = mv88e6xxx_port_stp_state_set,
7225 .port_mst_state_set = mv88e6xxx_port_mst_state_set,
7226 .port_fast_age = mv88e6xxx_port_fast_age,
7227 .port_vlan_fast_age = mv88e6xxx_port_vlan_fast_age,
7228 .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
7229 .port_vlan_add = mv88e6xxx_port_vlan_add,
7230 .port_vlan_del = mv88e6xxx_port_vlan_del,
7231 .vlan_msti_set = mv88e6xxx_vlan_msti_set,
7232 .port_fdb_add = mv88e6xxx_port_fdb_add,
7233 .port_fdb_del = mv88e6xxx_port_fdb_del,
7234 .port_fdb_dump = mv88e6xxx_port_fdb_dump,
7235 .port_mdb_add = mv88e6xxx_port_mdb_add,
7236 .port_mdb_del = mv88e6xxx_port_mdb_del,
7237 .port_mirror_add = mv88e6xxx_port_mirror_add,
7238 .port_mirror_del = mv88e6xxx_port_mirror_del,
7239 .crosschip_bridge_join = mv88e6xxx_crosschip_bridge_join,
7240 .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave,
7241 .port_hwtstamp_set = mv88e6xxx_port_hwtstamp_set,
7242 .port_hwtstamp_get = mv88e6xxx_port_hwtstamp_get,
7243 .port_txtstamp = mv88e6xxx_port_txtstamp,
7244 .port_rxtstamp = mv88e6xxx_port_rxtstamp,
7245 .cls_flower_add = mv88e6xxx_cls_flower_add,
7246 .cls_flower_del = mv88e6xxx_cls_flower_del,
7247 .get_ts_info = mv88e6xxx_get_ts_info,
7248 .devlink_param_get = mv88e6xxx_devlink_param_get,
7249 .devlink_param_set = mv88e6xxx_devlink_param_set,
7250 .devlink_info_get = mv88e6xxx_devlink_info_get,
7251 .port_lag_change = mv88e6xxx_port_lag_change,
7252 .port_lag_join = mv88e6xxx_port_lag_join,
7253 .port_lag_leave = mv88e6xxx_port_lag_leave,
7254 .crosschip_lag_change = mv88e6xxx_crosschip_lag_change,
7255 .crosschip_lag_join = mv88e6xxx_crosschip_lag_join,
7256 .crosschip_lag_leave = mv88e6xxx_crosschip_lag_leave,
7257 };
7258
mv88e6xxx_register_switch(struct mv88e6xxx_chip * chip)7259 static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
7260 {
7261 struct device *dev = chip->dev;
7262 struct dsa_switch *ds;
7263
7264 ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
7265 if (!ds)
7266 return -ENOMEM;
7267
7268 ds->dev = dev;
7269 ds->num_ports = mv88e6xxx_num_ports(chip);
7270 ds->priv = chip;
7271 ds->dev = dev;
7272 ds->ops = &mv88e6xxx_switch_ops;
7273 ds->phylink_mac_ops = &mv88e6xxx_phylink_mac_ops;
7274 ds->ageing_time_min = chip->info->age_time_coeff;
7275 ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
7276
7277 /* Some chips support up to 32, but that requires enabling the
7278 * 5-bit port mode, which we do not support. 640k^W16 ought to
7279 * be enough for anyone.
7280 */
7281 ds->num_lag_ids = mv88e6xxx_has_lag(chip) ? 16 : 0;
7282
7283 dev_set_drvdata(dev, ds);
7284
7285 return dsa_register_switch(ds);
7286 }
7287
mv88e6xxx_unregister_switch(struct mv88e6xxx_chip * chip)7288 static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
7289 {
7290 dsa_unregister_switch(chip->ds);
7291 }
7292
pdata_device_get_match_data(struct device * dev)7293 static const void *pdata_device_get_match_data(struct device *dev)
7294 {
7295 const struct of_device_id *matches = dev->driver->of_match_table;
7296 const struct dsa_mv88e6xxx_pdata *pdata = dev->platform_data;
7297
7298 for (; matches->name[0] || matches->type[0] || matches->compatible[0];
7299 matches++) {
7300 if (!strcmp(pdata->compatible, matches->compatible))
7301 return matches->data;
7302 }
7303 return NULL;
7304 }
7305
7306 /* There is no suspend to RAM support at DSA level yet, the switch configuration
7307 * would be lost after a power cycle so prevent it to be suspended.
7308 */
mv88e6xxx_suspend(struct device * dev)7309 static int __maybe_unused mv88e6xxx_suspend(struct device *dev)
7310 {
7311 return -EOPNOTSUPP;
7312 }
7313
mv88e6xxx_resume(struct device * dev)7314 static int __maybe_unused mv88e6xxx_resume(struct device *dev)
7315 {
7316 return 0;
7317 }
7318
7319 static SIMPLE_DEV_PM_OPS(mv88e6xxx_pm_ops, mv88e6xxx_suspend, mv88e6xxx_resume);
7320
mv88e6xxx_probe(struct mdio_device * mdiodev)7321 static int mv88e6xxx_probe(struct mdio_device *mdiodev)
7322 {
7323 struct dsa_mv88e6xxx_pdata *pdata = mdiodev->dev.platform_data;
7324 const struct mv88e6xxx_info *compat_info = NULL;
7325 struct device *dev = &mdiodev->dev;
7326 struct device_node *np = dev->of_node;
7327 struct mv88e6xxx_chip *chip;
7328 int port;
7329 int err;
7330
7331 if (!np && !pdata)
7332 return -EINVAL;
7333
7334 if (np)
7335 compat_info = of_device_get_match_data(dev);
7336
7337 if (pdata) {
7338 compat_info = pdata_device_get_match_data(dev);
7339
7340 if (!pdata->netdev)
7341 return -EINVAL;
7342
7343 for (port = 0; port < DSA_MAX_PORTS; port++) {
7344 if (!(pdata->enabled_ports & (1 << port)))
7345 continue;
7346 if (strcmp(pdata->cd.port_names[port], "cpu"))
7347 continue;
7348 pdata->cd.netdev[port] = &pdata->netdev->dev;
7349 break;
7350 }
7351 }
7352
7353 if (!compat_info)
7354 return -EINVAL;
7355
7356 chip = mv88e6xxx_alloc_chip(dev);
7357 if (!chip) {
7358 err = -ENOMEM;
7359 goto out;
7360 }
7361
7362 chip->info = compat_info;
7363
7364 chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
7365 if (IS_ERR(chip->reset)) {
7366 err = PTR_ERR(chip->reset);
7367 goto out;
7368 }
7369 if (chip->reset)
7370 usleep_range(10000, 20000);
7371
7372 /* Detect if the device is configured in single chip addressing mode,
7373 * otherwise continue with address specific smi init/detection.
7374 */
7375 err = mv88e6xxx_single_chip_detect(chip, mdiodev);
7376 if (err) {
7377 err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
7378 if (err)
7379 goto out;
7380
7381 err = mv88e6xxx_detect(chip);
7382 if (err)
7383 goto out;
7384 }
7385
7386 if (chip->info->edsa_support == MV88E6XXX_EDSA_SUPPORTED)
7387 chip->tag_protocol = DSA_TAG_PROTO_EDSA;
7388 else
7389 chip->tag_protocol = DSA_TAG_PROTO_DSA;
7390
7391 mv88e6xxx_phy_init(chip);
7392
7393 if (chip->info->ops->get_eeprom) {
7394 if (np)
7395 of_property_read_u32(np, "eeprom-length",
7396 &chip->eeprom_len);
7397 else
7398 chip->eeprom_len = pdata->eeprom_len;
7399 }
7400
7401 mv88e6xxx_reg_lock(chip);
7402 err = mv88e6xxx_switch_reset(chip);
7403 mv88e6xxx_reg_unlock(chip);
7404 if (err)
7405 goto out_phy;
7406
7407 if (np) {
7408 chip->irq = of_irq_get(np, 0);
7409 if (chip->irq == -EPROBE_DEFER) {
7410 err = chip->irq;
7411 goto out_phy;
7412 }
7413 }
7414
7415 if (pdata)
7416 chip->irq = pdata->irq;
7417
7418 /* Has to be performed before the MDIO bus is created, because
7419 * the PHYs will link their interrupts to these interrupt
7420 * controllers
7421 */
7422 mv88e6xxx_reg_lock(chip);
7423 if (chip->irq > 0)
7424 err = mv88e6xxx_g1_irq_setup(chip);
7425 else
7426 err = mv88e6xxx_irq_poll_setup(chip);
7427 mv88e6xxx_reg_unlock(chip);
7428
7429 if (err)
7430 goto out_phy;
7431
7432 if (chip->info->g2_irqs > 0) {
7433 err = mv88e6xxx_g2_irq_setup(chip);
7434 if (err)
7435 goto out_g1_irq;
7436 }
7437
7438 err = mv88e6xxx_g1_atu_prob_irq_setup(chip);
7439 if (err)
7440 goto out_g2_irq;
7441
7442 err = mv88e6xxx_g1_vtu_prob_irq_setup(chip);
7443 if (err)
7444 goto out_g1_atu_prob_irq;
7445
7446 err = mv88e6xxx_register_switch(chip);
7447 if (err)
7448 goto out_g1_vtu_prob_irq;
7449
7450 return 0;
7451
7452 out_g1_vtu_prob_irq:
7453 mv88e6xxx_g1_vtu_prob_irq_free(chip);
7454 out_g1_atu_prob_irq:
7455 mv88e6xxx_g1_atu_prob_irq_free(chip);
7456 out_g2_irq:
7457 if (chip->info->g2_irqs > 0)
7458 mv88e6xxx_g2_irq_free(chip);
7459 out_g1_irq:
7460 if (chip->irq > 0)
7461 mv88e6xxx_g1_irq_free(chip);
7462 else
7463 mv88e6xxx_irq_poll_free(chip);
7464 out_phy:
7465 mv88e6xxx_phy_destroy(chip);
7466 out:
7467 if (pdata)
7468 dev_put(pdata->netdev);
7469
7470 return err;
7471 }
7472
mv88e6xxx_remove(struct mdio_device * mdiodev)7473 static void mv88e6xxx_remove(struct mdio_device *mdiodev)
7474 {
7475 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
7476 struct mv88e6xxx_chip *chip;
7477
7478 if (!ds)
7479 return;
7480
7481 chip = ds->priv;
7482
7483 mv88e6xxx_unregister_switch(chip);
7484
7485 mv88e6xxx_g1_vtu_prob_irq_free(chip);
7486 mv88e6xxx_g1_atu_prob_irq_free(chip);
7487
7488 if (chip->info->g2_irqs > 0)
7489 mv88e6xxx_g2_irq_free(chip);
7490
7491 if (chip->irq > 0)
7492 mv88e6xxx_g1_irq_free(chip);
7493 else
7494 mv88e6xxx_irq_poll_free(chip);
7495
7496 mv88e6xxx_phy_destroy(chip);
7497 }
7498
mv88e6xxx_shutdown(struct mdio_device * mdiodev)7499 static void mv88e6xxx_shutdown(struct mdio_device *mdiodev)
7500 {
7501 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
7502
7503 if (!ds)
7504 return;
7505
7506 dsa_switch_shutdown(ds);
7507
7508 dev_set_drvdata(&mdiodev->dev, NULL);
7509 }
7510
7511 static const struct of_device_id mv88e6xxx_of_match[] = {
7512 {
7513 .compatible = "marvell,mv88e6085",
7514 .data = &mv88e6xxx_table[MV88E6085],
7515 },
7516 {
7517 .compatible = "marvell,mv88e6190",
7518 .data = &mv88e6xxx_table[MV88E6190],
7519 },
7520 {
7521 .compatible = "marvell,mv88e6250",
7522 .data = &mv88e6xxx_table[MV88E6250],
7523 },
7524 { /* sentinel */ },
7525 };
7526
7527 MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match);
7528
7529 static struct mdio_driver mv88e6xxx_driver = {
7530 .probe = mv88e6xxx_probe,
7531 .remove = mv88e6xxx_remove,
7532 .shutdown = mv88e6xxx_shutdown,
7533 .mdiodrv.driver = {
7534 .name = "mv88e6085",
7535 .of_match_table = mv88e6xxx_of_match,
7536 .pm = &mv88e6xxx_pm_ops,
7537 },
7538 };
7539
7540 mdio_module_driver(mv88e6xxx_driver);
7541
7542 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
7543 MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
7544 MODULE_LICENSE("GPL");
7545