2 * Marvell 88E6xxx Switch Global 2 Registers support
4 * Copyright (c) 2008 Marvell Semiconductor
6 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
7 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
15 #include <linux/bitfield.h>
16 #include <linux/interrupt.h>
17 #include <linux/irqdomain.h>
20 #include "global1.h" /* for MV88E6XXX_G1_STS_IRQ_DEVICE */
23 static int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
25 return mv88e6xxx_read(chip, MV88E6XXX_G2, reg, val);
28 static int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
30 return mv88e6xxx_write(chip, MV88E6XXX_G2, reg, val);
33 static int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update)
35 return mv88e6xxx_update(chip, MV88E6XXX_G2, reg, update);
38 static int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
40 return mv88e6xxx_wait(chip, MV88E6XXX_G2, reg, mask);
43 /* Offset 0x02: Management Enable 2x */
44 /* Offset 0x03: Management Enable 0x */
46 int mv88e6095_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
50 /* Consider the frames with reserved multicast destination
51 * addresses matching 01:80:c2:00:00:2x as MGMT.
53 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) {
54 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_2X, 0xffff);
59 /* Consider the frames with reserved multicast destination
60 * addresses matching 01:80:c2:00:00:0x as MGMT.
62 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X))
63 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_0X,
69 /* Offset 0x06: Device Mapping Table register */
71 static int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip,
74 u16 val = (target << 8) | (port & 0xf);
76 return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_DEVICE_MAPPING, val);
79 static int mv88e6xxx_g2_set_device_mapping(struct mv88e6xxx_chip *chip)
84 /* Initialize the routing port to the 32 possible target devices */
85 for (target = 0; target < 32; ++target) {
88 if (target < DSA_MAX_SWITCHES) {
89 port = chip->ds->rtable[target];
90 if (port == DSA_RTABLE_NONE)
94 err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
102 /* Offset 0x07: Trunk Mask Table register */
104 static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num,
107 u16 val = (num << 12) | (mask & mv88e6xxx_port_mask(chip));
110 val |= MV88E6XXX_G2_TRUNK_MASK_HASH;
112 return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_TRUNK_MASK, val);
115 /* Offset 0x08: Trunk Mapping Table register */
117 static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id,
120 const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
121 u16 val = (id << 11) | (map & port_mask);
123 return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_TRUNK_MAPPING, val);
126 static int mv88e6xxx_g2_clear_trunk(struct mv88e6xxx_chip *chip)
128 const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
131 /* Clear all eight possible Trunk Mask vectors */
132 for (i = 0; i < 8; ++i) {
133 err = mv88e6xxx_g2_trunk_mask_write(chip, i, false, port_mask);
138 /* Clear all sixteen possible Trunk ID routing vectors */
139 for (i = 0; i < 16; ++i) {
140 err = mv88e6xxx_g2_trunk_mapping_write(chip, i, 0);
148 /* Offset 0x09: Ingress Rate Command register
149 * Offset 0x0A: Ingress Rate Data register
152 static int mv88e6xxx_g2_irl_wait(struct mv88e6xxx_chip *chip)
154 return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_IRL_CMD,
155 MV88E6XXX_G2_IRL_CMD_BUSY);
158 static int mv88e6xxx_g2_irl_op(struct mv88e6xxx_chip *chip, u16 op, int port,
163 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_IRL_CMD,
164 MV88E6XXX_G2_IRL_CMD_BUSY | op | (port << 8) |
169 return mv88e6xxx_g2_irl_wait(chip);
172 int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
174 return mv88e6xxx_g2_irl_op(chip, MV88E6352_G2_IRL_CMD_OP_INIT_ALL, port,
178 int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
180 return mv88e6xxx_g2_irl_op(chip, MV88E6390_G2_IRL_CMD_OP_INIT_ALL, port,
184 /* Offset 0x0B: Cross-chip Port VLAN (Addr) Register
185 * Offset 0x0C: Cross-chip Port VLAN Data Register
188 static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip *chip)
190 return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_PVT_ADDR,
191 MV88E6XXX_G2_PVT_ADDR_BUSY);
194 static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip *chip, int src_dev,
195 int src_port, u16 op)
199 /* 9-bit Cross-chip PVT pointer: with MV88E6XXX_G2_MISC_5_BIT_PORT
200 * cleared, source device is 5-bit, source port is 4-bit.
202 op |= MV88E6XXX_G2_PVT_ADDR_BUSY;
203 op |= (src_dev & 0x1f) << 4;
204 op |= (src_port & 0xf);
206 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_ADDR, op);
210 return mv88e6xxx_g2_pvt_op_wait(chip);
213 int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
214 int src_port, u16 data)
218 err = mv88e6xxx_g2_pvt_op_wait(chip);
222 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_DATA, data);
226 return mv88e6xxx_g2_pvt_op(chip, src_dev, src_port,
227 MV88E6XXX_G2_PVT_ADDR_OP_WRITE_PVLAN);
230 /* Offset 0x0D: Switch MAC/WoL/WoF register */
232 static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
233 unsigned int pointer, u8 data)
235 u16 val = (pointer << 8) | data;
237 return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_SWITCH_MAC, val);
240 int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
244 for (i = 0; i < 6; i++) {
245 err = mv88e6xxx_g2_switch_mac_write(chip, i, addr[i]);
253 /* Offset 0x0F: Priority Override Table */
255 static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
258 u16 val = (pointer << 8) | (data & 0x7);
260 return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_PRIO_OVERRIDE, val);
263 static int mv88e6xxx_g2_clear_pot(struct mv88e6xxx_chip *chip)
267 /* Clear all sixteen possible Priority Override entries */
268 for (i = 0; i < 16; i++) {
269 err = mv88e6xxx_g2_pot_write(chip, i, 0);
277 /* Offset 0x14: EEPROM Command
278 * Offset 0x15: EEPROM Data (for 16-bit data access)
279 * Offset 0x15: EEPROM Addr (for 8-bit data access)
282 static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
284 return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_EEPROM_CMD,
285 MV88E6XXX_G2_EEPROM_CMD_BUSY |
286 MV88E6XXX_G2_EEPROM_CMD_RUNNING);
289 static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
293 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_EEPROM_CMD,
294 MV88E6XXX_G2_EEPROM_CMD_BUSY | cmd);
298 return mv88e6xxx_g2_eeprom_wait(chip);
301 static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip *chip,
304 u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ;
307 err = mv88e6xxx_g2_eeprom_wait(chip);
311 err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
315 err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
319 err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &cmd);
328 static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip *chip,
331 u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE |
332 MV88E6XXX_G2_EEPROM_CMD_WRITE_EN;
335 err = mv88e6xxx_g2_eeprom_wait(chip);
339 err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
343 return mv88e6xxx_g2_eeprom_cmd(chip, cmd | data);
346 static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
349 u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ | addr;
352 err = mv88e6xxx_g2_eeprom_wait(chip);
356 err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
360 return mv88e6xxx_g2_read(chip, MV88E6352_G2_EEPROM_DATA, data);
363 static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
366 u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE | addr;
369 err = mv88e6xxx_g2_eeprom_wait(chip);
373 err = mv88e6xxx_g2_write(chip, MV88E6352_G2_EEPROM_DATA, data);
377 return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
380 int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
381 struct ethtool_eeprom *eeprom, u8 *data)
383 unsigned int offset = eeprom->offset;
384 unsigned int len = eeprom->len;
390 err = mv88e6xxx_g2_eeprom_read8(chip, offset, data);
403 int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
404 struct ethtool_eeprom *eeprom, u8 *data)
406 unsigned int offset = eeprom->offset;
407 unsigned int len = eeprom->len;
413 err = mv88e6xxx_g2_eeprom_write8(chip, offset, *data);
426 int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
427 struct ethtool_eeprom *eeprom, u8 *data)
429 unsigned int offset = eeprom->offset;
430 unsigned int len = eeprom->len;
437 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
441 *data++ = (val >> 8) & 0xff;
449 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
453 *data++ = val & 0xff;
454 *data++ = (val >> 8) & 0xff;
462 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
466 *data++ = val & 0xff;
476 int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
477 struct ethtool_eeprom *eeprom, u8 *data)
479 unsigned int offset = eeprom->offset;
480 unsigned int len = eeprom->len;
484 /* Ensure the RO WriteEn bit is set */
485 err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &val);
489 if (!(val & MV88E6XXX_G2_EEPROM_CMD_WRITE_EN))
495 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
499 val = (*data++ << 8) | (val & 0xff);
501 err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
514 err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
524 err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
528 val = (val & 0xff00) | *data++;
530 err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
542 /* Offset 0x18: SMI PHY Command Register
543 * Offset 0x19: SMI PHY Data Register
546 static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
548 return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_SMI_PHY_CMD,
549 MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
552 static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
556 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_CMD,
557 MV88E6XXX_G2_SMI_PHY_CMD_BUSY | cmd);
561 return mv88e6xxx_g2_smi_phy_wait(chip);
564 static int mv88e6xxx_g2_smi_phy_access(struct mv88e6xxx_chip *chip,
565 bool external, bool c45, u16 op, int dev,
571 cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_EXTERNAL;
573 cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL; /* empty mask */
576 cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_45; /* empty mask */
578 cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_22;
580 dev <<= __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK);
581 cmd |= dev & MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK;
582 cmd |= reg & MV88E6XXX_G2_SMI_PHY_CMD_REG_ADDR_MASK;
584 return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
587 static int mv88e6xxx_g2_smi_phy_access_c22(struct mv88e6xxx_chip *chip,
588 bool external, u16 op, int dev,
591 return mv88e6xxx_g2_smi_phy_access(chip, external, false, op, dev, reg);
594 /* IEEE 802.3 Clause 22 Read Data Register */
595 static int mv88e6xxx_g2_smi_phy_read_data_c22(struct mv88e6xxx_chip *chip,
596 bool external, int dev, int reg,
599 u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_READ_DATA;
602 err = mv88e6xxx_g2_smi_phy_wait(chip);
606 err = mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
610 return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
613 /* IEEE 802.3 Clause 22 Write Data Register */
614 static int mv88e6xxx_g2_smi_phy_write_data_c22(struct mv88e6xxx_chip *chip,
615 bool external, int dev, int reg,
618 u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_WRITE_DATA;
621 err = mv88e6xxx_g2_smi_phy_wait(chip);
625 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
629 return mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
632 static int mv88e6xxx_g2_smi_phy_access_c45(struct mv88e6xxx_chip *chip,
633 bool external, u16 op, int port,
636 return mv88e6xxx_g2_smi_phy_access(chip, external, true, op, port, dev);
639 /* IEEE 802.3 Clause 45 Write Address Register */
640 static int mv88e6xxx_g2_smi_phy_write_addr_c45(struct mv88e6xxx_chip *chip,
641 bool external, int port, int dev,
644 u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_ADDR;
647 err = mv88e6xxx_g2_smi_phy_wait(chip);
651 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, addr);
655 return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
658 /* IEEE 802.3 Clause 45 Read Data Register */
659 static int mv88e6xxx_g2_smi_phy_read_data_c45(struct mv88e6xxx_chip *chip,
660 bool external, int port, int dev,
663 u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_READ_DATA;
666 err = mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
670 return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
673 static int mv88e6xxx_g2_smi_phy_read_c45(struct mv88e6xxx_chip *chip,
674 bool external, int port, int reg,
677 int dev = (reg >> 16) & 0x1f;
678 int addr = reg & 0xffff;
681 err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
686 return mv88e6xxx_g2_smi_phy_read_data_c45(chip, external, port, dev,
690 /* IEEE 802.3 Clause 45 Write Data Register */
691 static int mv88e6xxx_g2_smi_phy_write_data_c45(struct mv88e6xxx_chip *chip,
692 bool external, int port, int dev,
695 u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_DATA;
698 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
702 return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
705 static int mv88e6xxx_g2_smi_phy_write_c45(struct mv88e6xxx_chip *chip,
706 bool external, int port, int reg,
709 int dev = (reg >> 16) & 0x1f;
710 int addr = reg & 0xffff;
713 err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
718 return mv88e6xxx_g2_smi_phy_write_data_c45(chip, external, port, dev,
722 int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
723 int addr, int reg, u16 *val)
725 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
726 bool external = mdio_bus->external;
728 if (reg & MII_ADDR_C45)
729 return mv88e6xxx_g2_smi_phy_read_c45(chip, external, addr, reg,
732 return mv88e6xxx_g2_smi_phy_read_data_c22(chip, external, addr, reg,
736 int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
737 int addr, int reg, u16 val)
739 struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
740 bool external = mdio_bus->external;
742 if (reg & MII_ADDR_C45)
743 return mv88e6xxx_g2_smi_phy_write_c45(chip, external, addr, reg,
746 return mv88e6xxx_g2_smi_phy_write_data_c22(chip, external, addr, reg,
750 static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
754 mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, ®);
756 dev_info(chip->dev, "Watchdog event: 0x%04x", reg);
761 static void mv88e6097_watchdog_free(struct mv88e6xxx_chip *chip)
765 mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, ®);
767 reg &= ~(MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
768 MV88E6352_G2_WDOG_CTL_QC_ENABLE);
770 mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL, reg);
773 static int mv88e6097_watchdog_setup(struct mv88e6xxx_chip *chip)
775 return mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL,
776 MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
777 MV88E6352_G2_WDOG_CTL_QC_ENABLE |
778 MV88E6352_G2_WDOG_CTL_SWRESET);
781 const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {
782 .irq_action = mv88e6097_watchdog_action,
783 .irq_setup = mv88e6097_watchdog_setup,
784 .irq_free = mv88e6097_watchdog_free,
787 static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
789 return mv88e6xxx_g2_update(chip, MV88E6390_G2_WDOG_CTL,
790 MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
791 MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
792 MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
793 MV88E6390_G2_WDOG_CTL_EGRESS |
794 MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
797 static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
802 mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
803 MV88E6390_G2_WDOG_CTL_PTR_EVENT);
804 err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, ®);
806 dev_info(chip->dev, "Watchdog event: 0x%04x",
807 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
809 mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
810 MV88E6390_G2_WDOG_CTL_PTR_HISTORY);
811 err = mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, ®);
813 dev_info(chip->dev, "Watchdog history: 0x%04x",
814 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
816 /* Trigger a software reset to try to recover the switch */
817 if (chip->info->ops->reset)
818 chip->info->ops->reset(chip);
820 mv88e6390_watchdog_setup(chip);
825 static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
827 mv88e6xxx_g2_update(chip, MV88E6390_G2_WDOG_CTL,
828 MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
831 const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
832 .irq_action = mv88e6390_watchdog_action,
833 .irq_setup = mv88e6390_watchdog_setup,
834 .irq_free = mv88e6390_watchdog_free,
837 static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
839 struct mv88e6xxx_chip *chip = dev_id;
840 irqreturn_t ret = IRQ_NONE;
842 mutex_lock(&chip->reg_lock);
843 if (chip->info->ops->watchdog_ops->irq_action)
844 ret = chip->info->ops->watchdog_ops->irq_action(chip, irq);
845 mutex_unlock(&chip->reg_lock);
850 static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip *chip)
852 mutex_lock(&chip->reg_lock);
853 if (chip->info->ops->watchdog_ops->irq_free)
854 chip->info->ops->watchdog_ops->irq_free(chip);
855 mutex_unlock(&chip->reg_lock);
857 free_irq(chip->watchdog_irq, chip);
858 irq_dispose_mapping(chip->watchdog_irq);
861 static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip *chip)
865 chip->watchdog_irq = irq_find_mapping(chip->g2_irq.domain,
866 MV88E6XXX_G2_INT_SOURCE_WATCHDOG);
867 if (chip->watchdog_irq < 0)
868 return chip->watchdog_irq;
870 err = request_threaded_irq(chip->watchdog_irq, NULL,
871 mv88e6xxx_g2_watchdog_thread_fn,
872 IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
873 "mv88e6xxx-watchdog", chip);
877 mutex_lock(&chip->reg_lock);
878 if (chip->info->ops->watchdog_ops->irq_setup)
879 err = chip->info->ops->watchdog_ops->irq_setup(chip);
880 mutex_unlock(&chip->reg_lock);
885 /* Offset 0x1D: Misc Register */
887 static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip *chip,
893 err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_MISC, &val);
898 val |= MV88E6XXX_G2_MISC_5_BIT_PORT;
900 val &= ~MV88E6XXX_G2_MISC_5_BIT_PORT;
902 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MISC, val);
905 int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
907 return mv88e6xxx_g2_misc_5_bit_port(chip, false);
910 static void mv88e6xxx_g2_irq_mask(struct irq_data *d)
912 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
913 unsigned int n = d->hwirq;
915 chip->g2_irq.masked |= (1 << n);
918 static void mv88e6xxx_g2_irq_unmask(struct irq_data *d)
920 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
921 unsigned int n = d->hwirq;
923 chip->g2_irq.masked &= ~(1 << n);
926 static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id)
928 struct mv88e6xxx_chip *chip = dev_id;
929 unsigned int nhandled = 0;
930 unsigned int sub_irq;
935 mutex_lock(&chip->reg_lock);
936 err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_INT_SOURCE, ®);
937 mutex_unlock(&chip->reg_lock);
941 for (n = 0; n < 16; ++n) {
942 if (reg & (1 << n)) {
943 sub_irq = irq_find_mapping(chip->g2_irq.domain, n);
944 handle_nested_irq(sub_irq);
949 return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
952 static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d)
954 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
956 mutex_lock(&chip->reg_lock);
959 static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
961 struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
963 mv88e6xxx_g2_write(chip, MV88E6XXX_G2_INT_MASK, ~chip->g2_irq.masked);
965 mutex_unlock(&chip->reg_lock);
968 static struct irq_chip mv88e6xxx_g2_irq_chip = {
969 .name = "mv88e6xxx-g2",
970 .irq_mask = mv88e6xxx_g2_irq_mask,
971 .irq_unmask = mv88e6xxx_g2_irq_unmask,
972 .irq_bus_lock = mv88e6xxx_g2_irq_bus_lock,
973 .irq_bus_sync_unlock = mv88e6xxx_g2_irq_bus_sync_unlock,
976 static int mv88e6xxx_g2_irq_domain_map(struct irq_domain *d,
978 irq_hw_number_t hwirq)
980 struct mv88e6xxx_chip *chip = d->host_data;
982 irq_set_chip_data(irq, d->host_data);
983 irq_set_chip_and_handler(irq, &chip->g2_irq.chip, handle_level_irq);
984 irq_set_noprobe(irq);
989 static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops = {
990 .map = mv88e6xxx_g2_irq_domain_map,
991 .xlate = irq_domain_xlate_twocell,
994 void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
998 mv88e6xxx_g2_watchdog_free(chip);
1000 free_irq(chip->device_irq, chip);
1001 irq_dispose_mapping(chip->device_irq);
1003 for (irq = 0; irq < 16; irq++) {
1004 virq = irq_find_mapping(chip->g2_irq.domain, irq);
1005 irq_dispose_mapping(virq);
1008 irq_domain_remove(chip->g2_irq.domain);
1011 int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
1015 if (!chip->dev->of_node)
1018 chip->g2_irq.domain = irq_domain_add_simple(
1019 chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
1020 if (!chip->g2_irq.domain)
1023 for (irq = 0; irq < 16; irq++)
1024 irq_create_mapping(chip->g2_irq.domain, irq);
1026 chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
1027 chip->g2_irq.masked = ~0;
1029 chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
1030 MV88E6XXX_G1_STS_IRQ_DEVICE);
1031 if (chip->device_irq < 0) {
1032 err = chip->device_irq;
1036 err = request_threaded_irq(chip->device_irq, NULL,
1037 mv88e6xxx_g2_irq_thread_fn,
1038 IRQF_ONESHOT, "mv88e6xxx-g1", chip);
1042 return mv88e6xxx_g2_watchdog_setup(chip);
1045 for (irq = 0; irq < 16; irq++) {
1046 virq = irq_find_mapping(chip->g2_irq.domain, irq);
1047 irq_dispose_mapping(virq);
1050 irq_domain_remove(chip->g2_irq.domain);
1055 int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
1060 /* Ignore removed tag data on doubly tagged packets, disable
1061 * flow control messages, force flow control priority to the
1062 * highest, and send all special multicast frames to the CPU
1063 * port at the highest priority.
1065 reg = MV88E6XXX_G2_SWITCH_MGMT_FORCE_FLOW_CTL_PRI | (0x7 << 4);
1066 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X) ||
1067 mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X))
1068 reg |= MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU | 0x7;
1069 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, reg);
1073 /* Program the DSA routing table. */
1074 err = mv88e6xxx_g2_set_device_mapping(chip);
1078 /* Clear all trunk masks and mapping. */
1079 err = mv88e6xxx_g2_clear_trunk(chip);
1083 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_POT)) {
1084 /* Clear the priority override table. */
1085 err = mv88e6xxx_g2_clear_pot(chip);