diff options
author | David S. Miller <davem@davemloft.net> | 2016-09-30 01:26:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-09-30 01:26:04 -0400 |
commit | df90a497047e41a67c0563e81496a2dc0d2f562d (patch) | |
tree | 5b48db1d60b9cc0ef7e1afbe6f531db431b1265a | |
parent | 31fbe81fe3426dfb7f8056a7f5106c6b1841a9aa (diff) | |
parent | ee4dc2e75337e5925e9434f28ec48374a65ffcd9 (diff) |
Merge branch 'dsa-global-cosmetics'
Vivien Didelot says:
====================
net: dsa: mv88e6xxx: Global (1) cosmetics
The Global (1) internal SMI device of Marvell switches is a set of
registers providing support to different units for MAC addresses (ATU),
VLANs (VTU), PHY polling (PPU), etc.
Chips (like 88E6060) may use a different address for it, or have
subtleties in the units (e.g. different number of databases, changing
how registers must be accessed), making it hard to maintain properly.
This patchset is a first step to polish the Global (1) support, with no
functional changes though. Here's basically what it does:
- add helpers to access Global1 registers (same for Global2)
- remove a few family checks (VTU/STU FID registers)
- s/mv88e6xxx_vtu_stu_entry/mv88e6xxx_vtu_entry/
- add a per-chip mv88e6xxx_ops structure of function pointers:
struct mv88e6xxx_ops {
int (*get_eeprom)(struct mv88e6xxx_chip *chip,
struct ethtool_eeprom *eeprom, u8 *data);
int (*set_eeprom)(struct mv88e6xxx_chip *chip,
struct ethtool_eeprom *eeprom, u8 *data);
int (*set_switch_mac)(struct mv88e6xxx_chip *chip, u8 *addr);
int (*phy_read)(struct mv88e6xxx_chip *chip, int addr, int reg,
u16 *val);
int (*phy_write)(struct mv88e6xxx_chip *chip, int addr, int reg,
u16 val);
};
Future patchsets will add ATU/VTU ops, software reset, etc.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/chip.c | 804 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global1.c | 34 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global1.h | 23 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global2.c | 86 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 102 |
6 files changed, 607 insertions, 443 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile index 697103934317..10ce820daa48 100644 --- a/drivers/net/dsa/mv88e6xxx/Makefile +++ b/drivers/net/dsa/mv88e6xxx/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o | 1 | obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o |
2 | mv88e6xxx-objs := chip.o | 2 | mv88e6xxx-objs := chip.o |
3 | mv88e6xxx-objs += global1.o | ||
3 | mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2.o | 4 | mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2.o |
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index b2c25daef294..883fd9809dd2 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <net/switchdev.h> | 31 | #include <net/switchdev.h> |
32 | 32 | ||
33 | #include "mv88e6xxx.h" | 33 | #include "mv88e6xxx.h" |
34 | #include "global1.h" | ||
34 | #include "global2.h" | 35 | #include "global2.h" |
35 | 36 | ||
36 | static void assert_reg_lock(struct mv88e6xxx_chip *chip) | 37 | static void assert_reg_lock(struct mv88e6xxx_chip *chip) |
@@ -97,7 +98,7 @@ static int mv88e6xxx_smi_single_chip_write(struct mv88e6xxx_chip *chip, | |||
97 | return 0; | 98 | return 0; |
98 | } | 99 | } |
99 | 100 | ||
100 | static const struct mv88e6xxx_ops mv88e6xxx_smi_single_chip_ops = { | 101 | static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_single_chip_ops = { |
101 | .read = mv88e6xxx_smi_single_chip_read, | 102 | .read = mv88e6xxx_smi_single_chip_read, |
102 | .write = mv88e6xxx_smi_single_chip_write, | 103 | .write = mv88e6xxx_smi_single_chip_write, |
103 | }; | 104 | }; |
@@ -179,7 +180,7 @@ static int mv88e6xxx_smi_multi_chip_write(struct mv88e6xxx_chip *chip, | |||
179 | return 0; | 180 | return 0; |
180 | } | 181 | } |
181 | 182 | ||
182 | static const struct mv88e6xxx_ops mv88e6xxx_smi_multi_chip_ops = { | 183 | static const struct mv88e6xxx_bus_ops mv88e6xxx_smi_multi_chip_ops = { |
183 | .read = mv88e6xxx_smi_multi_chip_read, | 184 | .read = mv88e6xxx_smi_multi_chip_read, |
184 | .write = mv88e6xxx_smi_multi_chip_write, | 185 | .write = mv88e6xxx_smi_multi_chip_write, |
185 | }; | 186 | }; |
@@ -237,10 +238,10 @@ static int mv88e6xxx_phy_read(struct mv88e6xxx_chip *chip, int phy, | |||
237 | { | 238 | { |
238 | int addr = phy; /* PHY devices addresses start at 0x0 */ | 239 | int addr = phy; /* PHY devices addresses start at 0x0 */ |
239 | 240 | ||
240 | if (!chip->phy_ops) | 241 | if (!chip->info->ops->phy_read) |
241 | return -EOPNOTSUPP; | 242 | return -EOPNOTSUPP; |
242 | 243 | ||
243 | return chip->phy_ops->read(chip, addr, reg, val); | 244 | return chip->info->ops->phy_read(chip, addr, reg, val); |
244 | } | 245 | } |
245 | 246 | ||
246 | static int mv88e6xxx_phy_write(struct mv88e6xxx_chip *chip, int phy, | 247 | static int mv88e6xxx_phy_write(struct mv88e6xxx_chip *chip, int phy, |
@@ -248,10 +249,10 @@ static int mv88e6xxx_phy_write(struct mv88e6xxx_chip *chip, int phy, | |||
248 | { | 249 | { |
249 | int addr = phy; /* PHY devices addresses start at 0x0 */ | 250 | int addr = phy; /* PHY devices addresses start at 0x0 */ |
250 | 251 | ||
251 | if (!chip->phy_ops) | 252 | if (!chip->info->ops->phy_write) |
252 | return -EOPNOTSUPP; | 253 | return -EOPNOTSUPP; |
253 | 254 | ||
254 | return chip->phy_ops->write(chip, addr, reg, val); | 255 | return chip->info->ops->phy_write(chip, addr, reg, val); |
255 | } | 256 | } |
256 | 257 | ||
257 | static int mv88e6xxx_phy_page_get(struct mv88e6xxx_chip *chip, int phy, u8 page) | 258 | static int mv88e6xxx_phy_page_get(struct mv88e6xxx_chip *chip, int phy, u8 page) |
@@ -361,46 +362,27 @@ int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, u16 update) | |||
361 | return mv88e6xxx_write(chip, addr, reg, val); | 362 | return mv88e6xxx_write(chip, addr, reg, val); |
362 | } | 363 | } |
363 | 364 | ||
364 | static int _mv88e6xxx_reg_read(struct mv88e6xxx_chip *chip, int addr, int reg) | 365 | static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip) |
365 | { | 366 | { |
366 | u16 val; | 367 | u16 val; |
367 | int err; | 368 | int i, err; |
368 | 369 | ||
369 | err = mv88e6xxx_read(chip, addr, reg, &val); | 370 | err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &val); |
370 | if (err) | 371 | if (err) |
371 | return err; | 372 | return err; |
372 | 373 | ||
373 | return val; | 374 | err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, |
374 | } | 375 | val & ~GLOBAL_CONTROL_PPU_ENABLE); |
375 | 376 | if (err) | |
376 | static int _mv88e6xxx_reg_write(struct mv88e6xxx_chip *chip, int addr, | 377 | return err; |
377 | int reg, u16 val) | ||
378 | { | ||
379 | return mv88e6xxx_write(chip, addr, reg, val); | ||
380 | } | ||
381 | |||
382 | static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip) | ||
383 | { | ||
384 | int ret; | ||
385 | int i; | ||
386 | |||
387 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_CONTROL); | ||
388 | if (ret < 0) | ||
389 | return ret; | ||
390 | |||
391 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_CONTROL, | ||
392 | ret & ~GLOBAL_CONTROL_PPU_ENABLE); | ||
393 | if (ret) | ||
394 | return ret; | ||
395 | 378 | ||
396 | for (i = 0; i < 16; i++) { | 379 | for (i = 0; i < 16; i++) { |
397 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATUS); | 380 | err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &val); |
398 | if (ret < 0) | 381 | if (err) |
399 | return ret; | 382 | return err; |
400 | 383 | ||
401 | usleep_range(1000, 2000); | 384 | usleep_range(1000, 2000); |
402 | if ((ret & GLOBAL_STATUS_PPU_MASK) != | 385 | if ((val & GLOBAL_STATUS_PPU_MASK) != GLOBAL_STATUS_PPU_POLLING) |
403 | GLOBAL_STATUS_PPU_POLLING) | ||
404 | return 0; | 386 | return 0; |
405 | } | 387 | } |
406 | 388 | ||
@@ -409,25 +391,25 @@ static int mv88e6xxx_ppu_disable(struct mv88e6xxx_chip *chip) | |||
409 | 391 | ||
410 | static int mv88e6xxx_ppu_enable(struct mv88e6xxx_chip *chip) | 392 | static int mv88e6xxx_ppu_enable(struct mv88e6xxx_chip *chip) |
411 | { | 393 | { |
412 | int ret, err, i; | 394 | u16 val; |
395 | int i, err; | ||
413 | 396 | ||
414 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_CONTROL); | 397 | err = mv88e6xxx_g1_read(chip, GLOBAL_CONTROL, &val); |
415 | if (ret < 0) | 398 | if (err) |
416 | return ret; | 399 | return err; |
417 | 400 | ||
418 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_CONTROL, | 401 | err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, |
419 | ret | GLOBAL_CONTROL_PPU_ENABLE); | 402 | val | GLOBAL_CONTROL_PPU_ENABLE); |
420 | if (err) | 403 | if (err) |
421 | return err; | 404 | return err; |
422 | 405 | ||
423 | for (i = 0; i < 16; i++) { | 406 | for (i = 0; i < 16; i++) { |
424 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATUS); | 407 | err = mv88e6xxx_g1_read(chip, GLOBAL_STATUS, &val); |
425 | if (ret < 0) | 408 | if (err) |
426 | return ret; | 409 | return err; |
427 | 410 | ||
428 | usleep_range(1000, 2000); | 411 | usleep_range(1000, 2000); |
429 | if ((ret & GLOBAL_STATUS_PPU_MASK) == | 412 | if ((val & GLOBAL_STATUS_PPU_MASK) == GLOBAL_STATUS_PPU_POLLING) |
430 | GLOBAL_STATUS_PPU_POLLING) | ||
431 | return 0; | 413 | return 0; |
432 | } | 414 | } |
433 | 415 | ||
@@ -533,11 +515,6 @@ static int mv88e6xxx_phy_ppu_write(struct mv88e6xxx_chip *chip, int addr, | |||
533 | return err; | 515 | return err; |
534 | } | 516 | } |
535 | 517 | ||
536 | static const struct mv88e6xxx_ops mv88e6xxx_phy_ppu_ops = { | ||
537 | .read = mv88e6xxx_phy_ppu_read, | ||
538 | .write = mv88e6xxx_phy_ppu_write, | ||
539 | }; | ||
540 | |||
541 | static bool mv88e6xxx_6065_family(struct mv88e6xxx_chip *chip) | 518 | static bool mv88e6xxx_6065_family(struct mv88e6xxx_chip *chip) |
542 | { | 519 | { |
543 | return chip->info->family == MV88E6XXX_FAMILY_6065; | 520 | return chip->info->family == MV88E6XXX_FAMILY_6065; |
@@ -578,21 +555,6 @@ static bool mv88e6xxx_6352_family(struct mv88e6xxx_chip *chip) | |||
578 | return chip->info->family == MV88E6XXX_FAMILY_6352; | 555 | return chip->info->family == MV88E6XXX_FAMILY_6352; |
579 | } | 556 | } |
580 | 557 | ||
581 | static unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip) | ||
582 | { | ||
583 | return chip->info->num_databases; | ||
584 | } | ||
585 | |||
586 | static bool mv88e6xxx_has_fid_reg(struct mv88e6xxx_chip *chip) | ||
587 | { | ||
588 | /* Does the device have dedicated FID registers for ATU and VTU ops? */ | ||
589 | if (mv88e6xxx_6097_family(chip) || mv88e6xxx_6165_family(chip) || | ||
590 | mv88e6xxx_6351_family(chip) || mv88e6xxx_6352_family(chip)) | ||
591 | return true; | ||
592 | |||
593 | return false; | ||
594 | } | ||
595 | |||
596 | /* We expect the switch to perform auto negotiation if there is a real | 558 | /* We expect the switch to perform auto negotiation if there is a real |
597 | * phy. However, in the case of a fixed link phy, we force the port | 559 | * phy. However, in the case of a fixed link phy, we force the port |
598 | * settings from the fixed link settings. | 560 | * settings from the fixed link settings. |
@@ -646,7 +608,7 @@ static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port, | |||
646 | reg |= PORT_PCS_CTRL_DUPLEX_FULL; | 608 | reg |= PORT_PCS_CTRL_DUPLEX_FULL; |
647 | 609 | ||
648 | if ((mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip)) && | 610 | if ((mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip)) && |
649 | (port >= chip->info->num_ports - 2)) { | 611 | (port >= mv88e6xxx_num_ports(chip) - 2)) { |
650 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) | 612 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) |
651 | reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK; | 613 | reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK; |
652 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) | 614 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) |
@@ -663,12 +625,12 @@ out: | |||
663 | 625 | ||
664 | static int _mv88e6xxx_stats_wait(struct mv88e6xxx_chip *chip) | 626 | static int _mv88e6xxx_stats_wait(struct mv88e6xxx_chip *chip) |
665 | { | 627 | { |
666 | int ret; | 628 | u16 val; |
667 | int i; | 629 | int i, err; |
668 | 630 | ||
669 | for (i = 0; i < 10; i++) { | 631 | for (i = 0; i < 10; i++) { |
670 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATS_OP); | 632 | err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_OP, &val); |
671 | if ((ret & GLOBAL_STATS_OP_BUSY) == 0) | 633 | if ((val & GLOBAL_STATS_OP_BUSY) == 0) |
672 | return 0; | 634 | return 0; |
673 | } | 635 | } |
674 | 636 | ||
@@ -677,55 +639,52 @@ static int _mv88e6xxx_stats_wait(struct mv88e6xxx_chip *chip) | |||
677 | 639 | ||
678 | static int _mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port) | 640 | static int _mv88e6xxx_stats_snapshot(struct mv88e6xxx_chip *chip, int port) |
679 | { | 641 | { |
680 | int ret; | 642 | int err; |
681 | 643 | ||
682 | if (mv88e6xxx_6320_family(chip) || mv88e6xxx_6352_family(chip)) | 644 | if (mv88e6xxx_6320_family(chip) || mv88e6xxx_6352_family(chip)) |
683 | port = (port + 1) << 5; | 645 | port = (port + 1) << 5; |
684 | 646 | ||
685 | /* Snapshot the hardware statistics counters for this port. */ | 647 | /* Snapshot the hardware statistics counters for this port. */ |
686 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_STATS_OP, | 648 | err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP, |
687 | GLOBAL_STATS_OP_CAPTURE_PORT | | 649 | GLOBAL_STATS_OP_CAPTURE_PORT | |
688 | GLOBAL_STATS_OP_HIST_RX_TX | port); | 650 | GLOBAL_STATS_OP_HIST_RX_TX | port); |
689 | if (ret < 0) | 651 | if (err) |
690 | return ret; | 652 | return err; |
691 | 653 | ||
692 | /* Wait for the snapshotting to complete. */ | 654 | /* Wait for the snapshotting to complete. */ |
693 | ret = _mv88e6xxx_stats_wait(chip); | 655 | return _mv88e6xxx_stats_wait(chip); |
694 | if (ret < 0) | ||
695 | return ret; | ||
696 | |||
697 | return 0; | ||
698 | } | 656 | } |
699 | 657 | ||
700 | static void _mv88e6xxx_stats_read(struct mv88e6xxx_chip *chip, | 658 | static void _mv88e6xxx_stats_read(struct mv88e6xxx_chip *chip, |
701 | int stat, u32 *val) | 659 | int stat, u32 *val) |
702 | { | 660 | { |
703 | u32 _val; | 661 | u32 value; |
704 | int ret; | 662 | u16 reg; |
663 | int err; | ||
705 | 664 | ||
706 | *val = 0; | 665 | *val = 0; |
707 | 666 | ||
708 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_STATS_OP, | 667 | err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP, |
709 | GLOBAL_STATS_OP_READ_CAPTURED | | 668 | GLOBAL_STATS_OP_READ_CAPTURED | |
710 | GLOBAL_STATS_OP_HIST_RX_TX | stat); | 669 | GLOBAL_STATS_OP_HIST_RX_TX | stat); |
711 | if (ret < 0) | 670 | if (err) |
712 | return; | 671 | return; |
713 | 672 | ||
714 | ret = _mv88e6xxx_stats_wait(chip); | 673 | err = _mv88e6xxx_stats_wait(chip); |
715 | if (ret < 0) | 674 | if (err) |
716 | return; | 675 | return; |
717 | 676 | ||
718 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATS_COUNTER_32); | 677 | err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_COUNTER_32, ®); |
719 | if (ret < 0) | 678 | if (err) |
720 | return; | 679 | return; |
721 | 680 | ||
722 | _val = ret << 16; | 681 | value = reg << 16; |
723 | 682 | ||
724 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_STATS_COUNTER_01); | 683 | err = mv88e6xxx_g1_read(chip, GLOBAL_STATS_COUNTER_01, ®); |
725 | if (ret < 0) | 684 | if (err) |
726 | return; | 685 | return; |
727 | 686 | ||
728 | *val = _val | ret; | 687 | *val = value | reg; |
729 | } | 688 | } |
730 | 689 | ||
731 | static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = { | 690 | static struct mv88e6xxx_hw_stat mv88e6xxx_hw_stats[] = { |
@@ -932,8 +891,7 @@ static void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, | |||
932 | 891 | ||
933 | static int _mv88e6xxx_atu_wait(struct mv88e6xxx_chip *chip) | 892 | static int _mv88e6xxx_atu_wait(struct mv88e6xxx_chip *chip) |
934 | { | 893 | { |
935 | return mv88e6xxx_wait(chip, REG_GLOBAL, GLOBAL_ATU_OP, | 894 | return mv88e6xxx_g1_wait(chip, GLOBAL_ATU_OP, GLOBAL_ATU_OP_BUSY); |
936 | GLOBAL_ATU_OP_BUSY); | ||
937 | } | 895 | } |
938 | 896 | ||
939 | static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, | 897 | static int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, |
@@ -997,32 +955,31 @@ out: | |||
997 | 955 | ||
998 | static int _mv88e6xxx_atu_cmd(struct mv88e6xxx_chip *chip, u16 fid, u16 cmd) | 956 | static int _mv88e6xxx_atu_cmd(struct mv88e6xxx_chip *chip, u16 fid, u16 cmd) |
999 | { | 957 | { |
1000 | int ret; | 958 | u16 val; |
959 | int err; | ||
1001 | 960 | ||
1002 | if (mv88e6xxx_has_fid_reg(chip)) { | 961 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_ATU_FID)) { |
1003 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_ATU_FID, | 962 | err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_FID, fid); |
1004 | fid); | 963 | if (err) |
1005 | if (ret < 0) | 964 | return err; |
1006 | return ret; | ||
1007 | } else if (mv88e6xxx_num_databases(chip) == 256) { | 965 | } else if (mv88e6xxx_num_databases(chip) == 256) { |
1008 | /* ATU DBNum[7:4] are located in ATU Control 15:12 */ | 966 | /* ATU DBNum[7:4] are located in ATU Control 15:12 */ |
1009 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_ATU_CONTROL); | 967 | err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_CONTROL, &val); |
1010 | if (ret < 0) | 968 | if (err) |
1011 | return ret; | 969 | return err; |
1012 | 970 | ||
1013 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_ATU_CONTROL, | 971 | err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL, |
1014 | (ret & 0xfff) | | 972 | (val & 0xfff) | ((fid << 8) & 0xf000)); |
1015 | ((fid << 8) & 0xf000)); | 973 | if (err) |
1016 | if (ret < 0) | 974 | return err; |
1017 | return ret; | ||
1018 | 975 | ||
1019 | /* ATU DBNum[3:0] are located in ATU Operation 3:0 */ | 976 | /* ATU DBNum[3:0] are located in ATU Operation 3:0 */ |
1020 | cmd |= fid & 0xf; | 977 | cmd |= fid & 0xf; |
1021 | } | 978 | } |
1022 | 979 | ||
1023 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_ATU_OP, cmd); | 980 | err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_OP, cmd); |
1024 | if (ret < 0) | 981 | if (err) |
1025 | return ret; | 982 | return err; |
1026 | 983 | ||
1027 | return _mv88e6xxx_atu_wait(chip); | 984 | return _mv88e6xxx_atu_wait(chip); |
1028 | } | 985 | } |
@@ -1047,7 +1004,7 @@ static int _mv88e6xxx_atu_data_write(struct mv88e6xxx_chip *chip, | |||
1047 | data |= (entry->portv_trunkid << shift) & mask; | 1004 | data |= (entry->portv_trunkid << shift) & mask; |
1048 | } | 1005 | } |
1049 | 1006 | ||
1050 | return _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_ATU_DATA, data); | 1007 | return mv88e6xxx_g1_write(chip, GLOBAL_ATU_DATA, data); |
1051 | } | 1008 | } |
1052 | 1009 | ||
1053 | static int _mv88e6xxx_atu_flush_move(struct mv88e6xxx_chip *chip, | 1010 | static int _mv88e6xxx_atu_flush_move(struct mv88e6xxx_chip *chip, |
@@ -1150,7 +1107,7 @@ static int _mv88e6xxx_port_state(struct mv88e6xxx_chip *chip, int port, | |||
1150 | static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port) | 1107 | static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port) |
1151 | { | 1108 | { |
1152 | struct net_device *bridge = chip->ports[port].bridge_dev; | 1109 | struct net_device *bridge = chip->ports[port].bridge_dev; |
1153 | const u16 mask = (1 << chip->info->num_ports) - 1; | 1110 | const u16 mask = (1 << mv88e6xxx_num_ports(chip)) - 1; |
1154 | struct dsa_switch *ds = chip->ds; | 1111 | struct dsa_switch *ds = chip->ds; |
1155 | u16 output_ports = 0; | 1112 | u16 output_ports = 0; |
1156 | u16 reg; | 1113 | u16 reg; |
@@ -1161,7 +1118,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port) | |||
1161 | if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) { | 1118 | if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) { |
1162 | output_ports = mask; | 1119 | output_ports = mask; |
1163 | } else { | 1120 | } else { |
1164 | for (i = 0; i < chip->info->num_ports; ++i) { | 1121 | for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { |
1165 | /* allow sending frames to every group member */ | 1122 | /* allow sending frames to every group member */ |
1166 | if (bridge && chip->ports[i].bridge_dev == bridge) | 1123 | if (bridge && chip->ports[i].bridge_dev == bridge) |
1167 | output_ports |= BIT(i); | 1124 | output_ports |= BIT(i); |
@@ -1277,17 +1234,16 @@ static int _mv88e6xxx_port_pvid_set(struct mv88e6xxx_chip *chip, | |||
1277 | 1234 | ||
1278 | static int _mv88e6xxx_vtu_wait(struct mv88e6xxx_chip *chip) | 1235 | static int _mv88e6xxx_vtu_wait(struct mv88e6xxx_chip *chip) |
1279 | { | 1236 | { |
1280 | return mv88e6xxx_wait(chip, REG_GLOBAL, GLOBAL_VTU_OP, | 1237 | return mv88e6xxx_g1_wait(chip, GLOBAL_VTU_OP, GLOBAL_VTU_OP_BUSY); |
1281 | GLOBAL_VTU_OP_BUSY); | ||
1282 | } | 1238 | } |
1283 | 1239 | ||
1284 | static int _mv88e6xxx_vtu_cmd(struct mv88e6xxx_chip *chip, u16 op) | 1240 | static int _mv88e6xxx_vtu_cmd(struct mv88e6xxx_chip *chip, u16 op) |
1285 | { | 1241 | { |
1286 | int ret; | 1242 | int err; |
1287 | 1243 | ||
1288 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_VTU_OP, op); | 1244 | err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_OP, op); |
1289 | if (ret < 0) | 1245 | if (err) |
1290 | return ret; | 1246 | return err; |
1291 | 1247 | ||
1292 | return _mv88e6xxx_vtu_wait(chip); | 1248 | return _mv88e6xxx_vtu_wait(chip); |
1293 | } | 1249 | } |
@@ -1304,23 +1260,21 @@ static int _mv88e6xxx_vtu_stu_flush(struct mv88e6xxx_chip *chip) | |||
1304 | } | 1260 | } |
1305 | 1261 | ||
1306 | static int _mv88e6xxx_vtu_stu_data_read(struct mv88e6xxx_chip *chip, | 1262 | static int _mv88e6xxx_vtu_stu_data_read(struct mv88e6xxx_chip *chip, |
1307 | struct mv88e6xxx_vtu_stu_entry *entry, | 1263 | struct mv88e6xxx_vtu_entry *entry, |
1308 | unsigned int nibble_offset) | 1264 | unsigned int nibble_offset) |
1309 | { | 1265 | { |
1310 | u16 regs[3]; | 1266 | u16 regs[3]; |
1311 | int i; | 1267 | int i, err; |
1312 | int ret; | ||
1313 | 1268 | ||
1314 | for (i = 0; i < 3; ++i) { | 1269 | for (i = 0; i < 3; ++i) { |
1315 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, | 1270 | u16 *reg = ®s[i]; |
1316 | GLOBAL_VTU_DATA_0_3 + i); | ||
1317 | if (ret < 0) | ||
1318 | return ret; | ||
1319 | 1271 | ||
1320 | regs[i] = ret; | 1272 | err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_DATA_0_3 + i, reg); |
1273 | if (err) | ||
1274 | return err; | ||
1321 | } | 1275 | } |
1322 | 1276 | ||
1323 | for (i = 0; i < chip->info->num_ports; ++i) { | 1277 | for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { |
1324 | unsigned int shift = (i % 4) * 4 + nibble_offset; | 1278 | unsigned int shift = (i % 4) * 4 + nibble_offset; |
1325 | u16 reg = regs[i / 4]; | 1279 | u16 reg = regs[i / 4]; |
1326 | 1280 | ||
@@ -1331,26 +1285,25 @@ static int _mv88e6xxx_vtu_stu_data_read(struct mv88e6xxx_chip *chip, | |||
1331 | } | 1285 | } |
1332 | 1286 | ||
1333 | static int mv88e6xxx_vtu_data_read(struct mv88e6xxx_chip *chip, | 1287 | static int mv88e6xxx_vtu_data_read(struct mv88e6xxx_chip *chip, |
1334 | struct mv88e6xxx_vtu_stu_entry *entry) | 1288 | struct mv88e6xxx_vtu_entry *entry) |
1335 | { | 1289 | { |
1336 | return _mv88e6xxx_vtu_stu_data_read(chip, entry, 0); | 1290 | return _mv88e6xxx_vtu_stu_data_read(chip, entry, 0); |
1337 | } | 1291 | } |
1338 | 1292 | ||
1339 | static int mv88e6xxx_stu_data_read(struct mv88e6xxx_chip *chip, | 1293 | static int mv88e6xxx_stu_data_read(struct mv88e6xxx_chip *chip, |
1340 | struct mv88e6xxx_vtu_stu_entry *entry) | 1294 | struct mv88e6xxx_vtu_entry *entry) |
1341 | { | 1295 | { |
1342 | return _mv88e6xxx_vtu_stu_data_read(chip, entry, 2); | 1296 | return _mv88e6xxx_vtu_stu_data_read(chip, entry, 2); |
1343 | } | 1297 | } |
1344 | 1298 | ||
1345 | static int _mv88e6xxx_vtu_stu_data_write(struct mv88e6xxx_chip *chip, | 1299 | static int _mv88e6xxx_vtu_stu_data_write(struct mv88e6xxx_chip *chip, |
1346 | struct mv88e6xxx_vtu_stu_entry *entry, | 1300 | struct mv88e6xxx_vtu_entry *entry, |
1347 | unsigned int nibble_offset) | 1301 | unsigned int nibble_offset) |
1348 | { | 1302 | { |
1349 | u16 regs[3] = { 0 }; | 1303 | u16 regs[3] = { 0 }; |
1350 | int i; | 1304 | int i, err; |
1351 | int ret; | ||
1352 | 1305 | ||
1353 | for (i = 0; i < chip->info->num_ports; ++i) { | 1306 | for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { |
1354 | unsigned int shift = (i % 4) * 4 + nibble_offset; | 1307 | unsigned int shift = (i % 4) * 4 + nibble_offset; |
1355 | u8 data = entry->data[i]; | 1308 | u8 data = entry->data[i]; |
1356 | 1309 | ||
@@ -1358,86 +1311,85 @@ static int _mv88e6xxx_vtu_stu_data_write(struct mv88e6xxx_chip *chip, | |||
1358 | } | 1311 | } |
1359 | 1312 | ||
1360 | for (i = 0; i < 3; ++i) { | 1313 | for (i = 0; i < 3; ++i) { |
1361 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, | 1314 | u16 reg = regs[i]; |
1362 | GLOBAL_VTU_DATA_0_3 + i, regs[i]); | 1315 | |
1363 | if (ret < 0) | 1316 | err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_DATA_0_3 + i, reg); |
1364 | return ret; | 1317 | if (err) |
1318 | return err; | ||
1365 | } | 1319 | } |
1366 | 1320 | ||
1367 | return 0; | 1321 | return 0; |
1368 | } | 1322 | } |
1369 | 1323 | ||
1370 | static int mv88e6xxx_vtu_data_write(struct mv88e6xxx_chip *chip, | 1324 | static int mv88e6xxx_vtu_data_write(struct mv88e6xxx_chip *chip, |
1371 | struct mv88e6xxx_vtu_stu_entry *entry) | 1325 | struct mv88e6xxx_vtu_entry *entry) |
1372 | { | 1326 | { |
1373 | return _mv88e6xxx_vtu_stu_data_write(chip, entry, 0); | 1327 | return _mv88e6xxx_vtu_stu_data_write(chip, entry, 0); |
1374 | } | 1328 | } |
1375 | 1329 | ||
1376 | static int mv88e6xxx_stu_data_write(struct mv88e6xxx_chip *chip, | 1330 | static int mv88e6xxx_stu_data_write(struct mv88e6xxx_chip *chip, |
1377 | struct mv88e6xxx_vtu_stu_entry *entry) | 1331 | struct mv88e6xxx_vtu_entry *entry) |
1378 | { | 1332 | { |
1379 | return _mv88e6xxx_vtu_stu_data_write(chip, entry, 2); | 1333 | return _mv88e6xxx_vtu_stu_data_write(chip, entry, 2); |
1380 | } | 1334 | } |
1381 | 1335 | ||
1382 | static int _mv88e6xxx_vtu_vid_write(struct mv88e6xxx_chip *chip, u16 vid) | 1336 | static int _mv88e6xxx_vtu_vid_write(struct mv88e6xxx_chip *chip, u16 vid) |
1383 | { | 1337 | { |
1384 | return _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_VTU_VID, | 1338 | return mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, |
1385 | vid & GLOBAL_VTU_VID_MASK); | 1339 | vid & GLOBAL_VTU_VID_MASK); |
1386 | } | 1340 | } |
1387 | 1341 | ||
1388 | static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip, | 1342 | static int _mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip, |
1389 | struct mv88e6xxx_vtu_stu_entry *entry) | 1343 | struct mv88e6xxx_vtu_entry *entry) |
1390 | { | 1344 | { |
1391 | struct mv88e6xxx_vtu_stu_entry next = { 0 }; | 1345 | struct mv88e6xxx_vtu_entry next = { 0 }; |
1392 | int ret; | 1346 | u16 val; |
1347 | int err; | ||
1393 | 1348 | ||
1394 | ret = _mv88e6xxx_vtu_wait(chip); | 1349 | err = _mv88e6xxx_vtu_wait(chip); |
1395 | if (ret < 0) | 1350 | if (err) |
1396 | return ret; | 1351 | return err; |
1397 | 1352 | ||
1398 | ret = _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_VTU_GET_NEXT); | 1353 | err = _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_VTU_GET_NEXT); |
1399 | if (ret < 0) | 1354 | if (err) |
1400 | return ret; | 1355 | return err; |
1401 | 1356 | ||
1402 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_VTU_VID); | 1357 | err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_VID, &val); |
1403 | if (ret < 0) | 1358 | if (err) |
1404 | return ret; | 1359 | return err; |
1405 | 1360 | ||
1406 | next.vid = ret & GLOBAL_VTU_VID_MASK; | 1361 | next.vid = val & GLOBAL_VTU_VID_MASK; |
1407 | next.valid = !!(ret & GLOBAL_VTU_VID_VALID); | 1362 | next.valid = !!(val & GLOBAL_VTU_VID_VALID); |
1408 | 1363 | ||
1409 | if (next.valid) { | 1364 | if (next.valid) { |
1410 | ret = mv88e6xxx_vtu_data_read(chip, &next); | 1365 | err = mv88e6xxx_vtu_data_read(chip, &next); |
1411 | if (ret < 0) | 1366 | if (err) |
1412 | return ret; | 1367 | return err; |
1413 | 1368 | ||
1414 | if (mv88e6xxx_has_fid_reg(chip)) { | 1369 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_VTU_FID)) { |
1415 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, | 1370 | err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_FID, &val); |
1416 | GLOBAL_VTU_FID); | 1371 | if (err) |
1417 | if (ret < 0) | 1372 | return err; |
1418 | return ret; | ||
1419 | 1373 | ||
1420 | next.fid = ret & GLOBAL_VTU_FID_MASK; | 1374 | next.fid = val & GLOBAL_VTU_FID_MASK; |
1421 | } else if (mv88e6xxx_num_databases(chip) == 256) { | 1375 | } else if (mv88e6xxx_num_databases(chip) == 256) { |
1422 | /* VTU DBNum[7:4] are located in VTU Operation 11:8, and | 1376 | /* VTU DBNum[7:4] are located in VTU Operation 11:8, and |
1423 | * VTU DBNum[3:0] are located in VTU Operation 3:0 | 1377 | * VTU DBNum[3:0] are located in VTU Operation 3:0 |
1424 | */ | 1378 | */ |
1425 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, | 1379 | err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_OP, &val); |
1426 | GLOBAL_VTU_OP); | 1380 | if (err) |
1427 | if (ret < 0) | 1381 | return err; |
1428 | return ret; | ||
1429 | 1382 | ||
1430 | next.fid = (ret & 0xf00) >> 4; | 1383 | next.fid = (val & 0xf00) >> 4; |
1431 | next.fid |= ret & 0xf; | 1384 | next.fid |= val & 0xf; |
1432 | } | 1385 | } |
1433 | 1386 | ||
1434 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) { | 1387 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) { |
1435 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, | 1388 | err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_SID, &val); |
1436 | GLOBAL_VTU_SID); | 1389 | if (err) |
1437 | if (ret < 0) | 1390 | return err; |
1438 | return ret; | ||
1439 | 1391 | ||
1440 | next.sid = ret & GLOBAL_VTU_SID_MASK; | 1392 | next.sid = val & GLOBAL_VTU_SID_MASK; |
1441 | } | 1393 | } |
1442 | } | 1394 | } |
1443 | 1395 | ||
@@ -1450,7 +1402,7 @@ static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port, | |||
1450 | int (*cb)(struct switchdev_obj *obj)) | 1402 | int (*cb)(struct switchdev_obj *obj)) |
1451 | { | 1403 | { |
1452 | struct mv88e6xxx_chip *chip = ds->priv; | 1404 | struct mv88e6xxx_chip *chip = ds->priv; |
1453 | struct mv88e6xxx_vtu_stu_entry next; | 1405 | struct mv88e6xxx_vtu_entry next; |
1454 | u16 pvid; | 1406 | u16 pvid; |
1455 | int err; | 1407 | int err; |
1456 | 1408 | ||
@@ -1501,38 +1453,36 @@ unlock: | |||
1501 | } | 1453 | } |
1502 | 1454 | ||
1503 | static int _mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip, | 1455 | static int _mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip, |
1504 | struct mv88e6xxx_vtu_stu_entry *entry) | 1456 | struct mv88e6xxx_vtu_entry *entry) |
1505 | { | 1457 | { |
1506 | u16 op = GLOBAL_VTU_OP_VTU_LOAD_PURGE; | 1458 | u16 op = GLOBAL_VTU_OP_VTU_LOAD_PURGE; |
1507 | u16 reg = 0; | 1459 | u16 reg = 0; |
1508 | int ret; | 1460 | int err; |
1509 | 1461 | ||
1510 | ret = _mv88e6xxx_vtu_wait(chip); | 1462 | err = _mv88e6xxx_vtu_wait(chip); |
1511 | if (ret < 0) | 1463 | if (err) |
1512 | return ret; | 1464 | return err; |
1513 | 1465 | ||
1514 | if (!entry->valid) | 1466 | if (!entry->valid) |
1515 | goto loadpurge; | 1467 | goto loadpurge; |
1516 | 1468 | ||
1517 | /* Write port member tags */ | 1469 | /* Write port member tags */ |
1518 | ret = mv88e6xxx_vtu_data_write(chip, entry); | 1470 | err = mv88e6xxx_vtu_data_write(chip, entry); |
1519 | if (ret < 0) | 1471 | if (err) |
1520 | return ret; | 1472 | return err; |
1521 | 1473 | ||
1522 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) { | 1474 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_STU)) { |
1523 | reg = entry->sid & GLOBAL_VTU_SID_MASK; | 1475 | reg = entry->sid & GLOBAL_VTU_SID_MASK; |
1524 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_VTU_SID, | 1476 | err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, reg); |
1525 | reg); | 1477 | if (err) |
1526 | if (ret < 0) | 1478 | return err; |
1527 | return ret; | ||
1528 | } | 1479 | } |
1529 | 1480 | ||
1530 | if (mv88e6xxx_has_fid_reg(chip)) { | 1481 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G1_VTU_FID)) { |
1531 | reg = entry->fid & GLOBAL_VTU_FID_MASK; | 1482 | reg = entry->fid & GLOBAL_VTU_FID_MASK; |
1532 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_VTU_FID, | 1483 | err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_FID, reg); |
1533 | reg); | 1484 | if (err) |
1534 | if (ret < 0) | 1485 | return err; |
1535 | return ret; | ||
1536 | } else if (mv88e6xxx_num_databases(chip) == 256) { | 1486 | } else if (mv88e6xxx_num_databases(chip) == 256) { |
1537 | /* VTU DBNum[7:4] are located in VTU Operation 11:8, and | 1487 | /* VTU DBNum[7:4] are located in VTU Operation 11:8, and |
1538 | * VTU DBNum[3:0] are located in VTU Operation 3:0 | 1488 | * VTU DBNum[3:0] are located in VTU Operation 3:0 |
@@ -1544,48 +1494,49 @@ static int _mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip, | |||
1544 | reg = GLOBAL_VTU_VID_VALID; | 1494 | reg = GLOBAL_VTU_VID_VALID; |
1545 | loadpurge: | 1495 | loadpurge: |
1546 | reg |= entry->vid & GLOBAL_VTU_VID_MASK; | 1496 | reg |= entry->vid & GLOBAL_VTU_VID_MASK; |
1547 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_VTU_VID, reg); | 1497 | err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, reg); |
1548 | if (ret < 0) | 1498 | if (err) |
1549 | return ret; | 1499 | return err; |
1550 | 1500 | ||
1551 | return _mv88e6xxx_vtu_cmd(chip, op); | 1501 | return _mv88e6xxx_vtu_cmd(chip, op); |
1552 | } | 1502 | } |
1553 | 1503 | ||
1554 | static int _mv88e6xxx_stu_getnext(struct mv88e6xxx_chip *chip, u8 sid, | 1504 | static int _mv88e6xxx_stu_getnext(struct mv88e6xxx_chip *chip, u8 sid, |
1555 | struct mv88e6xxx_vtu_stu_entry *entry) | 1505 | struct mv88e6xxx_vtu_entry *entry) |
1556 | { | 1506 | { |
1557 | struct mv88e6xxx_vtu_stu_entry next = { 0 }; | 1507 | struct mv88e6xxx_vtu_entry next = { 0 }; |
1558 | int ret; | 1508 | u16 val; |
1509 | int err; | ||
1559 | 1510 | ||
1560 | ret = _mv88e6xxx_vtu_wait(chip); | 1511 | err = _mv88e6xxx_vtu_wait(chip); |
1561 | if (ret < 0) | 1512 | if (err) |
1562 | return ret; | 1513 | return err; |
1563 | 1514 | ||
1564 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_VTU_SID, | 1515 | err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, |
1565 | sid & GLOBAL_VTU_SID_MASK); | 1516 | sid & GLOBAL_VTU_SID_MASK); |
1566 | if (ret < 0) | 1517 | if (err) |
1567 | return ret; | 1518 | return err; |
1568 | 1519 | ||
1569 | ret = _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_GET_NEXT); | 1520 | err = _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_GET_NEXT); |
1570 | if (ret < 0) | 1521 | if (err) |
1571 | return ret; | 1522 | return err; |
1572 | 1523 | ||
1573 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_VTU_SID); | 1524 | err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_SID, &val); |
1574 | if (ret < 0) | 1525 | if (err) |
1575 | return ret; | 1526 | return err; |
1576 | 1527 | ||
1577 | next.sid = ret & GLOBAL_VTU_SID_MASK; | 1528 | next.sid = val & GLOBAL_VTU_SID_MASK; |
1578 | 1529 | ||
1579 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_VTU_VID); | 1530 | err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_VID, &val); |
1580 | if (ret < 0) | 1531 | if (err) |
1581 | return ret; | 1532 | return err; |
1582 | 1533 | ||
1583 | next.valid = !!(ret & GLOBAL_VTU_VID_VALID); | 1534 | next.valid = !!(val & GLOBAL_VTU_VID_VALID); |
1584 | 1535 | ||
1585 | if (next.valid) { | 1536 | if (next.valid) { |
1586 | ret = mv88e6xxx_stu_data_read(chip, &next); | 1537 | err = mv88e6xxx_stu_data_read(chip, &next); |
1587 | if (ret < 0) | 1538 | if (err) |
1588 | return ret; | 1539 | return err; |
1589 | } | 1540 | } |
1590 | 1541 | ||
1591 | *entry = next; | 1542 | *entry = next; |
@@ -1593,33 +1544,33 @@ static int _mv88e6xxx_stu_getnext(struct mv88e6xxx_chip *chip, u8 sid, | |||
1593 | } | 1544 | } |
1594 | 1545 | ||
1595 | static int _mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip, | 1546 | static int _mv88e6xxx_stu_loadpurge(struct mv88e6xxx_chip *chip, |
1596 | struct mv88e6xxx_vtu_stu_entry *entry) | 1547 | struct mv88e6xxx_vtu_entry *entry) |
1597 | { | 1548 | { |
1598 | u16 reg = 0; | 1549 | u16 reg = 0; |
1599 | int ret; | 1550 | int err; |
1600 | 1551 | ||
1601 | ret = _mv88e6xxx_vtu_wait(chip); | 1552 | err = _mv88e6xxx_vtu_wait(chip); |
1602 | if (ret < 0) | 1553 | if (err) |
1603 | return ret; | 1554 | return err; |
1604 | 1555 | ||
1605 | if (!entry->valid) | 1556 | if (!entry->valid) |
1606 | goto loadpurge; | 1557 | goto loadpurge; |
1607 | 1558 | ||
1608 | /* Write port states */ | 1559 | /* Write port states */ |
1609 | ret = mv88e6xxx_stu_data_write(chip, entry); | 1560 | err = mv88e6xxx_stu_data_write(chip, entry); |
1610 | if (ret < 0) | 1561 | if (err) |
1611 | return ret; | 1562 | return err; |
1612 | 1563 | ||
1613 | reg = GLOBAL_VTU_VID_VALID; | 1564 | reg = GLOBAL_VTU_VID_VALID; |
1614 | loadpurge: | 1565 | loadpurge: |
1615 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_VTU_VID, reg); | 1566 | err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, reg); |
1616 | if (ret < 0) | 1567 | if (err) |
1617 | return ret; | 1568 | return err; |
1618 | 1569 | ||
1619 | reg = entry->sid & GLOBAL_VTU_SID_MASK; | 1570 | reg = entry->sid & GLOBAL_VTU_SID_MASK; |
1620 | ret = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_VTU_SID, reg); | 1571 | err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_SID, reg); |
1621 | if (ret < 0) | 1572 | if (err) |
1622 | return ret; | 1573 | return err; |
1623 | 1574 | ||
1624 | return _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_LOAD_PURGE); | 1575 | return _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_LOAD_PURGE); |
1625 | } | 1576 | } |
@@ -1696,13 +1647,13 @@ static int _mv88e6xxx_port_fid_set(struct mv88e6xxx_chip *chip, | |||
1696 | static int _mv88e6xxx_fid_new(struct mv88e6xxx_chip *chip, u16 *fid) | 1647 | static int _mv88e6xxx_fid_new(struct mv88e6xxx_chip *chip, u16 *fid) |
1697 | { | 1648 | { |
1698 | DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID); | 1649 | DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID); |
1699 | struct mv88e6xxx_vtu_stu_entry vlan; | 1650 | struct mv88e6xxx_vtu_entry vlan; |
1700 | int i, err; | 1651 | int i, err; |
1701 | 1652 | ||
1702 | bitmap_zero(fid_bitmap, MV88E6XXX_N_FID); | 1653 | bitmap_zero(fid_bitmap, MV88E6XXX_N_FID); |
1703 | 1654 | ||
1704 | /* Set every FID bit used by the (un)bridged ports */ | 1655 | /* Set every FID bit used by the (un)bridged ports */ |
1705 | for (i = 0; i < chip->info->num_ports; ++i) { | 1656 | for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { |
1706 | err = _mv88e6xxx_port_fid_get(chip, i, fid); | 1657 | err = _mv88e6xxx_port_fid_get(chip, i, fid); |
1707 | if (err) | 1658 | if (err) |
1708 | return err; | 1659 | return err; |
@@ -1738,10 +1689,10 @@ static int _mv88e6xxx_fid_new(struct mv88e6xxx_chip *chip, u16 *fid) | |||
1738 | } | 1689 | } |
1739 | 1690 | ||
1740 | static int _mv88e6xxx_vtu_new(struct mv88e6xxx_chip *chip, u16 vid, | 1691 | static int _mv88e6xxx_vtu_new(struct mv88e6xxx_chip *chip, u16 vid, |
1741 | struct mv88e6xxx_vtu_stu_entry *entry) | 1692 | struct mv88e6xxx_vtu_entry *entry) |
1742 | { | 1693 | { |
1743 | struct dsa_switch *ds = chip->ds; | 1694 | struct dsa_switch *ds = chip->ds; |
1744 | struct mv88e6xxx_vtu_stu_entry vlan = { | 1695 | struct mv88e6xxx_vtu_entry vlan = { |
1745 | .valid = true, | 1696 | .valid = true, |
1746 | .vid = vid, | 1697 | .vid = vid, |
1747 | }; | 1698 | }; |
@@ -1752,14 +1703,14 @@ static int _mv88e6xxx_vtu_new(struct mv88e6xxx_chip *chip, u16 vid, | |||
1752 | return err; | 1703 | return err; |
1753 | 1704 | ||
1754 | /* exclude all ports except the CPU and DSA ports */ | 1705 | /* exclude all ports except the CPU and DSA ports */ |
1755 | for (i = 0; i < chip->info->num_ports; ++i) | 1706 | for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) |
1756 | vlan.data[i] = dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i) | 1707 | vlan.data[i] = dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i) |
1757 | ? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED | 1708 | ? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED |
1758 | : GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER; | 1709 | : GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER; |
1759 | 1710 | ||
1760 | if (mv88e6xxx_6097_family(chip) || mv88e6xxx_6165_family(chip) || | 1711 | if (mv88e6xxx_6097_family(chip) || mv88e6xxx_6165_family(chip) || |
1761 | mv88e6xxx_6351_family(chip) || mv88e6xxx_6352_family(chip)) { | 1712 | mv88e6xxx_6351_family(chip) || mv88e6xxx_6352_family(chip)) { |
1762 | struct mv88e6xxx_vtu_stu_entry vstp; | 1713 | struct mv88e6xxx_vtu_entry vstp; |
1763 | 1714 | ||
1764 | /* Adding a VTU entry requires a valid STU entry. As VSTP is not | 1715 | /* Adding a VTU entry requires a valid STU entry. As VSTP is not |
1765 | * implemented, only one STU entry is needed to cover all VTU | 1716 | * implemented, only one STU entry is needed to cover all VTU |
@@ -1786,7 +1737,7 @@ static int _mv88e6xxx_vtu_new(struct mv88e6xxx_chip *chip, u16 vid, | |||
1786 | } | 1737 | } |
1787 | 1738 | ||
1788 | static int _mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid, | 1739 | static int _mv88e6xxx_vtu_get(struct mv88e6xxx_chip *chip, u16 vid, |
1789 | struct mv88e6xxx_vtu_stu_entry *entry, bool creat) | 1740 | struct mv88e6xxx_vtu_entry *entry, bool creat) |
1790 | { | 1741 | { |
1791 | int err; | 1742 | int err; |
1792 | 1743 | ||
@@ -1818,7 +1769,7 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, | |||
1818 | u16 vid_begin, u16 vid_end) | 1769 | u16 vid_begin, u16 vid_end) |
1819 | { | 1770 | { |
1820 | struct mv88e6xxx_chip *chip = ds->priv; | 1771 | struct mv88e6xxx_chip *chip = ds->priv; |
1821 | struct mv88e6xxx_vtu_stu_entry vlan; | 1772 | struct mv88e6xxx_vtu_entry vlan; |
1822 | int i, err; | 1773 | int i, err; |
1823 | 1774 | ||
1824 | if (!vid_begin) | 1775 | if (!vid_begin) |
@@ -1841,7 +1792,7 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, | |||
1841 | if (vlan.vid > vid_end) | 1792 | if (vlan.vid > vid_end) |
1842 | break; | 1793 | break; |
1843 | 1794 | ||
1844 | for (i = 0; i < chip->info->num_ports; ++i) { | 1795 | for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { |
1845 | if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i)) | 1796 | if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i)) |
1846 | continue; | 1797 | continue; |
1847 | 1798 | ||
@@ -1943,7 +1894,7 @@ mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port, | |||
1943 | static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port, | 1894 | static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port, |
1944 | u16 vid, bool untagged) | 1895 | u16 vid, bool untagged) |
1945 | { | 1896 | { |
1946 | struct mv88e6xxx_vtu_stu_entry vlan; | 1897 | struct mv88e6xxx_vtu_entry vlan; |
1947 | int err; | 1898 | int err; |
1948 | 1899 | ||
1949 | err = _mv88e6xxx_vtu_get(chip, vid, &vlan, true); | 1900 | err = _mv88e6xxx_vtu_get(chip, vid, &vlan, true); |
@@ -1988,7 +1939,7 @@ static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_chip *chip, | |||
1988 | int port, u16 vid) | 1939 | int port, u16 vid) |
1989 | { | 1940 | { |
1990 | struct dsa_switch *ds = chip->ds; | 1941 | struct dsa_switch *ds = chip->ds; |
1991 | struct mv88e6xxx_vtu_stu_entry vlan; | 1942 | struct mv88e6xxx_vtu_entry vlan; |
1992 | int i, err; | 1943 | int i, err; |
1993 | 1944 | ||
1994 | err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false); | 1945 | err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false); |
@@ -2003,7 +1954,7 @@ static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_chip *chip, | |||
2003 | 1954 | ||
2004 | /* keep the VLAN unless all ports are excluded */ | 1955 | /* keep the VLAN unless all ports are excluded */ |
2005 | vlan.valid = false; | 1956 | vlan.valid = false; |
2006 | for (i = 0; i < chip->info->num_ports; ++i) { | 1957 | for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { |
2007 | if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)) | 1958 | if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)) |
2008 | continue; | 1959 | continue; |
2009 | 1960 | ||
@@ -2057,14 +2008,13 @@ unlock: | |||
2057 | static int _mv88e6xxx_atu_mac_write(struct mv88e6xxx_chip *chip, | 2008 | static int _mv88e6xxx_atu_mac_write(struct mv88e6xxx_chip *chip, |
2058 | const unsigned char *addr) | 2009 | const unsigned char *addr) |
2059 | { | 2010 | { |
2060 | int i, ret; | 2011 | int i, err; |
2061 | 2012 | ||
2062 | for (i = 0; i < 3; i++) { | 2013 | for (i = 0; i < 3; i++) { |
2063 | ret = _mv88e6xxx_reg_write( | 2014 | err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_MAC_01 + i, |
2064 | chip, REG_GLOBAL, GLOBAL_ATU_MAC_01 + i, | 2015 | (addr[i * 2] << 8) | addr[i * 2 + 1]); |
2065 | (addr[i * 2] << 8) | addr[i * 2 + 1]); | 2016 | if (err) |
2066 | if (ret < 0) | 2017 | return err; |
2067 | return ret; | ||
2068 | } | 2018 | } |
2069 | 2019 | ||
2070 | return 0; | 2020 | return 0; |
@@ -2073,15 +2023,16 @@ static int _mv88e6xxx_atu_mac_write(struct mv88e6xxx_chip *chip, | |||
2073 | static int _mv88e6xxx_atu_mac_read(struct mv88e6xxx_chip *chip, | 2023 | static int _mv88e6xxx_atu_mac_read(struct mv88e6xxx_chip *chip, |
2074 | unsigned char *addr) | 2024 | unsigned char *addr) |
2075 | { | 2025 | { |
2076 | int i, ret; | 2026 | u16 val; |
2027 | int i, err; | ||
2077 | 2028 | ||
2078 | for (i = 0; i < 3; i++) { | 2029 | for (i = 0; i < 3; i++) { |
2079 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, | 2030 | err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_MAC_01 + i, &val); |
2080 | GLOBAL_ATU_MAC_01 + i); | 2031 | if (err) |
2081 | if (ret < 0) | 2032 | return err; |
2082 | return ret; | 2033 | |
2083 | addr[i * 2] = ret >> 8; | 2034 | addr[i * 2] = val >> 8; |
2084 | addr[i * 2 + 1] = ret & 0xff; | 2035 | addr[i * 2 + 1] = val & 0xff; |
2085 | } | 2036 | } |
2086 | 2037 | ||
2087 | return 0; | 2038 | return 0; |
@@ -2147,7 +2098,7 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, | |||
2147 | const unsigned char *addr, u16 vid, | 2098 | const unsigned char *addr, u16 vid, |
2148 | u8 state) | 2099 | u8 state) |
2149 | { | 2100 | { |
2150 | struct mv88e6xxx_vtu_stu_entry vlan; | 2101 | struct mv88e6xxx_vtu_entry vlan; |
2151 | struct mv88e6xxx_atu_entry entry; | 2102 | struct mv88e6xxx_atu_entry entry; |
2152 | int err; | 2103 | int err; |
2153 | 2104 | ||
@@ -2217,31 +2168,32 @@ static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid, | |||
2217 | struct mv88e6xxx_atu_entry *entry) | 2168 | struct mv88e6xxx_atu_entry *entry) |
2218 | { | 2169 | { |
2219 | struct mv88e6xxx_atu_entry next = { 0 }; | 2170 | struct mv88e6xxx_atu_entry next = { 0 }; |
2220 | int ret; | 2171 | u16 val; |
2172 | int err; | ||
2221 | 2173 | ||
2222 | next.fid = fid; | 2174 | next.fid = fid; |
2223 | 2175 | ||
2224 | ret = _mv88e6xxx_atu_wait(chip); | 2176 | err = _mv88e6xxx_atu_wait(chip); |
2225 | if (ret < 0) | 2177 | if (err) |
2226 | return ret; | 2178 | return err; |
2227 | 2179 | ||
2228 | ret = _mv88e6xxx_atu_cmd(chip, fid, GLOBAL_ATU_OP_GET_NEXT_DB); | 2180 | err = _mv88e6xxx_atu_cmd(chip, fid, GLOBAL_ATU_OP_GET_NEXT_DB); |
2229 | if (ret < 0) | 2181 | if (err) |
2230 | return ret; | 2182 | return err; |
2231 | 2183 | ||
2232 | ret = _mv88e6xxx_atu_mac_read(chip, next.mac); | 2184 | err = _mv88e6xxx_atu_mac_read(chip, next.mac); |
2233 | if (ret < 0) | 2185 | if (err) |
2234 | return ret; | 2186 | return err; |
2235 | 2187 | ||
2236 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, GLOBAL_ATU_DATA); | 2188 | err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_DATA, &val); |
2237 | if (ret < 0) | 2189 | if (err) |
2238 | return ret; | 2190 | return err; |
2239 | 2191 | ||
2240 | next.state = ret & GLOBAL_ATU_DATA_STATE_MASK; | 2192 | next.state = val & GLOBAL_ATU_DATA_STATE_MASK; |
2241 | if (next.state != GLOBAL_ATU_DATA_STATE_UNUSED) { | 2193 | if (next.state != GLOBAL_ATU_DATA_STATE_UNUSED) { |
2242 | unsigned int mask, shift; | 2194 | unsigned int mask, shift; |
2243 | 2195 | ||
2244 | if (ret & GLOBAL_ATU_DATA_TRUNK) { | 2196 | if (val & GLOBAL_ATU_DATA_TRUNK) { |
2245 | next.trunk = true; | 2197 | next.trunk = true; |
2246 | mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK; | 2198 | mask = GLOBAL_ATU_DATA_TRUNK_ID_MASK; |
2247 | shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT; | 2199 | shift = GLOBAL_ATU_DATA_TRUNK_ID_SHIFT; |
@@ -2251,7 +2203,7 @@ static int _mv88e6xxx_atu_getnext(struct mv88e6xxx_chip *chip, u16 fid, | |||
2251 | shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT; | 2203 | shift = GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT; |
2252 | } | 2204 | } |
2253 | 2205 | ||
2254 | next.portv_trunkid = (ret & mask) >> shift; | 2206 | next.portv_trunkid = (val & mask) >> shift; |
2255 | } | 2207 | } |
2256 | 2208 | ||
2257 | *entry = next; | 2209 | *entry = next; |
@@ -2321,7 +2273,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port, | |||
2321 | struct switchdev_obj *obj, | 2273 | struct switchdev_obj *obj, |
2322 | int (*cb)(struct switchdev_obj *obj)) | 2274 | int (*cb)(struct switchdev_obj *obj)) |
2323 | { | 2275 | { |
2324 | struct mv88e6xxx_vtu_stu_entry vlan = { | 2276 | struct mv88e6xxx_vtu_entry vlan = { |
2325 | .vid = GLOBAL_VTU_VID_MASK, /* all ones */ | 2277 | .vid = GLOBAL_VTU_VID_MASK, /* all ones */ |
2326 | }; | 2278 | }; |
2327 | u16 fid; | 2279 | u16 fid; |
@@ -2383,7 +2335,7 @@ static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, | |||
2383 | /* Assign the bridge and remap each port's VLANTable */ | 2335 | /* Assign the bridge and remap each port's VLANTable */ |
2384 | chip->ports[port].bridge_dev = bridge; | 2336 | chip->ports[port].bridge_dev = bridge; |
2385 | 2337 | ||
2386 | for (i = 0; i < chip->info->num_ports; ++i) { | 2338 | for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { |
2387 | if (chip->ports[i].bridge_dev == bridge) { | 2339 | if (chip->ports[i].bridge_dev == bridge) { |
2388 | err = _mv88e6xxx_port_based_vlan_map(chip, i); | 2340 | err = _mv88e6xxx_port_based_vlan_map(chip, i); |
2389 | if (err) | 2341 | if (err) |
@@ -2407,7 +2359,7 @@ static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) | |||
2407 | /* Unassign the bridge and remap each port's VLANTable */ | 2359 | /* Unassign the bridge and remap each port's VLANTable */ |
2408 | chip->ports[port].bridge_dev = NULL; | 2360 | chip->ports[port].bridge_dev = NULL; |
2409 | 2361 | ||
2410 | for (i = 0; i < chip->info->num_ports; ++i) | 2362 | for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) |
2411 | if (i == port || chip->ports[i].bridge_dev == bridge) | 2363 | if (i == port || chip->ports[i].bridge_dev == bridge) |
2412 | if (_mv88e6xxx_port_based_vlan_map(chip, i)) | 2364 | if (_mv88e6xxx_port_based_vlan_map(chip, i)) |
2413 | netdev_warn(ds->ports[i].netdev, | 2365 | netdev_warn(ds->ports[i].netdev, |
@@ -2422,12 +2374,12 @@ static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip) | |||
2422 | u16 is_reset = (ppu_active ? 0x8800 : 0xc800); | 2374 | u16 is_reset = (ppu_active ? 0x8800 : 0xc800); |
2423 | struct gpio_desc *gpiod = chip->reset; | 2375 | struct gpio_desc *gpiod = chip->reset; |
2424 | unsigned long timeout; | 2376 | unsigned long timeout; |
2425 | int err, ret; | ||
2426 | u16 reg; | 2377 | u16 reg; |
2378 | int err; | ||
2427 | int i; | 2379 | int i; |
2428 | 2380 | ||
2429 | /* Set all ports to the disabled state. */ | 2381 | /* Set all ports to the disabled state. */ |
2430 | for (i = 0; i < chip->info->num_ports; i++) { | 2382 | for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { |
2431 | err = mv88e6xxx_port_read(chip, i, PORT_CONTROL, ®); | 2383 | err = mv88e6xxx_port_read(chip, i, PORT_CONTROL, ®); |
2432 | if (err) | 2384 | if (err) |
2433 | return err; | 2385 | return err; |
@@ -2454,20 +2406,20 @@ static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip) | |||
2454 | * through global registers 0x18 and 0x19. | 2406 | * through global registers 0x18 and 0x19. |
2455 | */ | 2407 | */ |
2456 | if (ppu_active) | 2408 | if (ppu_active) |
2457 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, 0x04, 0xc000); | 2409 | err = mv88e6xxx_g1_write(chip, 0x04, 0xc000); |
2458 | else | 2410 | else |
2459 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, 0x04, 0xc400); | 2411 | err = mv88e6xxx_g1_write(chip, 0x04, 0xc400); |
2460 | if (err) | 2412 | if (err) |
2461 | return err; | 2413 | return err; |
2462 | 2414 | ||
2463 | /* Wait up to one second for reset to complete. */ | 2415 | /* Wait up to one second for reset to complete. */ |
2464 | timeout = jiffies + 1 * HZ; | 2416 | timeout = jiffies + 1 * HZ; |
2465 | while (time_before(jiffies, timeout)) { | 2417 | while (time_before(jiffies, timeout)) { |
2466 | ret = _mv88e6xxx_reg_read(chip, REG_GLOBAL, 0x00); | 2418 | err = mv88e6xxx_g1_read(chip, 0x00, ®); |
2467 | if (ret < 0) | 2419 | if (err) |
2468 | return ret; | 2420 | return err; |
2469 | 2421 | ||
2470 | if ((ret & is_reset) == is_reset) | 2422 | if ((reg & is_reset) == is_reset) |
2471 | break; | 2423 | break; |
2472 | usleep_range(1000, 2000); | 2424 | usleep_range(1000, 2000); |
2473 | } | 2425 | } |
@@ -2749,22 +2701,23 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port) | |||
2749 | return mv88e6xxx_port_write(chip, port, PORT_DEFAULT_VLAN, 0x0000); | 2701 | return mv88e6xxx_port_write(chip, port, PORT_DEFAULT_VLAN, 0x0000); |
2750 | } | 2702 | } |
2751 | 2703 | ||
2752 | static int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr) | 2704 | int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr) |
2753 | { | 2705 | { |
2754 | int err; | 2706 | int err; |
2755 | 2707 | ||
2756 | err = mv88e6xxx_write(chip, REG_GLOBAL, GLOBAL_MAC_01, | 2708 | err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_01, (addr[0] << 8) | addr[1]); |
2757 | (addr[0] << 8) | addr[1]); | 2709 | if (err) |
2710 | return err; | ||
2711 | |||
2712 | err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]); | ||
2758 | if (err) | 2713 | if (err) |
2759 | return err; | 2714 | return err; |
2760 | 2715 | ||
2761 | err = mv88e6xxx_write(chip, REG_GLOBAL, GLOBAL_MAC_23, | 2716 | err = mv88e6xxx_g1_write(chip, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]); |
2762 | (addr[2] << 8) | addr[3]); | ||
2763 | if (err) | 2717 | if (err) |
2764 | return err; | 2718 | return err; |
2765 | 2719 | ||
2766 | return mv88e6xxx_write(chip, REG_GLOBAL, GLOBAL_MAC_45, | 2720 | return 0; |
2767 | (addr[4] << 8) | addr[5]); | ||
2768 | } | 2721 | } |
2769 | 2722 | ||
2770 | static int mv88e6xxx_g1_set_age_time(struct mv88e6xxx_chip *chip, | 2723 | static int mv88e6xxx_g1_set_age_time(struct mv88e6xxx_chip *chip, |
@@ -2783,7 +2736,7 @@ static int mv88e6xxx_g1_set_age_time(struct mv88e6xxx_chip *chip, | |||
2783 | /* Round to nearest multiple of coeff */ | 2736 | /* Round to nearest multiple of coeff */ |
2784 | age_time = (msecs + coeff / 2) / coeff; | 2737 | age_time = (msecs + coeff / 2) / coeff; |
2785 | 2738 | ||
2786 | err = mv88e6xxx_read(chip, REG_GLOBAL, GLOBAL_ATU_CONTROL, &val); | 2739 | err = mv88e6xxx_g1_read(chip, GLOBAL_ATU_CONTROL, &val); |
2787 | if (err) | 2740 | if (err) |
2788 | return err; | 2741 | return err; |
2789 | 2742 | ||
@@ -2791,7 +2744,7 @@ static int mv88e6xxx_g1_set_age_time(struct mv88e6xxx_chip *chip, | |||
2791 | val &= ~0xff0; | 2744 | val &= ~0xff0; |
2792 | val |= age_time << 4; | 2745 | val |= age_time << 4; |
2793 | 2746 | ||
2794 | return mv88e6xxx_write(chip, REG_GLOBAL, GLOBAL_ATU_CONTROL, val); | 2747 | return mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL, val); |
2795 | } | 2748 | } |
2796 | 2749 | ||
2797 | static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds, | 2750 | static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds, |
@@ -2822,7 +2775,7 @@ static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip) | |||
2822 | mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU_ACTIVE)) | 2775 | mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU_ACTIVE)) |
2823 | reg |= GLOBAL_CONTROL_PPU_ENABLE; | 2776 | reg |= GLOBAL_CONTROL_PPU_ENABLE; |
2824 | 2777 | ||
2825 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_CONTROL, reg); | 2778 | err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL, reg); |
2826 | if (err) | 2779 | if (err) |
2827 | return err; | 2780 | return err; |
2828 | 2781 | ||
@@ -2832,15 +2785,14 @@ static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip) | |||
2832 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | | 2785 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | |
2833 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | | 2786 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | |
2834 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; | 2787 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; |
2835 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, | 2788 | err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg); |
2836 | reg); | ||
2837 | if (err) | 2789 | if (err) |
2838 | return err; | 2790 | return err; |
2839 | 2791 | ||
2840 | /* Disable remote management, and set the switch's DSA device number. */ | 2792 | /* Disable remote management, and set the switch's DSA device number. */ |
2841 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_CONTROL_2, | 2793 | err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL_2, |
2842 | GLOBAL_CONTROL_2_MULTIPLE_CASCADE | | 2794 | GLOBAL_CONTROL_2_MULTIPLE_CASCADE | |
2843 | (ds->index & 0x1f)); | 2795 | (ds->index & 0x1f)); |
2844 | if (err) | 2796 | if (err) |
2845 | return err; | 2797 | return err; |
2846 | 2798 | ||
@@ -2853,8 +2805,8 @@ static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip) | |||
2853 | * enable address learn messages to be sent to all message | 2805 | * enable address learn messages to be sent to all message |
2854 | * ports. | 2806 | * ports. |
2855 | */ | 2807 | */ |
2856 | err = mv88e6xxx_write(chip, REG_GLOBAL, GLOBAL_ATU_CONTROL, | 2808 | err = mv88e6xxx_g1_write(chip, GLOBAL_ATU_CONTROL, |
2857 | GLOBAL_ATU_CONTROL_LEARN2ALL); | 2809 | GLOBAL_ATU_CONTROL_LEARN2ALL); |
2858 | if (err) | 2810 | if (err) |
2859 | return err; | 2811 | return err; |
2860 | 2812 | ||
@@ -2868,39 +2820,39 @@ static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip) | |||
2868 | return err; | 2820 | return err; |
2869 | 2821 | ||
2870 | /* Configure the IP ToS mapping registers. */ | 2822 | /* Configure the IP ToS mapping registers. */ |
2871 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000); | 2823 | err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_0, 0x0000); |
2872 | if (err) | 2824 | if (err) |
2873 | return err; | 2825 | return err; |
2874 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000); | 2826 | err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_1, 0x0000); |
2875 | if (err) | 2827 | if (err) |
2876 | return err; | 2828 | return err; |
2877 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555); | 2829 | err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_2, 0x5555); |
2878 | if (err) | 2830 | if (err) |
2879 | return err; | 2831 | return err; |
2880 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555); | 2832 | err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_3, 0x5555); |
2881 | if (err) | 2833 | if (err) |
2882 | return err; | 2834 | return err; |
2883 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa); | 2835 | err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_4, 0xaaaa); |
2884 | if (err) | 2836 | if (err) |
2885 | return err; | 2837 | return err; |
2886 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa); | 2838 | err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_5, 0xaaaa); |
2887 | if (err) | 2839 | if (err) |
2888 | return err; | 2840 | return err; |
2889 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff); | 2841 | err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_6, 0xffff); |
2890 | if (err) | 2842 | if (err) |
2891 | return err; | 2843 | return err; |
2892 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff); | 2844 | err = mv88e6xxx_g1_write(chip, GLOBAL_IP_PRI_7, 0xffff); |
2893 | if (err) | 2845 | if (err) |
2894 | return err; | 2846 | return err; |
2895 | 2847 | ||
2896 | /* Configure the IEEE 802.1p priority mapping register. */ | 2848 | /* Configure the IEEE 802.1p priority mapping register. */ |
2897 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41); | 2849 | err = mv88e6xxx_g1_write(chip, GLOBAL_IEEE_PRI, 0xfa41); |
2898 | if (err) | 2850 | if (err) |
2899 | return err; | 2851 | return err; |
2900 | 2852 | ||
2901 | /* Clear the statistics counters for all ports */ | 2853 | /* Clear the statistics counters for all ports */ |
2902 | err = _mv88e6xxx_reg_write(chip, REG_GLOBAL, GLOBAL_STATS_OP, | 2854 | err = mv88e6xxx_g1_write(chip, GLOBAL_STATS_OP, |
2903 | GLOBAL_STATS_OP_FLUSH_ALL); | 2855 | GLOBAL_STATS_OP_FLUSH_ALL); |
2904 | if (err) | 2856 | if (err) |
2905 | return err; | 2857 | return err; |
2906 | 2858 | ||
@@ -2928,7 +2880,7 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) | |||
2928 | goto unlock; | 2880 | goto unlock; |
2929 | 2881 | ||
2930 | /* Setup Switch Port Registers */ | 2882 | /* Setup Switch Port Registers */ |
2931 | for (i = 0; i < chip->info->num_ports; i++) { | 2883 | for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { |
2932 | err = mv88e6xxx_setup_port(chip, i); | 2884 | err = mv88e6xxx_setup_port(chip, i); |
2933 | if (err) | 2885 | if (err) |
2934 | goto unlock; | 2886 | goto unlock; |
@@ -2957,14 +2909,11 @@ static int mv88e6xxx_set_addr(struct dsa_switch *ds, u8 *addr) | |||
2957 | struct mv88e6xxx_chip *chip = ds->priv; | 2909 | struct mv88e6xxx_chip *chip = ds->priv; |
2958 | int err; | 2910 | int err; |
2959 | 2911 | ||
2960 | mutex_lock(&chip->reg_lock); | 2912 | if (!chip->info->ops->set_switch_mac) |
2961 | 2913 | return -EOPNOTSUPP; | |
2962 | /* Has an indirect Switch MAC/WoL/WoF register in Global 2? */ | ||
2963 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_SWITCH_MAC)) | ||
2964 | err = mv88e6xxx_g2_set_switch_mac(chip, addr); | ||
2965 | else | ||
2966 | err = mv88e6xxx_g1_set_switch_mac(chip, addr); | ||
2967 | 2914 | ||
2915 | mutex_lock(&chip->reg_lock); | ||
2916 | err = chip->info->ops->set_switch_mac(chip, addr); | ||
2968 | mutex_unlock(&chip->reg_lock); | 2917 | mutex_unlock(&chip->reg_lock); |
2969 | 2918 | ||
2970 | return err; | 2919 | return err; |
@@ -2976,7 +2925,7 @@ static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg) | |||
2976 | u16 val; | 2925 | u16 val; |
2977 | int err; | 2926 | int err; |
2978 | 2927 | ||
2979 | if (phy >= chip->info->num_ports) | 2928 | if (phy >= mv88e6xxx_num_ports(chip)) |
2980 | return 0xffff; | 2929 | return 0xffff; |
2981 | 2930 | ||
2982 | mutex_lock(&chip->reg_lock); | 2931 | mutex_lock(&chip->reg_lock); |
@@ -2991,7 +2940,7 @@ static int mv88e6xxx_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) | |||
2991 | struct mv88e6xxx_chip *chip = bus->priv; | 2940 | struct mv88e6xxx_chip *chip = bus->priv; |
2992 | int err; | 2941 | int err; |
2993 | 2942 | ||
2994 | if (phy >= chip->info->num_ports) | 2943 | if (phy >= mv88e6xxx_num_ports(chip)) |
2995 | return 0xffff; | 2944 | return 0xffff; |
2996 | 2945 | ||
2997 | mutex_lock(&chip->reg_lock); | 2946 | mutex_lock(&chip->reg_lock); |
@@ -3219,13 +3168,11 @@ static int mv88e6xxx_get_eeprom(struct dsa_switch *ds, | |||
3219 | struct mv88e6xxx_chip *chip = ds->priv; | 3168 | struct mv88e6xxx_chip *chip = ds->priv; |
3220 | int err; | 3169 | int err; |
3221 | 3170 | ||
3222 | mutex_lock(&chip->reg_lock); | 3171 | if (!chip->info->ops->get_eeprom) |
3223 | 3172 | return -EOPNOTSUPP; | |
3224 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_EEPROM16)) | ||
3225 | err = mv88e6xxx_g2_get_eeprom16(chip, eeprom, data); | ||
3226 | else | ||
3227 | err = -EOPNOTSUPP; | ||
3228 | 3173 | ||
3174 | mutex_lock(&chip->reg_lock); | ||
3175 | err = chip->info->ops->get_eeprom(chip, eeprom, data); | ||
3229 | mutex_unlock(&chip->reg_lock); | 3176 | mutex_unlock(&chip->reg_lock); |
3230 | 3177 | ||
3231 | if (err) | 3178 | if (err) |
@@ -3242,21 +3189,133 @@ static int mv88e6xxx_set_eeprom(struct dsa_switch *ds, | |||
3242 | struct mv88e6xxx_chip *chip = ds->priv; | 3189 | struct mv88e6xxx_chip *chip = ds->priv; |
3243 | int err; | 3190 | int err; |
3244 | 3191 | ||
3192 | if (!chip->info->ops->set_eeprom) | ||
3193 | return -EOPNOTSUPP; | ||
3194 | |||
3245 | if (eeprom->magic != 0xc3ec4951) | 3195 | if (eeprom->magic != 0xc3ec4951) |
3246 | return -EINVAL; | 3196 | return -EINVAL; |
3247 | 3197 | ||
3248 | mutex_lock(&chip->reg_lock); | 3198 | mutex_lock(&chip->reg_lock); |
3249 | 3199 | err = chip->info->ops->set_eeprom(chip, eeprom, data); | |
3250 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_EEPROM16)) | ||
3251 | err = mv88e6xxx_g2_set_eeprom16(chip, eeprom, data); | ||
3252 | else | ||
3253 | err = -EOPNOTSUPP; | ||
3254 | |||
3255 | mutex_unlock(&chip->reg_lock); | 3200 | mutex_unlock(&chip->reg_lock); |
3256 | 3201 | ||
3257 | return err; | 3202 | return err; |
3258 | } | 3203 | } |
3259 | 3204 | ||
3205 | static const struct mv88e6xxx_ops mv88e6085_ops = { | ||
3206 | .set_switch_mac = mv88e6xxx_g1_set_switch_mac, | ||
3207 | .phy_read = mv88e6xxx_phy_ppu_read, | ||
3208 | .phy_write = mv88e6xxx_phy_ppu_write, | ||
3209 | }; | ||
3210 | |||
3211 | static const struct mv88e6xxx_ops mv88e6095_ops = { | ||
3212 | .set_switch_mac = mv88e6xxx_g1_set_switch_mac, | ||
3213 | .phy_read = mv88e6xxx_phy_ppu_read, | ||
3214 | .phy_write = mv88e6xxx_phy_ppu_write, | ||
3215 | }; | ||
3216 | |||
3217 | static const struct mv88e6xxx_ops mv88e6123_ops = { | ||
3218 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3219 | .phy_read = mv88e6xxx_read, | ||
3220 | .phy_write = mv88e6xxx_write, | ||
3221 | }; | ||
3222 | |||
3223 | static const struct mv88e6xxx_ops mv88e6131_ops = { | ||
3224 | .set_switch_mac = mv88e6xxx_g1_set_switch_mac, | ||
3225 | .phy_read = mv88e6xxx_phy_ppu_read, | ||
3226 | .phy_write = mv88e6xxx_phy_ppu_write, | ||
3227 | }; | ||
3228 | |||
3229 | static const struct mv88e6xxx_ops mv88e6161_ops = { | ||
3230 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3231 | .phy_read = mv88e6xxx_read, | ||
3232 | .phy_write = mv88e6xxx_write, | ||
3233 | }; | ||
3234 | |||
3235 | static const struct mv88e6xxx_ops mv88e6165_ops = { | ||
3236 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3237 | .phy_read = mv88e6xxx_read, | ||
3238 | .phy_write = mv88e6xxx_write, | ||
3239 | }; | ||
3240 | |||
3241 | static const struct mv88e6xxx_ops mv88e6171_ops = { | ||
3242 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3243 | .phy_read = mv88e6xxx_g2_smi_phy_read, | ||
3244 | .phy_write = mv88e6xxx_g2_smi_phy_write, | ||
3245 | }; | ||
3246 | |||
3247 | static const struct mv88e6xxx_ops mv88e6172_ops = { | ||
3248 | .get_eeprom = mv88e6xxx_g2_get_eeprom16, | ||
3249 | .set_eeprom = mv88e6xxx_g2_set_eeprom16, | ||
3250 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3251 | .phy_read = mv88e6xxx_g2_smi_phy_read, | ||
3252 | .phy_write = mv88e6xxx_g2_smi_phy_write, | ||
3253 | }; | ||
3254 | |||
3255 | static const struct mv88e6xxx_ops mv88e6175_ops = { | ||
3256 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3257 | .phy_read = mv88e6xxx_g2_smi_phy_read, | ||
3258 | .phy_write = mv88e6xxx_g2_smi_phy_write, | ||
3259 | }; | ||
3260 | |||
3261 | static const struct mv88e6xxx_ops mv88e6176_ops = { | ||
3262 | .get_eeprom = mv88e6xxx_g2_get_eeprom16, | ||
3263 | .set_eeprom = mv88e6xxx_g2_set_eeprom16, | ||
3264 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3265 | .phy_read = mv88e6xxx_g2_smi_phy_read, | ||
3266 | .phy_write = mv88e6xxx_g2_smi_phy_write, | ||
3267 | }; | ||
3268 | |||
3269 | static const struct mv88e6xxx_ops mv88e6185_ops = { | ||
3270 | .set_switch_mac = mv88e6xxx_g1_set_switch_mac, | ||
3271 | .phy_read = mv88e6xxx_phy_ppu_read, | ||
3272 | .phy_write = mv88e6xxx_phy_ppu_write, | ||
3273 | }; | ||
3274 | |||
3275 | static const struct mv88e6xxx_ops mv88e6240_ops = { | ||
3276 | .get_eeprom = mv88e6xxx_g2_get_eeprom16, | ||
3277 | .set_eeprom = mv88e6xxx_g2_set_eeprom16, | ||
3278 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3279 | .phy_read = mv88e6xxx_g2_smi_phy_read, | ||
3280 | .phy_write = mv88e6xxx_g2_smi_phy_write, | ||
3281 | }; | ||
3282 | |||
3283 | static const struct mv88e6xxx_ops mv88e6320_ops = { | ||
3284 | .get_eeprom = mv88e6xxx_g2_get_eeprom16, | ||
3285 | .set_eeprom = mv88e6xxx_g2_set_eeprom16, | ||
3286 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3287 | .phy_read = mv88e6xxx_g2_smi_phy_read, | ||
3288 | .phy_write = mv88e6xxx_g2_smi_phy_write, | ||
3289 | }; | ||
3290 | |||
3291 | static const struct mv88e6xxx_ops mv88e6321_ops = { | ||
3292 | .get_eeprom = mv88e6xxx_g2_get_eeprom16, | ||
3293 | .set_eeprom = mv88e6xxx_g2_set_eeprom16, | ||
3294 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3295 | .phy_read = mv88e6xxx_g2_smi_phy_read, | ||
3296 | .phy_write = mv88e6xxx_g2_smi_phy_write, | ||
3297 | }; | ||
3298 | |||
3299 | static const struct mv88e6xxx_ops mv88e6350_ops = { | ||
3300 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3301 | .phy_read = mv88e6xxx_g2_smi_phy_read, | ||
3302 | .phy_write = mv88e6xxx_g2_smi_phy_write, | ||
3303 | }; | ||
3304 | |||
3305 | static const struct mv88e6xxx_ops mv88e6351_ops = { | ||
3306 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3307 | .phy_read = mv88e6xxx_g2_smi_phy_read, | ||
3308 | .phy_write = mv88e6xxx_g2_smi_phy_write, | ||
3309 | }; | ||
3310 | |||
3311 | static const struct mv88e6xxx_ops mv88e6352_ops = { | ||
3312 | .get_eeprom = mv88e6xxx_g2_get_eeprom16, | ||
3313 | .set_eeprom = mv88e6xxx_g2_set_eeprom16, | ||
3314 | .set_switch_mac = mv88e6xxx_g2_set_switch_mac, | ||
3315 | .phy_read = mv88e6xxx_g2_smi_phy_read, | ||
3316 | .phy_write = mv88e6xxx_g2_smi_phy_write, | ||
3317 | }; | ||
3318 | |||
3260 | static const struct mv88e6xxx_info mv88e6xxx_table[] = { | 3319 | static const struct mv88e6xxx_info mv88e6xxx_table[] = { |
3261 | [MV88E6085] = { | 3320 | [MV88E6085] = { |
3262 | .prod_num = PORT_SWITCH_ID_PROD_NUM_6085, | 3321 | .prod_num = PORT_SWITCH_ID_PROD_NUM_6085, |
@@ -3265,8 +3324,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3265 | .num_databases = 4096, | 3324 | .num_databases = 4096, |
3266 | .num_ports = 10, | 3325 | .num_ports = 10, |
3267 | .port_base_addr = 0x10, | 3326 | .port_base_addr = 0x10, |
3327 | .global1_addr = 0x1b, | ||
3268 | .age_time_coeff = 15000, | 3328 | .age_time_coeff = 15000, |
3269 | .flags = MV88E6XXX_FLAGS_FAMILY_6097, | 3329 | .flags = MV88E6XXX_FLAGS_FAMILY_6097, |
3330 | .ops = &mv88e6085_ops, | ||
3270 | }, | 3331 | }, |
3271 | 3332 | ||
3272 | [MV88E6095] = { | 3333 | [MV88E6095] = { |
@@ -3276,8 +3337,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3276 | .num_databases = 256, | 3337 | .num_databases = 256, |
3277 | .num_ports = 11, | 3338 | .num_ports = 11, |
3278 | .port_base_addr = 0x10, | 3339 | .port_base_addr = 0x10, |
3340 | .global1_addr = 0x1b, | ||
3279 | .age_time_coeff = 15000, | 3341 | .age_time_coeff = 15000, |
3280 | .flags = MV88E6XXX_FLAGS_FAMILY_6095, | 3342 | .flags = MV88E6XXX_FLAGS_FAMILY_6095, |
3343 | .ops = &mv88e6095_ops, | ||
3281 | }, | 3344 | }, |
3282 | 3345 | ||
3283 | [MV88E6123] = { | 3346 | [MV88E6123] = { |
@@ -3287,8 +3350,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3287 | .num_databases = 4096, | 3350 | .num_databases = 4096, |
3288 | .num_ports = 3, | 3351 | .num_ports = 3, |
3289 | .port_base_addr = 0x10, | 3352 | .port_base_addr = 0x10, |
3353 | .global1_addr = 0x1b, | ||
3290 | .age_time_coeff = 15000, | 3354 | .age_time_coeff = 15000, |
3291 | .flags = MV88E6XXX_FLAGS_FAMILY_6165, | 3355 | .flags = MV88E6XXX_FLAGS_FAMILY_6165, |
3356 | .ops = &mv88e6123_ops, | ||
3292 | }, | 3357 | }, |
3293 | 3358 | ||
3294 | [MV88E6131] = { | 3359 | [MV88E6131] = { |
@@ -3298,8 +3363,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3298 | .num_databases = 256, | 3363 | .num_databases = 256, |
3299 | .num_ports = 8, | 3364 | .num_ports = 8, |
3300 | .port_base_addr = 0x10, | 3365 | .port_base_addr = 0x10, |
3366 | .global1_addr = 0x1b, | ||
3301 | .age_time_coeff = 15000, | 3367 | .age_time_coeff = 15000, |
3302 | .flags = MV88E6XXX_FLAGS_FAMILY_6185, | 3368 | .flags = MV88E6XXX_FLAGS_FAMILY_6185, |
3369 | .ops = &mv88e6131_ops, | ||
3303 | }, | 3370 | }, |
3304 | 3371 | ||
3305 | [MV88E6161] = { | 3372 | [MV88E6161] = { |
@@ -3309,8 +3376,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3309 | .num_databases = 4096, | 3376 | .num_databases = 4096, |
3310 | .num_ports = 6, | 3377 | .num_ports = 6, |
3311 | .port_base_addr = 0x10, | 3378 | .port_base_addr = 0x10, |
3379 | .global1_addr = 0x1b, | ||
3312 | .age_time_coeff = 15000, | 3380 | .age_time_coeff = 15000, |
3313 | .flags = MV88E6XXX_FLAGS_FAMILY_6165, | 3381 | .flags = MV88E6XXX_FLAGS_FAMILY_6165, |
3382 | .ops = &mv88e6161_ops, | ||
3314 | }, | 3383 | }, |
3315 | 3384 | ||
3316 | [MV88E6165] = { | 3385 | [MV88E6165] = { |
@@ -3320,8 +3389,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3320 | .num_databases = 4096, | 3389 | .num_databases = 4096, |
3321 | .num_ports = 6, | 3390 | .num_ports = 6, |
3322 | .port_base_addr = 0x10, | 3391 | .port_base_addr = 0x10, |
3392 | .global1_addr = 0x1b, | ||
3323 | .age_time_coeff = 15000, | 3393 | .age_time_coeff = 15000, |
3324 | .flags = MV88E6XXX_FLAGS_FAMILY_6165, | 3394 | .flags = MV88E6XXX_FLAGS_FAMILY_6165, |
3395 | .ops = &mv88e6165_ops, | ||
3325 | }, | 3396 | }, |
3326 | 3397 | ||
3327 | [MV88E6171] = { | 3398 | [MV88E6171] = { |
@@ -3331,8 +3402,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3331 | .num_databases = 4096, | 3402 | .num_databases = 4096, |
3332 | .num_ports = 7, | 3403 | .num_ports = 7, |
3333 | .port_base_addr = 0x10, | 3404 | .port_base_addr = 0x10, |
3405 | .global1_addr = 0x1b, | ||
3334 | .age_time_coeff = 15000, | 3406 | .age_time_coeff = 15000, |
3335 | .flags = MV88E6XXX_FLAGS_FAMILY_6351, | 3407 | .flags = MV88E6XXX_FLAGS_FAMILY_6351, |
3408 | .ops = &mv88e6171_ops, | ||
3336 | }, | 3409 | }, |
3337 | 3410 | ||
3338 | [MV88E6172] = { | 3411 | [MV88E6172] = { |
@@ -3342,8 +3415,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3342 | .num_databases = 4096, | 3415 | .num_databases = 4096, |
3343 | .num_ports = 7, | 3416 | .num_ports = 7, |
3344 | .port_base_addr = 0x10, | 3417 | .port_base_addr = 0x10, |
3418 | .global1_addr = 0x1b, | ||
3345 | .age_time_coeff = 15000, | 3419 | .age_time_coeff = 15000, |
3346 | .flags = MV88E6XXX_FLAGS_FAMILY_6352, | 3420 | .flags = MV88E6XXX_FLAGS_FAMILY_6352, |
3421 | .ops = &mv88e6172_ops, | ||
3347 | }, | 3422 | }, |
3348 | 3423 | ||
3349 | [MV88E6175] = { | 3424 | [MV88E6175] = { |
@@ -3353,8 +3428,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3353 | .num_databases = 4096, | 3428 | .num_databases = 4096, |
3354 | .num_ports = 7, | 3429 | .num_ports = 7, |
3355 | .port_base_addr = 0x10, | 3430 | .port_base_addr = 0x10, |
3431 | .global1_addr = 0x1b, | ||
3356 | .age_time_coeff = 15000, | 3432 | .age_time_coeff = 15000, |
3357 | .flags = MV88E6XXX_FLAGS_FAMILY_6351, | 3433 | .flags = MV88E6XXX_FLAGS_FAMILY_6351, |
3434 | .ops = &mv88e6175_ops, | ||
3358 | }, | 3435 | }, |
3359 | 3436 | ||
3360 | [MV88E6176] = { | 3437 | [MV88E6176] = { |
@@ -3364,8 +3441,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3364 | .num_databases = 4096, | 3441 | .num_databases = 4096, |
3365 | .num_ports = 7, | 3442 | .num_ports = 7, |
3366 | .port_base_addr = 0x10, | 3443 | .port_base_addr = 0x10, |
3444 | .global1_addr = 0x1b, | ||
3367 | .age_time_coeff = 15000, | 3445 | .age_time_coeff = 15000, |
3368 | .flags = MV88E6XXX_FLAGS_FAMILY_6352, | 3446 | .flags = MV88E6XXX_FLAGS_FAMILY_6352, |
3447 | .ops = &mv88e6176_ops, | ||
3369 | }, | 3448 | }, |
3370 | 3449 | ||
3371 | [MV88E6185] = { | 3450 | [MV88E6185] = { |
@@ -3375,8 +3454,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3375 | .num_databases = 256, | 3454 | .num_databases = 256, |
3376 | .num_ports = 10, | 3455 | .num_ports = 10, |
3377 | .port_base_addr = 0x10, | 3456 | .port_base_addr = 0x10, |
3457 | .global1_addr = 0x1b, | ||
3378 | .age_time_coeff = 15000, | 3458 | .age_time_coeff = 15000, |
3379 | .flags = MV88E6XXX_FLAGS_FAMILY_6185, | 3459 | .flags = MV88E6XXX_FLAGS_FAMILY_6185, |
3460 | .ops = &mv88e6185_ops, | ||
3380 | }, | 3461 | }, |
3381 | 3462 | ||
3382 | [MV88E6240] = { | 3463 | [MV88E6240] = { |
@@ -3386,8 +3467,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3386 | .num_databases = 4096, | 3467 | .num_databases = 4096, |
3387 | .num_ports = 7, | 3468 | .num_ports = 7, |
3388 | .port_base_addr = 0x10, | 3469 | .port_base_addr = 0x10, |
3470 | .global1_addr = 0x1b, | ||
3389 | .age_time_coeff = 15000, | 3471 | .age_time_coeff = 15000, |
3390 | .flags = MV88E6XXX_FLAGS_FAMILY_6352, | 3472 | .flags = MV88E6XXX_FLAGS_FAMILY_6352, |
3473 | .ops = &mv88e6240_ops, | ||
3391 | }, | 3474 | }, |
3392 | 3475 | ||
3393 | [MV88E6320] = { | 3476 | [MV88E6320] = { |
@@ -3397,8 +3480,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3397 | .num_databases = 4096, | 3480 | .num_databases = 4096, |
3398 | .num_ports = 7, | 3481 | .num_ports = 7, |
3399 | .port_base_addr = 0x10, | 3482 | .port_base_addr = 0x10, |
3483 | .global1_addr = 0x1b, | ||
3400 | .age_time_coeff = 15000, | 3484 | .age_time_coeff = 15000, |
3401 | .flags = MV88E6XXX_FLAGS_FAMILY_6320, | 3485 | .flags = MV88E6XXX_FLAGS_FAMILY_6320, |
3486 | .ops = &mv88e6320_ops, | ||
3402 | }, | 3487 | }, |
3403 | 3488 | ||
3404 | [MV88E6321] = { | 3489 | [MV88E6321] = { |
@@ -3408,8 +3493,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3408 | .num_databases = 4096, | 3493 | .num_databases = 4096, |
3409 | .num_ports = 7, | 3494 | .num_ports = 7, |
3410 | .port_base_addr = 0x10, | 3495 | .port_base_addr = 0x10, |
3496 | .global1_addr = 0x1b, | ||
3411 | .age_time_coeff = 15000, | 3497 | .age_time_coeff = 15000, |
3412 | .flags = MV88E6XXX_FLAGS_FAMILY_6320, | 3498 | .flags = MV88E6XXX_FLAGS_FAMILY_6320, |
3499 | .ops = &mv88e6321_ops, | ||
3413 | }, | 3500 | }, |
3414 | 3501 | ||
3415 | [MV88E6350] = { | 3502 | [MV88E6350] = { |
@@ -3419,8 +3506,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3419 | .num_databases = 4096, | 3506 | .num_databases = 4096, |
3420 | .num_ports = 7, | 3507 | .num_ports = 7, |
3421 | .port_base_addr = 0x10, | 3508 | .port_base_addr = 0x10, |
3509 | .global1_addr = 0x1b, | ||
3422 | .age_time_coeff = 15000, | 3510 | .age_time_coeff = 15000, |
3423 | .flags = MV88E6XXX_FLAGS_FAMILY_6351, | 3511 | .flags = MV88E6XXX_FLAGS_FAMILY_6351, |
3512 | .ops = &mv88e6350_ops, | ||
3424 | }, | 3513 | }, |
3425 | 3514 | ||
3426 | [MV88E6351] = { | 3515 | [MV88E6351] = { |
@@ -3430,8 +3519,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3430 | .num_databases = 4096, | 3519 | .num_databases = 4096, |
3431 | .num_ports = 7, | 3520 | .num_ports = 7, |
3432 | .port_base_addr = 0x10, | 3521 | .port_base_addr = 0x10, |
3522 | .global1_addr = 0x1b, | ||
3433 | .age_time_coeff = 15000, | 3523 | .age_time_coeff = 15000, |
3434 | .flags = MV88E6XXX_FLAGS_FAMILY_6351, | 3524 | .flags = MV88E6XXX_FLAGS_FAMILY_6351, |
3525 | .ops = &mv88e6351_ops, | ||
3435 | }, | 3526 | }, |
3436 | 3527 | ||
3437 | [MV88E6352] = { | 3528 | [MV88E6352] = { |
@@ -3441,8 +3532,10 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { | |||
3441 | .num_databases = 4096, | 3532 | .num_databases = 4096, |
3442 | .num_ports = 7, | 3533 | .num_ports = 7, |
3443 | .port_base_addr = 0x10, | 3534 | .port_base_addr = 0x10, |
3535 | .global1_addr = 0x1b, | ||
3444 | .age_time_coeff = 15000, | 3536 | .age_time_coeff = 15000, |
3445 | .flags = MV88E6XXX_FLAGS_FAMILY_6352, | 3537 | .flags = MV88E6XXX_FLAGS_FAMILY_6352, |
3538 | .ops = &mv88e6352_ops, | ||
3446 | }, | 3539 | }, |
3447 | }; | 3540 | }; |
3448 | 3541 | ||
@@ -3505,33 +3598,16 @@ static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev) | |||
3505 | return chip; | 3598 | return chip; |
3506 | } | 3599 | } |
3507 | 3600 | ||
3508 | static const struct mv88e6xxx_ops mv88e6xxx_g2_smi_phy_ops = { | ||
3509 | .read = mv88e6xxx_g2_smi_phy_read, | ||
3510 | .write = mv88e6xxx_g2_smi_phy_write, | ||
3511 | }; | ||
3512 | |||
3513 | static const struct mv88e6xxx_ops mv88e6xxx_phy_ops = { | ||
3514 | .read = mv88e6xxx_read, | ||
3515 | .write = mv88e6xxx_write, | ||
3516 | }; | ||
3517 | |||
3518 | static void mv88e6xxx_phy_init(struct mv88e6xxx_chip *chip) | 3601 | static void mv88e6xxx_phy_init(struct mv88e6xxx_chip *chip) |
3519 | { | 3602 | { |
3520 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_SMI_PHY)) { | 3603 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU)) |
3521 | chip->phy_ops = &mv88e6xxx_g2_smi_phy_ops; | ||
3522 | } else if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU)) { | ||
3523 | chip->phy_ops = &mv88e6xxx_phy_ppu_ops; | ||
3524 | mv88e6xxx_ppu_state_init(chip); | 3604 | mv88e6xxx_ppu_state_init(chip); |
3525 | } else { | ||
3526 | chip->phy_ops = &mv88e6xxx_phy_ops; | ||
3527 | } | ||
3528 | } | 3605 | } |
3529 | 3606 | ||
3530 | static void mv88e6xxx_phy_destroy(struct mv88e6xxx_chip *chip) | 3607 | static void mv88e6xxx_phy_destroy(struct mv88e6xxx_chip *chip) |
3531 | { | 3608 | { |
3532 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU)) { | 3609 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_PPU)) |
3533 | mv88e6xxx_ppu_state_destroy(chip); | 3610 | mv88e6xxx_ppu_state_destroy(chip); |
3534 | } | ||
3535 | } | 3611 | } |
3536 | 3612 | ||
3537 | static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip, | 3613 | static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip, |
@@ -3757,7 +3833,7 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev) | |||
3757 | if (IS_ERR(chip->reset)) | 3833 | if (IS_ERR(chip->reset)) |
3758 | return PTR_ERR(chip->reset); | 3834 | return PTR_ERR(chip->reset); |
3759 | 3835 | ||
3760 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_EEPROM16) && | 3836 | if (chip->info->ops->get_eeprom && |
3761 | !of_property_read_u32(np, "eeprom-length", &eeprom_len)) | 3837 | !of_property_read_u32(np, "eeprom-length", &eeprom_len)) |
3762 | chip->eeprom_len = eeprom_len; | 3838 | chip->eeprom_len = eeprom_len; |
3763 | 3839 | ||
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c new file mode 100644 index 000000000000..d358720b6c2d --- /dev/null +++ b/drivers/net/dsa/mv88e6xxx/global1.c | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Marvell 88E6xxx Switch Global (1) Registers support | ||
3 | * | ||
4 | * Copyright (c) 2008 Marvell Semiconductor | ||
5 | * | ||
6 | * Copyright (c) 2016 Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include "mv88e6xxx.h" | ||
15 | #include "global1.h" | ||
16 | |||
17 | int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val) | ||
18 | { | ||
19 | int addr = chip->info->global1_addr; | ||
20 | |||
21 | return mv88e6xxx_read(chip, addr, reg, val); | ||
22 | } | ||
23 | |||
24 | int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val) | ||
25 | { | ||
26 | int addr = chip->info->global1_addr; | ||
27 | |||
28 | return mv88e6xxx_write(chip, addr, reg, val); | ||
29 | } | ||
30 | |||
31 | int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask) | ||
32 | { | ||
33 | return mv88e6xxx_wait(chip, chip->info->global1_addr, reg, mask); | ||
34 | } | ||
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h new file mode 100644 index 000000000000..62291e6fe3a3 --- /dev/null +++ b/drivers/net/dsa/mv88e6xxx/global1.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * Marvell 88E6xxx Switch Global (1) Registers support | ||
3 | * | ||
4 | * Copyright (c) 2008 Marvell Semiconductor | ||
5 | * | ||
6 | * Copyright (c) 2016 Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #ifndef _MV88E6XXX_GLOBAL1_H | ||
15 | #define _MV88E6XXX_GLOBAL1_H | ||
16 | |||
17 | #include "mv88e6xxx.h" | ||
18 | |||
19 | int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val); | ||
20 | int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val); | ||
21 | int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask); | ||
22 | |||
23 | #endif /* _MV88E6XXX_GLOBAL1_H */ | ||
diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c index 99ed028298ac..cf686e7506a9 100644 --- a/drivers/net/dsa/mv88e6xxx/global2.c +++ b/drivers/net/dsa/mv88e6xxx/global2.c | |||
@@ -14,6 +14,28 @@ | |||
14 | #include "mv88e6xxx.h" | 14 | #include "mv88e6xxx.h" |
15 | #include "global2.h" | 15 | #include "global2.h" |
16 | 16 | ||
17 | #define ADDR_GLOBAL2 0x1c | ||
18 | |||
19 | static int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val) | ||
20 | { | ||
21 | return mv88e6xxx_read(chip, ADDR_GLOBAL2, reg, val); | ||
22 | } | ||
23 | |||
24 | static int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val) | ||
25 | { | ||
26 | return mv88e6xxx_write(chip, ADDR_GLOBAL2, reg, val); | ||
27 | } | ||
28 | |||
29 | static int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update) | ||
30 | { | ||
31 | return mv88e6xxx_update(chip, ADDR_GLOBAL2, reg, update); | ||
32 | } | ||
33 | |||
34 | static int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask) | ||
35 | { | ||
36 | return mv88e6xxx_wait(chip, ADDR_GLOBAL2, reg, mask); | ||
37 | } | ||
38 | |||
17 | /* Offset 0x06: Device Mapping Table register */ | 39 | /* Offset 0x06: Device Mapping Table register */ |
18 | 40 | ||
19 | static int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, | 41 | static int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, |
@@ -21,7 +43,7 @@ static int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, | |||
21 | { | 43 | { |
22 | u16 val = (target << 8) | (port & 0xf); | 44 | u16 val = (target << 8) | (port & 0xf); |
23 | 45 | ||
24 | return mv88e6xxx_update(chip, REG_GLOBAL2, GLOBAL2_DEVICE_MAPPING, val); | 46 | return mv88e6xxx_g2_update(chip, GLOBAL2_DEVICE_MAPPING, val); |
25 | } | 47 | } |
26 | 48 | ||
27 | static int mv88e6xxx_g2_set_device_mapping(struct mv88e6xxx_chip *chip) | 49 | static int mv88e6xxx_g2_set_device_mapping(struct mv88e6xxx_chip *chip) |
@@ -52,13 +74,13 @@ static int mv88e6xxx_g2_set_device_mapping(struct mv88e6xxx_chip *chip) | |||
52 | static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num, | 74 | static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num, |
53 | bool hask, u16 mask) | 75 | bool hask, u16 mask) |
54 | { | 76 | { |
55 | const u16 port_mask = BIT(chip->info->num_ports) - 1; | 77 | const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1; |
56 | u16 val = (num << 12) | (mask & port_mask); | 78 | u16 val = (num << 12) | (mask & port_mask); |
57 | 79 | ||
58 | if (hask) | 80 | if (hask) |
59 | val |= GLOBAL2_TRUNK_MASK_HASK; | 81 | val |= GLOBAL2_TRUNK_MASK_HASK; |
60 | 82 | ||
61 | return mv88e6xxx_update(chip, REG_GLOBAL2, GLOBAL2_TRUNK_MASK, val); | 83 | return mv88e6xxx_g2_update(chip, GLOBAL2_TRUNK_MASK, val); |
62 | } | 84 | } |
63 | 85 | ||
64 | /* Offset 0x08: Trunk Mapping Table register */ | 86 | /* Offset 0x08: Trunk Mapping Table register */ |
@@ -66,15 +88,15 @@ static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num, | |||
66 | static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id, | 88 | static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id, |
67 | u16 map) | 89 | u16 map) |
68 | { | 90 | { |
69 | const u16 port_mask = BIT(chip->info->num_ports) - 1; | 91 | const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1; |
70 | u16 val = (id << 11) | (map & port_mask); | 92 | u16 val = (id << 11) | (map & port_mask); |
71 | 93 | ||
72 | return mv88e6xxx_update(chip, REG_GLOBAL2, GLOBAL2_TRUNK_MAPPING, val); | 94 | return mv88e6xxx_g2_update(chip, GLOBAL2_TRUNK_MAPPING, val); |
73 | } | 95 | } |
74 | 96 | ||
75 | static int mv88e6xxx_g2_clear_trunk(struct mv88e6xxx_chip *chip) | 97 | static int mv88e6xxx_g2_clear_trunk(struct mv88e6xxx_chip *chip) |
76 | { | 98 | { |
77 | const u16 port_mask = BIT(chip->info->num_ports) - 1; | 99 | const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1; |
78 | int i, err; | 100 | int i, err; |
79 | 101 | ||
80 | /* Clear all eight possible Trunk Mask vectors */ | 102 | /* Clear all eight possible Trunk Mask vectors */ |
@@ -103,17 +125,17 @@ static int mv88e6xxx_g2_clear_irl(struct mv88e6xxx_chip *chip) | |||
103 | int port, err; | 125 | int port, err; |
104 | 126 | ||
105 | /* Init all Ingress Rate Limit resources of all ports */ | 127 | /* Init all Ingress Rate Limit resources of all ports */ |
106 | for (port = 0; port < chip->info->num_ports; ++port) { | 128 | for (port = 0; port < mv88e6xxx_num_ports(chip); ++port) { |
107 | /* XXX newer chips (like 88E6390) have different 2-bit ops */ | 129 | /* XXX newer chips (like 88E6390) have different 2-bit ops */ |
108 | err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_IRL_CMD, | 130 | err = mv88e6xxx_g2_write(chip, GLOBAL2_IRL_CMD, |
109 | GLOBAL2_IRL_CMD_OP_INIT_ALL | | 131 | GLOBAL2_IRL_CMD_OP_INIT_ALL | |
110 | (port << 8)); | 132 | (port << 8)); |
111 | if (err) | 133 | if (err) |
112 | break; | 134 | break; |
113 | 135 | ||
114 | /* Wait for the operation to complete */ | 136 | /* Wait for the operation to complete */ |
115 | err = mv88e6xxx_wait(chip, REG_GLOBAL2, GLOBAL2_IRL_CMD, | 137 | err = mv88e6xxx_g2_wait(chip, GLOBAL2_IRL_CMD, |
116 | GLOBAL2_IRL_CMD_BUSY); | 138 | GLOBAL2_IRL_CMD_BUSY); |
117 | if (err) | 139 | if (err) |
118 | break; | 140 | break; |
119 | } | 141 | } |
@@ -128,7 +150,7 @@ static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip, | |||
128 | { | 150 | { |
129 | u16 val = (pointer << 8) | data; | 151 | u16 val = (pointer << 8) | data; |
130 | 152 | ||
131 | return mv88e6xxx_update(chip, REG_GLOBAL2, GLOBAL2_SWITCH_MAC, val); | 153 | return mv88e6xxx_g2_update(chip, GLOBAL2_SWITCH_MAC, val); |
132 | } | 154 | } |
133 | 155 | ||
134 | int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr) | 156 | int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr) |
@@ -151,7 +173,7 @@ static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer, | |||
151 | { | 173 | { |
152 | u16 val = (pointer << 8) | (data & 0x7); | 174 | u16 val = (pointer << 8) | (data & 0x7); |
153 | 175 | ||
154 | return mv88e6xxx_update(chip, REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE, val); | 176 | return mv88e6xxx_g2_update(chip, GLOBAL2_PRIO_OVERRIDE, val); |
155 | } | 177 | } |
156 | 178 | ||
157 | static int mv88e6xxx_g2_clear_pot(struct mv88e6xxx_chip *chip) | 179 | static int mv88e6xxx_g2_clear_pot(struct mv88e6xxx_chip *chip) |
@@ -174,16 +196,16 @@ static int mv88e6xxx_g2_clear_pot(struct mv88e6xxx_chip *chip) | |||
174 | 196 | ||
175 | static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) | 197 | static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) |
176 | { | 198 | { |
177 | return mv88e6xxx_wait(chip, REG_GLOBAL2, GLOBAL2_EEPROM_CMD, | 199 | return mv88e6xxx_g2_wait(chip, GLOBAL2_EEPROM_CMD, |
178 | GLOBAL2_EEPROM_CMD_BUSY | | 200 | GLOBAL2_EEPROM_CMD_BUSY | |
179 | GLOBAL2_EEPROM_CMD_RUNNING); | 201 | GLOBAL2_EEPROM_CMD_RUNNING); |
180 | } | 202 | } |
181 | 203 | ||
182 | static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd) | 204 | static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd) |
183 | { | 205 | { |
184 | int err; | 206 | int err; |
185 | 207 | ||
186 | err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_EEPROM_CMD, cmd); | 208 | err = mv88e6xxx_g2_write(chip, GLOBAL2_EEPROM_CMD, cmd); |
187 | if (err) | 209 | if (err) |
188 | return err; | 210 | return err; |
189 | 211 | ||
@@ -204,7 +226,7 @@ static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip, | |||
204 | if (err) | 226 | if (err) |
205 | return err; | 227 | return err; |
206 | 228 | ||
207 | return mv88e6xxx_read(chip, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data); | 229 | return mv88e6xxx_g2_read(chip, GLOBAL2_EEPROM_DATA, data); |
208 | } | 230 | } |
209 | 231 | ||
210 | static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip, | 232 | static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip, |
@@ -217,7 +239,7 @@ static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip, | |||
217 | if (err) | 239 | if (err) |
218 | return err; | 240 | return err; |
219 | 241 | ||
220 | err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_EEPROM_DATA, data); | 242 | err = mv88e6xxx_g2_write(chip, GLOBAL2_EEPROM_DATA, data); |
221 | if (err) | 243 | if (err) |
222 | return err; | 244 | return err; |
223 | 245 | ||
@@ -283,7 +305,7 @@ int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip, | |||
283 | int err; | 305 | int err; |
284 | 306 | ||
285 | /* Ensure the RO WriteEn bit is set */ | 307 | /* Ensure the RO WriteEn bit is set */ |
286 | err = mv88e6xxx_read(chip, REG_GLOBAL2, GLOBAL2_EEPROM_CMD, &val); | 308 | err = mv88e6xxx_g2_read(chip, GLOBAL2_EEPROM_CMD, &val); |
287 | if (err) | 309 | if (err) |
288 | return err; | 310 | return err; |
289 | 311 | ||
@@ -346,15 +368,15 @@ int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip, | |||
346 | 368 | ||
347 | static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip) | 369 | static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip) |
348 | { | 370 | { |
349 | return mv88e6xxx_wait(chip, REG_GLOBAL2, GLOBAL2_SMI_PHY_CMD, | 371 | return mv88e6xxx_g2_wait(chip, GLOBAL2_SMI_PHY_CMD, |
350 | GLOBAL2_SMI_PHY_CMD_BUSY); | 372 | GLOBAL2_SMI_PHY_CMD_BUSY); |
351 | } | 373 | } |
352 | 374 | ||
353 | static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd) | 375 | static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd) |
354 | { | 376 | { |
355 | int err; | 377 | int err; |
356 | 378 | ||
357 | err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_SMI_PHY_CMD, cmd); | 379 | err = mv88e6xxx_g2_write(chip, GLOBAL2_SMI_PHY_CMD, cmd); |
358 | if (err) | 380 | if (err) |
359 | return err; | 381 | return err; |
360 | 382 | ||
@@ -375,7 +397,7 @@ int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, int addr, int reg, | |||
375 | if (err) | 397 | if (err) |
376 | return err; | 398 | return err; |
377 | 399 | ||
378 | return mv88e6xxx_read(chip, REG_GLOBAL2, GLOBAL2_SMI_PHY_DATA, val); | 400 | return mv88e6xxx_g2_read(chip, GLOBAL2_SMI_PHY_DATA, val); |
379 | } | 401 | } |
380 | 402 | ||
381 | int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, int addr, int reg, | 403 | int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, int addr, int reg, |
@@ -388,7 +410,7 @@ int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, int addr, int reg, | |||
388 | if (err) | 410 | if (err) |
389 | return err; | 411 | return err; |
390 | 412 | ||
391 | err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_SMI_PHY_DATA, val); | 413 | err = mv88e6xxx_g2_write(chip, GLOBAL2_SMI_PHY_DATA, val); |
392 | if (err) | 414 | if (err) |
393 | return err; | 415 | return err; |
394 | 416 | ||
@@ -404,8 +426,7 @@ int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip) | |||
404 | /* Consider the frames with reserved multicast destination | 426 | /* Consider the frames with reserved multicast destination |
405 | * addresses matching 01:80:c2:00:00:2x as MGMT. | 427 | * addresses matching 01:80:c2:00:00:2x as MGMT. |
406 | */ | 428 | */ |
407 | err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_MGMT_EN_2X, | 429 | err = mv88e6xxx_g2_write(chip, GLOBAL2_MGMT_EN_2X, 0xffff); |
408 | 0xffff); | ||
409 | if (err) | 430 | if (err) |
410 | return err; | 431 | return err; |
411 | } | 432 | } |
@@ -414,8 +435,7 @@ int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip) | |||
414 | /* Consider the frames with reserved multicast destination | 435 | /* Consider the frames with reserved multicast destination |
415 | * addresses matching 01:80:c2:00:00:0x as MGMT. | 436 | * addresses matching 01:80:c2:00:00:0x as MGMT. |
416 | */ | 437 | */ |
417 | err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, | 438 | err = mv88e6xxx_g2_write(chip, GLOBAL2_MGMT_EN_0X, 0xffff); |
418 | 0xffff); | ||
419 | if (err) | 439 | if (err) |
420 | return err; | 440 | return err; |
421 | } | 441 | } |
@@ -429,7 +449,7 @@ int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip) | |||
429 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X) || | 449 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X) || |
430 | mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) | 450 | mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) |
431 | reg |= GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x7; | 451 | reg |= GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x7; |
432 | err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_SWITCH_MGMT, reg); | 452 | err = mv88e6xxx_g2_write(chip, GLOBAL2_SWITCH_MGMT, reg); |
433 | if (err) | 453 | if (err) |
434 | return err; | 454 | return err; |
435 | 455 | ||
@@ -454,8 +474,8 @@ int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip) | |||
454 | 474 | ||
455 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_PVT)) { | 475 | if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_PVT)) { |
456 | /* Initialize Cross-chip Port VLAN Table to reset defaults */ | 476 | /* Initialize Cross-chip Port VLAN Table to reset defaults */ |
457 | err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_PVT_ADDR, | 477 | err = mv88e6xxx_g2_write(chip, GLOBAL2_PVT_ADDR, |
458 | GLOBAL2_PVT_ADDR_OP_INIT_ONES); | 478 | GLOBAL2_PVT_ADDR_OP_INIT_ONES); |
459 | if (err) | 479 | if (err) |
460 | return err; | 480 | return err; |
461 | } | 481 | } |
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h index 827988397fd8..e572121c196e 100644 --- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | |||
@@ -159,7 +159,6 @@ | |||
159 | #define PORT_TAG_REGMAP_0123 0x18 | 159 | #define PORT_TAG_REGMAP_0123 0x18 |
160 | #define PORT_TAG_REGMAP_4567 0x19 | 160 | #define PORT_TAG_REGMAP_4567 0x19 |
161 | 161 | ||
162 | #define REG_GLOBAL 0x1b | ||
163 | #define GLOBAL_STATUS 0x00 | 162 | #define GLOBAL_STATUS 0x00 |
164 | #define GLOBAL_STATUS_PPU_STATE BIT(15) /* 6351 and 6171 */ | 163 | #define GLOBAL_STATUS_PPU_STATE BIT(15) /* 6351 and 6171 */ |
165 | /* Two bits for 6165, 6185 etc */ | 164 | /* Two bits for 6165, 6185 etc */ |
@@ -171,8 +170,8 @@ | |||
171 | #define GLOBAL_MAC_01 0x01 | 170 | #define GLOBAL_MAC_01 0x01 |
172 | #define GLOBAL_MAC_23 0x02 | 171 | #define GLOBAL_MAC_23 0x02 |
173 | #define GLOBAL_MAC_45 0x03 | 172 | #define GLOBAL_MAC_45 0x03 |
174 | #define GLOBAL_ATU_FID 0x01 /* 6097 6165 6351 6352 */ | 173 | #define GLOBAL_ATU_FID 0x01 |
175 | #define GLOBAL_VTU_FID 0x02 /* 6097 6165 6351 6352 */ | 174 | #define GLOBAL_VTU_FID 0x02 |
176 | #define GLOBAL_VTU_FID_MASK 0xfff | 175 | #define GLOBAL_VTU_FID_MASK 0xfff |
177 | #define GLOBAL_VTU_SID 0x03 /* 6097 6165 6351 6352 */ | 176 | #define GLOBAL_VTU_SID 0x03 /* 6097 6165 6351 6352 */ |
178 | #define GLOBAL_VTU_SID_MASK 0x3f | 177 | #define GLOBAL_VTU_SID_MASK 0x3f |
@@ -277,7 +276,6 @@ | |||
277 | #define GLOBAL_STATS_COUNTER_32 0x1e | 276 | #define GLOBAL_STATS_COUNTER_32 0x1e |
278 | #define GLOBAL_STATS_COUNTER_01 0x1f | 277 | #define GLOBAL_STATS_COUNTER_01 0x1f |
279 | 278 | ||
280 | #define REG_GLOBAL2 0x1c | ||
281 | #define GLOBAL2_INT_SOURCE 0x00 | 279 | #define GLOBAL2_INT_SOURCE 0x00 |
282 | #define GLOBAL2_INT_MASK 0x01 | 280 | #define GLOBAL2_INT_MASK 0x01 |
283 | #define GLOBAL2_MGMT_EN_2X 0x02 | 281 | #define GLOBAL2_MGMT_EN_2X 0x02 |
@@ -410,6 +408,11 @@ enum mv88e6xxx_cap { | |||
410 | */ | 408 | */ |
411 | MV88E6XXX_CAP_SERDES, | 409 | MV88E6XXX_CAP_SERDES, |
412 | 410 | ||
411 | /* Switch Global (1) Registers. | ||
412 | */ | ||
413 | MV88E6XXX_CAP_G1_ATU_FID, /* (0x01) ATU FID Register */ | ||
414 | MV88E6XXX_CAP_G1_VTU_FID, /* (0x02) VTU FID Register */ | ||
415 | |||
413 | /* Switch Global 2 Registers. | 416 | /* Switch Global 2 Registers. |
414 | * The device contains a second set of global 16-bit registers. | 417 | * The device contains a second set of global 16-bit registers. |
415 | */ | 418 | */ |
@@ -420,12 +423,7 @@ enum mv88e6xxx_cap { | |||
420 | MV88E6XXX_CAP_G2_IRL_DATA, /* (0x0a) Ingress Rate Data */ | 423 | MV88E6XXX_CAP_G2_IRL_DATA, /* (0x0a) Ingress Rate Data */ |
421 | MV88E6XXX_CAP_G2_PVT_ADDR, /* (0x0b) Cross Chip Port VLAN Addr */ | 424 | MV88E6XXX_CAP_G2_PVT_ADDR, /* (0x0b) Cross Chip Port VLAN Addr */ |
422 | MV88E6XXX_CAP_G2_PVT_DATA, /* (0x0c) Cross Chip Port VLAN Data */ | 425 | MV88E6XXX_CAP_G2_PVT_DATA, /* (0x0c) Cross Chip Port VLAN Data */ |
423 | MV88E6XXX_CAP_G2_SWITCH_MAC, /* (0x0d) Switch MAC/WoL/WoF */ | ||
424 | MV88E6XXX_CAP_G2_POT, /* (0x0f) Priority Override Table */ | 426 | MV88E6XXX_CAP_G2_POT, /* (0x0f) Priority Override Table */ |
425 | MV88E6XXX_CAP_G2_EEPROM_CMD, /* (0x14) EEPROM Command */ | ||
426 | MV88E6XXX_CAP_G2_EEPROM_DATA, /* (0x15) EEPROM Data */ | ||
427 | MV88E6XXX_CAP_G2_SMI_PHY_CMD, /* (0x18) SMI PHY Command */ | ||
428 | MV88E6XXX_CAP_G2_SMI_PHY_DATA, /* (0x19) SMI PHY Data */ | ||
429 | 427 | ||
430 | /* PHY Polling Unit. | 428 | /* PHY Polling Unit. |
431 | * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING. | 429 | * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING. |
@@ -462,6 +460,9 @@ enum mv88e6xxx_cap { | |||
462 | 460 | ||
463 | #define MV88E6XXX_FLAG_SERDES BIT_ULL(MV88E6XXX_CAP_SERDES) | 461 | #define MV88E6XXX_FLAG_SERDES BIT_ULL(MV88E6XXX_CAP_SERDES) |
464 | 462 | ||
463 | #define MV88E6XXX_FLAG_G1_ATU_FID BIT_ULL(MV88E6XXX_CAP_G1_ATU_FID) | ||
464 | #define MV88E6XXX_FLAG_G1_VTU_FID BIT_ULL(MV88E6XXX_CAP_G1_VTU_FID) | ||
465 | |||
465 | #define MV88E6XXX_FLAG_GLOBAL2 BIT_ULL(MV88E6XXX_CAP_GLOBAL2) | 466 | #define MV88E6XXX_FLAG_GLOBAL2 BIT_ULL(MV88E6XXX_CAP_GLOBAL2) |
466 | #define MV88E6XXX_FLAG_G2_MGMT_EN_2X BIT_ULL(MV88E6XXX_CAP_G2_MGMT_EN_2X) | 467 | #define MV88E6XXX_FLAG_G2_MGMT_EN_2X BIT_ULL(MV88E6XXX_CAP_G2_MGMT_EN_2X) |
467 | #define MV88E6XXX_FLAG_G2_MGMT_EN_0X BIT_ULL(MV88E6XXX_CAP_G2_MGMT_EN_0X) | 468 | #define MV88E6XXX_FLAG_G2_MGMT_EN_0X BIT_ULL(MV88E6XXX_CAP_G2_MGMT_EN_0X) |
@@ -469,12 +470,7 @@ enum mv88e6xxx_cap { | |||
469 | #define MV88E6XXX_FLAG_G2_IRL_DATA BIT_ULL(MV88E6XXX_CAP_G2_IRL_DATA) | 470 | #define MV88E6XXX_FLAG_G2_IRL_DATA BIT_ULL(MV88E6XXX_CAP_G2_IRL_DATA) |
470 | #define MV88E6XXX_FLAG_G2_PVT_ADDR BIT_ULL(MV88E6XXX_CAP_G2_PVT_ADDR) | 471 | #define MV88E6XXX_FLAG_G2_PVT_ADDR BIT_ULL(MV88E6XXX_CAP_G2_PVT_ADDR) |
471 | #define MV88E6XXX_FLAG_G2_PVT_DATA BIT_ULL(MV88E6XXX_CAP_G2_PVT_DATA) | 472 | #define MV88E6XXX_FLAG_G2_PVT_DATA BIT_ULL(MV88E6XXX_CAP_G2_PVT_DATA) |
472 | #define MV88E6XXX_FLAG_G2_SWITCH_MAC BIT_ULL(MV88E6XXX_CAP_G2_SWITCH_MAC) | ||
473 | #define MV88E6XXX_FLAG_G2_POT BIT_ULL(MV88E6XXX_CAP_G2_POT) | 473 | #define MV88E6XXX_FLAG_G2_POT BIT_ULL(MV88E6XXX_CAP_G2_POT) |
474 | #define MV88E6XXX_FLAG_G2_EEPROM_CMD BIT_ULL(MV88E6XXX_CAP_G2_EEPROM_CMD) | ||
475 | #define MV88E6XXX_FLAG_G2_EEPROM_DATA BIT_ULL(MV88E6XXX_CAP_G2_EEPROM_DATA) | ||
476 | #define MV88E6XXX_FLAG_G2_SMI_PHY_CMD BIT_ULL(MV88E6XXX_CAP_G2_SMI_PHY_CMD) | ||
477 | #define MV88E6XXX_FLAG_G2_SMI_PHY_DATA BIT_ULL(MV88E6XXX_CAP_G2_SMI_PHY_DATA) | ||
478 | 474 | ||
479 | #define MV88E6XXX_FLAG_PPU BIT_ULL(MV88E6XXX_CAP_PPU) | 475 | #define MV88E6XXX_FLAG_PPU BIT_ULL(MV88E6XXX_CAP_PPU) |
480 | #define MV88E6XXX_FLAG_PPU_ACTIVE BIT_ULL(MV88E6XXX_CAP_PPU_ACTIVE) | 476 | #define MV88E6XXX_FLAG_PPU_ACTIVE BIT_ULL(MV88E6XXX_CAP_PPU_ACTIVE) |
@@ -483,11 +479,6 @@ enum mv88e6xxx_cap { | |||
483 | #define MV88E6XXX_FLAG_TEMP_LIMIT BIT_ULL(MV88E6XXX_CAP_TEMP_LIMIT) | 479 | #define MV88E6XXX_FLAG_TEMP_LIMIT BIT_ULL(MV88E6XXX_CAP_TEMP_LIMIT) |
484 | #define MV88E6XXX_FLAG_VTU BIT_ULL(MV88E6XXX_CAP_VTU) | 480 | #define MV88E6XXX_FLAG_VTU BIT_ULL(MV88E6XXX_CAP_VTU) |
485 | 481 | ||
486 | /* EEPROM Programming via Global2 with 16-bit data */ | ||
487 | #define MV88E6XXX_FLAGS_EEPROM16 \ | ||
488 | (MV88E6XXX_FLAG_G2_EEPROM_CMD | \ | ||
489 | MV88E6XXX_FLAG_G2_EEPROM_DATA) | ||
490 | |||
491 | /* Ingress Rate Limit unit */ | 482 | /* Ingress Rate Limit unit */ |
492 | #define MV88E6XXX_FLAGS_IRL \ | 483 | #define MV88E6XXX_FLAGS_IRL \ |
493 | (MV88E6XXX_FLAG_G2_IRL_CMD | \ | 484 | (MV88E6XXX_FLAG_G2_IRL_CMD | \ |
@@ -508,11 +499,6 @@ enum mv88e6xxx_cap { | |||
508 | (MV88E6XXX_FLAG_PHY_PAGE | \ | 499 | (MV88E6XXX_FLAG_PHY_PAGE | \ |
509 | MV88E6XXX_FLAG_SERDES) | 500 | MV88E6XXX_FLAG_SERDES) |
510 | 501 | ||
511 | /* Indirect PHY access via Global2 SMI PHY registers */ | ||
512 | #define MV88E6XXX_FLAGS_SMI_PHY \ | ||
513 | (MV88E6XXX_FLAG_G2_SMI_PHY_CMD |\ | ||
514 | MV88E6XXX_FLAG_G2_SMI_PHY_DATA) | ||
515 | |||
516 | #define MV88E6XXX_FLAGS_FAMILY_6095 \ | 502 | #define MV88E6XXX_FLAGS_FAMILY_6095 \ |
517 | (MV88E6XXX_FLAG_GLOBAL2 | \ | 503 | (MV88E6XXX_FLAG_GLOBAL2 | \ |
518 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ | 504 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ |
@@ -521,7 +507,9 @@ enum mv88e6xxx_cap { | |||
521 | MV88E6XXX_FLAGS_MULTI_CHIP) | 507 | MV88E6XXX_FLAGS_MULTI_CHIP) |
522 | 508 | ||
523 | #define MV88E6XXX_FLAGS_FAMILY_6097 \ | 509 | #define MV88E6XXX_FLAGS_FAMILY_6097 \ |
524 | (MV88E6XXX_FLAG_GLOBAL2 | \ | 510 | (MV88E6XXX_FLAG_G1_ATU_FID | \ |
511 | MV88E6XXX_FLAG_G1_VTU_FID | \ | ||
512 | MV88E6XXX_FLAG_GLOBAL2 | \ | ||
525 | MV88E6XXX_FLAG_G2_MGMT_EN_2X | \ | 513 | MV88E6XXX_FLAG_G2_MGMT_EN_2X | \ |
526 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ | 514 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ |
527 | MV88E6XXX_FLAG_G2_POT | \ | 515 | MV88E6XXX_FLAG_G2_POT | \ |
@@ -533,10 +521,11 @@ enum mv88e6xxx_cap { | |||
533 | MV88E6XXX_FLAGS_PVT) | 521 | MV88E6XXX_FLAGS_PVT) |
534 | 522 | ||
535 | #define MV88E6XXX_FLAGS_FAMILY_6165 \ | 523 | #define MV88E6XXX_FLAGS_FAMILY_6165 \ |
536 | (MV88E6XXX_FLAG_GLOBAL2 | \ | 524 | (MV88E6XXX_FLAG_G1_ATU_FID | \ |
525 | MV88E6XXX_FLAG_G1_VTU_FID | \ | ||
526 | MV88E6XXX_FLAG_GLOBAL2 | \ | ||
537 | MV88E6XXX_FLAG_G2_MGMT_EN_2X | \ | 527 | MV88E6XXX_FLAG_G2_MGMT_EN_2X | \ |
538 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ | 528 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ |
539 | MV88E6XXX_FLAG_G2_SWITCH_MAC | \ | ||
540 | MV88E6XXX_FLAG_G2_POT | \ | 529 | MV88E6XXX_FLAG_G2_POT | \ |
541 | MV88E6XXX_FLAG_STU | \ | 530 | MV88E6XXX_FLAG_STU | \ |
542 | MV88E6XXX_FLAG_TEMP | \ | 531 | MV88E6XXX_FLAG_TEMP | \ |
@@ -558,24 +547,22 @@ enum mv88e6xxx_cap { | |||
558 | MV88E6XXX_FLAG_GLOBAL2 | \ | 547 | MV88E6XXX_FLAG_GLOBAL2 | \ |
559 | MV88E6XXX_FLAG_G2_MGMT_EN_2X | \ | 548 | MV88E6XXX_FLAG_G2_MGMT_EN_2X | \ |
560 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ | 549 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ |
561 | MV88E6XXX_FLAG_G2_SWITCH_MAC | \ | ||
562 | MV88E6XXX_FLAG_G2_POT | \ | 550 | MV88E6XXX_FLAG_G2_POT | \ |
563 | MV88E6XXX_FLAG_PPU_ACTIVE | \ | 551 | MV88E6XXX_FLAG_PPU_ACTIVE | \ |
564 | MV88E6XXX_FLAG_TEMP | \ | 552 | MV88E6XXX_FLAG_TEMP | \ |
565 | MV88E6XXX_FLAG_TEMP_LIMIT | \ | 553 | MV88E6XXX_FLAG_TEMP_LIMIT | \ |
566 | MV88E6XXX_FLAG_VTU | \ | 554 | MV88E6XXX_FLAG_VTU | \ |
567 | MV88E6XXX_FLAGS_EEPROM16 | \ | ||
568 | MV88E6XXX_FLAGS_IRL | \ | 555 | MV88E6XXX_FLAGS_IRL | \ |
569 | MV88E6XXX_FLAGS_MULTI_CHIP | \ | 556 | MV88E6XXX_FLAGS_MULTI_CHIP | \ |
570 | MV88E6XXX_FLAGS_PVT | \ | 557 | MV88E6XXX_FLAGS_PVT) |
571 | MV88E6XXX_FLAGS_SMI_PHY) | ||
572 | 558 | ||
573 | #define MV88E6XXX_FLAGS_FAMILY_6351 \ | 559 | #define MV88E6XXX_FLAGS_FAMILY_6351 \ |
574 | (MV88E6XXX_FLAG_EDSA | \ | 560 | (MV88E6XXX_FLAG_EDSA | \ |
561 | MV88E6XXX_FLAG_G1_ATU_FID | \ | ||
562 | MV88E6XXX_FLAG_G1_VTU_FID | \ | ||
575 | MV88E6XXX_FLAG_GLOBAL2 | \ | 563 | MV88E6XXX_FLAG_GLOBAL2 | \ |
576 | MV88E6XXX_FLAG_G2_MGMT_EN_2X | \ | 564 | MV88E6XXX_FLAG_G2_MGMT_EN_2X | \ |
577 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ | 565 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ |
578 | MV88E6XXX_FLAG_G2_SWITCH_MAC | \ | ||
579 | MV88E6XXX_FLAG_G2_POT | \ | 566 | MV88E6XXX_FLAG_G2_POT | \ |
580 | MV88E6XXX_FLAG_PPU_ACTIVE | \ | 567 | MV88E6XXX_FLAG_PPU_ACTIVE | \ |
581 | MV88E6XXX_FLAG_STU | \ | 568 | MV88E6XXX_FLAG_STU | \ |
@@ -583,28 +570,28 @@ enum mv88e6xxx_cap { | |||
583 | MV88E6XXX_FLAG_VTU | \ | 570 | MV88E6XXX_FLAG_VTU | \ |
584 | MV88E6XXX_FLAGS_IRL | \ | 571 | MV88E6XXX_FLAGS_IRL | \ |
585 | MV88E6XXX_FLAGS_MULTI_CHIP | \ | 572 | MV88E6XXX_FLAGS_MULTI_CHIP | \ |
586 | MV88E6XXX_FLAGS_PVT | \ | 573 | MV88E6XXX_FLAGS_PVT) |
587 | MV88E6XXX_FLAGS_SMI_PHY) | ||
588 | 574 | ||
589 | #define MV88E6XXX_FLAGS_FAMILY_6352 \ | 575 | #define MV88E6XXX_FLAGS_FAMILY_6352 \ |
590 | (MV88E6XXX_FLAG_EDSA | \ | 576 | (MV88E6XXX_FLAG_EDSA | \ |
591 | MV88E6XXX_FLAG_EEE | \ | 577 | MV88E6XXX_FLAG_EEE | \ |
578 | MV88E6XXX_FLAG_G1_ATU_FID | \ | ||
579 | MV88E6XXX_FLAG_G1_VTU_FID | \ | ||
592 | MV88E6XXX_FLAG_GLOBAL2 | \ | 580 | MV88E6XXX_FLAG_GLOBAL2 | \ |
593 | MV88E6XXX_FLAG_G2_MGMT_EN_2X | \ | 581 | MV88E6XXX_FLAG_G2_MGMT_EN_2X | \ |
594 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ | 582 | MV88E6XXX_FLAG_G2_MGMT_EN_0X | \ |
595 | MV88E6XXX_FLAG_G2_SWITCH_MAC | \ | ||
596 | MV88E6XXX_FLAG_G2_POT | \ | 583 | MV88E6XXX_FLAG_G2_POT | \ |
597 | MV88E6XXX_FLAG_PPU_ACTIVE | \ | 584 | MV88E6XXX_FLAG_PPU_ACTIVE | \ |
598 | MV88E6XXX_FLAG_STU | \ | 585 | MV88E6XXX_FLAG_STU | \ |
599 | MV88E6XXX_FLAG_TEMP | \ | 586 | MV88E6XXX_FLAG_TEMP | \ |
600 | MV88E6XXX_FLAG_TEMP_LIMIT | \ | 587 | MV88E6XXX_FLAG_TEMP_LIMIT | \ |
601 | MV88E6XXX_FLAG_VTU | \ | 588 | MV88E6XXX_FLAG_VTU | \ |
602 | MV88E6XXX_FLAGS_EEPROM16 | \ | ||
603 | MV88E6XXX_FLAGS_IRL | \ | 589 | MV88E6XXX_FLAGS_IRL | \ |
604 | MV88E6XXX_FLAGS_MULTI_CHIP | \ | 590 | MV88E6XXX_FLAGS_MULTI_CHIP | \ |
605 | MV88E6XXX_FLAGS_PVT | \ | 591 | MV88E6XXX_FLAGS_PVT | \ |
606 | MV88E6XXX_FLAGS_SERDES | \ | 592 | MV88E6XXX_FLAGS_SERDES) |
607 | MV88E6XXX_FLAGS_SMI_PHY) | 593 | |
594 | struct mv88e6xxx_ops; | ||
608 | 595 | ||
609 | struct mv88e6xxx_info { | 596 | struct mv88e6xxx_info { |
610 | enum mv88e6xxx_family family; | 597 | enum mv88e6xxx_family family; |
@@ -613,8 +600,10 @@ struct mv88e6xxx_info { | |||
613 | unsigned int num_databases; | 600 | unsigned int num_databases; |
614 | unsigned int num_ports; | 601 | unsigned int num_ports; |
615 | unsigned int port_base_addr; | 602 | unsigned int port_base_addr; |
603 | unsigned int global1_addr; | ||
616 | unsigned int age_time_coeff; | 604 | unsigned int age_time_coeff; |
617 | unsigned long long flags; | 605 | unsigned long long flags; |
606 | const struct mv88e6xxx_ops *ops; | ||
618 | }; | 607 | }; |
619 | 608 | ||
620 | struct mv88e6xxx_atu_entry { | 609 | struct mv88e6xxx_atu_entry { |
@@ -625,18 +614,15 @@ struct mv88e6xxx_atu_entry { | |||
625 | u8 mac[ETH_ALEN]; | 614 | u8 mac[ETH_ALEN]; |
626 | }; | 615 | }; |
627 | 616 | ||
628 | struct mv88e6xxx_vtu_stu_entry { | 617 | struct mv88e6xxx_vtu_entry { |
629 | /* VTU only */ | ||
630 | u16 vid; | 618 | u16 vid; |
631 | u16 fid; | 619 | u16 fid; |
632 | |||
633 | /* VTU and STU */ | ||
634 | u8 sid; | 620 | u8 sid; |
635 | bool valid; | 621 | bool valid; |
636 | u8 data[DSA_MAX_PORTS]; | 622 | u8 data[DSA_MAX_PORTS]; |
637 | }; | 623 | }; |
638 | 624 | ||
639 | struct mv88e6xxx_ops; | 625 | struct mv88e6xxx_bus_ops; |
640 | 626 | ||
641 | struct mv88e6xxx_priv_port { | 627 | struct mv88e6xxx_priv_port { |
642 | struct net_device *bridge_dev; | 628 | struct net_device *bridge_dev; |
@@ -657,14 +643,14 @@ struct mv88e6xxx_chip { | |||
657 | /* The MII bus and the address on the bus that is used to | 643 | /* The MII bus and the address on the bus that is used to |
658 | * communication with the switch | 644 | * communication with the switch |
659 | */ | 645 | */ |
660 | const struct mv88e6xxx_ops *smi_ops; | 646 | const struct mv88e6xxx_bus_ops *smi_ops; |
661 | struct mii_bus *bus; | 647 | struct mii_bus *bus; |
662 | int sw_addr; | 648 | int sw_addr; |
663 | 649 | ||
664 | /* Handles automatic disabling and re-enabling of the PHY | 650 | /* Handles automatic disabling and re-enabling of the PHY |
665 | * polling unit. | 651 | * polling unit. |
666 | */ | 652 | */ |
667 | const struct mv88e6xxx_ops *phy_ops; | 653 | const struct mv88e6xxx_bus_ops *phy_ops; |
668 | struct mutex ppu_mutex; | 654 | struct mutex ppu_mutex; |
669 | int ppu_disabled; | 655 | int ppu_disabled; |
670 | struct work_struct ppu_work; | 656 | struct work_struct ppu_work; |
@@ -693,11 +679,25 @@ struct mv88e6xxx_chip { | |||
693 | struct mii_bus *mdio_bus; | 679 | struct mii_bus *mdio_bus; |
694 | }; | 680 | }; |
695 | 681 | ||
696 | struct mv88e6xxx_ops { | 682 | struct mv88e6xxx_bus_ops { |
697 | int (*read)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); | 683 | int (*read)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); |
698 | int (*write)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); | 684 | int (*write)(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); |
699 | }; | 685 | }; |
700 | 686 | ||
687 | struct mv88e6xxx_ops { | ||
688 | int (*get_eeprom)(struct mv88e6xxx_chip *chip, | ||
689 | struct ethtool_eeprom *eeprom, u8 *data); | ||
690 | int (*set_eeprom)(struct mv88e6xxx_chip *chip, | ||
691 | struct ethtool_eeprom *eeprom, u8 *data); | ||
692 | |||
693 | int (*set_switch_mac)(struct mv88e6xxx_chip *chip, u8 *addr); | ||
694 | |||
695 | int (*phy_read)(struct mv88e6xxx_chip *chip, int addr, int reg, | ||
696 | u16 *val); | ||
697 | int (*phy_write)(struct mv88e6xxx_chip *chip, int addr, int reg, | ||
698 | u16 val); | ||
699 | }; | ||
700 | |||
701 | enum stat_type { | 701 | enum stat_type { |
702 | BANK0, | 702 | BANK0, |
703 | BANK1, | 703 | BANK1, |
@@ -717,6 +717,16 @@ static inline bool mv88e6xxx_has(struct mv88e6xxx_chip *chip, | |||
717 | return (chip->info->flags & flags) == flags; | 717 | return (chip->info->flags & flags) == flags; |
718 | } | 718 | } |
719 | 719 | ||
720 | static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip) | ||
721 | { | ||
722 | return chip->info->num_databases; | ||
723 | } | ||
724 | |||
725 | static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip) | ||
726 | { | ||
727 | return chip->info->num_ports; | ||
728 | } | ||
729 | |||
720 | int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); | 730 | int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); |
721 | int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); | 731 | int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); |
722 | int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, | 732 | int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, |