]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/net/dsa/mv88e6xxx/chip.c
net: dsa: mv88e6xxx: Mask g1 interrupts and free interrupt
[mirror_ubuntu-bionic-kernel.git] / drivers / net / dsa / mv88e6xxx / chip.c
CommitLineData
91da11f8 1/*
0d3cd4b6
VD
2 * Marvell 88e6xxx Ethernet switch single-chip support
3 *
91da11f8
LB
4 * Copyright (c) 2008 Marvell Semiconductor
5 *
b8fee957
VD
6 * Copyright (c) 2015 CMC Electronics, Inc.
7 * Added support for VLAN Table Unit operations
8 *
14c7b3c3
AL
9 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
10 *
91da11f8
LB
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
19b2f97e 17#include <linux/delay.h>
defb05b9 18#include <linux/etherdevice.h>
dea87024 19#include <linux/ethtool.h>
facd95b2 20#include <linux/if_bridge.h>
dc30c35b
AL
21#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/irqdomain.h>
19b2f97e 24#include <linux/jiffies.h>
91da11f8 25#include <linux/list.h>
14c7b3c3 26#include <linux/mdio.h>
2bbba277 27#include <linux/module.h>
caac8545 28#include <linux/of_device.h>
dc30c35b 29#include <linux/of_irq.h>
b516d453 30#include <linux/of_mdio.h>
91da11f8 31#include <linux/netdevice.h>
c8c1b39a 32#include <linux/gpio/consumer.h>
91da11f8 33#include <linux/phy.h>
c8f0b869 34#include <net/dsa.h>
1f36faf2 35#include <net/switchdev.h>
ec561276 36
91da11f8 37#include "mv88e6xxx.h"
a935c052 38#include "global1.h"
ec561276 39#include "global2.h"
18abed21 40#include "port.h"
91da11f8 41
fad09c73 42static void assert_reg_lock(struct mv88e6xxx_chip *chip)
3996a4ff 43{
fad09c73
VD
44 if (unlikely(!mutex_is_locked(&chip->reg_lock))) {
45 dev_err(chip->dev, "Switch registers lock not held!\n");
3996a4ff
VD
46 dump_stack();
47 }
48}
49
914b32f6
VD
50/* The switch ADDR[4:1] configuration pins define the chip SMI device address
51 * (ADDR[0] is always zero, thus only even SMI addresses can be strapped).
52 *
53 * When ADDR is all zero, the chip uses Single-chip Addressing Mode, assuming it
54 * is the only device connected to the SMI master. In this mode it responds to
55 * all 32 possible SMI addresses, and thus maps directly the internal devices.
56 *
57 * When ADDR is non-zero, the chip uses Multi-chip Addressing Mode, allowing
58 * multiple devices to share the SMI interface. In this mode it responds to only
59 * 2 registers, used to indirectly access the internal SMI devices.
91da11f8 60 */
914b32f6 61
fad09c73 62static int mv88e6xxx_smi_read(struct mv88e6xxx_chip *chip,
914b32f6
VD
63 int addr, int reg, u16 *val)
64{
fad09c73 65 if (!chip->smi_ops)
914b32f6
VD
66 return -EOPNOTSUPP;
67
fad09c73 68 return chip->smi_ops->read(chip, addr, reg, val);
914b32f6
VD
69}
70
fad09c73 71static int mv88e6xxx_smi_write(struct mv88e6xxx_chip *chip,
914b32f6
VD
72 int addr, int reg, u16 val)
73{
fad09c73 74 if (!chip->smi_ops)
914b32f6
VD
75 return -EOPNOTSUPP;
76
fad09c73 77 return chip->smi_ops->write(chip, addr, reg, val);
914b32f6
VD
78}
79
fad09c73 80static int mv88e6xxx_smi_single_chip_read(struct mv88e6xxx_chip *chip,
914b32f6
VD
81 int addr, int reg, u16 *val)
82{
83 int ret;
84
fad09c73 85 ret = mdiobus_read_nested(chip->bus, addr, reg);
914b32f6
VD
86 if (ret < 0)
87 return ret;
88
89 *val = ret & 0xffff;
90
91 return 0;
92}
93
fad09c73 94static int mv88e6xxx_smi_single_chip_write(struct mv88e6xxx_chip *chip,
914b32f6
VD
95 int addr, int reg, u16 val)
96{
97 int ret;
98
fad09c73 99 ret = mdiobus_write_nested(chip->bus, addr, reg, val);
914b32f6
VD
100 if (ret < 0)
101 return ret;
102
103 return 0;
104}
105
c08026ab 106static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_single_chip_ops = {
914b32f6
VD
107 .read = mv88e6xxx_smi_single_chip_read,
108 .write = mv88e6xxx_smi_single_chip_write,
109};
110
fad09c73 111static int mv88e6xxx_smi_multi_chip_wait(struct mv88e6xxx_chip *chip)
91da11f8
LB
112{
113 int ret;
114 int i;
115
116 for (i = 0; i < 16; i++) {
fad09c73 117 ret = mdiobus_read_nested(chip->bus, chip->sw_addr, SMI_CMD);
91da11f8
LB
118 if (ret < 0)
119 return ret;
120
cca8b133 121 if ((ret & SMI_CMD_BUSY) == 0)
91da11f8
LB
122 return 0;
123 }
124
125 return -ETIMEDOUT;
126}
127
fad09c73 128static int mv88e6xxx_smi_multi_chip_read(struct mv88e6xxx_chip *chip,
914b32f6 129 int addr, int reg, u16 *val)
91da11f8
LB
130{
131 int ret;
132
3675c8d7 133 /* Wait for the bus to become free. */
fad09c73 134 ret = mv88e6xxx_smi_multi_chip_wait(chip);
91da11f8
LB
135 if (ret < 0)
136 return ret;
137
3675c8d7 138 /* Transmit the read command. */
fad09c73 139 ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_CMD,
6e899e6c 140 SMI_CMD_OP_22_READ | (addr << 5) | reg);
91da11f8
LB
141 if (ret < 0)
142 return ret;
143
3675c8d7 144 /* Wait for the read command to complete. */
fad09c73 145 ret = mv88e6xxx_smi_multi_chip_wait(chip);
91da11f8
LB
146 if (ret < 0)
147 return ret;
148
3675c8d7 149 /* Read the data. */
fad09c73 150 ret = mdiobus_read_nested(chip->bus, chip->sw_addr, SMI_DATA);
bb92ea5e
VD
151 if (ret < 0)
152 return ret;
153
914b32f6 154 *val = ret & 0xffff;
91da11f8 155
914b32f6 156 return 0;
8d6d09e7
GR
157}
158
fad09c73 159static int mv88e6xxx_smi_multi_chip_write(struct mv88e6xxx_chip *chip,
914b32f6 160 int addr, int reg, u16 val)
91da11f8
LB
161{
162 int ret;
163
3675c8d7 164 /* Wait for the bus to become free. */
fad09c73 165 ret = mv88e6xxx_smi_multi_chip_wait(chip);
91da11f8
LB
166 if (ret < 0)
167 return ret;
168
3675c8d7 169 /* Transmit the data to write. */
fad09c73 170 ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_DATA, val);
91da11f8
LB
171 if (ret < 0)
172 return ret;
173
3675c8d7 174 /* Transmit the write command. */
fad09c73 175 ret = mdiobus_write_nested(chip->bus, chip->sw_addr, SMI_CMD,
6e899e6c 176 SMI_CMD_OP_22_WRITE | (addr << 5) | reg);
91da11f8
LB
177 if (ret < 0)
178 return ret;
179
3675c8d7 180 /* Wait for the write command to complete. */
fad09c73 181 ret = mv88e6xxx_smi_multi_chip_wait(chip);
91da11f8
LB
182 if (ret < 0)
183 return ret;
184
185 return 0;
186}
187
c08026ab 188static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_multi_chip_ops = {
914b32f6
VD
189 .read = mv88e6xxx_smi_multi_chip_read,
190 .write = mv88e6xxx_smi_multi_chip_write,
191};
192
ec561276 193int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val)
914b32f6
VD
194{
195 int err;
196
fad09c73 197 assert_reg_lock(chip);
914b32f6 198
fad09c73 199 err = mv88e6xxx_smi_read(chip, addr, reg, val);
914b32f6
VD
200 if (err)
201 return err;
202
fad09c73 203 dev_dbg(chip->dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
914b32f6
VD
204 addr, reg, *val);
205
206 return 0;
207}
208
ec561276 209int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
91da11f8 210{
914b32f6
VD
211 int err;
212
fad09c73 213 assert_reg_lock(chip);
91da11f8 214
fad09c73 215 err = mv88e6xxx_smi_write(chip, addr, reg, val);
914b32f6
VD
216 if (err)
217 return err;
218
fad09c73 219 dev_dbg(chip->dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n",
bb92ea5e
VD
220 addr, reg, val);
221
914b32f6
VD
222 return 0;
223}
224
e57e5e77
VD
225static int mv88e6xxx_phy_read(struct mv88e6xxx_chip *chip, int phy,
226 int reg, u16 *val)
227{
228 int addr = phy; /* PHY devices addresses start at 0x0 */
229
b3469dd8 230 if (!chip->info->ops->phy_read)
e57e5e77
VD
231 return -EOPNOTSUPP;
232
b3469dd8 233 return chip->info->ops->phy_read(chip, addr, reg, val);
e57e5e77
VD
234}
235
236static int mv88e6xxx_phy_write(struct mv88e6xxx_chip *chip, int phy,
237 int reg, u16 val)
238{
239 int addr = phy; /* PHY devices addresses start at 0x0 */
240
b3469dd8 241 if (!chip->info->ops->phy_write)
e57e5e77
VD
242 return -EOPNOTSUPP;
243
b3469dd8 244 return chip->info->ops->phy_write(chip, addr, reg, val);
e57e5e77
VD
245}
246
09cb7dfd
VD
247static int mv88e6xxx_phy_page_get(struct mv88e6xxx_chip *chip, int phy, u8 page)
248{
249 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_PHY_PAGE))
250 return -EOPNOTSUPP;
251
252 return mv88e6xxx_phy_write(chip, phy, PHY_PAGE, page);
253}
254
255static void mv88e6xxx_phy_page_put(struct mv88e6xxx_chip *chip, int phy)
256{
257 int err;
258
259 /* Restore PHY page Copper 0x0 for access via the registered MDIO bus */
260 err = mv88e6xxx_phy_write(chip, phy, PHY_PAGE, PHY_PAGE_COPPER);
261 if (unlikely(err)) {
262 dev_err(chip->dev, "failed to restore PHY %d page Copper (%d)\n",
263 phy, err);
264 }
265}
266
267static int mv88e6xxx_phy_page_read(struct mv88e6xxx_chip *chip, int phy,
268 u8 page, int reg, u16 *val)
269{
270 int err;
271
272 /* There is no paging for registers 22 */
273 if (reg == PHY_PAGE)
274 return -EINVAL;
275
276 err = mv88e6xxx_phy_page_get(chip, phy, page);
277 if (!err) {
278 err = mv88e6xxx_phy_read(chip, phy, reg, val);
279 mv88e6xxx_phy_page_put(chip, phy);
280 }
281
282 return err;
283}
284
285static int mv88e6xxx_phy_page_write(struct mv88e6xxx_chip *chip, int phy,
286 u8 page, int reg, u16 val)
287{
288 int err;
289
290 /* There is no paging for registers 22 */
291 if (reg == PHY_PAGE)
292 return -EINVAL;
293
294 err = mv88e6xxx_phy_page_get(chip, phy, page);
295 if (!err) {
296 err = mv88e6xxx_phy_write(chip, phy, PHY_PAGE, page);
297 mv88e6xxx_phy_page_put(chip, phy);
298 }
299
300 return err;
301}
302
303static int mv88e6xxx_serdes_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
304{
305 return mv88e6xxx_phy_page_read(chip, ADDR_SERDES, SERDES_PAGE_FIBER,
306 reg, val);
307}
308
309static int mv88e6xxx_serdes_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
310{
311 return mv88e6xxx_phy_page_write(chip, ADDR_SERDES, SERDES_PAGE_FIBER,
312 reg, val);
313}
314
dc30c35b
AL
315static void mv88e6xxx_g1_irq_mask(struct irq_data *d)
316{
317 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
318 unsigned int n = d->hwirq;
319
320 chip->g1_irq.masked |= (1 << n);
321}
322
323static void mv88e6xxx_g1_irq_unmask(struct irq_data *d)
324{
325 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
326 unsigned int n = d->hwirq;
327
328 chip->g1_irq.masked &= ~(1 << n);
329}
330
331static irqreturn_t mv88e6xxx_g1_irq_thread_fn(int irq, void *dev_id)
332{
333 struct mv88e6xxx_chip *chip = dev_id;
334 unsigned int nhandled = 0;
335 unsigned int sub_irq;
336 unsigned int n;
337 u16 reg;
338 int err;
339
340 mutex_lock(&chip->reg_lock);
341 err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &reg);
342 mutex_unlock(&chip->reg_lock);
343
344 if (err)
345 goto out;
346
347 for (n = 0; n < chip->g1_irq.nirqs; ++n) {
348 if (reg & (1 << n)) {
349 sub_irq = irq_find_mapping(chip->g1_irq.domain, n);
350 handle_nested_irq(sub_irq);
351 ++nhandled;
352 }
353 }
354out:
355 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
356}
357
358static void mv88e6xxx_g1_irq_bus_lock(struct irq_data *d)
359{
360 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
361
362 mutex_lock(&chip->reg_lock);
363}
364
365static void mv88e6xxx_g1_irq_bus_sync_unlock(struct irq_data *d)
366{
367 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
368 u16 mask = GENMASK(chip->g1_irq.nirqs, 0);
369 u16 reg;
370 int err;
371
372 err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &reg);
373 if (err)
374 goto out;
375
376 reg &= ~mask;
377 reg |= (~chip->g1_irq.masked & mask);
378
379 err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, reg);
380 if (err)
381 goto out;
382
383out:
384 mutex_unlock(&chip->reg_lock);
385}
386
387static struct irq_chip mv88e6xxx_g1_irq_chip = {
388 .name = "mv88e6xxx-g1",
389 .irq_mask = mv88e6xxx_g1_irq_mask,
390 .irq_unmask = mv88e6xxx_g1_irq_unmask,
391 .irq_bus_lock = mv88e6xxx_g1_irq_bus_lock,
392 .irq_bus_sync_unlock = mv88e6xxx_g1_irq_bus_sync_unlock,
393};
394
395static int mv88e6xxx_g1_irq_domain_map(struct irq_domain *d,
396 unsigned int irq,
397 irq_hw_number_t hwirq)
398{
399 struct mv88e6xxx_chip *chip = d->host_data;
400
401 irq_set_chip_data(irq, d->host_data);
402 irq_set_chip_and_handler(irq, &chip->g1_irq.chip, handle_level_irq);
403 irq_set_noprobe(irq);
404
405 return 0;
406}
407
408static const struct irq_domain_ops mv88e6xxx_g1_irq_domain_ops = {
409 .map = mv88e6xxx_g1_irq_domain_map,
410 .xlate = irq_domain_xlate_twocell,
411};
412
413static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
414{
415 int irq, virq;
3460a577
AL
416 u16 mask;
417
418 mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &mask);
419 mask |= GENMASK(chip->g1_irq.nirqs, 0);
420 mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, mask);
421
422 free_irq(chip->irq, chip);
dc30c35b
AL
423
424 for (irq = 0; irq < 16; irq++) {
a3db3d3a 425 virq = irq_find_mapping(chip->g1_irq.domain, irq);
dc30c35b
AL
426 irq_dispose_mapping(virq);
427 }
428
a3db3d3a 429 irq_domain_remove(chip->g1_irq.domain);
dc30c35b
AL
430}
431
432static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
433{
434 int err, irq;
435 u16 reg;
436
437 chip->g1_irq.nirqs = chip->info->g1_irqs;
438 chip->g1_irq.domain = irq_domain_add_simple(
439 NULL, chip->g1_irq.nirqs, 0,
440 &mv88e6xxx_g1_irq_domain_ops, chip);
441 if (!chip->g1_irq.domain)
442 return -ENOMEM;
443
444 for (irq = 0; irq < chip->g1_irq.nirqs; irq++)
445 irq_create_mapping(chip->g1_irq.domain, irq);
446
447 chip->g1_irq.chip = mv88e6xxx_g1_irq_chip;
448 chip->g1_irq.masked = ~0;
449
450 err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &reg);
451 if (err)
452 goto out;
453
454 reg &= ~GENMASK(chip->g1_irq.nirqs, 0);
455
456 err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, reg);
457 if (err)
458 goto out;
459
460 /* Reading the interrupt status clears (most of) them */
461 err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &reg);
462 if (err)
463 goto out;
464
465 err = request_threaded_irq(chip->irq, NULL,
466 mv88e6xxx_g1_irq_thread_fn,
467 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
468 dev_name(chip->dev), chip);
469 if (err)
470 goto out;
471
472 return 0;
473
474out:
475 mv88e6xxx_g1_irq_free(chip);
476
477 return err;
478}
479
ec561276 480int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask)
2d79af6e 481{
6441e669 482 int i;
2d79af6e 483
6441e669 484 for (i = 0; i < 16; i++) {
2d79af6e
VD
485 u16 val;
486 int err;
487
488 err = mv88e6xxx_read(chip, addr, reg, &val);
489 if (err)
490 return err;
491
492 if (!(val & mask))
493 return 0;
494
495 usleep_range(1000, 2000);
496 }
497
30853553 498 dev_err(chip->dev, "Timeout while waiting for switch\n");
2d79af6e
VD
499 return -ETIMEDOUT;
500}
501
f22ab641 502/* Indirect write to single pointer-data register with an Update bit */
ec561276 503int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, u16 update)
f22ab641
VD
504{
505 u16 val;
0f02b4f7 506 int err;
f22ab641
VD
507
508 /* Wait until the previous operation is completed */
0f02b4f7
AL
509 err = mv88e6xxx_wait(chip, addr, reg, BIT(15));
510 if (err)
511 return err;
f22ab641
VD
512
513 /* Set the Update bit to trigger a write operation */
514 val = BIT(15) | update;
515
516 return mv88e6xxx_write(chip, addr, reg, val);
517}
518
a935c052 519static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip)
914b32f6
VD
520{
521 u16 val;
a935c052 522 int i, err;
914b32f6 523
a935c052 524 err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &val);
914b32f6
VD
525 if (err)
526 return err;
527
a935c052
VD
528 err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL,
529 val & ~GLOBAL_CONTROL_PPU_ENABLE);
530 if (err)
531 return err;
2e5f0320 532
6441e669 533 for (i = 0; i < 16; i++) {
a935c052
VD
534 err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &val);
535 if (err)
536 return err;
48ace4ef 537
19b2f97e 538 usleep_range(1000, 2000);
a935c052 539 if ((val & GLOBAL_STATUS_PPU_MASK) != GLOBAL_STATUS_PPU_POLLING)
85686581 540 return 0;
2e5f0320
LB
541 }
542
543 return -ETIMEDOUT;
544}
545
fad09c73 546static int mv88e6xxx_ppu_enable(struct mv88e6xxx_chip *chip)
2e5f0320 547{
a935c052
VD
548 u16 val;
549 int i, err;
2e5f0320 550
a935c052
VD
551 err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &val);
552 if (err)
553 return err;
48ace4ef 554
a935c052
VD
555 err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL,
556 val | GLOBAL_CONTROL_PPU_ENABLE);
48ace4ef
AL
557 if (err)
558 return err;
2e5f0320 559
6441e669 560 for (i = 0; i < 16; i++) {
a935c052
VD
561 err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &val);
562 if (err)
563 return err;
48ace4ef 564
19b2f97e 565 usleep_range(1000, 2000);
a935c052 566 if ((val & GLOBAL_STATUS_PPU_MASK) == GLOBAL_STATUS_PPU_POLLING)
85686581 567 return 0;
2e5f0320
LB
568 }
569
570 return -ETIMEDOUT;
571}
572
573static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
574{
fad09c73 575 struct mv88e6xxx_chip *chip;
2e5f0320 576
fad09c73 577 chip = container_of(ugly, struct mv88e6xxx_chip, ppu_work);
762eb67b 578
fad09c73 579 mutex_lock(&chip->reg_lock);
762eb67b 580
fad09c73
VD
581 if (mutex_trylock(&chip->ppu_mutex)) {
582 if (mv88e6xxx_ppu_enable(chip) == 0)
583 chip->ppu_disabled = 0;
584 mutex_unlock(&chip->ppu_mutex);
2e5f0320 585 }
762eb67b 586
fad09c73 587 mutex_unlock(&chip->reg_lock);
2e5f0320
LB
588}
589
590static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
591{
fad09c73 592 struct mv88e6xxx_chip *chip = (void *)_ps;
2e5f0320 593
fad09c73 594 schedule_work(&chip->ppu_work);
2e5f0320
LB
595}
596
fad09c73 597static int mv88e6xxx_ppu_access_get(struct mv88e6xxx_chip *chip)
2e5f0320 598{
2e5f0320
LB
599 int ret;
600
fad09c73 601 mutex_lock(&chip->ppu_mutex);
2e5f0320 602
3675c8d7 603 /* If the PHY polling unit is enabled, disable it so that
2e5f0320
LB
604 * we can access the PHY registers. If it was already
605 * disabled, cancel the timer that is going to re-enable
606 * it.
607 */
fad09c73
VD
608 if (!chip->ppu_disabled) {
609 ret = mv88e6xxx_ppu_disable(chip);
85686581 610 if (ret < 0) {
fad09c73 611 mutex_unlock(&chip->ppu_mutex);
85686581
BG
612 return ret;
613 }
fad09c73 614 chip->ppu_disabled = 1;
2e5f0320 615 } else {
fad09c73 616 del_timer(&chip->ppu_timer);
85686581 617 ret = 0;
2e5f0320
LB
618 }
619
620 return ret;
621}
622
fad09c73 623static void mv88e6xxx_ppu_access_put(struct mv88e6xxx_chip *chip)
2e5f0320 624{
3675c8d7 625 /* Schedule a timer to re-enable the PHY polling unit. */
fad09c73
VD
626 mod_timer(&chip->ppu_timer, jiffies + msecs_to_jiffies(10));
627 mutex_unlock(&chip->ppu_mutex);
2e5f0320
LB
628}
629
fad09c73 630static void mv88e6xxx_ppu_state_init(struct mv88e6xxx_chip *chip)
2e5f0320 631{
fad09c73
VD
632 mutex_init(&chip->ppu_mutex);
633 INIT_WORK(&chip->ppu_work, mv88e6xxx_ppu_reenable_work);
68497a87
WY
634 setup_timer(&chip->ppu_timer, mv88e6xxx_ppu_reenable_timer,
635 (unsigned long)chip);
2e5f0320
LB
636}
637
930188ce
AL
638static void mv88e6xxx_ppu_state_destroy(struct mv88e6xxx_chip *chip)
639{
640 del_timer_sync(&chip->ppu_timer);
641}
642
e57e5e77
VD
643static int mv88e6xxx_phy_ppu_read(struct mv88e6xxx_chip *chip, int addr,
644 int reg, u16 *val)
2e5f0320 645{
e57e5e77 646 int err;
2e5f0320 647
e57e5e77
VD
648 err = mv88e6xxx_ppu_access_get(chip);
649 if (!err) {
650 err = mv88e6xxx_read(chip, addr, reg, val);
fad09c73 651 mv88e6xxx_ppu_access_put(chip);
2e5f0320
LB
652 }
653
e57e5e77 654 return err;
2e5f0320
LB
655}
656
e57e5e77
VD
657static int mv88e6xxx_phy_ppu_write(struct mv88e6xxx_chip *chip, int addr,
658 int reg, u16 val)
2e5f0320 659{
e57e5e77 660 int err;
2e5f0320 661
e57e5e77
VD
662 err = mv88e6xxx_ppu_access_get(chip);
663 if (!err) {
664 err = mv88e6xxx_write(chip, addr, reg, val);
fad09c73 665 mv88e6xxx_ppu_access_put(chip);
2e5f0320
LB
666 }
667
e57e5e77 668 return err;
2e5f0320 669}
2e5f0320 670
fad09c73 671static bool mv88e6xxx_6065_family(struct mv88e6xxx_chip *chip)
54d792f2 672{
fad09c73 673 return chip->info->family == MV88E6XXX_FAMILY_6065;
54d792f2
AL
674}
675
fad09c73 676static bool mv88e6xxx_6095_family(struct mv88e6xxx_chip *chip)
54d792f2 677{
fad09c73 678 return chip->info->family == MV88E6XXX_FAMILY_6095;
54d792f2
AL
679}
680
fad09c73 681static bool mv88e6xxx_6097_family(struct mv88e6xxx_chip *chip)
54d792f2 682{
fad09c73 683 return chip->info->family == MV88E6XXX_FAMILY_6097;
54d792f2
AL
684}
685
fad09c73 686static bool mv88e6xxx_6165_family(struct mv88e6xxx_chip *chip)
54d792f2 687{
fad09c73 688 return chip->info->family == MV88E6XXX_FAMILY_6165;
54d792f2
AL
689}
690
fad09c73 691static bool mv88e6xxx_6185_family(struct mv88e6xxx_chip *chip)
54d792f2 692{
fad09c73 693 return chip->info->family == MV88E6XXX_FAMILY_6185;
54d792f2
AL
694}
695
fad09c73 696static bool mv88e6xxx_6320_family(struct mv88e6xxx_chip *chip)
7c3d0d67 697{
fad09c73 698 return chip->info->family == MV88E6XXX_FAMILY_6320;
7c3d0d67
AK
699}
700
fad09c73 701static bool mv88e6xxx_6351_family(struct mv88e6xxx_chip *chip)
54d792f2 702{
fad09c73 703 return chip->info->family == MV88E6XXX_FAMILY_6351;
54d792f2
AL
704}
705
fad09c73 706static bool mv88e6xxx_6352_family(struct mv88e6xxx_chip *chip)
f3a8b6b6 707{
fad09c73 708 return chip->info->family == MV88E6XXX_FAMILY_6352;
f3a8b6b6
AL
709}
710
d78343d2
VD
711static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
712 int link, int speed, int duplex,
713 phy_interface_t mode)
714{
715 int err;
716
717 if (!chip->info->ops->port_set_link)
718 return 0;
719
720 /* Port's MAC control must not be changed unless the link is down */
721 err = chip->info->ops->port_set_link(chip, port, 0);
722 if (err)
723 return err;
724
725 if (chip->info->ops->port_set_speed) {
726 err = chip->info->ops->port_set_speed(chip, port, speed);
727 if (err && err != -EOPNOTSUPP)
728 goto restore_link;
729 }
730
731 if (chip->info->ops->port_set_duplex) {
732 err = chip->info->ops->port_set_duplex(chip, port, duplex);
733 if (err && err != -EOPNOTSUPP)
734 goto restore_link;
735 }
736
737 if (chip->info->ops->port_set_rgmii_delay) {
738 err = chip->info->ops->port_set_rgmii_delay(chip, port, mode);
739 if (err && err != -EOPNOTSUPP)
740 goto restore_link;
741 }
742
743 err = 0;
744restore_link:
745 if (chip->info->ops->port_set_link(chip, port, link))
746 netdev_err(chip->ds->ports[port].netdev,
747 "failed to restore MAC's link\n");
748
749 return err;
750}
751
dea87024
AL
752/* We expect the switch to perform auto negotiation if there is a real
753 * phy. However, in the case of a fixed link phy, we force the port
754 * settings from the fixed link settings.
755 */
f81ec90f
VD
756static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
757 struct phy_device *phydev)
dea87024 758{
04bed143 759 struct mv88e6xxx_chip *chip = ds->priv;
0e7b9925 760 int err;
dea87024
AL
761
762 if (!phy_is_pseudo_fixed_link(phydev))
763 return;
764
fad09c73 765 mutex_lock(&chip->reg_lock);
d78343d2
VD
766 err = mv88e6xxx_port_setup_mac(chip, port, phydev->link, phydev->speed,
767 phydev->duplex, phydev->interface);
fad09c73 768 mutex_unlock(&chip->reg_lock);
d78343d2
VD
769
770 if (err && err != -EOPNOTSUPP)
771 netdev_err(ds->ports[port].netdev, "failed to configure MAC\n");
dea87024
AL
772}
773
fad09c73 774static int _mv88e6xxx_stats_wait(struct mv88e6xxx_chip *chip)
91da11f8 775{
a935c052
VD
776 u16 val;
777 int i, err;
91da11f8
LB
778
779 for (i = 0; i < 10; i++) {
a935c052
VD
780 err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_OP, &val);
781 if ((val & GLOBAL_STATS_OP_BUSY) == 0)
91da11f8
LB
782 return 0;
783 }
784
785 return -ETIMEDOUT;
786}
787
fad09c73 788static int _mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
91da11f8 789{
a935c052 790 int err;
91da11f8 791
fad09c73 792 if (mv88e6xxx_6320_family(chip) || mv88e6xxx_6352_family(chip))
f3a8b6b6
AL
793 port = (port + 1) << 5;
794
3675c8d7 795 /* Snapshot the hardware statistics counters for this port. */
a935c052
VD
796 err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP,
797 GLOBAL_STATS_OP_CAPTURE_PORT |
798 GLOBAL_STATS_OP_HIST_RX_TX | port);
799 if (err)
800 return err;
91da11f8 801
3675c8d7 802 /* Wait for the snapshotting to complete. */
a935c052 803 return _mv88e6xxx_stats_wait(chip);
91da11f8
LB
804}
805
fad09c73 806static void _mv88e6xxx_stats_read(struct mv88e6xxx_chip *chip,
158bc065 807 int stat, u32 *val)
91da11f8 808{
a935c052
VD
809 u32 value;
810 u16 reg;
811 int err;
91da11f8
LB
812
813 *val = 0;
814
a935c052
VD
815 err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP,
816 GLOBAL_STATS_OP_READ_CAPTURED |
817 GLOBAL_STATS_OP_HIST_RX_TX | stat);
818 if (err)
91da11f8
LB
819 return;
820
a935c052
VD
821 err = _mv88e6xxx_stats_wait(chip);
822 if (err)
91da11f8
LB
823 return;
824
a935c052
VD
825 err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_COUNTER_32, &reg);
826 if (err)
91da11f8
LB
827 return;
828
a935c052 829 value = reg << 16;
91da11f8 830
a935c052
VD
831 err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_COUNTER_01, &reg);
832 if (err)
91da11f8
LB
833 return;
834
a935c052 835 *val = value | reg;
91da11f8
LB
836}
837
e413e7e1 838static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = {
f5e2ed02
AL
839 { "in_good_octets", 8, 0x00, BANK0, },
840 { "in_bad_octets", 4, 0x02, BANK0, },
841 { "in_unicast", 4, 0x04, BANK0, },
842 { "in_broadcasts", 4, 0x06, BANK0, },
843 { "in_multicasts", 4, 0x07, BANK0, },
844 { "in_pause", 4, 0x16, BANK0, },
845 { "in_undersize", 4, 0x18, BANK0, },
846 { "in_fragments", 4, 0x19, BANK0, },
847 { "in_oversize", 4, 0x1a, BANK0, },
848 { "in_jabber", 4, 0x1b, BANK0, },
849 { "in_rx_error", 4, 0x1c, BANK0, },
850 { "in_fcs_error", 4, 0x1d, BANK0, },
851 { "out_octets", 8, 0x0e, BANK0, },
852 { "out_unicast", 4, 0x10, BANK0, },
853 { "out_broadcasts", 4, 0x13, BANK0, },
854 { "out_multicasts", 4, 0x12, BANK0, },
855 { "out_pause", 4, 0x15, BANK0, },
856 { "excessive", 4, 0x11, BANK0, },
857 { "collisions", 4, 0x1e, BANK0, },
858 { "deferred", 4, 0x05, BANK0, },
859 { "single", 4, 0x14, BANK0, },
860 { "multiple", 4, 0x17, BANK0, },
861 { "out_fcs_error", 4, 0x03, BANK0, },
862 { "late", 4, 0x1f, BANK0, },
863 { "hist_64bytes", 4, 0x08, BANK0, },
864 { "hist_65_127bytes", 4, 0x09, BANK0, },
865 { "hist_128_255bytes", 4, 0x0a, BANK0, },
866 { "hist_256_511bytes", 4, 0x0b, BANK0, },
867 { "hist_512_1023bytes", 4, 0x0c, BANK0, },
868 { "hist_1024_max_bytes", 4, 0x0d, BANK0, },
869 { "sw_in_discards", 4, 0x10, PORT, },
870 { "sw_in_filtered", 2, 0x12, PORT, },
871 { "sw_out_filtered", 2, 0x13, PORT, },
872 { "in_discards", 4, 0x00 | GLOBAL_STATS_OP_BANK_1, BANK1, },
873 { "in_filtered", 4, 0x01 | GLOBAL_STATS_OP_BANK_1, BANK1, },
874 { "in_accepted", 4, 0x02 | GLOBAL_STATS_OP_BANK_1, BANK1, },
875 { "in_bad_accepted", 4, 0x03 | GLOBAL_STATS_OP_BANK_1, BANK1, },
876 { "in_good_avb_class_a", 4, 0x04 | GLOBAL_STATS_OP_BANK_1, BANK1, },
877 { "in_good_avb_class_b", 4, 0x05 | GLOBAL_STATS_OP_BANK_1, BANK1, },
878 { "in_bad_avb_class_a", 4, 0x06 | GLOBAL_STATS_OP_BANK_1, BANK1, },
879 { "in_bad_avb_class_b", 4, 0x07 | GLOBAL_STATS_OP_BANK_1, BANK1, },
880 { "tcam_counter_0", 4, 0x08 | GLOBAL_STATS_OP_BANK_1, BANK1, },
881 { "tcam_counter_1", 4, 0x09 | GLOBAL_STATS_OP_BANK_1, BANK1, },
882 { "tcam_counter_2", 4, 0x0a | GLOBAL_STATS_OP_BANK_1, BANK1, },
883 { "tcam_counter_3", 4, 0x0b | GLOBAL_STATS_OP_BANK_1, BANK1, },
884 { "in_da_unknown", 4, 0x0e | GLOBAL_STATS_OP_BANK_1, BANK1, },
885 { "in_management", 4, 0x0f | GLOBAL_STATS_OP_BANK_1, BANK1, },
886 { "out_queue_0", 4, 0x10 | GLOBAL_STATS_OP_BANK_1, BANK1, },
887 { "out_queue_1", 4, 0x11 | GLOBAL_STATS_OP_BANK_1, BANK1, },
888 { "out_queue_2", 4, 0x12 | GLOBAL_STATS_OP_BANK_1, BANK1, },
889 { "out_queue_3", 4, 0x13 | GLOBAL_STATS_OP_BANK_1, BANK1, },
890 { "out_queue_4", 4, 0x14 | GLOBAL_STATS_OP_BANK_1, BANK1, },
891 { "out_queue_5", 4, 0x15 | GLOBAL_STATS_OP_BANK_1, BANK1, },
892 { "out_queue_6", 4, 0x16 | GLOBAL_STATS_OP_BANK_1, BANK1, },
893 { "out_queue_7", 4, 0x17 | GLOBAL_STATS_OP_BANK_1, BANK1, },
894 { "out_cut_through", 4, 0x18 | GLOBAL_STATS_OP_BANK_1, BANK1, },
895 { "out_octets_a", 4, 0x1a | GLOBAL_STATS_OP_BANK_1, BANK1, },
896 { "out_octets_b", 4, 0x1b | GLOBAL_STATS_OP_BANK_1, BANK1, },
897 { "out_management", 4, 0x1f | GLOBAL_STATS_OP_BANK_1, BANK1, },
e413e7e1
AL
898};
899
fad09c73 900static bool mv88e6xxx_has_stat(struct mv88e6xxx_chip *chip,
f5e2ed02 901 struct mv88e6xxx_hw_stat *stat)
e413e7e1 902{
f5e2ed02
AL
903 switch (stat->type) {
904 case BANK0:
e413e7e1 905 return true;
f5e2ed02 906 case BANK1:
fad09c73 907 return mv88e6xxx_6320_family(chip);
f5e2ed02 908 case PORT:
fad09c73
VD
909 return mv88e6xxx_6095_family(chip) ||
910 mv88e6xxx_6185_family(chip) ||
911 mv88e6xxx_6097_family(chip) ||
912 mv88e6xxx_6165_family(chip) ||
913 mv88e6xxx_6351_family(chip) ||
914 mv88e6xxx_6352_family(chip);
91da11f8 915 }
f5e2ed02 916 return false;
91da11f8
LB
917}
918
fad09c73 919static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
f5e2ed02 920 struct mv88e6xxx_hw_stat *s,
80c4627b
AL
921 int port)
922{
80c4627b
AL
923 u32 low;
924 u32 high = 0;
0e7b9925
AL
925 int err;
926 u16 reg;
80c4627b
AL
927 u64 value;
928
f5e2ed02
AL
929 switch (s->type) {
930 case PORT:
0e7b9925
AL
931 err = mv88e6xxx_port_read(chip, port, s->reg, &reg);
932 if (err)
80c4627b
AL
933 return UINT64_MAX;
934
0e7b9925 935 low = reg;
80c4627b 936 if (s->sizeof_stat == 4) {
0e7b9925
AL
937 err = mv88e6xxx_port_read(chip, port, s->reg + 1, &reg);
938 if (err)
80c4627b 939 return UINT64_MAX;
0e7b9925 940 high = reg;
80c4627b 941 }
f5e2ed02
AL
942 break;
943 case BANK0:
944 case BANK1:
fad09c73 945 _mv88e6xxx_stats_read(chip, s->reg, &low);
80c4627b 946 if (s->sizeof_stat == 8)
fad09c73 947 _mv88e6xxx_stats_read(chip, s->reg + 1, &high);
80c4627b
AL
948 }
949 value = (((u64)high) << 16) | low;
950 return value;
951}
952
f81ec90f
VD
953static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
954 uint8_t *data)
91da11f8 955{
04bed143 956 struct mv88e6xxx_chip *chip = ds->priv;
f5e2ed02
AL
957 struct mv88e6xxx_hw_stat *stat;
958 int i, j;
91da11f8 959
f5e2ed02
AL
960 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
961 stat = &mv88e6xxx_hw_stats[i];
fad09c73 962 if (mv88e6xxx_has_stat(chip, stat)) {
f5e2ed02
AL
963 memcpy(data + j * ETH_GSTRING_LEN, stat->string,
964 ETH_GSTRING_LEN);
965 j++;
966 }
91da11f8 967 }
e413e7e1
AL
968}
969
f81ec90f 970static int mv88e6xxx_get_sset_count(struct dsa_switch *ds)
e413e7e1 971{
04bed143 972 struct mv88e6xxx_chip *chip = ds->priv;
f5e2ed02
AL
973 struct mv88e6xxx_hw_stat *stat;
974 int i, j;
975
976 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
977 stat = &mv88e6xxx_hw_stats[i];
fad09c73 978 if (mv88e6xxx_has_stat(chip, stat))
f5e2ed02
AL
979 j++;
980 }
981 return j;
e413e7e1
AL
982}
983
f81ec90f
VD
984static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
985 uint64_t *data)
e413e7e1 986{
04bed143 987 struct mv88e6xxx_chip *chip = ds->priv;
f5e2ed02
AL
988 struct mv88e6xxx_hw_stat *stat;
989 int ret;
990 int i, j;
991
fad09c73 992 mutex_lock(&chip->reg_lock);
f5e2ed02 993
fad09c73 994 ret = _mv88e6xxx_stats_snapshot(chip, port);
f5e2ed02 995 if (ret < 0) {
fad09c73 996 mutex_unlock(&chip->reg_lock);
f5e2ed02
AL
997 return;
998 }
999 for (i = 0, j = 0; i < ARRAY_SIZE(mv88e6xxx_hw_stats); i++) {
1000 stat = &mv88e6xxx_hw_stats[i];
fad09c73
VD
1001 if (mv88e6xxx_has_stat(chip, stat)) {
1002 data[j] = _mv88e6xxx_get_ethtool_stat(chip, stat, port);
f5e2ed02
AL
1003 j++;
1004 }
1005 }
1006
fad09c73 1007 mutex_unlock(&chip->reg_lock);
e413e7e1
AL
1008}
1009
f81ec90f 1010static int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port)
a1ab91f3
GR
1011{
1012 return 32 * sizeof(u16);
1013}
1014
f81ec90f
VD
1015static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port,
1016 struct ethtool_regs *regs, void *_p)
a1ab91f3 1017{
04bed143 1018 struct mv88e6xxx_chip *chip = ds->priv;
0e7b9925
AL
1019 int err;
1020 u16 reg;
a1ab91f3
GR
1021 u16 *p = _p;
1022 int i;
1023
1024 regs->version = 0;
1025
1026 memset(p, 0xff, 32 * sizeof(u16));
1027
fad09c73 1028 mutex_lock(&chip->reg_lock);
23062513 1029
a1ab91f3 1030 for (i = 0; i < 32; i++) {
a1ab91f3 1031
0e7b9925
AL
1032 err = mv88e6xxx_port_read(chip, port, i, &reg);
1033 if (!err)
1034 p[i] = reg;
a1ab91f3 1035 }
23062513 1036
fad09c73 1037 mutex_unlock(&chip->reg_lock);
a1ab91f3
GR
1038}
1039
fad09c73 1040static int _mv88e6xxx_atu_wait(struct mv88e6xxx_chip *chip)
facd95b2 1041{
a935c052 1042 return mv88e6xxx_g1_wait(chip, GLOBAL_ATU_OP, GLOBAL_ATU_OP_BUSY);
facd95b2
GR
1043}
1044
f81ec90f
VD
1045static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port,
1046 struct ethtool_eee *e)
11b3b45d 1047{
04bed143 1048 struct mv88e6xxx_chip *chip = ds->priv;
9c93829c
VD
1049 u16 reg;
1050 int err;
11b3b45d 1051
fad09c73 1052 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEE))
aadbdb8a
VD
1053 return -EOPNOTSUPP;
1054
fad09c73 1055 mutex_lock(&chip->reg_lock);
2f40c698 1056
9c93829c
VD
1057 err = mv88e6xxx_phy_read(chip, port, 16, &reg);
1058 if (err)
2f40c698 1059 goto out;
11b3b45d
GR
1060
1061 e->eee_enabled = !!(reg & 0x0200);
1062 e->tx_lpi_enabled = !!(reg & 0x0100);
1063
0e7b9925 1064 err = mv88e6xxx_port_read(chip, port, PORT_STATUS, &reg);
9c93829c 1065 if (err)
2f40c698 1066 goto out;
11b3b45d 1067
cca8b133 1068 e->eee_active = !!(reg & PORT_STATUS_EEE);
2f40c698 1069out:
fad09c73 1070 mutex_unlock(&chip->reg_lock);
9c93829c
VD
1071
1072 return err;
11b3b45d
GR
1073}
1074
f81ec90f
VD
1075static int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
1076 struct phy_device *phydev, struct ethtool_eee *e)
11b3b45d 1077{
04bed143 1078 struct mv88e6xxx_chip *chip = ds->priv;
9c93829c
VD
1079 u16 reg;
1080 int err;
11b3b45d 1081
fad09c73 1082 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_EEE))
aadbdb8a
VD
1083 return -EOPNOTSUPP;
1084
fad09c73 1085 mutex_lock(&chip->reg_lock);
11b3b45d 1086
9c93829c
VD
1087 err = mv88e6xxx_phy_read(chip, port, 16, &reg);
1088 if (err)
2f40c698
AL
1089 goto out;
1090
9c93829c 1091 reg &= ~0x0300;
2f40c698
AL
1092 if (e->eee_enabled)
1093 reg |= 0x0200;
1094 if (e->tx_lpi_enabled)
1095 reg |= 0x0100;
1096
9c93829c 1097 err = mv88e6xxx_phy_write(chip, port, 16, reg);
2f40c698 1098out:
fad09c73 1099 mutex_unlock(&chip->reg_lock);
2f40c698 1100
9c93829c 1101 return err;
11b3b45d
GR
1102}
1103
fad09c73 1104static int _mv88e6xxx_atu_cmd(struct mv88e6xxx_chip *chip, u16 fid, u16 cmd)
facd95b2 1105{
a935c052
VD
1106 u16 val;
1107 int err;
facd95b2 1108
6dc10bbc 1109 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_ATU_FID)) {
a935c052
VD
1110 err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_FID, fid);
1111 if (err)
1112 return err;
fad09c73 1113 } else if (mv88e6xxx_num_databases(chip) == 256) {
11ea809f 1114 /* ATU DBNum[7:4] are located in ATU Control 15:12 */
a935c052
VD
1115 err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_CONTROL, &val);
1116 if (err)
1117 return err;
11ea809f 1118
a935c052
VD
1119 err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL,
1120 (val & 0xfff) | ((fid << 8) & 0xf000));
1121 if (err)
1122 return err;
11ea809f
VD
1123
1124 /* ATU DBNum[3:0] are located in ATU Operation 3:0 */
1125 cmd |= fid & 0xf;
b426e5f7
VD
1126 }
1127
a935c052
VD
1128 err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_OP, cmd);
1129 if (err)
1130 return err;
facd95b2 1131
fad09c73 1132 return _mv88e6xxx_atu_wait(chip);
facd95b2
GR
1133}
1134
fad09c73 1135static int _mv88e6xxx_atu_data_write(struct mv88e6xxx_chip *chip,
37705b73
VD
1136 struct mv88e6xxx_atu_entry *entry)
1137{
1138 u16 data = entry->state & GLOBAL_ATU_DATA_STATE_MASK;
1139
1140 if (entry->state != GLOBAL_ATU_DATA_STATE_UNUSED) {
1141 unsigned int mask, shift;
1142
1143 if (entry->trunk) {
1144 data |= GLOBAL_ATU_DATA_TRUNK;
1145 mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK;
1146 shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT;
1147 } else {
1148 mask = GLOBAL_ATU_DATA_PORT_VECTOR_MASK;
1149 shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT;
1150 }
1151
1152 data |= (entry->portv_trunkid << shift) & mask;
1153 }
1154
a935c052 1155 return mv88e6xxx_g1_write(chip, GLOBAL_ATU_DATA, data);
37705b73
VD
1156}
1157
fad09c73 1158static int _mv88e6xxx_atu_flush_move(struct mv88e6xxx_chip *chip,
7fb5e755
VD
1159 struct mv88e6xxx_atu_entry *entry,
1160 bool static_too)
facd95b2 1161{
7fb5e755
VD
1162 int op;
1163 int err;
facd95b2 1164
fad09c73 1165 err = _mv88e6xxx_atu_wait(chip);
7fb5e755
VD
1166 if (err)
1167 return err;
facd95b2 1168
fad09c73 1169 err = _mv88e6xxx_atu_data_write(chip, entry);
7fb5e755
VD
1170 if (err)
1171 return err;
1172
1173 if (entry->fid) {
7fb5e755
VD
1174 op = static_too ? GLOBAL_ATU_OP_FLUSH_MOVE_ALL_DB :
1175 GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC_DB;
1176 } else {
1177 op = static_too ? GLOBAL_ATU_OP_FLUSH_MOVE_ALL :
1178 GLOBAL_ATU_OP_FLUSH_MOVE_NON_STATIC;
1179 }
1180
fad09c73 1181 return _mv88e6xxx_atu_cmd(chip, entry->fid, op);
7fb5e755
VD
1182}
1183
fad09c73 1184static int _mv88e6xxx_atu_flush(struct mv88e6xxx_chip *chip,
158bc065 1185 u16 fid, bool static_too)
7fb5e755
VD
1186{
1187 struct mv88e6xxx_atu_entry entry = {
1188 .fid = fid,
1189 .state = 0, /* EntryState bits must be 0 */
1190 };
70cc99d1 1191
fad09c73 1192 return _mv88e6xxx_atu_flush_move(chip, &entry, static_too);
7fb5e755
VD
1193}
1194
fad09c73 1195static int _mv88e6xxx_atu_move(struct mv88e6xxx_chip *chip, u16 fid,
158bc065 1196 int from_port, int to_port, bool static_too)
9f4d55d2
VD
1197{
1198 struct mv88e6xxx_atu_entry entry = {
1199 .trunk = false,
1200 .fid = fid,
1201 };
1202
1203 /* EntryState bits must be 0xF */
1204 entry.state = GLOBAL_ATU_DATA_STATE_MASK;
1205
1206 /* ToPort and FromPort are respectively in PortVec bits 7:4 and 3:0 */
1207 entry.portv_trunkid = (to_port & 0x0f) << 4;
1208 entry.portv_trunkid |= from_port & 0x0f;
1209
fad09c73 1210 return _mv88e6xxx_atu_flush_move(chip, &entry, static_too);
9f4d55d2
VD
1211}
1212
fad09c73 1213static int _mv88e6xxx_atu_remove(struct mv88e6xxx_chip *chip, u16 fid,
158bc065 1214 int port, bool static_too)
9f4d55d2
VD
1215{
1216 /* Destination port 0xF means remove the entries */
fad09c73 1217 return _mv88e6xxx_atu_move(chip, fid, port, 0x0f, static_too);
9f4d55d2
VD
1218}
1219
fad09c73 1220static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port)
facd95b2 1221{
fad09c73 1222 struct net_device *bridge = chip->ports[port].bridge_dev;
fad09c73 1223 struct dsa_switch *ds = chip->ds;
b7666efe 1224 u16 output_ports = 0;
b7666efe
VD
1225 int i;
1226
1227 /* allow CPU port or DSA link(s) to send frames to every port */
1228 if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
5a7921f4 1229 output_ports = ~0;
b7666efe 1230 } else {
370b4ffb 1231 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
b7666efe 1232 /* allow sending frames to every group member */
fad09c73 1233 if (bridge && chip->ports[i].bridge_dev == bridge)
b7666efe
VD
1234 output_ports |= BIT(i);
1235
1236 /* allow sending frames to CPU port and DSA link(s) */
1237 if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
1238 output_ports |= BIT(i);
1239 }
1240 }
1241
1242 /* prevent frames from going back out of the port they came in on */
1243 output_ports &= ~BIT(port);
facd95b2 1244
5a7921f4 1245 return mv88e6xxx_port_set_vlan_map(chip, port, output_ports);
facd95b2
GR
1246}
1247
f81ec90f
VD
1248static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
1249 u8 state)
facd95b2 1250{
04bed143 1251 struct mv88e6xxx_chip *chip = ds->priv;
facd95b2 1252 int stp_state;
553eb544 1253 int err;
facd95b2
GR
1254
1255 switch (state) {
1256 case BR_STATE_DISABLED:
cca8b133 1257 stp_state = PORT_CONTROL_STATE_DISABLED;
facd95b2
GR
1258 break;
1259 case BR_STATE_BLOCKING:
1260 case BR_STATE_LISTENING:
cca8b133 1261 stp_state = PORT_CONTROL_STATE_BLOCKING;
facd95b2
GR
1262 break;
1263 case BR_STATE_LEARNING:
cca8b133 1264 stp_state = PORT_CONTROL_STATE_LEARNING;
facd95b2
GR
1265 break;
1266 case BR_STATE_FORWARDING:
1267 default:
cca8b133 1268 stp_state = PORT_CONTROL_STATE_FORWARDING;
facd95b2
GR
1269 break;
1270 }
1271
fad09c73 1272 mutex_lock(&chip->reg_lock);
e28def33 1273 err = mv88e6xxx_port_set_state(chip, port, stp_state);
fad09c73 1274 mutex_unlock(&chip->reg_lock);
553eb544
VD
1275
1276 if (err)
e28def33 1277 netdev_err(ds->ports[port].netdev, "failed to update state\n");
facd95b2
GR
1278}
1279
749efcb8
VD
1280static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port)
1281{
1282 struct mv88e6xxx_chip *chip = ds->priv;
1283 int err;
1284
1285 mutex_lock(&chip->reg_lock);
1286 err = _mv88e6xxx_atu_remove(chip, 0, port, false);
1287 mutex_unlock(&chip->reg_lock);
1288
1289 if (err)
1290 netdev_err(ds->ports[port].netdev, "failed to flush ATU\n");
1291}
1292
fad09c73 1293static int _mv88e6xxx_vtu_wait(struct mv88e6xxx_chip *chip)
6b17e864 1294{
a935c052 1295 return mv88e6xxx_g1_wait(chip, GLOBAL_VTU_OP, GLOBAL_VTU_OP_BUSY);
6b17e864
VD
1296}
1297
fad09c73 1298static int _mv88e6xxx_vtu_cmd(struct mv88e6xxx_chip *chip, u16 op)
6b17e864 1299{
a935c052 1300 int err;
6b17e864 1301
a935c052
VD
1302 err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_OP, op);
1303 if (err)
1304 return err;
6b17e864 1305
fad09c73 1306 return _mv88e6xxx_vtu_wait(chip);
6b17e864
VD
1307}
1308
fad09c73 1309static int _mv88e6xxx_vtu_stu_flush(struct mv88e6xxx_chip *chip)
6b17e864
VD
1310{
1311 int ret;
1312
fad09c73 1313 ret = _mv88e6xxx_vtu_wait(chip);
6b17e864
VD
1314 if (ret < 0)
1315 return ret;
1316
fad09c73 1317 return _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_FLUSH_ALL);
6b17e864
VD
1318}
1319
fad09c73 1320static int _mv88e6xxx_vtu_stu_data_read(struct mv88e6xxx_chip *chip,
b4e47c0f 1321 struct mv88e6xxx_vtu_entry *entry,
b8fee957
VD
1322 unsigned int nibble_offset)
1323{
b8fee957 1324 u16 regs[3];
a935c052 1325 int i, err;
b8fee957
VD
1326
1327 for (i = 0; i < 3; ++i) {
a935c052 1328 u16 *reg = &regs[i];
b8fee957 1329
a935c052
VD
1330 err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_DATA_0_3 + i, reg);
1331 if (err)
1332 return err;
b8fee957
VD
1333 }
1334
370b4ffb 1335 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
b8fee957
VD
1336 unsigned int shift = (i % 4) * 4 + nibble_offset;
1337 u16 reg = regs[i / 4];
1338
1339 entry->data[i] = (reg >> shift) & GLOBAL_VTU_STU_DATA_MASK;
1340 }
1341
1342 return 0;
1343}
1344
fad09c73 1345static int mv88e6xxx_vtu_data_read(struct mv88e6xxx_chip *chip,
b4e47c0f 1346 struct mv88e6xxx_vtu_entry *entry)
15d7d7d4 1347{
fad09c73 1348 return _mv88e6xxx_vtu_stu_data_read(chip, entry, 0);
15d7d7d4
VD
1349}
1350
fad09c73 1351static int mv88e6xxx_stu_data_read(struct mv88e6xxx_chip *chip,
b4e47c0f 1352 struct mv88e6xxx_vtu_entry *entry)
15d7d7d4 1353{
fad09c73 1354 return _mv88e6xxx_vtu_stu_data_read(chip, entry, 2);
15d7d7d4
VD
1355}
1356
fad09c73 1357static int _mv88e6xxx_vtu_stu_data_write(struct mv88e6xxx_chip *chip,
b4e47c0f 1358 struct mv88e6xxx_vtu_entry *entry,
7dad08d7
VD
1359 unsigned int nibble_offset)
1360{
7dad08d7 1361 u16 regs[3] = { 0 };
a935c052 1362 int i, err;
7dad08d7 1363
370b4ffb 1364 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
7dad08d7
VD
1365 unsigned int shift = (i % 4) * 4 + nibble_offset;
1366 u8 data = entry->data[i];
1367
1368 regs[i / 4] |= (data & GLOBAL_VTU_STU_DATA_MASK) << shift;
1369 }
1370
1371 for (i = 0; i < 3; ++i) {
a935c052
VD
1372 u16 reg = regs[i];
1373
1374 err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_DATA_0_3 + i, reg);
1375 if (err)
1376 return err;
7dad08d7
VD
1377 }
1378
1379 return 0;
1380}
1381
fad09c73 1382static int mv88e6xxx_vtu_data_write(struct mv88e6xxx_chip *chip,
b4e47c0f 1383 struct mv88e6xxx_vtu_entry *entry)
15d7d7d4 1384{
fad09c73 1385 return _mv88e6xxx_vtu_stu_data_write(chip, entry, 0);
15d7d7d4
VD
1386}
1387
fad09c73 1388static int mv88e6xxx_stu_data_write(struct mv88e6xxx_chip *chip,
b4e47c0f 1389 struct mv88e6xxx_vtu_entry *entry)
15d7d7d4 1390{
fad09c73 1391 return _mv88e6xxx_vtu_stu_data_write(chip, entry, 2);
15d7d7d4
VD
1392}
1393
fad09c73 1394static int _mv88e6xxx_vtu_vid_write(struct mv88e6xxx_chip *chip, u16 vid)
36d04ba1 1395{
a935c052
VD
1396 return mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID,
1397 vid & GLOBAL_VTU_VID_MASK);
36d04ba1
VD
1398}
1399
fad09c73 1400static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
b4e47c0f 1401 struct mv88e6xxx_vtu_entry *entry)
b8fee957 1402{
b4e47c0f 1403 struct mv88e6xxx_vtu_entry next = { 0 };
a935c052
VD
1404 u16 val;
1405 int err;
b8fee957 1406
a935c052
VD
1407 err = _mv88e6xxx_vtu_wait(chip);
1408 if (err)
1409 return err;
b8fee957 1410
a935c052
VD
1411 err = _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_VTU_GET_NEXT);
1412 if (err)
1413 return err;
b8fee957 1414
a935c052
VD
1415 err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_VID, &val);
1416 if (err)
1417 return err;
b8fee957 1418
a935c052
VD
1419 next.vid = val & GLOBAL_VTU_VID_MASK;
1420 next.valid = !!(val & GLOBAL_VTU_VID_VALID);
b8fee957
VD
1421
1422 if (next.valid) {
a935c052
VD
1423 err = mv88e6xxx_vtu_data_read(chip, &next);
1424 if (err)
1425 return err;
b8fee957 1426
6dc10bbc 1427 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_VTU_FID)) {
a935c052
VD
1428 err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_FID, &val);
1429 if (err)
1430 return err;
b8fee957 1431
a935c052 1432 next.fid = val & GLOBAL_VTU_FID_MASK;
fad09c73 1433 } else if (mv88e6xxx_num_databases(chip) == 256) {
11ea809f
VD
1434 /* VTU DBNum[7:4] are located in VTU Operation 11:8, and
1435 * VTU DBNum[3:0] are located in VTU Operation 3:0
1436 */
a935c052
VD
1437 err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_OP, &val);
1438 if (err)
1439 return err;
11ea809f 1440
a935c052
VD
1441 next.fid = (val & 0xf00) >> 4;
1442 next.fid |= val & 0xf;
2e7bd5ef 1443 }
b8fee957 1444
fad09c73 1445 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) {
a935c052
VD
1446 err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_SID, &val);
1447 if (err)
1448 return err;
b8fee957 1449
a935c052 1450 next.sid = val & GLOBAL_VTU_SID_MASK;
b8fee957
VD
1451 }
1452 }
1453
1454 *entry = next;
1455 return 0;
1456}
1457
f81ec90f
VD
1458static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
1459 struct switchdev_obj_port_vlan *vlan,
1460 int (*cb)(struct switchdev_obj *obj))
ceff5eff 1461{
04bed143 1462 struct mv88e6xxx_chip *chip = ds->priv;
b4e47c0f 1463 struct mv88e6xxx_vtu_entry next;
ceff5eff
VD
1464 u16 pvid;
1465 int err;
1466
fad09c73 1467 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
54d77b5b
VD
1468 return -EOPNOTSUPP;
1469
fad09c73 1470 mutex_lock(&chip->reg_lock);
ceff5eff 1471
77064f37 1472 err = mv88e6xxx_port_get_pvid(chip, port, &pvid);
ceff5eff
VD
1473 if (err)
1474 goto unlock;
1475
fad09c73 1476 err = _mv88e6xxx_vtu_vid_write(chip, GLOBAL_VTU_VID_MASK);
ceff5eff
VD
1477 if (err)
1478 goto unlock;
1479
1480 do {
fad09c73 1481 err = _mv88e6xxx_vtu_getnext(chip, &next);
ceff5eff
VD
1482 if (err)
1483 break;
1484
1485 if (!next.valid)
1486 break;
1487
1488 if (next.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
1489 continue;
1490
1491 /* reinit and dump this VLAN obj */
57d32310
VD
1492 vlan->vid_begin = next.vid;
1493 vlan->vid_end = next.vid;
ceff5eff
VD
1494 vlan->flags = 0;
1495
1496 if (next.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED)
1497 vlan->flags |= BRIDGE_VLAN_INFO_UNTAGGED;
1498
1499 if (next.vid == pvid)
1500 vlan->flags |= BRIDGE_VLAN_INFO_PVID;
1501
1502 err = cb(&vlan->obj);
1503 if (err)
1504 break;
1505 } while (next.vid < GLOBAL_VTU_VID_MASK);
1506
1507unlock:
fad09c73 1508 mutex_unlock(&chip->reg_lock);
ceff5eff
VD
1509
1510 return err;
1511}
1512
fad09c73 1513static int _mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
b4e47c0f 1514 struct mv88e6xxx_vtu_entry *entry)
7dad08d7 1515{
11ea809f 1516 u16 op = GLOBAL_VTU_OP_VTU_LOAD_PURGE;
7dad08d7 1517 u16 reg = 0;
a935c052 1518 int err;
7dad08d7 1519
a935c052
VD
1520 err = _mv88e6xxx_vtu_wait(chip);
1521 if (err)
1522 return err;
7dad08d7
VD
1523
1524 if (!entry->valid)
1525 goto loadpurge;
1526
1527 /* Write port member tags */
a935c052
VD
1528 err = mv88e6xxx_vtu_data_write(chip, entry);
1529 if (err)
1530 return err;
7dad08d7 1531
fad09c73 1532 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) {
7dad08d7 1533 reg = entry->sid & GLOBAL_VTU_SID_MASK;
a935c052
VD
1534 err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, reg);
1535 if (err)
1536 return err;
b426e5f7 1537 }
7dad08d7 1538
6dc10bbc 1539 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_VTU_FID)) {
7dad08d7 1540 reg = entry->fid & GLOBAL_VTU_FID_MASK;
a935c052
VD
1541 err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_FID, reg);
1542 if (err)
1543 return err;
fad09c73 1544 } else if (mv88e6xxx_num_databases(chip) == 256) {
11ea809f
VD
1545 /* VTU DBNum[7:4] are located in VTU Operation 11:8, and
1546 * VTU DBNum[3:0] are located in VTU Operation 3:0
1547 */
1548 op |= (entry->fid & 0xf0) << 8;
1549 op |= entry->fid & 0xf;
7dad08d7
VD
1550 }
1551
1552 reg = GLOBAL_VTU_VID_VALID;
1553loadpurge:
1554 reg |= entry->vid & GLOBAL_VTU_VID_MASK;
a935c052
VD
1555 err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, reg);
1556 if (err)
1557 return err;
7dad08d7 1558
fad09c73 1559 return _mv88e6xxx_vtu_cmd(chip, op);
7dad08d7
VD
1560}
1561
fad09c73 1562static int _mv88e6xxx_stu_getnext(struct mv88e6xxx_chip *chip, u8 sid,
b4e47c0f 1563 struct mv88e6xxx_vtu_entry *entry)
0d3b33e6 1564{
b4e47c0f 1565 struct mv88e6xxx_vtu_entry next = { 0 };
a935c052
VD
1566 u16 val;
1567 int err;
0d3b33e6 1568
a935c052
VD
1569 err = _mv88e6xxx_vtu_wait(chip);
1570 if (err)
1571 return err;
0d3b33e6 1572
a935c052
VD
1573 err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID,
1574 sid & GLOBAL_VTU_SID_MASK);
1575 if (err)
1576 return err;
0d3b33e6 1577
a935c052
VD
1578 err = _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_GET_NEXT);
1579 if (err)
1580 return err;
0d3b33e6 1581
a935c052
VD
1582 err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_SID, &val);
1583 if (err)
1584 return err;
0d3b33e6 1585
a935c052 1586 next.sid = val & GLOBAL_VTU_SID_MASK;
0d3b33e6 1587
a935c052
VD
1588 err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_VID, &val);
1589 if (err)
1590 return err;
0d3b33e6 1591
a935c052 1592 next.valid = !!(val & GLOBAL_VTU_VID_VALID);
0d3b33e6
VD
1593
1594 if (next.valid) {
a935c052
VD
1595 err = mv88e6xxx_stu_data_read(chip, &next);
1596 if (err)
1597 return err;
0d3b33e6
VD
1598 }
1599
1600 *entry = next;
1601 return 0;
1602}
1603
fad09c73 1604static int _mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip,
b4e47c0f 1605 struct mv88e6xxx_vtu_entry *entry)
0d3b33e6
VD
1606{
1607 u16 reg = 0;
a935c052 1608 int err;
0d3b33e6 1609
a935c052
VD
1610 err = _mv88e6xxx_vtu_wait(chip);
1611 if (err)
1612 return err;
0d3b33e6
VD
1613
1614 if (!entry->valid)
1615 goto loadpurge;
1616
1617 /* Write port states */
a935c052
VD
1618 err = mv88e6xxx_stu_data_write(chip, entry);
1619 if (err)
1620 return err;
0d3b33e6
VD
1621
1622 reg = GLOBAL_VTU_VID_VALID;
1623loadpurge:
a935c052
VD
1624 err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, reg);
1625 if (err)
1626 return err;
0d3b33e6
VD
1627
1628 reg = entry->sid & GLOBAL_VTU_SID_MASK;
a935c052
VD
1629 err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, reg);
1630 if (err)
1631 return err;
0d3b33e6 1632
fad09c73 1633 return _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_LOAD_PURGE);
0d3b33e6
VD
1634}
1635
fad09c73 1636static int _mv88e6xxx_fid_new(struct mv88e6xxx_chip *chip, u16 *fid)
3285f9e8
VD
1637{
1638 DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
b4e47c0f 1639 struct mv88e6xxx_vtu_entry vlan;
2db9ce1f 1640 int i, err;
3285f9e8
VD
1641
1642 bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
1643
2db9ce1f 1644 /* Set every FID bit used by the (un)bridged ports */
370b4ffb 1645 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
b4e48c50 1646 err = mv88e6xxx_port_get_fid(chip, i, fid);
2db9ce1f
VD
1647 if (err)
1648 return err;
1649
1650 set_bit(*fid, fid_bitmap);
1651 }
1652
3285f9e8 1653 /* Set every FID bit used by the VLAN entries */
fad09c73 1654 err = _mv88e6xxx_vtu_vid_write(chip, GLOBAL_VTU_VID_MASK);
3285f9e8
VD
1655 if (err)
1656 return err;
1657
1658 do {
fad09c73 1659 err = _mv88e6xxx_vtu_getnext(chip, &vlan);
3285f9e8
VD
1660 if (err)
1661 return err;
1662
1663 if (!vlan.valid)
1664 break;
1665
1666 set_bit(vlan.fid, fid_bitmap);
1667 } while (vlan.vid < GLOBAL_VTU_VID_MASK);
1668
1669 /* The reset value 0x000 is used to indicate that multiple address
1670 * databases are not needed. Return the next positive available.
1671 */
1672 *fid = find_next_zero_bit(fid_bitmap, MV88E6XXX_N_FID, 1);
fad09c73 1673 if (unlikely(*fid >= mv88e6xxx_num_databases(chip)))
3285f9e8
VD
1674 return -ENOSPC;
1675
1676 /* Clear the database */
fad09c73 1677 return _mv88e6xxx_atu_flush(chip, *fid, true);
3285f9e8
VD
1678}
1679
fad09c73 1680static int _mv88e6xxx_vtu_new(struct mv88e6xxx_chip *chip, u16 vid,
b4e47c0f 1681 struct mv88e6xxx_vtu_entry *entry)
0d3b33e6 1682{
fad09c73 1683 struct dsa_switch *ds = chip->ds;
b4e47c0f 1684 struct mv88e6xxx_vtu_entry vlan = {
0d3b33e6
VD
1685 .valid = true,
1686 .vid = vid,
1687 };
3285f9e8
VD
1688 int i, err;
1689
fad09c73 1690 err = _mv88e6xxx_fid_new(chip, &vlan.fid);
3285f9e8
VD
1691 if (err)
1692 return err;
0d3b33e6 1693
3d131f07 1694 /* exclude all ports except the CPU and DSA ports */
370b4ffb 1695 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
3d131f07
VD
1696 vlan.data[i] = dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)
1697 ? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED
1698 : GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
0d3b33e6 1699
fad09c73
VD
1700 if (mv88e6xxx_6097_family(chip) || mv88e6xxx_6165_family(chip) ||
1701 mv88e6xxx_6351_family(chip) || mv88e6xxx_6352_family(chip)) {
b4e47c0f 1702 struct mv88e6xxx_vtu_entry vstp;
0d3b33e6
VD
1703
1704 /* Adding a VTU entry requires a valid STU entry. As VSTP is not
1705 * implemented, only one STU entry is needed to cover all VTU
1706 * entries. Thus, validate the SID 0.
1707 */
1708 vlan.sid = 0;
fad09c73 1709 err = _mv88e6xxx_stu_getnext(chip, GLOBAL_VTU_SID_MASK, &vstp);
0d3b33e6
VD
1710 if (err)
1711 return err;
1712
1713 if (vstp.sid != vlan.sid || !vstp.valid) {
1714 memset(&vstp, 0, sizeof(vstp));
1715 vstp.valid = true;
1716 vstp.sid = vlan.sid;
1717
fad09c73 1718 err = _mv88e6xxx_stu_loadpurge(chip, &vstp);
0d3b33e6
VD
1719 if (err)
1720 return err;
1721 }
0d3b33e6
VD
1722 }
1723
1724 *entry = vlan;
1725 return 0;
1726}
1727
fad09c73 1728static int _mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid,
b4e47c0f 1729 struct mv88e6xxx_vtu_entry *entry, bool creat)
2fb5ef09
VD
1730{
1731 int err;
1732
1733 if (!vid)
1734 return -EINVAL;
1735
fad09c73 1736 err = _mv88e6xxx_vtu_vid_write(chip, vid - 1);
2fb5ef09
VD
1737 if (err)
1738 return err;
1739
fad09c73 1740 err = _mv88e6xxx_vtu_getnext(chip, entry);
2fb5ef09
VD
1741 if (err)
1742 return err;
1743
1744 if (entry->vid != vid || !entry->valid) {
1745 if (!creat)
1746 return -EOPNOTSUPP;
1747 /* -ENOENT would've been more appropriate, but switchdev expects
1748 * -EOPNOTSUPP to inform bridge about an eventual software VLAN.
1749 */
1750
fad09c73 1751 err = _mv88e6xxx_vtu_new(chip, vid, entry);
2fb5ef09
VD
1752 }
1753
1754 return err;
1755}
1756
da9c359e
VD
1757static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
1758 u16 vid_begin, u16 vid_end)
1759{
04bed143 1760 struct mv88e6xxx_chip *chip = ds->priv;
b4e47c0f 1761 struct mv88e6xxx_vtu_entry vlan;
da9c359e
VD
1762 int i, err;
1763
1764 if (!vid_begin)
1765 return -EOPNOTSUPP;
1766
fad09c73 1767 mutex_lock(&chip->reg_lock);
da9c359e 1768
fad09c73 1769 err = _mv88e6xxx_vtu_vid_write(chip, vid_begin - 1);
da9c359e
VD
1770 if (err)
1771 goto unlock;
1772
1773 do {
fad09c73 1774 err = _mv88e6xxx_vtu_getnext(chip, &vlan);
da9c359e
VD
1775 if (err)
1776 goto unlock;
1777
1778 if (!vlan.valid)
1779 break;
1780
1781 if (vlan.vid > vid_end)
1782 break;
1783
370b4ffb 1784 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
da9c359e
VD
1785 if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
1786 continue;
1787
1788 if (vlan.data[i] ==
1789 GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
1790 continue;
1791
fad09c73
VD
1792 if (chip->ports[i].bridge_dev ==
1793 chip->ports[port].bridge_dev)
da9c359e
VD
1794 break; /* same bridge, check next VLAN */
1795
c8b09808 1796 netdev_warn(ds->ports[port].netdev,
da9c359e
VD
1797 "hardware VLAN %d already used by %s\n",
1798 vlan.vid,
fad09c73 1799 netdev_name(chip->ports[i].bridge_dev));
da9c359e
VD
1800 err = -EOPNOTSUPP;
1801 goto unlock;
1802 }
1803 } while (vlan.vid < vid_end);
1804
1805unlock:
fad09c73 1806 mutex_unlock(&chip->reg_lock);
da9c359e
VD
1807
1808 return err;
1809}
1810
f81ec90f
VD
1811static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port,
1812 bool vlan_filtering)
214cdb99 1813{
04bed143 1814 struct mv88e6xxx_chip *chip = ds->priv;
385a0995 1815 u16 mode = vlan_filtering ? PORT_CONTROL_2_8021Q_SECURE :
214cdb99 1816 PORT_CONTROL_2_8021Q_DISABLED;
0e7b9925 1817 int err;
214cdb99 1818
fad09c73 1819 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
54d77b5b
VD
1820 return -EOPNOTSUPP;
1821
fad09c73 1822 mutex_lock(&chip->reg_lock);
385a0995 1823 err = mv88e6xxx_port_set_8021q_mode(chip, port, mode);
fad09c73 1824 mutex_unlock(&chip->reg_lock);
214cdb99 1825
0e7b9925 1826 return err;
214cdb99
VD
1827}
1828
57d32310
VD
1829static int
1830mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
1831 const struct switchdev_obj_port_vlan *vlan,
1832 struct switchdev_trans *trans)
76e398a6 1833{
04bed143 1834 struct mv88e6xxx_chip *chip = ds->priv;
da9c359e
VD
1835 int err;
1836
fad09c73 1837 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
54d77b5b
VD
1838 return -EOPNOTSUPP;
1839
da9c359e
VD
1840 /* If the requested port doesn't belong to the same bridge as the VLAN
1841 * members, do not support it (yet) and fallback to software VLAN.
1842 */
1843 err = mv88e6xxx_port_check_hw_vlan(ds, port, vlan->vid_begin,
1844 vlan->vid_end);
1845 if (err)
1846 return err;
1847
76e398a6
VD
1848 /* We don't need any dynamic resource from the kernel (yet),
1849 * so skip the prepare phase.
1850 */
1851 return 0;
1852}
1853
fad09c73 1854static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
158bc065 1855 u16 vid, bool untagged)
0d3b33e6 1856{
b4e47c0f 1857 struct mv88e6xxx_vtu_entry vlan;
0d3b33e6
VD
1858 int err;
1859
fad09c73 1860 err = _mv88e6xxx_vtu_get(chip, vid, &vlan, true);
0d3b33e6 1861 if (err)
76e398a6 1862 return err;
0d3b33e6 1863
0d3b33e6
VD
1864 vlan.data[port] = untagged ?
1865 GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED :
1866 GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED;
1867
fad09c73 1868 return _mv88e6xxx_vtu_loadpurge(chip, &vlan);
76e398a6
VD
1869}
1870
f81ec90f
VD
1871static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
1872 const struct switchdev_obj_port_vlan *vlan,
1873 struct switchdev_trans *trans)
76e398a6 1874{
04bed143 1875 struct mv88e6xxx_chip *chip = ds->priv;
76e398a6
VD
1876 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
1877 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
1878 u16 vid;
76e398a6 1879
fad09c73 1880 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
54d77b5b
VD
1881 return;
1882
fad09c73 1883 mutex_lock(&chip->reg_lock);
76e398a6 1884
4d5770b3 1885 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid)
fad09c73 1886 if (_mv88e6xxx_port_vlan_add(chip, port, vid, untagged))
c8b09808
AL
1887 netdev_err(ds->ports[port].netdev,
1888 "failed to add VLAN %d%c\n",
4d5770b3 1889 vid, untagged ? 'u' : 't');
76e398a6 1890
77064f37 1891 if (pvid && mv88e6xxx_port_set_pvid(chip, port, vlan->vid_end))
c8b09808 1892 netdev_err(ds->ports[port].netdev, "failed to set PVID %d\n",
4d5770b3 1893 vlan->vid_end);
0d3b33e6 1894
fad09c73 1895 mutex_unlock(&chip->reg_lock);
0d3b33e6
VD
1896}
1897
fad09c73 1898static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_chip *chip,
158bc065 1899 int port, u16 vid)
7dad08d7 1900{
fad09c73 1901 struct dsa_switch *ds = chip->ds;
b4e47c0f 1902 struct mv88e6xxx_vtu_entry vlan;
7dad08d7
VD
1903 int i, err;
1904
fad09c73 1905 err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false);
7dad08d7 1906 if (err)
76e398a6 1907 return err;
7dad08d7 1908
2fb5ef09
VD
1909 /* Tell switchdev if this VLAN is handled in software */
1910 if (vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
3c06f08b 1911 return -EOPNOTSUPP;
7dad08d7
VD
1912
1913 vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
1914
1915 /* keep the VLAN unless all ports are excluded */
f02bdffc 1916 vlan.valid = false;
370b4ffb 1917 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
3d131f07 1918 if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
7dad08d7
VD
1919 continue;
1920
1921 if (vlan.data[i] != GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
f02bdffc 1922 vlan.valid = true;
7dad08d7
VD
1923 break;
1924 }
1925 }
1926
fad09c73 1927 err = _mv88e6xxx_vtu_loadpurge(chip, &vlan);
76e398a6
VD
1928 if (err)
1929 return err;
1930
fad09c73 1931 return _mv88e6xxx_atu_remove(chip, vlan.fid, port, false);
76e398a6
VD
1932}
1933
f81ec90f
VD
1934static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
1935 const struct switchdev_obj_port_vlan *vlan)
76e398a6 1936{
04bed143 1937 struct mv88e6xxx_chip *chip = ds->priv;
76e398a6
VD
1938 u16 pvid, vid;
1939 int err = 0;
1940
fad09c73 1941 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU))
54d77b5b
VD
1942 return -EOPNOTSUPP;
1943
fad09c73 1944 mutex_lock(&chip->reg_lock);
76e398a6 1945
77064f37 1946 err = mv88e6xxx_port_get_pvid(chip, port, &pvid);
7dad08d7
VD
1947 if (err)
1948 goto unlock;
1949
76e398a6 1950 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
fad09c73 1951 err = _mv88e6xxx_port_vlan_del(chip, port, vid);
76e398a6
VD
1952 if (err)
1953 goto unlock;
1954
1955 if (vid == pvid) {
77064f37 1956 err = mv88e6xxx_port_set_pvid(chip, port, 0);
76e398a6
VD
1957 if (err)
1958 goto unlock;
1959 }
1960 }
1961
7dad08d7 1962unlock:
fad09c73 1963 mutex_unlock(&chip->reg_lock);
7dad08d7
VD
1964
1965 return err;
1966}
1967
fad09c73 1968static int _mv88e6xxx_atu_mac_write(struct mv88e6xxx_chip *chip,
c5723ac5 1969 const unsigned char *addr)
defb05b9 1970{
a935c052 1971 int i, err;
defb05b9
GR
1972
1973 for (i = 0; i < 3; i++) {
a935c052
VD
1974 err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_MAC_01 + i,
1975 (addr[i * 2] << 8) | addr[i * 2 + 1]);
1976 if (err)
1977 return err;
defb05b9
GR
1978 }
1979
1980 return 0;
1981}
1982
fad09c73 1983static int _mv88e6xxx_atu_mac_read(struct mv88e6xxx_chip *chip,
158bc065 1984 unsigned char *addr)
defb05b9 1985{
a935c052
VD
1986 u16 val;
1987 int i, err;
defb05b9
GR
1988
1989 for (i = 0; i < 3; i++) {
a935c052
VD
1990 err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_MAC_01 + i, &val);
1991 if (err)
1992 return err;
1993
1994 addr[i * 2] = val >> 8;
1995 addr[i * 2 + 1] = val & 0xff;
defb05b9
GR
1996 }
1997
1998 return 0;
1999}
2000
fad09c73 2001static int _mv88e6xxx_atu_load(struct mv88e6xxx_chip *chip,
fd231c82 2002 struct mv88e6xxx_atu_entry *entry)
defb05b9 2003{
6630e236
VD
2004 int ret;
2005
fad09c73 2006 ret = _mv88e6xxx_atu_wait(chip);
defb05b9
GR
2007 if (ret < 0)
2008 return ret;
2009
fad09c73 2010 ret = _mv88e6xxx_atu_mac_write(chip, entry->mac);
defb05b9
GR
2011 if (ret < 0)
2012 return ret;
2013
fad09c73 2014 ret = _mv88e6xxx_atu_data_write(chip, entry);
fd231c82 2015 if (ret < 0)
87820510
VD
2016 return ret;
2017
fad09c73 2018 return _mv88e6xxx_atu_cmd(chip, entry->fid, GLOBAL_ATU_OP_LOAD_DB);
fd231c82 2019}
87820510 2020
88472939
VD
2021static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid,
2022 struct mv88e6xxx_atu_entry *entry);
2023
2024static int mv88e6xxx_atu_get(struct mv88e6xxx_chip *chip, int fid,
2025 const u8 *addr, struct mv88e6xxx_atu_entry *entry)
2026{
2027 struct mv88e6xxx_atu_entry next;
2028 int err;
2029
2030 eth_broadcast_addr(next.mac);
2031
2032 err = _mv88e6xxx_atu_mac_write(chip, next.mac);
2033 if (err)
2034 return err;
2035
2036 do {
2037 err = _mv88e6xxx_atu_getnext(chip, fid, &next);
2038 if (err)
2039 return err;
2040
2041 if (next.state == GLOBAL_ATU_DATA_STATE_UNUSED)
2042 break;
2043
2044 if (ether_addr_equal(next.mac, addr)) {
2045 *entry = next;
2046 return 0;
2047 }
2048 } while (!is_broadcast_ether_addr(next.mac));
2049
2050 memset(entry, 0, sizeof(*entry));
2051 entry->fid = fid;
2052 ether_addr_copy(entry->mac, addr);
2053
2054 return 0;
2055}
2056
83dabd1f
VD
2057static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
2058 const unsigned char *addr, u16 vid,
2059 u8 state)
fd231c82 2060{
b4e47c0f 2061 struct mv88e6xxx_vtu_entry vlan;
88472939 2062 struct mv88e6xxx_atu_entry entry;
3285f9e8
VD
2063 int err;
2064
2db9ce1f
VD
2065 /* Null VLAN ID corresponds to the port private database */
2066 if (vid == 0)
b4e48c50 2067 err = mv88e6xxx_port_get_fid(chip, port, &vlan.fid);
2db9ce1f 2068 else
fad09c73 2069 err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false);
3285f9e8
VD
2070 if (err)
2071 return err;
fd231c82 2072
88472939
VD
2073 err = mv88e6xxx_atu_get(chip, vlan.fid, addr, &entry);
2074 if (err)
2075 return err;
2076
2077 /* Purge the ATU entry only if no port is using it anymore */
2078 if (state == GLOBAL_ATU_DATA_STATE_UNUSED) {
2079 entry.portv_trunkid &= ~BIT(port);
2080 if (!entry.portv_trunkid)
2081 entry.state = GLOBAL_ATU_DATA_STATE_UNUSED;
2082 } else {
2083 entry.portv_trunkid |= BIT(port);
2084 entry.state = state;
fd231c82
VD
2085 }
2086
fad09c73 2087 return _mv88e6xxx_atu_load(chip, &entry);
87820510
VD
2088}
2089
f81ec90f
VD
2090static int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
2091 const struct switchdev_obj_port_fdb *fdb,
2092 struct switchdev_trans *trans)
146a3206
VD
2093{
2094 /* We don't need any dynamic resource from the kernel (yet),
2095 * so skip the prepare phase.
2096 */
2097 return 0;
2098}
2099
f81ec90f
VD
2100static void mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
2101 const struct switchdev_obj_port_fdb *fdb,
2102 struct switchdev_trans *trans)
87820510 2103{
04bed143 2104 struct mv88e6xxx_chip *chip = ds->priv;
87820510 2105
fad09c73 2106 mutex_lock(&chip->reg_lock);
83dabd1f
VD
2107 if (mv88e6xxx_port_db_load_purge(chip, port, fdb->addr, fdb->vid,
2108 GLOBAL_ATU_DATA_STATE_UC_STATIC))
2109 netdev_err(ds->ports[port].netdev, "failed to load unicast MAC address\n");
fad09c73 2110 mutex_unlock(&chip->reg_lock);
87820510
VD
2111}
2112
f81ec90f
VD
2113static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
2114 const struct switchdev_obj_port_fdb *fdb)
87820510 2115{
04bed143 2116 struct mv88e6xxx_chip *chip = ds->priv;
83dabd1f 2117 int err;
87820510 2118
fad09c73 2119 mutex_lock(&chip->reg_lock);
83dabd1f
VD
2120 err = mv88e6xxx_port_db_load_purge(chip, port, fdb->addr, fdb->vid,
2121 GLOBAL_ATU_DATA_STATE_UNUSED);
fad09c73 2122 mutex_unlock(&chip->reg_lock);
87820510 2123
83dabd1f 2124 return err;
87820510
VD
2125}
2126
fad09c73 2127static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid,
1d194046 2128 struct mv88e6xxx_atu_entry *entry)
6630e236 2129{
1d194046 2130 struct mv88e6xxx_atu_entry next = { 0 };
a935c052
VD
2131 u16 val;
2132 int err;
1d194046
VD
2133
2134 next.fid = fid;
defb05b9 2135
a935c052
VD
2136 err = _mv88e6xxx_atu_wait(chip);
2137 if (err)
2138 return err;
6630e236 2139
a935c052
VD
2140 err = _mv88e6xxx_atu_cmd(chip, fid, GLOBAL_ATU_OP_GET_NEXT_DB);
2141 if (err)
2142 return err;
6630e236 2143
a935c052
VD
2144 err = _mv88e6xxx_atu_mac_read(chip, next.mac);
2145 if (err)
2146 return err;
6630e236 2147
a935c052
VD
2148 err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_DATA, &val);
2149 if (err)
2150 return err;
6630e236 2151
a935c052 2152 next.state = val & GLOBAL_ATU_DATA_STATE_MASK;
1d194046
VD
2153 if (next.state != GLOBAL_ATU_DATA_STATE_UNUSED) {
2154 unsigned int mask, shift;
2155
a935c052 2156 if (val & GLOBAL_ATU_DATA_TRUNK) {
1d194046
VD
2157 next.trunk = true;
2158 mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK;
2159 shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT;
2160 } else {
2161 next.trunk = false;
2162 mask = GLOBAL_ATU_DATA_PORT_VECTOR_MASK;
2163 shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT;
2164 }
2165
a935c052 2166 next.portv_trunkid = (val & mask) >> shift;
1d194046 2167 }
cdf09697 2168
1d194046 2169 *entry = next;
cdf09697
DM
2170 return 0;
2171}
2172
83dabd1f
VD
2173static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
2174 u16 fid, u16 vid, int port,
2175 struct switchdev_obj *obj,
2176 int (*cb)(struct switchdev_obj *obj))
74b6ba0d
VD
2177{
2178 struct mv88e6xxx_atu_entry addr = {
2179 .mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
2180 };
2181 int err;
2182
fad09c73 2183 err = _mv88e6xxx_atu_mac_write(chip, addr.mac);
74b6ba0d
VD
2184 if (err)
2185 return err;
2186
2187 do {
fad09c73 2188 err = _mv88e6xxx_atu_getnext(chip, fid, &addr);
74b6ba0d 2189 if (err)
83dabd1f 2190 return err;
74b6ba0d
VD
2191
2192 if (addr.state == GLOBAL_ATU_DATA_STATE_UNUSED)
2193 break;
2194
83dabd1f
VD
2195 if (addr.trunk || (addr.portv_trunkid & BIT(port)) == 0)
2196 continue;
2197
2198 if (obj->id == SWITCHDEV_OBJ_ID_PORT_FDB) {
2199 struct switchdev_obj_port_fdb *fdb;
74b6ba0d 2200
83dabd1f
VD
2201 if (!is_unicast_ether_addr(addr.mac))
2202 continue;
2203
2204 fdb = SWITCHDEV_OBJ_PORT_FDB(obj);
74b6ba0d
VD
2205 fdb->vid = vid;
2206 ether_addr_copy(fdb->addr, addr.mac);
83dabd1f
VD
2207 if (addr.state == GLOBAL_ATU_DATA_STATE_UC_STATIC)
2208 fdb->ndm_state = NUD_NOARP;
2209 else
2210 fdb->ndm_state = NUD_REACHABLE;
7df8fbdd
VD
2211 } else if (obj->id == SWITCHDEV_OBJ_ID_PORT_MDB) {
2212 struct switchdev_obj_port_mdb *mdb;
2213
2214 if (!is_multicast_ether_addr(addr.mac))
2215 continue;
2216
2217 mdb = SWITCHDEV_OBJ_PORT_MDB(obj);
2218 mdb->vid = vid;
2219 ether_addr_copy(mdb->addr, addr.mac);
83dabd1f
VD
2220 } else {
2221 return -EOPNOTSUPP;
74b6ba0d 2222 }
83dabd1f
VD
2223
2224 err = cb(obj);
2225 if (err)
2226 return err;
74b6ba0d
VD
2227 } while (!is_broadcast_ether_addr(addr.mac));
2228
2229 return err;
2230}
2231
83dabd1f
VD
2232static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
2233 struct switchdev_obj *obj,
2234 int (*cb)(struct switchdev_obj *obj))
f33475bd 2235{
b4e47c0f 2236 struct mv88e6xxx_vtu_entry vlan = {
f33475bd
VD
2237 .vid = GLOBAL_VTU_VID_MASK, /* all ones */
2238 };
2db9ce1f 2239 u16 fid;
f33475bd
VD
2240 int err;
2241
2db9ce1f 2242 /* Dump port's default Filtering Information Database (VLAN ID 0) */
b4e48c50 2243 err = mv88e6xxx_port_get_fid(chip, port, &fid);
2db9ce1f 2244 if (err)
83dabd1f 2245 return err;
2db9ce1f 2246
83dabd1f 2247 err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, obj, cb);
2db9ce1f 2248 if (err)
83dabd1f 2249 return err;
2db9ce1f 2250
74b6ba0d 2251 /* Dump VLANs' Filtering Information Databases */
fad09c73 2252 err = _mv88e6xxx_vtu_vid_write(chip, vlan.vid);
f33475bd 2253 if (err)
83dabd1f 2254 return err;
f33475bd
VD
2255
2256 do {
fad09c73 2257 err = _mv88e6xxx_vtu_getnext(chip, &vlan);
f33475bd 2258 if (err)
83dabd1f 2259 return err;
f33475bd
VD
2260
2261 if (!vlan.valid)
2262 break;
2263
83dabd1f
VD
2264 err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
2265 obj, cb);
f33475bd 2266 if (err)
83dabd1f 2267 return err;
f33475bd
VD
2268 } while (vlan.vid < GLOBAL_VTU_VID_MASK);
2269
83dabd1f
VD
2270 return err;
2271}
2272
2273static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
2274 struct switchdev_obj_port_fdb *fdb,
2275 int (*cb)(struct switchdev_obj *obj))
2276{
04bed143 2277 struct mv88e6xxx_chip *chip = ds->priv;
83dabd1f
VD
2278 int err;
2279
2280 mutex_lock(&chip->reg_lock);
2281 err = mv88e6xxx_port_db_dump(chip, port, &fdb->obj, cb);
fad09c73 2282 mutex_unlock(&chip->reg_lock);
f33475bd
VD
2283
2284 return err;
2285}
2286
f81ec90f
VD
2287static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
2288 struct net_device *bridge)
e79a8bcb 2289{
04bed143 2290 struct mv88e6xxx_chip *chip = ds->priv;
1d9619d5 2291 int i, err = 0;
466dfa07 2292
fad09c73 2293 mutex_lock(&chip->reg_lock);
466dfa07 2294
b7666efe 2295 /* Assign the bridge and remap each port's VLANTable */
fad09c73 2296 chip->ports[port].bridge_dev = bridge;
b7666efe 2297
370b4ffb 2298 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
fad09c73
VD
2299 if (chip->ports[i].bridge_dev == bridge) {
2300 err = _mv88e6xxx_port_based_vlan_map(chip, i);
b7666efe
VD
2301 if (err)
2302 break;
2303 }
2304 }
2305
fad09c73 2306 mutex_unlock(&chip->reg_lock);
a6692754 2307
466dfa07 2308 return err;
e79a8bcb
VD
2309}
2310
f81ec90f 2311static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
66d9cd0f 2312{
04bed143 2313 struct mv88e6xxx_chip *chip = ds->priv;
fad09c73 2314 struct net_device *bridge = chip->ports[port].bridge_dev;
16bfa702 2315 int i;
466dfa07 2316
fad09c73 2317 mutex_lock(&chip->reg_lock);
466dfa07 2318
b7666efe 2319 /* Unassign the bridge and remap each port's VLANTable */
fad09c73 2320 chip->ports[port].bridge_dev = NULL;
b7666efe 2321
370b4ffb 2322 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
fad09c73
VD
2323 if (i == port || chip->ports[i].bridge_dev == bridge)
2324 if (_mv88e6xxx_port_based_vlan_map(chip, i))
c8b09808
AL
2325 netdev_warn(ds->ports[i].netdev,
2326 "failed to remap\n");
b7666efe 2327
fad09c73 2328 mutex_unlock(&chip->reg_lock);
66d9cd0f
VD
2329}
2330
fad09c73 2331static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
552238b5 2332{
fad09c73 2333 bool ppu_active = mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU_ACTIVE);
552238b5 2334 u16 is_reset = (ppu_active ? 0x8800 : 0xc800);
fad09c73 2335 struct gpio_desc *gpiod = chip->reset;
552238b5 2336 unsigned long timeout;
0e7b9925 2337 u16 reg;
a935c052 2338 int err;
552238b5
VD
2339 int i;
2340
2341 /* Set all ports to the disabled state. */
370b4ffb 2342 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
e28def33
VD
2343 err = mv88e6xxx_port_set_state(chip, i,
2344 PORT_CONTROL_STATE_DISABLED);
0e7b9925
AL
2345 if (err)
2346 return err;
552238b5
VD
2347 }
2348
2349 /* Wait for transmit queues to drain. */
2350 usleep_range(2000, 4000);
2351
2352 /* If there is a gpio connected to the reset pin, toggle it */
2353 if (gpiod) {
2354 gpiod_set_value_cansleep(gpiod, 1);
2355 usleep_range(10000, 20000);
2356 gpiod_set_value_cansleep(gpiod, 0);
2357 usleep_range(10000, 20000);
2358 }
2359
2360 /* Reset the switch. Keep the PPU active if requested. The PPU
2361 * needs to be active to support indirect phy register access
2362 * through global registers 0x18 and 0x19.
2363 */
2364 if (ppu_active)
a935c052 2365 err = mv88e6xxx_g1_write(chip, 0x04, 0xc000);
552238b5 2366 else
a935c052 2367 err = mv88e6xxx_g1_write(chip, 0x04, 0xc400);
0e7b9925
AL
2368 if (err)
2369 return err;
552238b5
VD
2370
2371 /* Wait up to one second for reset to complete. */
2372 timeout = jiffies + 1 * HZ;
2373 while (time_before(jiffies, timeout)) {
a935c052
VD
2374 err = mv88e6xxx_g1_read(chip, 0x00, &reg);
2375 if (err)
2376 return err;
552238b5 2377
a935c052 2378 if ((reg & is_reset) == is_reset)
552238b5
VD
2379 break;
2380 usleep_range(1000, 2000);
2381 }
2382 if (time_after(jiffies, timeout))
0e7b9925 2383 err = -ETIMEDOUT;
552238b5 2384 else
0e7b9925 2385 err = 0;
552238b5 2386
0e7b9925 2387 return err;
552238b5
VD
2388}
2389
09cb7dfd 2390static int mv88e6xxx_serdes_power_on(struct mv88e6xxx_chip *chip)
13a7ebb3 2391{
09cb7dfd
VD
2392 u16 val;
2393 int err;
13a7ebb3 2394
09cb7dfd
VD
2395 /* Clear Power Down bit */
2396 err = mv88e6xxx_serdes_read(chip, MII_BMCR, &val);
2397 if (err)
2398 return err;
13a7ebb3 2399
09cb7dfd
VD
2400 if (val & BMCR_PDOWN) {
2401 val &= ~BMCR_PDOWN;
2402 err = mv88e6xxx_serdes_write(chip, MII_BMCR, val);
13a7ebb3
PU
2403 }
2404
09cb7dfd 2405 return err;
13a7ebb3
PU
2406}
2407
fad09c73 2408static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
d827e88a 2409{
fad09c73 2410 struct dsa_switch *ds = chip->ds;
0e7b9925 2411 int err;
54d792f2 2412 u16 reg;
d827e88a 2413
d78343d2
VD
2414 /* MAC Forcing register: don't force link, speed, duplex or flow control
2415 * state to any particular values on physical ports, but force the CPU
2416 * port and all DSA ports to their maximum bandwidth and full duplex.
2417 */
2418 if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
2419 err = mv88e6xxx_port_setup_mac(chip, port, LINK_FORCED_UP,
2420 SPEED_MAX, DUPLEX_FULL,
2421 PHY_INTERFACE_MODE_NA);
2422 else
2423 err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED,
2424 SPEED_UNFORCED, DUPLEX_UNFORCED,
2425 PHY_INTERFACE_MODE_NA);
2426 if (err)
2427 return err;
54d792f2
AL
2428
2429 /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
2430 * disable Header mode, enable IGMP/MLD snooping, disable VLAN
2431 * tunneling, determine priority by looking at 802.1p and IP
2432 * priority fields (IP prio has precedence), and set STP state
2433 * to Forwarding.
2434 *
2435 * If this is the CPU link, use DSA or EDSA tagging depending
2436 * on which tagging mode was configured.
2437 *
2438 * If this is a link to another switch, use DSA tagging mode.
2439 *
2440 * If this is the upstream port for this switch, enable
2441 * forwarding of unknown unicasts and multicasts.
2442 */
2443 reg = 0;
fad09c73
VD
2444 if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
2445 mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
2446 mv88e6xxx_6095_family(chip) || mv88e6xxx_6065_family(chip) ||
2447 mv88e6xxx_6185_family(chip) || mv88e6xxx_6320_family(chip))
54d792f2
AL
2448 reg = PORT_CONTROL_IGMP_MLD_SNOOP |
2449 PORT_CONTROL_USE_TAG | PORT_CONTROL_USE_IP |
2450 PORT_CONTROL_STATE_FORWARDING;
2451 if (dsa_is_cpu_port(ds, port)) {
2bbb33be 2452 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA))
5377b802 2453 reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA |
c047a1f9 2454 PORT_CONTROL_FORWARD_UNKNOWN_MC;
2bbb33be
AL
2455 else
2456 reg |= PORT_CONTROL_DSA_TAG;
f027e0cc
JL
2457 reg |= PORT_CONTROL_EGRESS_ADD_TAG |
2458 PORT_CONTROL_FORWARD_UNKNOWN;
54d792f2 2459 }
6083ce71 2460 if (dsa_is_dsa_port(ds, port)) {
fad09c73
VD
2461 if (mv88e6xxx_6095_family(chip) ||
2462 mv88e6xxx_6185_family(chip))
6083ce71 2463 reg |= PORT_CONTROL_DSA_TAG;
fad09c73
VD
2464 if (mv88e6xxx_6352_family(chip) ||
2465 mv88e6xxx_6351_family(chip) ||
2466 mv88e6xxx_6165_family(chip) ||
2467 mv88e6xxx_6097_family(chip) ||
2468 mv88e6xxx_6320_family(chip)) {
54d792f2 2469 reg |= PORT_CONTROL_FRAME_MODE_DSA;
6083ce71
AL
2470 }
2471
54d792f2
AL
2472 if (port == dsa_upstream_port(ds))
2473 reg |= PORT_CONTROL_FORWARD_UNKNOWN |
2474 PORT_CONTROL_FORWARD_UNKNOWN_MC;
2475 }
2476 if (reg) {
0e7b9925
AL
2477 err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
2478 if (err)
2479 return err;
54d792f2
AL
2480 }
2481
13a7ebb3
PU
2482 /* If this port is connected to a SerDes, make sure the SerDes is not
2483 * powered down.
2484 */
09cb7dfd 2485 if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_SERDES)) {
0e7b9925
AL
2486 err = mv88e6xxx_port_read(chip, port, PORT_STATUS, &reg);
2487 if (err)
2488 return err;
2489 reg &= PORT_STATUS_CMODE_MASK;
2490 if ((reg == PORT_STATUS_CMODE_100BASE_X) ||
2491 (reg == PORT_STATUS_CMODE_1000BASE_X) ||
2492 (reg == PORT_STATUS_CMODE_SGMII)) {
2493 err = mv88e6xxx_serdes_power_on(chip);
2494 if (err < 0)
2495 return err;
13a7ebb3
PU
2496 }
2497 }
2498
8efdda4a 2499 /* Port Control 2: don't force a good FCS, set the maximum frame size to
46fbe5e5 2500 * 10240 bytes, disable 802.1q tags checking, don't discard tagged or
8efdda4a
VD
2501 * untagged frames on this port, do a destination address lookup on all
2502 * received packets as usual, disable ARP mirroring and don't send a
2503 * copy of all transmitted/received frames on this port to the CPU.
54d792f2
AL
2504 */
2505 reg = 0;
fad09c73
VD
2506 if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
2507 mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
2508 mv88e6xxx_6095_family(chip) || mv88e6xxx_6320_family(chip) ||
2509 mv88e6xxx_6185_family(chip))
54d792f2
AL
2510 reg = PORT_CONTROL_2_MAP_DA;
2511
fad09c73
VD
2512 if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
2513 mv88e6xxx_6165_family(chip) || mv88e6xxx_6320_family(chip))
54d792f2
AL
2514 reg |= PORT_CONTROL_2_JUMBO_10240;
2515
fad09c73 2516 if (mv88e6xxx_6095_family(chip) || mv88e6xxx_6185_family(chip)) {
54d792f2
AL
2517 /* Set the upstream port this port should use */
2518 reg |= dsa_upstream_port(ds);
2519 /* enable forwarding of unknown multicast addresses to
2520 * the upstream port
2521 */
2522 if (port == dsa_upstream_port(ds))
2523 reg |= PORT_CONTROL_2_FORWARD_UNKNOWN;
2524 }
2525
46fbe5e5 2526 reg |= PORT_CONTROL_2_8021Q_DISABLED;
8efdda4a 2527
54d792f2 2528 if (reg) {
0e7b9925
AL
2529 err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
2530 if (err)
2531 return err;
54d792f2
AL
2532 }
2533
2534 /* Port Association Vector: when learning source addresses
2535 * of packets, add the address to the address database using
2536 * a port bitmap that has only the bit for this port set and
2537 * the other bits clear.
2538 */
4c7ea3c0 2539 reg = 1 << port;
996ecb82
VD
2540 /* Disable learning for CPU port */
2541 if (dsa_is_cpu_port(ds, port))
65fa4027 2542 reg = 0;
4c7ea3c0 2543
0e7b9925
AL
2544 err = mv88e6xxx_port_write(chip, port, PORT_ASSOC_VECTOR, reg);
2545 if (err)
2546 return err;
54d792f2
AL
2547
2548 /* Egress rate control 2: disable egress rate control. */
0e7b9925
AL
2549 err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL_2, 0x0000);
2550 if (err)
2551 return err;
54d792f2 2552
fad09c73
VD
2553 if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
2554 mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
2555 mv88e6xxx_6320_family(chip)) {
54d792f2
AL
2556 /* Do not limit the period of time that this port can
2557 * be paused for by the remote end or the period of
2558 * time that this port can pause the remote end.
2559 */
0e7b9925
AL
2560 err = mv88e6xxx_port_write(chip, port, PORT_PAUSE_CTRL, 0x0000);
2561 if (err)
2562 return err;
54d792f2
AL
2563
2564 /* Port ATU control: disable limiting the number of
2565 * address database entries that this port is allowed
2566 * to use.
2567 */
0e7b9925
AL
2568 err = mv88e6xxx_port_write(chip, port, PORT_ATU_CONTROL,
2569 0x0000);
54d792f2
AL
2570 /* Priority Override: disable DA, SA and VTU priority
2571 * override.
2572 */
0e7b9925
AL
2573 err = mv88e6xxx_port_write(chip, port, PORT_PRI_OVERRIDE,
2574 0x0000);
2575 if (err)
2576 return err;
54d792f2
AL
2577
2578 /* Port Ethertype: use the Ethertype DSA Ethertype
2579 * value.
2580 */
2bbb33be 2581 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA)) {
0e7b9925
AL
2582 err = mv88e6xxx_port_write(chip, port, PORT_ETH_TYPE,
2583 ETH_P_EDSA);
2584 if (err)
2585 return err;
2bbb33be
AL
2586 }
2587
54d792f2
AL
2588 /* Tag Remap: use an identity 802.1p prio -> switch
2589 * prio mapping.
2590 */
0e7b9925
AL
2591 err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_0123,
2592 0x3210);
2593 if (err)
2594 return err;
54d792f2
AL
2595
2596 /* Tag Remap 2: use an identity 802.1p prio -> switch
2597 * prio mapping.
2598 */
0e7b9925
AL
2599 err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_4567,
2600 0x7654);
2601 if (err)
2602 return err;
54d792f2
AL
2603 }
2604
1bc261fa 2605 /* Rate Control: disable ingress rate limiting. */
fad09c73
VD
2606 if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
2607 mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
fad09c73 2608 mv88e6xxx_6320_family(chip)) {
0e7b9925
AL
2609 err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL,
2610 0x0001);
2611 if (err)
2612 return err;
1bc261fa 2613 } else if (mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip)) {
0e7b9925
AL
2614 err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL,
2615 0x0000);
2616 if (err)
2617 return err;
54d792f2
AL
2618 }
2619
366f0a0f
GR
2620 /* Port Control 1: disable trunking, disable sending
2621 * learning messages to this port.
d827e88a 2622 */
0e7b9925
AL
2623 err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_1, 0x0000);
2624 if (err)
2625 return err;
d827e88a 2626
207afda1 2627 /* Port based VLAN map: give each port the same default address
b7666efe
VD
2628 * database, and allow bidirectional communication between the
2629 * CPU and DSA port(s), and the other ports.
d827e88a 2630 */
b4e48c50 2631 err = mv88e6xxx_port_set_fid(chip, port, 0);
0e7b9925
AL
2632 if (err)
2633 return err;
2db9ce1f 2634
0e7b9925
AL
2635 err = _mv88e6xxx_port_based_vlan_map(chip, port);
2636 if (err)
2637 return err;
d827e88a
GR
2638
2639 /* Default VLAN ID and priority: don't set a default VLAN
2640 * ID, and set the default packet priority to zero.
2641 */
0e7b9925 2642 return mv88e6xxx_port_write(chip, port, PORT_DEFAULT_VLAN, 0x0000);
dbde9e66
AL
2643}
2644
aa0938c6 2645static int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
3b4caa1b
VD
2646{
2647 int err;
2648
a935c052 2649 err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_01, (addr[0] << 8) | addr[1]);
3b4caa1b
VD
2650 if (err)
2651 return err;
2652
a935c052 2653 err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]);
3b4caa1b
VD
2654 if (err)
2655 return err;
2656
a935c052
VD
2657 err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]);
2658 if (err)
2659 return err;
2660
2661 return 0;
3b4caa1b
VD
2662}
2663
acddbd21
VD
2664static int mv88e6xxx_g1_set_age_time(struct mv88e6xxx_chip *chip,
2665 unsigned int msecs)
2666{
2667 const unsigned int coeff = chip->info->age_time_coeff;
2668 const unsigned int min = 0x01 * coeff;
2669 const unsigned int max = 0xff * coeff;
2670 u8 age_time;
2671 u16 val;
2672 int err;
2673
2674 if (msecs < min || msecs > max)
2675 return -ERANGE;
2676
2677 /* Round to nearest multiple of coeff */
2678 age_time = (msecs + coeff / 2) / coeff;
2679
a935c052 2680 err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_CONTROL, &val);
acddbd21
VD
2681 if (err)
2682 return err;
2683
2684 /* AgeTime is 11:4 bits */
2685 val &= ~0xff0;
2686 val |= age_time << 4;
2687
a935c052 2688 return mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL, val);
acddbd21
VD
2689}
2690
2cfcd964
VD
2691static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
2692 unsigned int ageing_time)
2693{
04bed143 2694 struct mv88e6xxx_chip *chip = ds->priv;
2cfcd964
VD
2695 int err;
2696
2697 mutex_lock(&chip->reg_lock);
2698 err = mv88e6xxx_g1_set_age_time(chip, ageing_time);
2699 mutex_unlock(&chip->reg_lock);
2700
2701 return err;
2702}
2703
9729934c 2704static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
acdaffcc 2705{
fad09c73 2706 struct dsa_switch *ds = chip->ds;
b0745e87 2707 u32 upstream_port = dsa_upstream_port(ds);
119477bd 2708 u16 reg;
552238b5 2709 int err;
54d792f2 2710
119477bd
VD
2711 /* Enable the PHY Polling Unit if present, don't discard any packets,
2712 * and mask all interrupt sources.
2713 */
dc30c35b
AL
2714 err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &reg);
2715 if (err < 0)
2716 return err;
2717
2718 reg &= ~GLOBAL_CONTROL_PPU_ENABLE;
fad09c73
VD
2719 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU) ||
2720 mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU_ACTIVE))
119477bd
VD
2721 reg |= GLOBAL_CONTROL_PPU_ENABLE;
2722
a935c052 2723 err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, reg);
119477bd
VD
2724 if (err)
2725 return err;
2726
b0745e87
VD
2727 /* Configure the upstream port, and configure it as the port to which
2728 * ingress and egress and ARP monitor frames are to be sent.
2729 */
2730 reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
2731 upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
2732 upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
a935c052 2733 err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
b0745e87
VD
2734 if (err)
2735 return err;
2736
50484ff4 2737 /* Disable remote management, and set the switch's DSA device number. */
a935c052
VD
2738 err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL_2,
2739 GLOBAL_CONTROL_2_MULTIPLE_CASCADE |
2740 (ds->index & 0x1f));
50484ff4
VD
2741 if (err)
2742 return err;
2743
acddbd21
VD
2744 /* Clear all the VTU and STU entries */
2745 err = _mv88e6xxx_vtu_stu_flush(chip);
2746 if (err < 0)
2747 return err;
2748
54d792f2
AL
2749 /* Set the default address aging time to 5 minutes, and
2750 * enable address learn messages to be sent to all message
2751 * ports.
2752 */
a935c052
VD
2753 err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL,
2754 GLOBAL_ATU_CONTROL_LEARN2ALL);
48ace4ef 2755 if (err)
08a01261 2756 return err;
54d792f2 2757
acddbd21
VD
2758 err = mv88e6xxx_g1_set_age_time(chip, 300000);
2759 if (err)
9729934c
VD
2760 return err;
2761
2762 /* Clear all ATU entries */
2763 err = _mv88e6xxx_atu_flush(chip, 0, true);
2764 if (err)
2765 return err;
2766
54d792f2 2767 /* Configure the IP ToS mapping registers. */
a935c052 2768 err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_0, 0x0000);
48ace4ef 2769 if (err)
08a01261 2770 return err;
a935c052 2771 err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_1, 0x0000);
48ace4ef 2772 if (err)
08a01261 2773 return err;
a935c052 2774 err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_2, 0x5555);
48ace4ef 2775 if (err)
08a01261 2776 return err;
a935c052 2777 err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_3, 0x5555);
48ace4ef 2778 if (err)
08a01261 2779 return err;
a935c052 2780 err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_4, 0xaaaa);
48ace4ef 2781 if (err)
08a01261 2782 return err;
a935c052 2783 err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_5, 0xaaaa);
48ace4ef 2784 if (err)
08a01261 2785 return err;
a935c052 2786 err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_6, 0xffff);
48ace4ef 2787 if (err)
08a01261 2788 return err;
a935c052 2789 err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_7, 0xffff);
48ace4ef 2790 if (err)
08a01261 2791 return err;
54d792f2
AL
2792
2793 /* Configure the IEEE 802.1p priority mapping register. */
a935c052 2794 err = mv88e6xxx_g1_write(chip, GLOBAL_IEEE_PRI, 0xfa41);
48ace4ef 2795 if (err)
08a01261 2796 return err;
54d792f2 2797
9729934c 2798 /* Clear the statistics counters for all ports */
a935c052
VD
2799 err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP,
2800 GLOBAL_STATS_OP_FLUSH_ALL);
9729934c
VD
2801 if (err)
2802 return err;
2803
2804 /* Wait for the flush to complete. */
2805 err = _mv88e6xxx_stats_wait(chip);
2806 if (err)
2807 return err;
2808
2809 return 0;
2810}
2811
f81ec90f 2812static int mv88e6xxx_setup(struct dsa_switch *ds)
08a01261 2813{
04bed143 2814 struct mv88e6xxx_chip *chip = ds->priv;
08a01261 2815 int err;
a1a6a4d1
VD
2816 int i;
2817
fad09c73
VD
2818 chip->ds = ds;
2819 ds->slave_mii_bus = chip->mdio_bus;
08a01261 2820
fad09c73 2821 mutex_lock(&chip->reg_lock);
08a01261 2822
9729934c 2823 /* Setup Switch Port Registers */
370b4ffb 2824 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
9729934c
VD
2825 err = mv88e6xxx_setup_port(chip, i);
2826 if (err)
2827 goto unlock;
2828 }
2829
2830 /* Setup Switch Global 1 Registers */
2831 err = mv88e6xxx_g1_setup(chip);
a1a6a4d1
VD
2832 if (err)
2833 goto unlock;
2834
9729934c
VD
2835 /* Setup Switch Global 2 Registers */
2836 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_GLOBAL2)) {
2837 err = mv88e6xxx_g2_setup(chip);
a1a6a4d1
VD
2838 if (err)
2839 goto unlock;
2840 }
08a01261 2841
6b17e864 2842unlock:
fad09c73 2843 mutex_unlock(&chip->reg_lock);
db687a56 2844
48ace4ef 2845 return err;
54d792f2
AL
2846}
2847
3b4caa1b
VD
2848static int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr)
2849{
04bed143 2850 struct mv88e6xxx_chip *chip = ds->priv;
3b4caa1b
VD
2851 int err;
2852
b073d4e2
VD
2853 if (!chip->info->ops->set_switch_mac)
2854 return -EOPNOTSUPP;
3b4caa1b 2855
b073d4e2
VD
2856 mutex_lock(&chip->reg_lock);
2857 err = chip->info->ops->set_switch_mac(chip, addr);
3b4caa1b
VD
2858 mutex_unlock(&chip->reg_lock);
2859
2860 return err;
2861}
2862
e57e5e77 2863static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
fd3a0ee4 2864{
fad09c73 2865 struct mv88e6xxx_chip *chip = bus->priv;
e57e5e77
VD
2866 u16 val;
2867 int err;
fd3a0ee4 2868
370b4ffb 2869 if (phy >= mv88e6xxx_num_ports(chip))
158bc065 2870 return 0xffff;
fd3a0ee4 2871
fad09c73 2872 mutex_lock(&chip->reg_lock);
e57e5e77 2873 err = mv88e6xxx_phy_read(chip, phy, reg, &val);
fad09c73 2874 mutex_unlock(&chip->reg_lock);
e57e5e77
VD
2875
2876 return err ? err : val;
fd3a0ee4
AL
2877}
2878
e57e5e77 2879static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
fd3a0ee4 2880{
fad09c73 2881 struct mv88e6xxx_chip *chip = bus->priv;
e57e5e77 2882 int err;
fd3a0ee4 2883
370b4ffb 2884 if (phy >= mv88e6xxx_num_ports(chip))
158bc065 2885 return 0xffff;
fd3a0ee4 2886
fad09c73 2887 mutex_lock(&chip->reg_lock);
e57e5e77 2888 err = mv88e6xxx_phy_write(chip, phy, reg, val);
fad09c73 2889 mutex_unlock(&chip->reg_lock);
e57e5e77
VD
2890
2891 return err;
fd3a0ee4
AL
2892}
2893
fad09c73 2894static int mv88e6xxx_mdio_register(struct mv88e6xxx_chip *chip,
b516d453
AL
2895 struct device_node *np)
2896{
2897 static int index;
2898 struct mii_bus *bus;
2899 int err;
2900
b516d453 2901 if (np)
fad09c73 2902 chip->mdio_np = of_get_child_by_name(np, "mdio");
b516d453 2903
fad09c73 2904 bus = devm_mdiobus_alloc(chip->dev);
b516d453
AL
2905 if (!bus)
2906 return -ENOMEM;
2907
fad09c73 2908 bus->priv = (void *)chip;
b516d453
AL
2909 if (np) {
2910 bus->name = np->full_name;
2911 snprintf(bus->id, MII_BUS_ID_SIZE, "%s", np->full_name);
2912 } else {
2913 bus->name = "mv88e6xxx SMI";
2914 snprintf(bus->id, MII_BUS_ID_SIZE, "mv88e6xxx-%d", index++);
2915 }
2916
2917 bus->read = mv88e6xxx_mdio_read;
2918 bus->write = mv88e6xxx_mdio_write;
fad09c73 2919 bus->parent = chip->dev;
b516d453 2920
fad09c73
VD
2921 if (chip->mdio_np)
2922 err = of_mdiobus_register(bus, chip->mdio_np);
b516d453
AL
2923 else
2924 err = mdiobus_register(bus);
2925 if (err) {
fad09c73 2926 dev_err(chip->dev, "Cannot register MDIO bus (%d)\n", err);
b516d453
AL
2927 goto out;
2928 }
fad09c73 2929 chip->mdio_bus = bus;
b516d453
AL
2930
2931 return 0;
2932
2933out:
fad09c73
VD
2934 if (chip->mdio_np)
2935 of_node_put(chip->mdio_np);
b516d453
AL
2936
2937 return err;
2938}
2939
fad09c73 2940static void mv88e6xxx_mdio_unregister(struct mv88e6xxx_chip *chip)
b516d453
AL
2941
2942{
fad09c73 2943 struct mii_bus *bus = chip->mdio_bus;
b516d453
AL
2944
2945 mdiobus_unregister(bus);
2946
fad09c73
VD
2947 if (chip->mdio_np)
2948 of_node_put(chip->mdio_np);
b516d453
AL
2949}
2950
c22995c5
GR
2951#ifdef CONFIG_NET_DSA_HWMON
2952
2953static int mv88e61xx_get_temp(struct dsa_switch *ds, int *temp)
2954{
04bed143 2955 struct mv88e6xxx_chip *chip = ds->priv;
9c93829c 2956 u16 val;
c22995c5 2957 int ret;
c22995c5
GR
2958
2959 *temp = 0;
2960
fad09c73 2961 mutex_lock(&chip->reg_lock);
c22995c5 2962
9c93829c 2963 ret = mv88e6xxx_phy_write(chip, 0x0, 0x16, 0x6);
c22995c5
GR
2964 if (ret < 0)
2965 goto error;
2966
2967 /* Enable temperature sensor */
9c93829c 2968 ret = mv88e6xxx_phy_read(chip, 0x0, 0x1a, &val);
c22995c5
GR
2969 if (ret < 0)
2970 goto error;
2971
9c93829c 2972 ret = mv88e6xxx_phy_write(chip, 0x0, 0x1a, val | (1 << 5));
c22995c5
GR
2973 if (ret < 0)
2974 goto error;
2975
2976 /* Wait for temperature to stabilize */
2977 usleep_range(10000, 12000);
2978
9c93829c
VD
2979 ret = mv88e6xxx_phy_read(chip, 0x0, 0x1a, &val);
2980 if (ret < 0)
c22995c5 2981 goto error;
c22995c5
GR
2982
2983 /* Disable temperature sensor */
9c93829c 2984 ret = mv88e6xxx_phy_write(chip, 0x0, 0x1a, val & ~(1 << 5));
c22995c5
GR
2985 if (ret < 0)
2986 goto error;
2987
2988 *temp = ((val & 0x1f) - 5) * 5;
2989
2990error:
9c93829c 2991 mv88e6xxx_phy_write(chip, 0x0, 0x16, 0x0);
fad09c73 2992 mutex_unlock(&chip->reg_lock);
c22995c5
GR
2993 return ret;
2994}
2995
2996static int mv88e63xx_get_temp(struct dsa_switch *ds, int *temp)
2997{
04bed143 2998 struct mv88e6xxx_chip *chip = ds->priv;
fad09c73 2999 int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
9c93829c 3000 u16 val;
c22995c5
GR
3001 int ret;
3002
3003 *temp = 0;
3004
9c93829c
VD
3005 mutex_lock(&chip->reg_lock);
3006 ret = mv88e6xxx_phy_page_read(chip, phy, 6, 27, &val);
3007 mutex_unlock(&chip->reg_lock);
c22995c5
GR
3008 if (ret < 0)
3009 return ret;
3010
9c93829c 3011 *temp = (val & 0xff) - 25;
c22995c5
GR
3012
3013 return 0;
3014}
3015
f81ec90f 3016static int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp)
c22995c5 3017{
04bed143 3018 struct mv88e6xxx_chip *chip = ds->priv;
158bc065 3019
fad09c73 3020 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP))
6594f615
VD
3021 return -EOPNOTSUPP;
3022
fad09c73 3023 if (mv88e6xxx_6320_family(chip) || mv88e6xxx_6352_family(chip))
c22995c5
GR
3024 return mv88e63xx_get_temp(ds, temp);
3025
3026 return mv88e61xx_get_temp(ds, temp);
3027}
3028
f81ec90f 3029static int mv88e6xxx_get_temp_limit(struct dsa_switch *ds, int *temp)
c22995c5 3030{
04bed143 3031 struct mv88e6xxx_chip *chip = ds->priv;
fad09c73 3032 int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
9c93829c 3033 u16 val;
c22995c5
GR
3034 int ret;
3035
fad09c73 3036 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP_LIMIT))
c22995c5
GR
3037 return -EOPNOTSUPP;
3038
3039 *temp = 0;
3040
9c93829c
VD
3041 mutex_lock(&chip->reg_lock);
3042 ret = mv88e6xxx_phy_page_read(chip, phy, 6, 26, &val);
3043 mutex_unlock(&chip->reg_lock);
c22995c5
GR
3044 if (ret < 0)
3045 return ret;
3046
9c93829c 3047 *temp = (((val >> 8) & 0x1f) * 5) - 25;
c22995c5
GR
3048
3049 return 0;
3050}
3051
f81ec90f 3052static int mv88e6xxx_set_temp_limit(struct dsa_switch *ds, int temp)
c22995c5 3053{
04bed143 3054 struct mv88e6xxx_chip *chip = ds->priv;
fad09c73 3055 int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
9c93829c
VD
3056 u16 val;
3057 int err;
c22995c5 3058
fad09c73 3059 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP_LIMIT))
c22995c5
GR
3060 return -EOPNOTSUPP;
3061
9c93829c
VD
3062 mutex_lock(&chip->reg_lock);
3063 err = mv88e6xxx_phy_page_read(chip, phy, 6, 26, &val);
3064 if (err)
3065 goto unlock;
c22995c5 3066 temp = clamp_val(DIV_ROUND_CLOSEST(temp, 5) + 5, 0, 0x1f);
9c93829c
VD
3067 err = mv88e6xxx_phy_page_write(chip, phy, 6, 26,
3068 (val & 0xe0ff) | (temp << 8));
3069unlock:
3070 mutex_unlock(&chip->reg_lock);
3071
3072 return err;
c22995c5
GR
3073}
3074
f81ec90f 3075static int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
c22995c5 3076{
04bed143 3077 struct mv88e6xxx_chip *chip = ds->priv;
fad09c73 3078 int phy = mv88e6xxx_6320_family(chip) ? 3 : 0;
9c93829c 3079 u16 val;
c22995c5
GR
3080 int ret;
3081
fad09c73 3082 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_TEMP_LIMIT))
c22995c5
GR
3083 return -EOPNOTSUPP;
3084
3085 *alarm = false;
3086
9c93829c
VD
3087 mutex_lock(&chip->reg_lock);
3088 ret = mv88e6xxx_phy_page_read(chip, phy, 6, 26, &val);
3089 mutex_unlock(&chip->reg_lock);
c22995c5
GR
3090 if (ret < 0)
3091 return ret;
3092
9c93829c 3093 *alarm = !!(val & 0x40);
c22995c5
GR
3094
3095 return 0;
3096}
3097#endif /* CONFIG_NET_DSA_HWMON */
3098
855b1932
VD
3099static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
3100{
04bed143 3101 struct mv88e6xxx_chip *chip = ds->priv;
855b1932
VD
3102
3103 return chip->eeprom_len;
3104}
3105
855b1932
VD
3106static int mv88e6xxx_get_eeprom(struct dsa_switch *ds,
3107 struct ethtool_eeprom *eeprom, u8 *data)
3108{
04bed143 3109 struct mv88e6xxx_chip *chip = ds->priv;
855b1932
VD
3110 int err;
3111
ee4dc2e7
VD
3112 if (!chip->info->ops->get_eeprom)
3113 return -EOPNOTSUPP;
855b1932 3114
ee4dc2e7
VD
3115 mutex_lock(&chip->reg_lock);
3116 err = chip->info->ops->get_eeprom(chip, eeprom, data);
855b1932
VD
3117 mutex_unlock(&chip->reg_lock);
3118
3119 if (err)
3120 return err;
3121
3122 eeprom->magic = 0xc3ec4951;
3123
3124 return 0;
3125}
3126
855b1932
VD
3127static int mv88e6xxx_set_eeprom(struct dsa_switch *ds,
3128 struct ethtool_eeprom *eeprom, u8 *data)
3129{
04bed143 3130 struct mv88e6xxx_chip *chip = ds->priv;
855b1932
VD
3131 int err;
3132
ee4dc2e7
VD
3133 if (!chip->info->ops->set_eeprom)
3134 return -EOPNOTSUPP;
3135
855b1932
VD
3136 if (eeprom->magic != 0xc3ec4951)
3137 return -EINVAL;
3138
3139 mutex_lock(&chip->reg_lock);
ee4dc2e7 3140 err = chip->info->ops->set_eeprom(chip, eeprom, data);
855b1932
VD
3141 mutex_unlock(&chip->reg_lock);
3142
3143 return err;
3144}
3145
b3469dd8 3146static const struct mv88e6xxx_ops mv88e6085_ops = {
b073d4e2 3147 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
b3469dd8
VD
3148 .phy_read = mv88e6xxx_phy_ppu_read,
3149 .phy_write = mv88e6xxx_phy_ppu_write,
08ef7f10 3150 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3151 .port_set_duplex = mv88e6xxx_port_set_duplex,
96a2b40c 3152 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3153};
3154
3155static const struct mv88e6xxx_ops mv88e6095_ops = {
b073d4e2 3156 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
b3469dd8
VD
3157 .phy_read = mv88e6xxx_phy_ppu_read,
3158 .phy_write = mv88e6xxx_phy_ppu_write,
08ef7f10 3159 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3160 .port_set_duplex = mv88e6xxx_port_set_duplex,
96a2b40c 3161 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3162};
3163
3164static const struct mv88e6xxx_ops mv88e6123_ops = {
b073d4e2 3165 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3166 .phy_read = mv88e6xxx_read,
3167 .phy_write = mv88e6xxx_write,
08ef7f10 3168 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3169 .port_set_duplex = mv88e6xxx_port_set_duplex,
96a2b40c 3170 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3171};
3172
3173static const struct mv88e6xxx_ops mv88e6131_ops = {
b073d4e2 3174 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
b3469dd8
VD
3175 .phy_read = mv88e6xxx_phy_ppu_read,
3176 .phy_write = mv88e6xxx_phy_ppu_write,
08ef7f10 3177 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3178 .port_set_duplex = mv88e6xxx_port_set_duplex,
96a2b40c 3179 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3180};
3181
3182static const struct mv88e6xxx_ops mv88e6161_ops = {
b073d4e2 3183 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3184 .phy_read = mv88e6xxx_read,
3185 .phy_write = mv88e6xxx_write,
08ef7f10 3186 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3187 .port_set_duplex = mv88e6xxx_port_set_duplex,
96a2b40c 3188 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3189};
3190
3191static const struct mv88e6xxx_ops mv88e6165_ops = {
b073d4e2 3192 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3193 .phy_read = mv88e6xxx_read,
3194 .phy_write = mv88e6xxx_write,
08ef7f10 3195 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3196 .port_set_duplex = mv88e6xxx_port_set_duplex,
96a2b40c 3197 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3198};
3199
3200static const struct mv88e6xxx_ops mv88e6171_ops = {
b073d4e2 3201 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3202 .phy_read = mv88e6xxx_g2_smi_phy_read,
3203 .phy_write = mv88e6xxx_g2_smi_phy_write,
08ef7f10 3204 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3205 .port_set_duplex = mv88e6xxx_port_set_duplex,
94d66ae6 3206 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
96a2b40c 3207 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3208};
3209
3210static const struct mv88e6xxx_ops mv88e6172_ops = {
ee4dc2e7
VD
3211 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
3212 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
b073d4e2 3213 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3214 .phy_read = mv88e6xxx_g2_smi_phy_read,
3215 .phy_write = mv88e6xxx_g2_smi_phy_write,
08ef7f10 3216 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3217 .port_set_duplex = mv88e6xxx_port_set_duplex,
a0a0f622 3218 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
96a2b40c 3219 .port_set_speed = mv88e6352_port_set_speed,
b3469dd8
VD
3220};
3221
3222static const struct mv88e6xxx_ops mv88e6175_ops = {
b073d4e2 3223 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3224 .phy_read = mv88e6xxx_g2_smi_phy_read,
3225 .phy_write = mv88e6xxx_g2_smi_phy_write,
08ef7f10 3226 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3227 .port_set_duplex = mv88e6xxx_port_set_duplex,
94d66ae6 3228 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
96a2b40c 3229 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3230};
3231
3232static const struct mv88e6xxx_ops mv88e6176_ops = {
ee4dc2e7
VD
3233 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
3234 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
b073d4e2 3235 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3236 .phy_read = mv88e6xxx_g2_smi_phy_read,
3237 .phy_write = mv88e6xxx_g2_smi_phy_write,
08ef7f10 3238 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3239 .port_set_duplex = mv88e6xxx_port_set_duplex,
a0a0f622 3240 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
96a2b40c 3241 .port_set_speed = mv88e6352_port_set_speed,
b3469dd8
VD
3242};
3243
3244static const struct mv88e6xxx_ops mv88e6185_ops = {
b073d4e2 3245 .set_switch_mac = mv88e6xxx_g1_set_switch_mac,
b3469dd8
VD
3246 .phy_read = mv88e6xxx_phy_ppu_read,
3247 .phy_write = mv88e6xxx_phy_ppu_write,
08ef7f10 3248 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3249 .port_set_duplex = mv88e6xxx_port_set_duplex,
96a2b40c 3250 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3251};
3252
3253static const struct mv88e6xxx_ops mv88e6240_ops = {
ee4dc2e7
VD
3254 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
3255 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
b073d4e2 3256 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3257 .phy_read = mv88e6xxx_g2_smi_phy_read,
3258 .phy_write = mv88e6xxx_g2_smi_phy_write,
08ef7f10 3259 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3260 .port_set_duplex = mv88e6xxx_port_set_duplex,
a0a0f622 3261 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
96a2b40c 3262 .port_set_speed = mv88e6352_port_set_speed,
b3469dd8
VD
3263};
3264
3265static const struct mv88e6xxx_ops mv88e6320_ops = {
ee4dc2e7
VD
3266 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
3267 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
b073d4e2 3268 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3269 .phy_read = mv88e6xxx_g2_smi_phy_read,
3270 .phy_write = mv88e6xxx_g2_smi_phy_write,
08ef7f10 3271 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3272 .port_set_duplex = mv88e6xxx_port_set_duplex,
96a2b40c 3273 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3274};
3275
3276static const struct mv88e6xxx_ops mv88e6321_ops = {
ee4dc2e7
VD
3277 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
3278 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
b073d4e2 3279 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3280 .phy_read = mv88e6xxx_g2_smi_phy_read,
3281 .phy_write = mv88e6xxx_g2_smi_phy_write,
08ef7f10 3282 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3283 .port_set_duplex = mv88e6xxx_port_set_duplex,
96a2b40c 3284 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3285};
3286
3287static const struct mv88e6xxx_ops mv88e6350_ops = {
b073d4e2 3288 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3289 .phy_read = mv88e6xxx_g2_smi_phy_read,
3290 .phy_write = mv88e6xxx_g2_smi_phy_write,
08ef7f10 3291 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3292 .port_set_duplex = mv88e6xxx_port_set_duplex,
94d66ae6 3293 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
96a2b40c 3294 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3295};
3296
3297static const struct mv88e6xxx_ops mv88e6351_ops = {
b073d4e2 3298 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3299 .phy_read = mv88e6xxx_g2_smi_phy_read,
3300 .phy_write = mv88e6xxx_g2_smi_phy_write,
08ef7f10 3301 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3302 .port_set_duplex = mv88e6xxx_port_set_duplex,
94d66ae6 3303 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
96a2b40c 3304 .port_set_speed = mv88e6185_port_set_speed,
b3469dd8
VD
3305};
3306
3307static const struct mv88e6xxx_ops mv88e6352_ops = {
ee4dc2e7
VD
3308 .get_eeprom = mv88e6xxx_g2_get_eeprom16,
3309 .set_eeprom = mv88e6xxx_g2_set_eeprom16,
b073d4e2 3310 .set_switch_mac = mv88e6xxx_g2_set_switch_mac,
b3469dd8
VD
3311 .phy_read = mv88e6xxx_g2_smi_phy_read,
3312 .phy_write = mv88e6xxx_g2_smi_phy_write,
08ef7f10 3313 .port_set_link = mv88e6xxx_port_set_link,
7f1ae07b 3314 .port_set_duplex = mv88e6xxx_port_set_duplex,
a0a0f622 3315 .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
96a2b40c 3316 .port_set_speed = mv88e6352_port_set_speed,
b3469dd8
VD
3317};
3318
f81ec90f
VD
3319static const struct mv88e6xxx_info mv88e6xxx_table[] = {
3320 [MV88E6085] = {
3321 .prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
3322 .family = MV88E6XXX_FAMILY_6097,
3323 .name = "Marvell 88E6085",
3324 .num_databases = 4096,
3325 .num_ports = 10,
9dddd478 3326 .port_base_addr = 0x10,
a935c052 3327 .global1_addr = 0x1b,
acddbd21 3328 .age_time_coeff = 15000,
dc30c35b 3329 .g1_irqs = 8,
f81ec90f 3330 .flags = MV88E6XXX_FLAGS_FAMILY_6097,
b3469dd8 3331 .ops = &mv88e6085_ops,
f81ec90f
VD
3332 },
3333
3334 [MV88E6095] = {
3335 .prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
3336 .family = MV88E6XXX_FAMILY_6095,
3337 .name = "Marvell 88E6095/88E6095F",
3338 .num_databases = 256,
3339 .num_ports = 11,
9dddd478 3340 .port_base_addr = 0x10,
a935c052 3341 .global1_addr = 0x1b,
acddbd21 3342 .age_time_coeff = 15000,
dc30c35b 3343 .g1_irqs = 8,
f81ec90f 3344 .flags = MV88E6XXX_FLAGS_FAMILY_6095,
b3469dd8 3345 .ops = &mv88e6095_ops,
f81ec90f
VD
3346 },
3347
3348 [MV88E6123] = {
3349 .prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
3350 .family = MV88E6XXX_FAMILY_6165,
3351 .name = "Marvell 88E6123",
3352 .num_databases = 4096,
3353 .num_ports = 3,
9dddd478 3354 .port_base_addr = 0x10,
a935c052 3355 .global1_addr = 0x1b,
acddbd21 3356 .age_time_coeff = 15000,
dc30c35b 3357 .g1_irqs = 9,
f81ec90f 3358 .flags = MV88E6XXX_FLAGS_FAMILY_6165,
b3469dd8 3359 .ops = &mv88e6123_ops,
f81ec90f
VD
3360 },
3361
3362 [MV88E6131] = {
3363 .prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
3364 .family = MV88E6XXX_FAMILY_6185,
3365 .name = "Marvell 88E6131",
3366 .num_databases = 256,
3367 .num_ports = 8,
9dddd478 3368 .port_base_addr = 0x10,
a935c052 3369 .global1_addr = 0x1b,
acddbd21 3370 .age_time_coeff = 15000,
dc30c35b 3371 .g1_irqs = 9,
f81ec90f 3372 .flags = MV88E6XXX_FLAGS_FAMILY_6185,
b3469dd8 3373 .ops = &mv88e6131_ops,
f81ec90f
VD
3374 },
3375
3376 [MV88E6161] = {
3377 .prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
3378 .family = MV88E6XXX_FAMILY_6165,
3379 .name = "Marvell 88E6161",
3380 .num_databases = 4096,
3381 .num_ports = 6,
9dddd478 3382 .port_base_addr = 0x10,
a935c052 3383 .global1_addr = 0x1b,
acddbd21 3384 .age_time_coeff = 15000,
dc30c35b 3385 .g1_irqs = 9,
f81ec90f 3386 .flags = MV88E6XXX_FLAGS_FAMILY_6165,
b3469dd8 3387 .ops = &mv88e6161_ops,
f81ec90f
VD
3388 },
3389
3390 [MV88E6165] = {
3391 .prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
3392 .family = MV88E6XXX_FAMILY_6165,
3393 .name = "Marvell 88E6165",
3394 .num_databases = 4096,
3395 .num_ports = 6,
9dddd478 3396 .port_base_addr = 0x10,
a935c052 3397 .global1_addr = 0x1b,
acddbd21 3398 .age_time_coeff = 15000,
dc30c35b 3399 .g1_irqs = 9,
f81ec90f 3400 .flags = MV88E6XXX_FLAGS_FAMILY_6165,
b3469dd8 3401 .ops = &mv88e6165_ops,
f81ec90f
VD
3402 },
3403
3404 [MV88E6171] = {
3405 .prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
3406 .family = MV88E6XXX_FAMILY_6351,
3407 .name = "Marvell 88E6171",
3408 .num_databases = 4096,
3409 .num_ports = 7,
9dddd478 3410 .port_base_addr = 0x10,
a935c052 3411 .global1_addr = 0x1b,
acddbd21 3412 .age_time_coeff = 15000,
dc30c35b 3413 .g1_irqs = 9,
f81ec90f 3414 .flags = MV88E6XXX_FLAGS_FAMILY_6351,
b3469dd8 3415 .ops = &mv88e6171_ops,
f81ec90f
VD
3416 },
3417
3418 [MV88E6172] = {
3419 .prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
3420 .family = MV88E6XXX_FAMILY_6352,
3421 .name = "Marvell 88E6172",
3422 .num_databases = 4096,
3423 .num_ports = 7,
9dddd478 3424 .port_base_addr = 0x10,
a935c052 3425 .global1_addr = 0x1b,
acddbd21 3426 .age_time_coeff = 15000,
dc30c35b 3427 .g1_irqs = 9,
f81ec90f 3428 .flags = MV88E6XXX_FLAGS_FAMILY_6352,
b3469dd8 3429 .ops = &mv88e6172_ops,
f81ec90f
VD
3430 },
3431
3432 [MV88E6175] = {
3433 .prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
3434 .family = MV88E6XXX_FAMILY_6351,
3435 .name = "Marvell 88E6175",
3436 .num_databases = 4096,
3437 .num_ports = 7,
9dddd478 3438 .port_base_addr = 0x10,
a935c052 3439 .global1_addr = 0x1b,
acddbd21 3440 .age_time_coeff = 15000,
dc30c35b 3441 .g1_irqs = 9,
f81ec90f 3442 .flags = MV88E6XXX_FLAGS_FAMILY_6351,
b3469dd8 3443 .ops = &mv88e6175_ops,
f81ec90f
VD
3444 },
3445
3446 [MV88E6176] = {
3447 .prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
3448 .family = MV88E6XXX_FAMILY_6352,
3449 .name = "Marvell 88E6176",
3450 .num_databases = 4096,
3451 .num_ports = 7,
9dddd478 3452 .port_base_addr = 0x10,
a935c052 3453 .global1_addr = 0x1b,
acddbd21 3454 .age_time_coeff = 15000,
dc30c35b 3455 .g1_irqs = 9,
f81ec90f 3456 .flags = MV88E6XXX_FLAGS_FAMILY_6352,
b3469dd8 3457 .ops = &mv88e6176_ops,
f81ec90f
VD
3458 },
3459
3460 [MV88E6185] = {
3461 .prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
3462 .family = MV88E6XXX_FAMILY_6185,
3463 .name = "Marvell 88E6185",
3464 .num_databases = 256,
3465 .num_ports = 10,
9dddd478 3466 .port_base_addr = 0x10,
a935c052 3467 .global1_addr = 0x1b,
acddbd21 3468 .age_time_coeff = 15000,
dc30c35b 3469 .g1_irqs = 8,
f81ec90f 3470 .flags = MV88E6XXX_FLAGS_FAMILY_6185,
b3469dd8 3471 .ops = &mv88e6185_ops,
f81ec90f
VD
3472 },
3473
3474 [MV88E6240] = {
3475 .prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
3476 .family = MV88E6XXX_FAMILY_6352,
3477 .name = "Marvell 88E6240",
3478 .num_databases = 4096,
3479 .num_ports = 7,
9dddd478 3480 .port_base_addr = 0x10,
a935c052 3481 .global1_addr = 0x1b,
acddbd21 3482 .age_time_coeff = 15000,
dc30c35b 3483 .g1_irqs = 9,
f81ec90f 3484 .flags = MV88E6XXX_FLAGS_FAMILY_6352,
b3469dd8 3485 .ops = &mv88e6240_ops,
f81ec90f
VD
3486 },
3487
3488 [MV88E6320] = {
3489 .prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
3490 .family = MV88E6XXX_FAMILY_6320,
3491 .name = "Marvell 88E6320",
3492 .num_databases = 4096,
3493 .num_ports = 7,
9dddd478 3494 .port_base_addr = 0x10,
a935c052 3495 .global1_addr = 0x1b,
acddbd21 3496 .age_time_coeff = 15000,
dc30c35b 3497 .g1_irqs = 8,
f81ec90f 3498 .flags = MV88E6XXX_FLAGS_FAMILY_6320,
b3469dd8 3499 .ops = &mv88e6320_ops,
f81ec90f
VD
3500 },
3501
3502 [MV88E6321] = {
3503 .prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
3504 .family = MV88E6XXX_FAMILY_6320,
3505 .name = "Marvell 88E6321",
3506 .num_databases = 4096,
3507 .num_ports = 7,
9dddd478 3508 .port_base_addr = 0x10,
a935c052 3509 .global1_addr = 0x1b,
acddbd21 3510 .age_time_coeff = 15000,
dc30c35b 3511 .g1_irqs = 8,
f81ec90f 3512 .flags = MV88E6XXX_FLAGS_FAMILY_6320,
b3469dd8 3513 .ops = &mv88e6321_ops,
f81ec90f
VD
3514 },
3515
3516 [MV88E6350] = {
3517 .prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
3518 .family = MV88E6XXX_FAMILY_6351,
3519 .name = "Marvell 88E6350",
3520 .num_databases = 4096,
3521 .num_ports = 7,
9dddd478 3522 .port_base_addr = 0x10,
a935c052 3523 .global1_addr = 0x1b,
acddbd21 3524 .age_time_coeff = 15000,
dc30c35b 3525 .g1_irqs = 9,
f81ec90f 3526 .flags = MV88E6XXX_FLAGS_FAMILY_6351,
b3469dd8 3527 .ops = &mv88e6350_ops,
f81ec90f
VD
3528 },
3529
3530 [MV88E6351] = {
3531 .prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
3532 .family = MV88E6XXX_FAMILY_6351,
3533 .name = "Marvell 88E6351",
3534 .num_databases = 4096,
3535 .num_ports = 7,
9dddd478 3536 .port_base_addr = 0x10,
a935c052 3537 .global1_addr = 0x1b,
acddbd21 3538 .age_time_coeff = 15000,
dc30c35b 3539 .g1_irqs = 9,
f81ec90f 3540 .flags = MV88E6XXX_FLAGS_FAMILY_6351,
b3469dd8 3541 .ops = &mv88e6351_ops,
f81ec90f
VD
3542 },
3543
3544 [MV88E6352] = {
3545 .prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
3546 .family = MV88E6XXX_FAMILY_6352,
3547 .name = "Marvell 88E6352",
3548 .num_databases = 4096,
3549 .num_ports = 7,
9dddd478 3550 .port_base_addr = 0x10,
a935c052 3551 .global1_addr = 0x1b,
acddbd21 3552 .age_time_coeff = 15000,
dc30c35b 3553 .g1_irqs = 9,
f81ec90f 3554 .flags = MV88E6XXX_FLAGS_FAMILY_6352,
b3469dd8 3555 .ops = &mv88e6352_ops,
f81ec90f
VD
3556 },
3557};
3558
5f7c0367 3559static const struct mv88e6xxx_info *mv88e6xxx_lookup_info(unsigned int prod_num)
b9b37713 3560{
a439c061 3561 int i;
b9b37713 3562
5f7c0367
VD
3563 for (i = 0; i < ARRAY_SIZE(mv88e6xxx_table); ++i)
3564 if (mv88e6xxx_table[i].prod_num == prod_num)
3565 return &mv88e6xxx_table[i];
b9b37713 3566
b9b37713
VD
3567 return NULL;
3568}
3569
fad09c73 3570static int mv88e6xxx_detect(struct mv88e6xxx_chip *chip)
bc46a3d5
VD
3571{
3572 const struct mv88e6xxx_info *info;
8f6345b2
VD
3573 unsigned int prod_num, rev;
3574 u16 id;
3575 int err;
bc46a3d5 3576
8f6345b2
VD
3577 mutex_lock(&chip->reg_lock);
3578 err = mv88e6xxx_port_read(chip, 0, PORT_SWITCH_ID, &id);
3579 mutex_unlock(&chip->reg_lock);
3580 if (err)
3581 return err;
bc46a3d5
VD
3582
3583 prod_num = (id & 0xfff0) >> 4;
3584 rev = id & 0x000f;
3585
3586 info = mv88e6xxx_lookup_info(prod_num);
3587 if (!info)
3588 return -ENODEV;
3589
caac8545 3590 /* Update the compatible info with the probed one */
fad09c73 3591 chip->info = info;
bc46a3d5 3592
ca070c10
VD
3593 err = mv88e6xxx_g2_require(chip);
3594 if (err)
3595 return err;
3596
fad09c73
VD
3597 dev_info(chip->dev, "switch 0x%x detected: %s, revision %u\n",
3598 chip->info->prod_num, chip->info->name, rev);
bc46a3d5
VD
3599
3600 return 0;
3601}
3602
fad09c73 3603static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)
469d729f 3604{
fad09c73 3605 struct mv88e6xxx_chip *chip;
469d729f 3606
fad09c73
VD
3607 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
3608 if (!chip)
469d729f
VD
3609 return NULL;
3610
fad09c73 3611 chip->dev = dev;
469d729f 3612
fad09c73 3613 mutex_init(&chip->reg_lock);
469d729f 3614
fad09c73 3615 return chip;
469d729f
VD
3616}
3617
e57e5e77
VD
3618static void mv88e6xxx_phy_init(struct mv88e6xxx_chip *chip)
3619{
b3469dd8 3620 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU))
e57e5e77 3621 mv88e6xxx_ppu_state_init(chip);
e57e5e77
VD
3622}
3623
930188ce
AL
3624static void mv88e6xxx_phy_destroy(struct mv88e6xxx_chip *chip)
3625{
b3469dd8 3626 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU))
930188ce 3627 mv88e6xxx_ppu_state_destroy(chip);
930188ce
AL
3628}
3629
fad09c73 3630static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip,
4a70c4ab
VD
3631 struct mii_bus *bus, int sw_addr)
3632{
3633 /* ADDR[0] pin is unavailable externally and considered zero */
3634 if (sw_addr & 0x1)
3635 return -EINVAL;
3636
914b32f6 3637 if (sw_addr == 0)
fad09c73 3638 chip->smi_ops = &mv88e6xxx_smi_single_chip_ops;
a0ffff24 3639 else if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_MULTI_CHIP))
fad09c73 3640 chip->smi_ops = &mv88e6xxx_smi_multi_chip_ops;
914b32f6
VD
3641 else
3642 return -EINVAL;
3643
fad09c73
VD
3644 chip->bus = bus;
3645 chip->sw_addr = sw_addr;
4a70c4ab
VD
3646
3647 return 0;
3648}
3649
7b314362
AL
3650static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds)
3651{
04bed143 3652 struct mv88e6xxx_chip *chip = ds->priv;
2bbb33be
AL
3653
3654 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA))
3655 return DSA_TAG_PROTO_EDSA;
3656
3657 return DSA_TAG_PROTO_DSA;
7b314362
AL
3658}
3659
fcdce7d0
AL
3660static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
3661 struct device *host_dev, int sw_addr,
3662 void **priv)
a77d43f1 3663{
fad09c73 3664 struct mv88e6xxx_chip *chip;
a439c061 3665 struct mii_bus *bus;
b516d453 3666 int err;
a77d43f1 3667
a439c061 3668 bus = dsa_host_dev_to_mii_bus(host_dev);
c156913b
AL
3669 if (!bus)
3670 return NULL;
3671
fad09c73
VD
3672 chip = mv88e6xxx_alloc_chip(dsa_dev);
3673 if (!chip)
469d729f
VD
3674 return NULL;
3675
caac8545 3676 /* Legacy SMI probing will only support chips similar to 88E6085 */
fad09c73 3677 chip->info = &mv88e6xxx_table[MV88E6085];
caac8545 3678
fad09c73 3679 err = mv88e6xxx_smi_init(chip, bus, sw_addr);
4a70c4ab
VD
3680 if (err)
3681 goto free;
3682
fad09c73 3683 err = mv88e6xxx_detect(chip);
bc46a3d5 3684 if (err)
469d729f 3685 goto free;
a439c061 3686
dc30c35b
AL
3687 mutex_lock(&chip->reg_lock);
3688 err = mv88e6xxx_switch_reset(chip);
3689 mutex_unlock(&chip->reg_lock);
3690 if (err)
3691 goto free;
3692
e57e5e77
VD
3693 mv88e6xxx_phy_init(chip);
3694
fad09c73 3695 err = mv88e6xxx_mdio_register(chip, NULL);
b516d453 3696 if (err)
469d729f 3697 goto free;
b516d453 3698
fad09c73 3699 *priv = chip;
a439c061 3700
fad09c73 3701 return chip->info->name;
469d729f 3702free:
fad09c73 3703 devm_kfree(dsa_dev, chip);
469d729f
VD
3704
3705 return NULL;
a77d43f1
AL
3706}
3707
7df8fbdd
VD
3708static int mv88e6xxx_port_mdb_prepare(struct dsa_switch *ds, int port,
3709 const struct switchdev_obj_port_mdb *mdb,
3710 struct switchdev_trans *trans)
3711{
3712 /* We don't need any dynamic resource from the kernel (yet),
3713 * so skip the prepare phase.
3714 */
3715
3716 return 0;
3717}
3718
3719static void mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
3720 const struct switchdev_obj_port_mdb *mdb,
3721 struct switchdev_trans *trans)
3722{
04bed143 3723 struct mv88e6xxx_chip *chip = ds->priv;
7df8fbdd
VD
3724
3725 mutex_lock(&chip->reg_lock);
3726 if (mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
3727 GLOBAL_ATU_DATA_STATE_MC_STATIC))
3728 netdev_err(ds->ports[port].netdev, "failed to load multicast MAC address\n");
3729 mutex_unlock(&chip->reg_lock);
3730}
3731
3732static int mv88e6xxx_port_mdb_del(struct dsa_switch *ds, int port,
3733 const struct switchdev_obj_port_mdb *mdb)
3734{
04bed143 3735 struct mv88e6xxx_chip *chip = ds->priv;
7df8fbdd
VD
3736 int err;
3737
3738 mutex_lock(&chip->reg_lock);
3739 err = mv88e6xxx_port_db_load_purge(chip, port, mdb->addr, mdb->vid,
3740 GLOBAL_ATU_DATA_STATE_UNUSED);
3741 mutex_unlock(&chip->reg_lock);
3742
3743 return err;
3744}
3745
3746static int mv88e6xxx_port_mdb_dump(struct dsa_switch *ds, int port,
3747 struct switchdev_obj_port_mdb *mdb,
3748 int (*cb)(struct switchdev_obj *obj))
3749{
04bed143 3750 struct mv88e6xxx_chip *chip = ds->priv;
7df8fbdd
VD
3751 int err;
3752
3753 mutex_lock(&chip->reg_lock);
3754 err = mv88e6xxx_port_db_dump(chip, port, &mdb->obj, cb);
3755 mutex_unlock(&chip->reg_lock);
3756
3757 return err;
3758}
3759
9d490b4e 3760static struct dsa_switch_ops mv88e6xxx_switch_ops = {
fcdce7d0 3761 .probe = mv88e6xxx_drv_probe,
7b314362 3762 .get_tag_protocol = mv88e6xxx_get_tag_protocol,
f81ec90f
VD
3763 .setup = mv88e6xxx_setup,
3764 .set_addr = mv88e6xxx_set_addr,
f81ec90f
VD
3765 .adjust_link = mv88e6xxx_adjust_link,
3766 .get_strings = mv88e6xxx_get_strings,
3767 .get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
3768 .get_sset_count = mv88e6xxx_get_sset_count,
3769 .set_eee = mv88e6xxx_set_eee,
3770 .get_eee = mv88e6xxx_get_eee,
3771#ifdef CONFIG_NET_DSA_HWMON
3772 .get_temp = mv88e6xxx_get_temp,
3773 .get_temp_limit = mv88e6xxx_get_temp_limit,
3774 .set_temp_limit = mv88e6xxx_set_temp_limit,
3775 .get_temp_alarm = mv88e6xxx_get_temp_alarm,
3776#endif
f8cd8753 3777 .get_eeprom_len = mv88e6xxx_get_eeprom_len,
f81ec90f
VD
3778 .get_eeprom = mv88e6xxx_get_eeprom,
3779 .set_eeprom = mv88e6xxx_set_eeprom,
3780 .get_regs_len = mv88e6xxx_get_regs_len,
3781 .get_regs = mv88e6xxx_get_regs,
2cfcd964 3782 .set_ageing_time = mv88e6xxx_set_ageing_time,
f81ec90f
VD
3783 .port_bridge_join = mv88e6xxx_port_bridge_join,
3784 .port_bridge_leave = mv88e6xxx_port_bridge_leave,
3785 .port_stp_state_set = mv88e6xxx_port_stp_state_set,
749efcb8 3786 .port_fast_age = mv88e6xxx_port_fast_age,
f81ec90f
VD
3787 .port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
3788 .port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
3789 .port_vlan_add = mv88e6xxx_port_vlan_add,
3790 .port_vlan_del = mv88e6xxx_port_vlan_del,
3791 .port_vlan_dump = mv88e6xxx_port_vlan_dump,
3792 .port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
3793 .port_fdb_add = mv88e6xxx_port_fdb_add,
3794 .port_fdb_del = mv88e6xxx_port_fdb_del,
3795 .port_fdb_dump = mv88e6xxx_port_fdb_dump,
7df8fbdd
VD
3796 .port_mdb_prepare = mv88e6xxx_port_mdb_prepare,
3797 .port_mdb_add = mv88e6xxx_port_mdb_add,
3798 .port_mdb_del = mv88e6xxx_port_mdb_del,
3799 .port_mdb_dump = mv88e6xxx_port_mdb_dump,
f81ec90f
VD
3800};
3801
fad09c73 3802static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip,
b7e66a5f
VD
3803 struct device_node *np)
3804{
fad09c73 3805 struct device *dev = chip->dev;
b7e66a5f
VD
3806 struct dsa_switch *ds;
3807
3808 ds = devm_kzalloc(dev, sizeof(*ds), GFP_KERNEL);
3809 if (!ds)
3810 return -ENOMEM;
3811
3812 ds->dev = dev;
fad09c73 3813 ds->priv = chip;
9d490b4e 3814 ds->ops = &mv88e6xxx_switch_ops;
b7e66a5f
VD
3815
3816 dev_set_drvdata(dev, ds);
3817
3818 return dsa_register_switch(ds, np);
3819}
3820
fad09c73 3821static void mv88e6xxx_unregister_switch(struct mv88e6xxx_chip *chip)
b7e66a5f 3822{
fad09c73 3823 dsa_unregister_switch(chip->ds);
b7e66a5f
VD
3824}
3825
57d32310 3826static int mv88e6xxx_probe(struct mdio_device *mdiodev)
98e67308 3827{
14c7b3c3 3828 struct device *dev = &mdiodev->dev;
f8cd8753 3829 struct device_node *np = dev->of_node;
caac8545 3830 const struct mv88e6xxx_info *compat_info;
fad09c73 3831 struct mv88e6xxx_chip *chip;
f8cd8753 3832 u32 eeprom_len;
52638f71 3833 int err;
14c7b3c3 3834
caac8545
VD
3835 compat_info = of_device_get_match_data(dev);
3836 if (!compat_info)
3837 return -EINVAL;
3838
fad09c73
VD
3839 chip = mv88e6xxx_alloc_chip(dev);
3840 if (!chip)
14c7b3c3
AL
3841 return -ENOMEM;
3842
fad09c73 3843 chip->info = compat_info;
caac8545 3844
fad09c73 3845 err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
4a70c4ab
VD
3846 if (err)
3847 return err;
14c7b3c3 3848
fad09c73 3849 err = mv88e6xxx_detect(chip);
bc46a3d5
VD
3850 if (err)
3851 return err;
14c7b3c3 3852
e57e5e77
VD
3853 mv88e6xxx_phy_init(chip);
3854
fad09c73
VD
3855 chip->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
3856 if (IS_ERR(chip->reset))
3857 return PTR_ERR(chip->reset);
52638f71 3858
ee4dc2e7 3859 if (chip->info->ops->get_eeprom &&
f8cd8753 3860 !of_property_read_u32(np, "eeprom-length", &eeprom_len))
fad09c73 3861 chip->eeprom_len = eeprom_len;
f8cd8753 3862
dc30c35b
AL
3863 mutex_lock(&chip->reg_lock);
3864 err = mv88e6xxx_switch_reset(chip);
3865 mutex_unlock(&chip->reg_lock);
3866 if (err)
3867 goto out;
3868
3869 chip->irq = of_irq_get(np, 0);
3870 if (chip->irq == -EPROBE_DEFER) {
3871 err = chip->irq;
3872 goto out;
3873 }
3874
3875 if (chip->irq > 0) {
3876 /* Has to be performed before the MDIO bus is created,
3877 * because the PHYs will link there interrupts to these
3878 * interrupt controllers
3879 */
3880 mutex_lock(&chip->reg_lock);
3881 err = mv88e6xxx_g1_irq_setup(chip);
3882 mutex_unlock(&chip->reg_lock);
3883
3884 if (err)
3885 goto out;
3886
3887 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_INT)) {
3888 err = mv88e6xxx_g2_irq_setup(chip);
3889 if (err)
3890 goto out_g1_irq;
3891 }
3892 }
3893
fad09c73 3894 err = mv88e6xxx_mdio_register(chip, np);
b516d453 3895 if (err)
dc30c35b 3896 goto out_g2_irq;
b516d453 3897
fad09c73 3898 err = mv88e6xxx_register_switch(chip, np);
dc30c35b
AL
3899 if (err)
3900 goto out_mdio;
83c0afae 3901
98e67308 3902 return 0;
dc30c35b
AL
3903
3904out_mdio:
3905 mv88e6xxx_mdio_unregister(chip);
3906out_g2_irq:
46712644 3907 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_INT) && chip->irq > 0)
dc30c35b
AL
3908 mv88e6xxx_g2_irq_free(chip);
3909out_g1_irq:
46712644
AL
3910 if (chip->irq > 0)
3911 mv88e6xxx_g1_irq_free(chip);
dc30c35b
AL
3912out:
3913 return err;
98e67308 3914}
14c7b3c3
AL
3915
3916static void mv88e6xxx_remove(struct mdio_device *mdiodev)
3917{
3918 struct dsa_switch *ds = dev_get_drvdata(&mdiodev->dev);
04bed143 3919 struct mv88e6xxx_chip *chip = ds->priv;
14c7b3c3 3920
930188ce 3921 mv88e6xxx_phy_destroy(chip);
fad09c73
VD
3922 mv88e6xxx_unregister_switch(chip);
3923 mv88e6xxx_mdio_unregister(chip);
dc30c35b 3924
46712644
AL
3925 if (chip->irq > 0) {
3926 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_INT))
3927 mv88e6xxx_g2_irq_free(chip);
3928 mv88e6xxx_g1_irq_free(chip);
3929 }
14c7b3c3
AL
3930}
3931
3932static const struct of_device_id mv88e6xxx_of_match[] = {
caac8545
VD
3933 {
3934 .compatible = "marvell,mv88e6085",
3935 .data = &mv88e6xxx_table[MV88E6085],
3936 },
14c7b3c3
AL
3937 { /* sentinel */ },
3938};
3939
3940MODULE_DEVICE_TABLE(of, mv88e6xxx_of_match);
3941
3942static struct mdio_driver mv88e6xxx_driver = {
3943 .probe = mv88e6xxx_probe,
3944 .remove = mv88e6xxx_remove,
3945 .mdiodrv.driver = {
3946 .name = "mv88e6085",
3947 .of_match_table = mv88e6xxx_of_match,
3948 },
3949};
3950
3951static int __init mv88e6xxx_init(void)
3952{
9d490b4e 3953 register_switch_driver(&mv88e6xxx_switch_ops);
14c7b3c3
AL
3954 return mdio_driver_register(&mv88e6xxx_driver);
3955}
98e67308
BH
3956module_init(mv88e6xxx_init);
3957
3958static void __exit mv88e6xxx_cleanup(void)
3959{
14c7b3c3 3960 mdio_driver_unregister(&mv88e6xxx_driver);
9d490b4e 3961 unregister_switch_driver(&mv88e6xxx_switch_ops);
98e67308
BH
3962}
3963module_exit(mv88e6xxx_cleanup);
3d825ede
BH
3964
3965MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
3966MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
3967MODULE_LICENSE("GPL");