1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Marvell 88E6xxx Switch Global 2 Registers support
5 * Copyright (c) 2008 Marvell Semiconductor
7 * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
8 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
11 #include <linux/bitfield.h>
12 #include <linux/interrupt.h>
13 #include <linux/irqdomain.h>
16 #include "global1.h" /* for MV88E6XXX_G1_STS_IRQ_DEVICE */
19 int mv88e6xxx_g2_read(struct mv88e6xxx_chip
*chip
, int reg
, u16
*val
)
21 return mv88e6xxx_read(chip
, chip
->info
->global2_addr
, reg
, val
);
24 int mv88e6xxx_g2_write(struct mv88e6xxx_chip
*chip
, int reg
, u16 val
)
26 return mv88e6xxx_write(chip
, chip
->info
->global2_addr
, reg
, val
);
29 int mv88e6xxx_g2_update(struct mv88e6xxx_chip
*chip
, int reg
, u16 update
)
31 return mv88e6xxx_update(chip
, chip
->info
->global2_addr
, reg
, update
);
34 int mv88e6xxx_g2_wait(struct mv88e6xxx_chip
*chip
, int reg
, u16 mask
)
36 return mv88e6xxx_wait(chip
, chip
->info
->global2_addr
, reg
, mask
);
39 /* Offset 0x00: Interrupt Source Register */
41 static int mv88e6xxx_g2_int_source(struct mv88e6xxx_chip
*chip
, u16
*src
)
43 /* Read (and clear most of) the Interrupt Source bits */
44 return mv88e6xxx_g2_read(chip
, MV88E6XXX_G2_INT_SRC
, src
);
47 /* Offset 0x01: Interrupt Mask Register */
49 static int mv88e6xxx_g2_int_mask(struct mv88e6xxx_chip
*chip
, u16 mask
)
51 return mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_INT_MASK
, mask
);
54 /* Offset 0x02: Management Enable 2x */
56 static int mv88e6xxx_g2_mgmt_enable_2x(struct mv88e6xxx_chip
*chip
, u16 en2x
)
58 return mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_MGMT_EN_2X
, en2x
);
61 /* Offset 0x03: Management Enable 0x */
63 static int mv88e6xxx_g2_mgmt_enable_0x(struct mv88e6xxx_chip
*chip
, u16 en0x
)
65 return mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_MGMT_EN_0X
, en0x
);
68 /* Offset 0x05: Switch Management Register */
70 static int mv88e6xxx_g2_switch_mgmt_rsvd2cpu(struct mv88e6xxx_chip
*chip
,
76 err
= mv88e6xxx_g2_read(chip
, MV88E6XXX_G2_SWITCH_MGMT
, &val
);
81 val
|= MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU
;
83 val
&= ~MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU
;
85 return mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_SWITCH_MGMT
, val
);
88 int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip
*chip
)
92 /* Consider the frames with reserved multicast destination
93 * addresses matching 01:80:c2:00:00:0x as MGMT.
95 err
= mv88e6xxx_g2_mgmt_enable_0x(chip
, 0xffff);
99 return mv88e6xxx_g2_switch_mgmt_rsvd2cpu(chip
, true);
102 int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip
*chip
)
106 /* Consider the frames with reserved multicast destination
107 * addresses matching 01:80:c2:00:00:2x as MGMT.
109 err
= mv88e6xxx_g2_mgmt_enable_2x(chip
, 0xffff);
113 return mv88e6185_g2_mgmt_rsvd2cpu(chip
);
116 /* Offset 0x06: Device Mapping Table register */
118 int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip
*chip
, int target
,
121 u16 val
= (target
<< 8) | (port
& 0x1f);
122 /* Modern chips use 5 bits to define a device mapping port,
123 * but bit 4 is reserved on older chips, so it is safe to use.
126 return mv88e6xxx_g2_update(chip
, MV88E6XXX_G2_DEVICE_MAPPING
, val
);
129 /* Offset 0x07: Trunk Mask Table register */
131 static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip
*chip
, int num
,
134 u16 val
= (num
<< 12) | (mask
& mv88e6xxx_port_mask(chip
));
137 val
|= MV88E6XXX_G2_TRUNK_MASK_HASH
;
139 return mv88e6xxx_g2_update(chip
, MV88E6XXX_G2_TRUNK_MASK
, val
);
142 /* Offset 0x08: Trunk Mapping Table register */
144 static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip
*chip
, int id
,
147 const u16 port_mask
= BIT(mv88e6xxx_num_ports(chip
)) - 1;
148 u16 val
= (id
<< 11) | (map
& port_mask
);
150 return mv88e6xxx_g2_update(chip
, MV88E6XXX_G2_TRUNK_MAPPING
, val
);
153 int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip
*chip
)
155 const u16 port_mask
= BIT(mv88e6xxx_num_ports(chip
)) - 1;
158 /* Clear all eight possible Trunk Mask vectors */
159 for (i
= 0; i
< 8; ++i
) {
160 err
= mv88e6xxx_g2_trunk_mask_write(chip
, i
, false, port_mask
);
165 /* Clear all sixteen possible Trunk ID routing vectors */
166 for (i
= 0; i
< 16; ++i
) {
167 err
= mv88e6xxx_g2_trunk_mapping_write(chip
, i
, 0);
175 /* Offset 0x09: Ingress Rate Command register
176 * Offset 0x0A: Ingress Rate Data register
179 static int mv88e6xxx_g2_irl_wait(struct mv88e6xxx_chip
*chip
)
181 return mv88e6xxx_g2_wait(chip
, MV88E6XXX_G2_IRL_CMD
,
182 MV88E6XXX_G2_IRL_CMD_BUSY
);
185 static int mv88e6xxx_g2_irl_op(struct mv88e6xxx_chip
*chip
, u16 op
, int port
,
190 err
= mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_IRL_CMD
,
191 MV88E6XXX_G2_IRL_CMD_BUSY
| op
| (port
<< 8) |
196 return mv88e6xxx_g2_irl_wait(chip
);
199 int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip
*chip
, int port
)
201 return mv88e6xxx_g2_irl_op(chip
, MV88E6352_G2_IRL_CMD_OP_INIT_ALL
, port
,
205 int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip
*chip
, int port
)
207 return mv88e6xxx_g2_irl_op(chip
, MV88E6390_G2_IRL_CMD_OP_INIT_ALL
, port
,
211 /* Offset 0x0B: Cross-chip Port VLAN (Addr) Register
212 * Offset 0x0C: Cross-chip Port VLAN Data Register
215 static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip
*chip
)
217 return mv88e6xxx_g2_wait(chip
, MV88E6XXX_G2_PVT_ADDR
,
218 MV88E6XXX_G2_PVT_ADDR_BUSY
);
221 static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip
*chip
, int src_dev
,
222 int src_port
, u16 op
)
226 /* 9-bit Cross-chip PVT pointer: with MV88E6XXX_G2_MISC_5_BIT_PORT
227 * cleared, source device is 5-bit, source port is 4-bit.
229 op
|= MV88E6XXX_G2_PVT_ADDR_BUSY
;
230 op
|= (src_dev
& 0x1f) << 4;
231 op
|= (src_port
& 0xf);
233 err
= mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_PVT_ADDR
, op
);
237 return mv88e6xxx_g2_pvt_op_wait(chip
);
240 int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip
*chip
, int src_dev
,
241 int src_port
, u16 data
)
245 err
= mv88e6xxx_g2_pvt_op_wait(chip
);
249 err
= mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_PVT_DATA
, data
);
253 return mv88e6xxx_g2_pvt_op(chip
, src_dev
, src_port
,
254 MV88E6XXX_G2_PVT_ADDR_OP_WRITE_PVLAN
);
257 /* Offset 0x0D: Switch MAC/WoL/WoF register */
259 static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip
*chip
,
260 unsigned int pointer
, u8 data
)
262 u16 val
= (pointer
<< 8) | data
;
264 return mv88e6xxx_g2_update(chip
, MV88E6XXX_G2_SWITCH_MAC
, val
);
267 int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip
*chip
, u8
*addr
)
271 for (i
= 0; i
< 6; i
++) {
272 err
= mv88e6xxx_g2_switch_mac_write(chip
, i
, addr
[i
]);
280 /* Offset 0x0F: Priority Override Table */
282 static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip
*chip
, int pointer
,
285 u16 val
= (pointer
<< 8) | (data
& 0x7);
287 return mv88e6xxx_g2_update(chip
, MV88E6XXX_G2_PRIO_OVERRIDE
, val
);
290 int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip
*chip
)
294 /* Clear all sixteen possible Priority Override entries */
295 for (i
= 0; i
< 16; i
++) {
296 err
= mv88e6xxx_g2_pot_write(chip
, i
, 0);
304 /* Offset 0x14: EEPROM Command
305 * Offset 0x15: EEPROM Data (for 16-bit data access)
306 * Offset 0x15: EEPROM Addr (for 8-bit data access)
309 static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip
*chip
)
311 return mv88e6xxx_g2_wait(chip
, MV88E6XXX_G2_EEPROM_CMD
,
312 MV88E6XXX_G2_EEPROM_CMD_BUSY
|
313 MV88E6XXX_G2_EEPROM_CMD_RUNNING
);
316 static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip
*chip
, u16 cmd
)
320 err
= mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_EEPROM_CMD
,
321 MV88E6XXX_G2_EEPROM_CMD_BUSY
| cmd
);
325 return mv88e6xxx_g2_eeprom_wait(chip
);
328 static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip
*chip
,
331 u16 cmd
= MV88E6XXX_G2_EEPROM_CMD_OP_READ
;
334 err
= mv88e6xxx_g2_eeprom_wait(chip
);
338 err
= mv88e6xxx_g2_write(chip
, MV88E6390_G2_EEPROM_ADDR
, addr
);
342 err
= mv88e6xxx_g2_eeprom_cmd(chip
, cmd
);
346 err
= mv88e6xxx_g2_read(chip
, MV88E6XXX_G2_EEPROM_CMD
, &cmd
);
355 static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip
*chip
,
358 u16 cmd
= MV88E6XXX_G2_EEPROM_CMD_OP_WRITE
|
359 MV88E6XXX_G2_EEPROM_CMD_WRITE_EN
;
362 err
= mv88e6xxx_g2_eeprom_wait(chip
);
366 err
= mv88e6xxx_g2_write(chip
, MV88E6390_G2_EEPROM_ADDR
, addr
);
370 return mv88e6xxx_g2_eeprom_cmd(chip
, cmd
| data
);
373 static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip
*chip
,
376 u16 cmd
= MV88E6XXX_G2_EEPROM_CMD_OP_READ
| addr
;
379 err
= mv88e6xxx_g2_eeprom_wait(chip
);
383 err
= mv88e6xxx_g2_eeprom_cmd(chip
, cmd
);
387 return mv88e6xxx_g2_read(chip
, MV88E6352_G2_EEPROM_DATA
, data
);
390 static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip
*chip
,
393 u16 cmd
= MV88E6XXX_G2_EEPROM_CMD_OP_WRITE
| addr
;
396 err
= mv88e6xxx_g2_eeprom_wait(chip
);
400 err
= mv88e6xxx_g2_write(chip
, MV88E6352_G2_EEPROM_DATA
, data
);
404 return mv88e6xxx_g2_eeprom_cmd(chip
, cmd
);
407 int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip
*chip
,
408 struct ethtool_eeprom
*eeprom
, u8
*data
)
410 unsigned int offset
= eeprom
->offset
;
411 unsigned int len
= eeprom
->len
;
417 err
= mv88e6xxx_g2_eeprom_read8(chip
, offset
, data
);
430 int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip
*chip
,
431 struct ethtool_eeprom
*eeprom
, u8
*data
)
433 unsigned int offset
= eeprom
->offset
;
434 unsigned int len
= eeprom
->len
;
440 err
= mv88e6xxx_g2_eeprom_write8(chip
, offset
, *data
);
453 int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip
*chip
,
454 struct ethtool_eeprom
*eeprom
, u8
*data
)
456 unsigned int offset
= eeprom
->offset
;
457 unsigned int len
= eeprom
->len
;
464 err
= mv88e6xxx_g2_eeprom_read16(chip
, offset
>> 1, &val
);
468 *data
++ = (val
>> 8) & 0xff;
476 err
= mv88e6xxx_g2_eeprom_read16(chip
, offset
>> 1, &val
);
480 *data
++ = val
& 0xff;
481 *data
++ = (val
>> 8) & 0xff;
489 err
= mv88e6xxx_g2_eeprom_read16(chip
, offset
>> 1, &val
);
493 *data
++ = val
& 0xff;
503 int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip
*chip
,
504 struct ethtool_eeprom
*eeprom
, u8
*data
)
506 unsigned int offset
= eeprom
->offset
;
507 unsigned int len
= eeprom
->len
;
511 /* Ensure the RO WriteEn bit is set */
512 err
= mv88e6xxx_g2_read(chip
, MV88E6XXX_G2_EEPROM_CMD
, &val
);
516 if (!(val
& MV88E6XXX_G2_EEPROM_CMD_WRITE_EN
))
522 err
= mv88e6xxx_g2_eeprom_read16(chip
, offset
>> 1, &val
);
526 val
= (*data
++ << 8) | (val
& 0xff);
528 err
= mv88e6xxx_g2_eeprom_write16(chip
, offset
>> 1, val
);
541 err
= mv88e6xxx_g2_eeprom_write16(chip
, offset
>> 1, val
);
551 err
= mv88e6xxx_g2_eeprom_read16(chip
, offset
>> 1, &val
);
555 val
= (val
& 0xff00) | *data
++;
557 err
= mv88e6xxx_g2_eeprom_write16(chip
, offset
>> 1, val
);
569 /* Offset 0x18: SMI PHY Command Register
570 * Offset 0x19: SMI PHY Data Register
573 static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip
*chip
)
575 return mv88e6xxx_g2_wait(chip
, MV88E6XXX_G2_SMI_PHY_CMD
,
576 MV88E6XXX_G2_SMI_PHY_CMD_BUSY
);
579 static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip
*chip
, u16 cmd
)
583 err
= mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_SMI_PHY_CMD
,
584 MV88E6XXX_G2_SMI_PHY_CMD_BUSY
| cmd
);
588 return mv88e6xxx_g2_smi_phy_wait(chip
);
591 static int mv88e6xxx_g2_smi_phy_access(struct mv88e6xxx_chip
*chip
,
592 bool external
, bool c45
, u16 op
, int dev
,
598 cmd
|= MV88E6390_G2_SMI_PHY_CMD_FUNC_EXTERNAL
;
600 cmd
|= MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL
; /* empty mask */
603 cmd
|= MV88E6XXX_G2_SMI_PHY_CMD_MODE_45
; /* empty mask */
605 cmd
|= MV88E6XXX_G2_SMI_PHY_CMD_MODE_22
;
607 dev
<<= __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK
);
608 cmd
|= dev
& MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK
;
609 cmd
|= reg
& MV88E6XXX_G2_SMI_PHY_CMD_REG_ADDR_MASK
;
611 return mv88e6xxx_g2_smi_phy_cmd(chip
, cmd
);
614 static int mv88e6xxx_g2_smi_phy_access_c22(struct mv88e6xxx_chip
*chip
,
615 bool external
, u16 op
, int dev
,
618 return mv88e6xxx_g2_smi_phy_access(chip
, external
, false, op
, dev
, reg
);
621 /* IEEE 802.3 Clause 22 Read Data Register */
622 static int mv88e6xxx_g2_smi_phy_read_data_c22(struct mv88e6xxx_chip
*chip
,
623 bool external
, int dev
, int reg
,
626 u16 op
= MV88E6XXX_G2_SMI_PHY_CMD_OP_22_READ_DATA
;
629 err
= mv88e6xxx_g2_smi_phy_wait(chip
);
633 err
= mv88e6xxx_g2_smi_phy_access_c22(chip
, external
, op
, dev
, reg
);
637 return mv88e6xxx_g2_read(chip
, MV88E6XXX_G2_SMI_PHY_DATA
, data
);
640 /* IEEE 802.3 Clause 22 Write Data Register */
641 static int mv88e6xxx_g2_smi_phy_write_data_c22(struct mv88e6xxx_chip
*chip
,
642 bool external
, int dev
, int reg
,
645 u16 op
= MV88E6XXX_G2_SMI_PHY_CMD_OP_22_WRITE_DATA
;
648 err
= mv88e6xxx_g2_smi_phy_wait(chip
);
652 err
= mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_SMI_PHY_DATA
, data
);
656 return mv88e6xxx_g2_smi_phy_access_c22(chip
, external
, op
, dev
, reg
);
659 static int mv88e6xxx_g2_smi_phy_access_c45(struct mv88e6xxx_chip
*chip
,
660 bool external
, u16 op
, int port
,
663 return mv88e6xxx_g2_smi_phy_access(chip
, external
, true, op
, port
, dev
);
666 /* IEEE 802.3 Clause 45 Write Address Register */
667 static int mv88e6xxx_g2_smi_phy_write_addr_c45(struct mv88e6xxx_chip
*chip
,
668 bool external
, int port
, int dev
,
671 u16 op
= MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_ADDR
;
674 err
= mv88e6xxx_g2_smi_phy_wait(chip
);
678 err
= mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_SMI_PHY_DATA
, addr
);
682 return mv88e6xxx_g2_smi_phy_access_c45(chip
, external
, op
, port
, dev
);
685 /* IEEE 802.3 Clause 45 Read Data Register */
686 static int mv88e6xxx_g2_smi_phy_read_data_c45(struct mv88e6xxx_chip
*chip
,
687 bool external
, int port
, int dev
,
690 u16 op
= MV88E6XXX_G2_SMI_PHY_CMD_OP_45_READ_DATA
;
693 err
= mv88e6xxx_g2_smi_phy_access_c45(chip
, external
, op
, port
, dev
);
697 return mv88e6xxx_g2_read(chip
, MV88E6XXX_G2_SMI_PHY_DATA
, data
);
700 static int mv88e6xxx_g2_smi_phy_read_c45(struct mv88e6xxx_chip
*chip
,
701 bool external
, int port
, int reg
,
704 int dev
= (reg
>> 16) & 0x1f;
705 int addr
= reg
& 0xffff;
708 err
= mv88e6xxx_g2_smi_phy_write_addr_c45(chip
, external
, port
, dev
,
713 return mv88e6xxx_g2_smi_phy_read_data_c45(chip
, external
, port
, dev
,
717 /* IEEE 802.3 Clause 45 Write Data Register */
718 static int mv88e6xxx_g2_smi_phy_write_data_c45(struct mv88e6xxx_chip
*chip
,
719 bool external
, int port
, int dev
,
722 u16 op
= MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_DATA
;
725 err
= mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_SMI_PHY_DATA
, data
);
729 return mv88e6xxx_g2_smi_phy_access_c45(chip
, external
, op
, port
, dev
);
732 static int mv88e6xxx_g2_smi_phy_write_c45(struct mv88e6xxx_chip
*chip
,
733 bool external
, int port
, int reg
,
736 int dev
= (reg
>> 16) & 0x1f;
737 int addr
= reg
& 0xffff;
740 err
= mv88e6xxx_g2_smi_phy_write_addr_c45(chip
, external
, port
, dev
,
745 return mv88e6xxx_g2_smi_phy_write_data_c45(chip
, external
, port
, dev
,
749 int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip
*chip
, struct mii_bus
*bus
,
750 int addr
, int reg
, u16
*val
)
752 struct mv88e6xxx_mdio_bus
*mdio_bus
= bus
->priv
;
753 bool external
= mdio_bus
->external
;
755 if (reg
& MII_ADDR_C45
)
756 return mv88e6xxx_g2_smi_phy_read_c45(chip
, external
, addr
, reg
,
759 return mv88e6xxx_g2_smi_phy_read_data_c22(chip
, external
, addr
, reg
,
763 int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip
*chip
, struct mii_bus
*bus
,
764 int addr
, int reg
, u16 val
)
766 struct mv88e6xxx_mdio_bus
*mdio_bus
= bus
->priv
;
767 bool external
= mdio_bus
->external
;
769 if (reg
& MII_ADDR_C45
)
770 return mv88e6xxx_g2_smi_phy_write_c45(chip
, external
, addr
, reg
,
773 return mv88e6xxx_g2_smi_phy_write_data_c22(chip
, external
, addr
, reg
,
777 /* Offset 0x1B: Watchdog Control */
778 static int mv88e6097_watchdog_action(struct mv88e6xxx_chip
*chip
, int irq
)
782 mv88e6xxx_g2_read(chip
, MV88E6352_G2_WDOG_CTL
, ®
);
784 dev_info(chip
->dev
, "Watchdog event: 0x%04x", reg
);
789 static void mv88e6097_watchdog_free(struct mv88e6xxx_chip
*chip
)
793 mv88e6xxx_g2_read(chip
, MV88E6352_G2_WDOG_CTL
, ®
);
795 reg
&= ~(MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE
|
796 MV88E6352_G2_WDOG_CTL_QC_ENABLE
);
798 mv88e6xxx_g2_write(chip
, MV88E6352_G2_WDOG_CTL
, reg
);
801 static int mv88e6097_watchdog_setup(struct mv88e6xxx_chip
*chip
)
803 return mv88e6xxx_g2_write(chip
, MV88E6352_G2_WDOG_CTL
,
804 MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE
|
805 MV88E6352_G2_WDOG_CTL_QC_ENABLE
|
806 MV88E6352_G2_WDOG_CTL_SWRESET
);
809 const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops
= {
810 .irq_action
= mv88e6097_watchdog_action
,
811 .irq_setup
= mv88e6097_watchdog_setup
,
812 .irq_free
= mv88e6097_watchdog_free
,
815 static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip
*chip
)
817 return mv88e6xxx_g2_update(chip
, MV88E6390_G2_WDOG_CTL
,
818 MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE
|
819 MV88E6390_G2_WDOG_CTL_CUT_THROUGH
|
820 MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER
|
821 MV88E6390_G2_WDOG_CTL_EGRESS
|
822 MV88E6390_G2_WDOG_CTL_FORCE_IRQ
);
825 static int mv88e6390_watchdog_action(struct mv88e6xxx_chip
*chip
, int irq
)
830 mv88e6xxx_g2_write(chip
, MV88E6390_G2_WDOG_CTL
,
831 MV88E6390_G2_WDOG_CTL_PTR_EVENT
);
832 err
= mv88e6xxx_g2_read(chip
, MV88E6390_G2_WDOG_CTL
, ®
);
834 dev_info(chip
->dev
, "Watchdog event: 0x%04x",
835 reg
& MV88E6390_G2_WDOG_CTL_DATA_MASK
);
837 mv88e6xxx_g2_write(chip
, MV88E6390_G2_WDOG_CTL
,
838 MV88E6390_G2_WDOG_CTL_PTR_HISTORY
);
839 err
= mv88e6xxx_g2_read(chip
, MV88E6390_G2_WDOG_CTL
, ®
);
841 dev_info(chip
->dev
, "Watchdog history: 0x%04x",
842 reg
& MV88E6390_G2_WDOG_CTL_DATA_MASK
);
844 /* Trigger a software reset to try to recover the switch */
845 if (chip
->info
->ops
->reset
)
846 chip
->info
->ops
->reset(chip
);
848 mv88e6390_watchdog_setup(chip
);
853 static void mv88e6390_watchdog_free(struct mv88e6xxx_chip
*chip
)
855 mv88e6xxx_g2_update(chip
, MV88E6390_G2_WDOG_CTL
,
856 MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE
);
859 const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops
= {
860 .irq_action
= mv88e6390_watchdog_action
,
861 .irq_setup
= mv88e6390_watchdog_setup
,
862 .irq_free
= mv88e6390_watchdog_free
,
865 static irqreturn_t
mv88e6xxx_g2_watchdog_thread_fn(int irq
, void *dev_id
)
867 struct mv88e6xxx_chip
*chip
= dev_id
;
868 irqreturn_t ret
= IRQ_NONE
;
870 mutex_lock(&chip
->reg_lock
);
871 if (chip
->info
->ops
->watchdog_ops
->irq_action
)
872 ret
= chip
->info
->ops
->watchdog_ops
->irq_action(chip
, irq
);
873 mutex_unlock(&chip
->reg_lock
);
878 static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip
*chip
)
880 mutex_lock(&chip
->reg_lock
);
881 if (chip
->info
->ops
->watchdog_ops
->irq_free
)
882 chip
->info
->ops
->watchdog_ops
->irq_free(chip
);
883 mutex_unlock(&chip
->reg_lock
);
885 free_irq(chip
->watchdog_irq
, chip
);
886 irq_dispose_mapping(chip
->watchdog_irq
);
889 static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip
*chip
)
893 chip
->watchdog_irq
= irq_find_mapping(chip
->g2_irq
.domain
,
894 MV88E6XXX_G2_INT_SOURCE_WATCHDOG
);
895 if (chip
->watchdog_irq
< 0)
896 return chip
->watchdog_irq
;
898 err
= request_threaded_irq(chip
->watchdog_irq
, NULL
,
899 mv88e6xxx_g2_watchdog_thread_fn
,
900 IRQF_ONESHOT
| IRQF_TRIGGER_FALLING
,
901 "mv88e6xxx-watchdog", chip
);
905 mutex_lock(&chip
->reg_lock
);
906 if (chip
->info
->ops
->watchdog_ops
->irq_setup
)
907 err
= chip
->info
->ops
->watchdog_ops
->irq_setup(chip
);
908 mutex_unlock(&chip
->reg_lock
);
913 /* Offset 0x1D: Misc Register */
915 static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip
*chip
,
921 err
= mv88e6xxx_g2_read(chip
, MV88E6XXX_G2_MISC
, &val
);
926 val
|= MV88E6XXX_G2_MISC_5_BIT_PORT
;
928 val
&= ~MV88E6XXX_G2_MISC_5_BIT_PORT
;
930 return mv88e6xxx_g2_write(chip
, MV88E6XXX_G2_MISC
, val
);
933 int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip
*chip
)
935 return mv88e6xxx_g2_misc_5_bit_port(chip
, false);
938 static void mv88e6xxx_g2_irq_mask(struct irq_data
*d
)
940 struct mv88e6xxx_chip
*chip
= irq_data_get_irq_chip_data(d
);
941 unsigned int n
= d
->hwirq
;
943 chip
->g2_irq
.masked
|= (1 << n
);
946 static void mv88e6xxx_g2_irq_unmask(struct irq_data
*d
)
948 struct mv88e6xxx_chip
*chip
= irq_data_get_irq_chip_data(d
);
949 unsigned int n
= d
->hwirq
;
951 chip
->g2_irq
.masked
&= ~(1 << n
);
954 static irqreturn_t
mv88e6xxx_g2_irq_thread_fn(int irq
, void *dev_id
)
956 struct mv88e6xxx_chip
*chip
= dev_id
;
957 unsigned int nhandled
= 0;
958 unsigned int sub_irq
;
963 mutex_lock(&chip
->reg_lock
);
964 err
= mv88e6xxx_g2_int_source(chip
, ®
);
965 mutex_unlock(&chip
->reg_lock
);
969 for (n
= 0; n
< 16; ++n
) {
970 if (reg
& (1 << n
)) {
971 sub_irq
= irq_find_mapping(chip
->g2_irq
.domain
, n
);
972 handle_nested_irq(sub_irq
);
977 return (nhandled
> 0 ? IRQ_HANDLED
: IRQ_NONE
);
980 static void mv88e6xxx_g2_irq_bus_lock(struct irq_data
*d
)
982 struct mv88e6xxx_chip
*chip
= irq_data_get_irq_chip_data(d
);
984 mutex_lock(&chip
->reg_lock
);
987 static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data
*d
)
989 struct mv88e6xxx_chip
*chip
= irq_data_get_irq_chip_data(d
);
992 err
= mv88e6xxx_g2_int_mask(chip
, ~chip
->g2_irq
.masked
);
994 dev_err(chip
->dev
, "failed to mask interrupts\n");
996 mutex_unlock(&chip
->reg_lock
);
999 static const struct irq_chip mv88e6xxx_g2_irq_chip
= {
1000 .name
= "mv88e6xxx-g2",
1001 .irq_mask
= mv88e6xxx_g2_irq_mask
,
1002 .irq_unmask
= mv88e6xxx_g2_irq_unmask
,
1003 .irq_bus_lock
= mv88e6xxx_g2_irq_bus_lock
,
1004 .irq_bus_sync_unlock
= mv88e6xxx_g2_irq_bus_sync_unlock
,
1007 static int mv88e6xxx_g2_irq_domain_map(struct irq_domain
*d
,
1009 irq_hw_number_t hwirq
)
1011 struct mv88e6xxx_chip
*chip
= d
->host_data
;
1013 irq_set_chip_data(irq
, d
->host_data
);
1014 irq_set_chip_and_handler(irq
, &chip
->g2_irq
.chip
, handle_level_irq
);
1015 irq_set_noprobe(irq
);
1020 static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops
= {
1021 .map
= mv88e6xxx_g2_irq_domain_map
,
1022 .xlate
= irq_domain_xlate_twocell
,
1025 void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip
*chip
)
1029 mv88e6xxx_g2_watchdog_free(chip
);
1031 free_irq(chip
->device_irq
, chip
);
1032 irq_dispose_mapping(chip
->device_irq
);
1034 for (irq
= 0; irq
< 16; irq
++) {
1035 virq
= irq_find_mapping(chip
->g2_irq
.domain
, irq
);
1036 irq_dispose_mapping(virq
);
1039 irq_domain_remove(chip
->g2_irq
.domain
);
1042 int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip
*chip
)
1046 chip
->g2_irq
.domain
= irq_domain_add_simple(
1047 chip
->dev
->of_node
, 16, 0, &mv88e6xxx_g2_irq_domain_ops
, chip
);
1048 if (!chip
->g2_irq
.domain
)
1051 for (irq
= 0; irq
< 16; irq
++)
1052 irq_create_mapping(chip
->g2_irq
.domain
, irq
);
1054 chip
->g2_irq
.chip
= mv88e6xxx_g2_irq_chip
;
1055 chip
->g2_irq
.masked
= ~0;
1057 chip
->device_irq
= irq_find_mapping(chip
->g1_irq
.domain
,
1058 MV88E6XXX_G1_STS_IRQ_DEVICE
);
1059 if (chip
->device_irq
< 0) {
1060 err
= chip
->device_irq
;
1064 err
= request_threaded_irq(chip
->device_irq
, NULL
,
1065 mv88e6xxx_g2_irq_thread_fn
,
1066 IRQF_ONESHOT
, "mv88e6xxx-g2", chip
);
1070 return mv88e6xxx_g2_watchdog_setup(chip
);
1073 for (irq
= 0; irq
< 16; irq
++) {
1074 virq
= irq_find_mapping(chip
->g2_irq
.domain
, irq
);
1075 irq_dispose_mapping(virq
);
1078 irq_domain_remove(chip
->g2_irq
.domain
);
1083 int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip
*chip
,
1084 struct mii_bus
*bus
)
1086 int phy
, irq
, err
, err_phy
;
1088 for (phy
= 0; phy
< chip
->info
->num_internal_phys
; phy
++) {
1089 irq
= irq_find_mapping(chip
->g2_irq
.domain
, phy
);
1094 bus
->irq
[chip
->info
->phy_base_addr
+ phy
] = irq
;
1100 for (phy
= 0; phy
< err_phy
; phy
++)
1101 irq_dispose_mapping(bus
->irq
[phy
]);
1106 void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip
*chip
,
1107 struct mii_bus
*bus
)
1111 for (phy
= 0; phy
< chip
->info
->num_internal_phys
; phy
++)
1112 irq_dispose_mapping(bus
->irq
[phy
]);