Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Marvell 88E6xxx Switch Global 2 Registers support
0004  *
0005  * Copyright (c) 2008 Marvell Semiconductor
0006  *
0007  * Copyright (c) 2016-2017 Savoir-faire Linux Inc.
0008  *  Vivien Didelot <vivien.didelot@savoirfairelinux.com>
0009  */
0010 
0011 #include <linux/bitfield.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/irqdomain.h>
0014 
0015 #include "chip.h"
0016 #include "global1.h" /* for MV88E6XXX_G1_STS_IRQ_DEVICE */
0017 #include "global2.h"
0018 
0019 int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
0020 {
0021     return mv88e6xxx_read(chip, chip->info->global2_addr, reg, val);
0022 }
0023 
0024 int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
0025 {
0026     return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
0027 }
0028 
0029 int mv88e6xxx_g2_wait_bit(struct mv88e6xxx_chip *chip, int reg, int
0030               bit, int val)
0031 {
0032     return mv88e6xxx_wait_bit(chip, chip->info->global2_addr, reg,
0033                   bit, val);
0034 }
0035 
0036 /* Offset 0x00: Interrupt Source Register */
0037 
0038 static int mv88e6xxx_g2_int_source(struct mv88e6xxx_chip *chip, u16 *src)
0039 {
0040     /* Read (and clear most of) the Interrupt Source bits */
0041     return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_INT_SRC, src);
0042 }
0043 
0044 /* Offset 0x01: Interrupt Mask Register */
0045 
0046 static int mv88e6xxx_g2_int_mask(struct mv88e6xxx_chip *chip, u16 mask)
0047 {
0048     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_INT_MASK, mask);
0049 }
0050 
0051 /* Offset 0x02: Management Enable 2x */
0052 
0053 static int mv88e6xxx_g2_mgmt_enable_2x(struct mv88e6xxx_chip *chip, u16 en2x)
0054 {
0055     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_2X, en2x);
0056 }
0057 
0058 /* Offset 0x03: Management Enable 0x */
0059 
0060 static int mv88e6xxx_g2_mgmt_enable_0x(struct mv88e6xxx_chip *chip, u16 en0x)
0061 {
0062     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_0X, en0x);
0063 }
0064 
0065 /* Offset 0x05: Switch Management Register */
0066 
0067 static int mv88e6xxx_g2_switch_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip,
0068                          bool enable)
0069 {
0070     u16 val;
0071     int err;
0072 
0073     err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SWITCH_MGMT, &val);
0074     if (err)
0075         return err;
0076 
0077     if (enable)
0078         val |= MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
0079     else
0080         val &= ~MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
0081 
0082     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, val);
0083 }
0084 
0085 int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
0086 {
0087     int err;
0088 
0089     /* Consider the frames with reserved multicast destination
0090      * addresses matching 01:80:c2:00:00:0x as MGMT.
0091      */
0092     err = mv88e6xxx_g2_mgmt_enable_0x(chip, 0xffff);
0093     if (err)
0094         return err;
0095 
0096     return mv88e6xxx_g2_switch_mgmt_rsvd2cpu(chip, true);
0097 }
0098 
0099 int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
0100 {
0101     int err;
0102 
0103     /* Consider the frames with reserved multicast destination
0104      * addresses matching 01:80:c2:00:00:2x as MGMT.
0105      */
0106     err = mv88e6xxx_g2_mgmt_enable_2x(chip, 0xffff);
0107     if (err)
0108         return err;
0109 
0110     return mv88e6185_g2_mgmt_rsvd2cpu(chip);
0111 }
0112 
0113 /* Offset 0x06: Device Mapping Table register */
0114 
0115 int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
0116                       int port)
0117 {
0118     u16 val = (target << 8) | (port & 0x1f);
0119     /* Modern chips use 5 bits to define a device mapping port,
0120      * but bit 4 is reserved on older chips, so it is safe to use.
0121      */
0122 
0123     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_DEVICE_MAPPING,
0124                   MV88E6XXX_G2_DEVICE_MAPPING_UPDATE | val);
0125 }
0126 
0127 /* Offset 0x07: Trunk Mask Table register */
0128 
0129 int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num,
0130                   bool hash, u16 mask)
0131 {
0132     u16 val = (num << 12) | (mask & mv88e6xxx_port_mask(chip));
0133 
0134     if (hash)
0135         val |= MV88E6XXX_G2_TRUNK_MASK_HASH;
0136 
0137     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MASK,
0138                   MV88E6XXX_G2_TRUNK_MASK_UPDATE | val);
0139 }
0140 
0141 /* Offset 0x08: Trunk Mapping Table register */
0142 
0143 int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id,
0144                      u16 map)
0145 {
0146     const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
0147     u16 val = (id << 11) | (map & port_mask);
0148 
0149     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MAPPING,
0150                   MV88E6XXX_G2_TRUNK_MAPPING_UPDATE | val);
0151 }
0152 
0153 int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip)
0154 {
0155     const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
0156     int i, err;
0157 
0158     /* Clear all eight possible Trunk Mask vectors */
0159     for (i = 0; i < 8; ++i) {
0160         err = mv88e6xxx_g2_trunk_mask_write(chip, i, false, port_mask);
0161         if (err)
0162             return err;
0163     }
0164 
0165     /* Clear all sixteen possible Trunk ID routing vectors */
0166     for (i = 0; i < 16; ++i) {
0167         err = mv88e6xxx_g2_trunk_mapping_write(chip, i, 0);
0168         if (err)
0169             return err;
0170     }
0171 
0172     return 0;
0173 }
0174 
0175 /* Offset 0x09: Ingress Rate Command register
0176  * Offset 0x0A: Ingress Rate Data register
0177  */
0178 
0179 static int mv88e6xxx_g2_irl_wait(struct mv88e6xxx_chip *chip)
0180 {
0181     int bit = __bf_shf(MV88E6XXX_G2_IRL_CMD_BUSY);
0182 
0183     return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_IRL_CMD, bit, 0);
0184 }
0185 
0186 static int mv88e6xxx_g2_irl_op(struct mv88e6xxx_chip *chip, u16 op, int port,
0187                    int res, int reg)
0188 {
0189     int err;
0190 
0191     err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_IRL_CMD,
0192                  MV88E6XXX_G2_IRL_CMD_BUSY | op | (port << 8) |
0193                  (res << 5) | reg);
0194     if (err)
0195         return err;
0196 
0197     return mv88e6xxx_g2_irl_wait(chip);
0198 }
0199 
0200 int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
0201 {
0202     return mv88e6xxx_g2_irl_op(chip, MV88E6352_G2_IRL_CMD_OP_INIT_ALL, port,
0203                    0, 0);
0204 }
0205 
0206 int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
0207 {
0208     return mv88e6xxx_g2_irl_op(chip, MV88E6390_G2_IRL_CMD_OP_INIT_ALL, port,
0209                    0, 0);
0210 }
0211 
0212 /* Offset 0x0B: Cross-chip Port VLAN (Addr) Register
0213  * Offset 0x0C: Cross-chip Port VLAN Data Register
0214  */
0215 
0216 static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip *chip)
0217 {
0218     int bit = __bf_shf(MV88E6XXX_G2_PVT_ADDR_BUSY);
0219 
0220     return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_PVT_ADDR, bit, 0);
0221 }
0222 
0223 static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip *chip, int src_dev,
0224                    int src_port, u16 op)
0225 {
0226     int err;
0227 
0228     /* 9-bit Cross-chip PVT pointer: with MV88E6XXX_G2_MISC_5_BIT_PORT
0229      * cleared, source device is 5-bit, source port is 4-bit.
0230      */
0231     op |= MV88E6XXX_G2_PVT_ADDR_BUSY;
0232     op |= (src_dev & 0x1f) << 4;
0233     op |= (src_port & 0xf);
0234 
0235     err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_ADDR, op);
0236     if (err)
0237         return err;
0238 
0239     return mv88e6xxx_g2_pvt_op_wait(chip);
0240 }
0241 
0242 int mv88e6xxx_g2_pvt_read(struct mv88e6xxx_chip *chip, int src_dev,
0243               int src_port, u16 *data)
0244 {
0245     int err;
0246 
0247     err = mv88e6xxx_g2_pvt_op_wait(chip);
0248     if (err)
0249         return err;
0250 
0251     err = mv88e6xxx_g2_pvt_op(chip, src_dev, src_port,
0252                   MV88E6XXX_G2_PVT_ADDR_OP_READ);
0253     if (err)
0254         return err;
0255 
0256     return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_PVT_DATA, data);
0257 }
0258 
0259 int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
0260                int src_port, u16 data)
0261 {
0262     int err;
0263 
0264     err = mv88e6xxx_g2_pvt_op_wait(chip);
0265     if (err)
0266         return err;
0267 
0268     err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PVT_DATA, data);
0269     if (err)
0270         return err;
0271 
0272     return mv88e6xxx_g2_pvt_op(chip, src_dev, src_port,
0273                    MV88E6XXX_G2_PVT_ADDR_OP_WRITE_PVLAN);
0274 }
0275 
0276 /* Offset 0x0D: Switch MAC/WoL/WoF register */
0277 
0278 static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
0279                      unsigned int pointer, u8 data)
0280 {
0281     u16 val = (pointer << 8) | data;
0282 
0283     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MAC,
0284                   MV88E6XXX_G2_SWITCH_MAC_UPDATE | val);
0285 }
0286 
0287 int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
0288 {
0289     int i, err;
0290 
0291     for (i = 0; i < 6; i++) {
0292         err = mv88e6xxx_g2_switch_mac_write(chip, i, addr[i]);
0293         if (err)
0294             break;
0295     }
0296 
0297     return err;
0298 }
0299 
0300 /* Offset 0x0E: ATU Statistics */
0301 
0302 int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin)
0303 {
0304     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_ATU_STATS,
0305                   kind | bin);
0306 }
0307 
0308 int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats)
0309 {
0310     return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_ATU_STATS, stats);
0311 }
0312 
0313 /* Offset 0x0F: Priority Override Table */
0314 
0315 static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
0316                   u8 data)
0317 {
0318     u16 val = (pointer << 8) | (data & 0x7);
0319 
0320     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PRIO_OVERRIDE,
0321                   MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE | val);
0322 }
0323 
0324 int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
0325 {
0326     int i, err;
0327 
0328     /* Clear all sixteen possible Priority Override entries */
0329     for (i = 0; i < 16; i++) {
0330         err = mv88e6xxx_g2_pot_write(chip, i, 0);
0331         if (err)
0332             break;
0333     }
0334 
0335     return err;
0336 }
0337 
0338 /* Offset 0x14: EEPROM Command
0339  * Offset 0x15: EEPROM Data (for 16-bit data access)
0340  * Offset 0x15: EEPROM Addr (for 8-bit data access)
0341  */
0342 
0343 static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
0344 {
0345     int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY);
0346     int err;
0347 
0348     err = mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
0349     if (err)
0350         return err;
0351 
0352     bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_RUNNING);
0353 
0354     return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
0355 }
0356 
0357 static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
0358 {
0359     int err;
0360 
0361     err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_EEPROM_CMD,
0362                  MV88E6XXX_G2_EEPROM_CMD_BUSY | cmd);
0363     if (err)
0364         return err;
0365 
0366     return mv88e6xxx_g2_eeprom_wait(chip);
0367 }
0368 
0369 static int mv88e6xxx_g2_eeprom_read8(struct mv88e6xxx_chip *chip,
0370                      u16 addr, u8 *data)
0371 {
0372     u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ;
0373     int err;
0374 
0375     err = mv88e6xxx_g2_eeprom_wait(chip);
0376     if (err)
0377         return err;
0378 
0379     err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
0380     if (err)
0381         return err;
0382 
0383     err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
0384     if (err)
0385         return err;
0386 
0387     err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &cmd);
0388     if (err)
0389         return err;
0390 
0391     *data = cmd & 0xff;
0392 
0393     return 0;
0394 }
0395 
0396 static int mv88e6xxx_g2_eeprom_write8(struct mv88e6xxx_chip *chip,
0397                       u16 addr, u8 data)
0398 {
0399     u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE |
0400         MV88E6XXX_G2_EEPROM_CMD_WRITE_EN;
0401     int err;
0402 
0403     err = mv88e6xxx_g2_eeprom_wait(chip);
0404     if (err)
0405         return err;
0406 
0407     err = mv88e6xxx_g2_write(chip, MV88E6390_G2_EEPROM_ADDR, addr);
0408     if (err)
0409         return err;
0410 
0411     return mv88e6xxx_g2_eeprom_cmd(chip, cmd | data);
0412 }
0413 
0414 static int mv88e6xxx_g2_eeprom_read16(struct mv88e6xxx_chip *chip,
0415                       u8 addr, u16 *data)
0416 {
0417     u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_READ | addr;
0418     int err;
0419 
0420     err = mv88e6xxx_g2_eeprom_wait(chip);
0421     if (err)
0422         return err;
0423 
0424     err = mv88e6xxx_g2_eeprom_cmd(chip, cmd);
0425     if (err)
0426         return err;
0427 
0428     return mv88e6xxx_g2_read(chip, MV88E6352_G2_EEPROM_DATA, data);
0429 }
0430 
0431 static int mv88e6xxx_g2_eeprom_write16(struct mv88e6xxx_chip *chip,
0432                        u8 addr, u16 data)
0433 {
0434     u16 cmd = MV88E6XXX_G2_EEPROM_CMD_OP_WRITE | addr;
0435     int err;
0436 
0437     err = mv88e6xxx_g2_eeprom_wait(chip);
0438     if (err)
0439         return err;
0440 
0441     err = mv88e6xxx_g2_write(chip, MV88E6352_G2_EEPROM_DATA, data);
0442     if (err)
0443         return err;
0444 
0445     return mv88e6xxx_g2_eeprom_cmd(chip, cmd);
0446 }
0447 
0448 int mv88e6xxx_g2_get_eeprom8(struct mv88e6xxx_chip *chip,
0449                  struct ethtool_eeprom *eeprom, u8 *data)
0450 {
0451     unsigned int offset = eeprom->offset;
0452     unsigned int len = eeprom->len;
0453     int err;
0454 
0455     eeprom->len = 0;
0456 
0457     while (len) {
0458         err = mv88e6xxx_g2_eeprom_read8(chip, offset, data);
0459         if (err)
0460             return err;
0461 
0462         eeprom->len++;
0463         offset++;
0464         data++;
0465         len--;
0466     }
0467 
0468     return 0;
0469 }
0470 
0471 int mv88e6xxx_g2_set_eeprom8(struct mv88e6xxx_chip *chip,
0472                  struct ethtool_eeprom *eeprom, u8 *data)
0473 {
0474     unsigned int offset = eeprom->offset;
0475     unsigned int len = eeprom->len;
0476     int err;
0477 
0478     eeprom->len = 0;
0479 
0480     while (len) {
0481         err = mv88e6xxx_g2_eeprom_write8(chip, offset, *data);
0482         if (err)
0483             return err;
0484 
0485         eeprom->len++;
0486         offset++;
0487         data++;
0488         len--;
0489     }
0490 
0491     return 0;
0492 }
0493 
0494 int mv88e6xxx_g2_get_eeprom16(struct mv88e6xxx_chip *chip,
0495                   struct ethtool_eeprom *eeprom, u8 *data)
0496 {
0497     unsigned int offset = eeprom->offset;
0498     unsigned int len = eeprom->len;
0499     u16 val;
0500     int err;
0501 
0502     eeprom->len = 0;
0503 
0504     if (offset & 1) {
0505         err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
0506         if (err)
0507             return err;
0508 
0509         *data++ = (val >> 8) & 0xff;
0510 
0511         offset++;
0512         len--;
0513         eeprom->len++;
0514     }
0515 
0516     while (len >= 2) {
0517         err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
0518         if (err)
0519             return err;
0520 
0521         *data++ = val & 0xff;
0522         *data++ = (val >> 8) & 0xff;
0523 
0524         offset += 2;
0525         len -= 2;
0526         eeprom->len += 2;
0527     }
0528 
0529     if (len) {
0530         err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
0531         if (err)
0532             return err;
0533 
0534         *data++ = val & 0xff;
0535 
0536         offset++;
0537         len--;
0538         eeprom->len++;
0539     }
0540 
0541     return 0;
0542 }
0543 
0544 int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
0545                   struct ethtool_eeprom *eeprom, u8 *data)
0546 {
0547     unsigned int offset = eeprom->offset;
0548     unsigned int len = eeprom->len;
0549     u16 val;
0550     int err;
0551 
0552     /* Ensure the RO WriteEn bit is set */
0553     err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_EEPROM_CMD, &val);
0554     if (err)
0555         return err;
0556 
0557     if (!(val & MV88E6XXX_G2_EEPROM_CMD_WRITE_EN))
0558         return -EROFS;
0559 
0560     eeprom->len = 0;
0561 
0562     if (offset & 1) {
0563         err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
0564         if (err)
0565             return err;
0566 
0567         val = (*data++ << 8) | (val & 0xff);
0568 
0569         err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
0570         if (err)
0571             return err;
0572 
0573         offset++;
0574         len--;
0575         eeprom->len++;
0576     }
0577 
0578     while (len >= 2) {
0579         val = *data++;
0580         val |= *data++ << 8;
0581 
0582         err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
0583         if (err)
0584             return err;
0585 
0586         offset += 2;
0587         len -= 2;
0588         eeprom->len += 2;
0589     }
0590 
0591     if (len) {
0592         err = mv88e6xxx_g2_eeprom_read16(chip, offset >> 1, &val);
0593         if (err)
0594             return err;
0595 
0596         val = (val & 0xff00) | *data++;
0597 
0598         err = mv88e6xxx_g2_eeprom_write16(chip, offset >> 1, val);
0599         if (err)
0600             return err;
0601 
0602         offset++;
0603         len--;
0604         eeprom->len++;
0605     }
0606 
0607     return 0;
0608 }
0609 
0610 /* Offset 0x18: SMI PHY Command Register
0611  * Offset 0x19: SMI PHY Data Register
0612  */
0613 
0614 static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
0615 {
0616     int bit = __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
0617 
0618     return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_SMI_PHY_CMD, bit, 0);
0619 }
0620 
0621 static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
0622 {
0623     int err;
0624 
0625     err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_CMD,
0626                  MV88E6XXX_G2_SMI_PHY_CMD_BUSY | cmd);
0627     if (err)
0628         return err;
0629 
0630     return mv88e6xxx_g2_smi_phy_wait(chip);
0631 }
0632 
0633 static int mv88e6xxx_g2_smi_phy_access(struct mv88e6xxx_chip *chip,
0634                        bool external, bool c45, u16 op, int dev,
0635                        int reg)
0636 {
0637     u16 cmd = op;
0638 
0639     if (external)
0640         cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_EXTERNAL;
0641     else
0642         cmd |= MV88E6390_G2_SMI_PHY_CMD_FUNC_INTERNAL; /* empty mask */
0643 
0644     if (c45)
0645         cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_45; /* empty mask */
0646     else
0647         cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_22;
0648 
0649     dev <<= __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK);
0650     cmd |= dev & MV88E6XXX_G2_SMI_PHY_CMD_DEV_ADDR_MASK;
0651     cmd |= reg & MV88E6XXX_G2_SMI_PHY_CMD_REG_ADDR_MASK;
0652 
0653     return mv88e6xxx_g2_smi_phy_cmd(chip, cmd);
0654 }
0655 
0656 static int mv88e6xxx_g2_smi_phy_access_c22(struct mv88e6xxx_chip *chip,
0657                        bool external, u16 op, int dev,
0658                        int reg)
0659 {
0660     return mv88e6xxx_g2_smi_phy_access(chip, external, false, op, dev, reg);
0661 }
0662 
0663 /* IEEE 802.3 Clause 22 Read Data Register */
0664 static int mv88e6xxx_g2_smi_phy_read_data_c22(struct mv88e6xxx_chip *chip,
0665                           bool external, int dev, int reg,
0666                           u16 *data)
0667 {
0668     u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_READ_DATA;
0669     int err;
0670 
0671     err = mv88e6xxx_g2_smi_phy_wait(chip);
0672     if (err)
0673         return err;
0674 
0675     err = mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
0676     if (err)
0677         return err;
0678 
0679     return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
0680 }
0681 
0682 /* IEEE 802.3 Clause 22 Write Data Register */
0683 static int mv88e6xxx_g2_smi_phy_write_data_c22(struct mv88e6xxx_chip *chip,
0684                            bool external, int dev, int reg,
0685                            u16 data)
0686 {
0687     u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_22_WRITE_DATA;
0688     int err;
0689 
0690     err = mv88e6xxx_g2_smi_phy_wait(chip);
0691     if (err)
0692         return err;
0693 
0694     err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
0695     if (err)
0696         return err;
0697 
0698     return mv88e6xxx_g2_smi_phy_access_c22(chip, external, op, dev, reg);
0699 }
0700 
0701 static int mv88e6xxx_g2_smi_phy_access_c45(struct mv88e6xxx_chip *chip,
0702                        bool external, u16 op, int port,
0703                        int dev)
0704 {
0705     return mv88e6xxx_g2_smi_phy_access(chip, external, true, op, port, dev);
0706 }
0707 
0708 /* IEEE 802.3 Clause 45 Write Address Register */
0709 static int mv88e6xxx_g2_smi_phy_write_addr_c45(struct mv88e6xxx_chip *chip,
0710                            bool external, int port, int dev,
0711                            int addr)
0712 {
0713     u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_ADDR;
0714     int err;
0715 
0716     err = mv88e6xxx_g2_smi_phy_wait(chip);
0717     if (err)
0718         return err;
0719 
0720     err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, addr);
0721     if (err)
0722         return err;
0723 
0724     return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
0725 }
0726 
0727 /* IEEE 802.3 Clause 45 Read Data Register */
0728 static int mv88e6xxx_g2_smi_phy_read_data_c45(struct mv88e6xxx_chip *chip,
0729                           bool external, int port, int dev,
0730                           u16 *data)
0731 {
0732     u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_READ_DATA;
0733     int err;
0734 
0735     err = mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
0736     if (err)
0737         return err;
0738 
0739     return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
0740 }
0741 
0742 static int mv88e6xxx_g2_smi_phy_read_c45(struct mv88e6xxx_chip *chip,
0743                      bool external, int port, int reg,
0744                      u16 *data)
0745 {
0746     int dev = (reg >> 16) & 0x1f;
0747     int addr = reg & 0xffff;
0748     int err;
0749 
0750     err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
0751                           addr);
0752     if (err)
0753         return err;
0754 
0755     return mv88e6xxx_g2_smi_phy_read_data_c45(chip, external, port, dev,
0756                           data);
0757 }
0758 
0759 /* IEEE 802.3 Clause 45 Write Data Register */
0760 static int mv88e6xxx_g2_smi_phy_write_data_c45(struct mv88e6xxx_chip *chip,
0761                            bool external, int port, int dev,
0762                            u16 data)
0763 {
0764     u16 op = MV88E6XXX_G2_SMI_PHY_CMD_OP_45_WRITE_DATA;
0765     int err;
0766 
0767     err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SMI_PHY_DATA, data);
0768     if (err)
0769         return err;
0770 
0771     return mv88e6xxx_g2_smi_phy_access_c45(chip, external, op, port, dev);
0772 }
0773 
0774 static int mv88e6xxx_g2_smi_phy_write_c45(struct mv88e6xxx_chip *chip,
0775                       bool external, int port, int reg,
0776                       u16 data)
0777 {
0778     int dev = (reg >> 16) & 0x1f;
0779     int addr = reg & 0xffff;
0780     int err;
0781 
0782     err = mv88e6xxx_g2_smi_phy_write_addr_c45(chip, external, port, dev,
0783                           addr);
0784     if (err)
0785         return err;
0786 
0787     return mv88e6xxx_g2_smi_phy_write_data_c45(chip, external, port, dev,
0788                            data);
0789 }
0790 
0791 int mv88e6xxx_g2_smi_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
0792                   int addr, int reg, u16 *val)
0793 {
0794     struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
0795     bool external = mdio_bus->external;
0796 
0797     if (reg & MII_ADDR_C45)
0798         return mv88e6xxx_g2_smi_phy_read_c45(chip, external, addr, reg,
0799                              val);
0800 
0801     return mv88e6xxx_g2_smi_phy_read_data_c22(chip, external, addr, reg,
0802                           val);
0803 }
0804 
0805 int mv88e6xxx_g2_smi_phy_write(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
0806                    int addr, int reg, u16 val)
0807 {
0808     struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
0809     bool external = mdio_bus->external;
0810 
0811     if (reg & MII_ADDR_C45)
0812         return mv88e6xxx_g2_smi_phy_write_c45(chip, external, addr, reg,
0813                               val);
0814 
0815     return mv88e6xxx_g2_smi_phy_write_data_c22(chip, external, addr, reg,
0816                            val);
0817 }
0818 
0819 /* Offset 0x1B: Watchdog Control */
0820 static int mv88e6097_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
0821 {
0822     u16 reg;
0823 
0824     mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);
0825 
0826     dev_info(chip->dev, "Watchdog event: 0x%04x", reg);
0827 
0828     return IRQ_HANDLED;
0829 }
0830 
0831 static void mv88e6097_watchdog_free(struct mv88e6xxx_chip *chip)
0832 {
0833     u16 reg;
0834 
0835     mv88e6xxx_g2_read(chip, MV88E6352_G2_WDOG_CTL, &reg);
0836 
0837     reg &= ~(MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
0838          MV88E6352_G2_WDOG_CTL_QC_ENABLE);
0839 
0840     mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL, reg);
0841 }
0842 
0843 static int mv88e6097_watchdog_setup(struct mv88e6xxx_chip *chip)
0844 {
0845     return mv88e6xxx_g2_write(chip, MV88E6352_G2_WDOG_CTL,
0846                   MV88E6352_G2_WDOG_CTL_EGRESS_ENABLE |
0847                   MV88E6352_G2_WDOG_CTL_QC_ENABLE |
0848                   MV88E6352_G2_WDOG_CTL_SWRESET);
0849 }
0850 
0851 const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops = {
0852     .irq_action = mv88e6097_watchdog_action,
0853     .irq_setup = mv88e6097_watchdog_setup,
0854     .irq_free = mv88e6097_watchdog_free,
0855 };
0856 
0857 static void mv88e6250_watchdog_free(struct mv88e6xxx_chip *chip)
0858 {
0859     u16 reg;
0860 
0861     mv88e6xxx_g2_read(chip, MV88E6250_G2_WDOG_CTL, &reg);
0862 
0863     reg &= ~(MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
0864          MV88E6250_G2_WDOG_CTL_QC_ENABLE);
0865 
0866     mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL, reg);
0867 }
0868 
0869 static int mv88e6250_watchdog_setup(struct mv88e6xxx_chip *chip)
0870 {
0871     return mv88e6xxx_g2_write(chip, MV88E6250_G2_WDOG_CTL,
0872                   MV88E6250_G2_WDOG_CTL_EGRESS_ENABLE |
0873                   MV88E6250_G2_WDOG_CTL_QC_ENABLE |
0874                   MV88E6250_G2_WDOG_CTL_SWRESET);
0875 }
0876 
0877 const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops = {
0878     .irq_action = mv88e6097_watchdog_action,
0879     .irq_setup = mv88e6250_watchdog_setup,
0880     .irq_free = mv88e6250_watchdog_free,
0881 };
0882 
0883 static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
0884 {
0885     return mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
0886                   MV88E6390_G2_WDOG_CTL_UPDATE |
0887                   MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
0888                   MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
0889                   MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
0890                   MV88E6390_G2_WDOG_CTL_EGRESS |
0891                   MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
0892 }
0893 
0894 static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
0895 {
0896     u16 reg;
0897 
0898     mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
0899                MV88E6390_G2_WDOG_CTL_PTR_EVENT);
0900     mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
0901 
0902     dev_info(chip->dev, "Watchdog event: 0x%04x",
0903          reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
0904 
0905     mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
0906                MV88E6390_G2_WDOG_CTL_PTR_HISTORY);
0907     mv88e6xxx_g2_read(chip, MV88E6390_G2_WDOG_CTL, &reg);
0908 
0909     dev_info(chip->dev, "Watchdog history: 0x%04x",
0910          reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
0911 
0912     /* Trigger a software reset to try to recover the switch */
0913     if (chip->info->ops->reset)
0914         chip->info->ops->reset(chip);
0915 
0916     mv88e6390_watchdog_setup(chip);
0917 
0918     return IRQ_HANDLED;
0919 }
0920 
0921 static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
0922 {
0923     mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
0924                MV88E6390_G2_WDOG_CTL_UPDATE |
0925                MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
0926 }
0927 
0928 const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
0929     .irq_action = mv88e6390_watchdog_action,
0930     .irq_setup = mv88e6390_watchdog_setup,
0931     .irq_free = mv88e6390_watchdog_free,
0932 };
0933 
0934 static irqreturn_t mv88e6xxx_g2_watchdog_thread_fn(int irq, void *dev_id)
0935 {
0936     struct mv88e6xxx_chip *chip = dev_id;
0937     irqreturn_t ret = IRQ_NONE;
0938 
0939     mv88e6xxx_reg_lock(chip);
0940     if (chip->info->ops->watchdog_ops->irq_action)
0941         ret = chip->info->ops->watchdog_ops->irq_action(chip, irq);
0942     mv88e6xxx_reg_unlock(chip);
0943 
0944     return ret;
0945 }
0946 
0947 static void mv88e6xxx_g2_watchdog_free(struct mv88e6xxx_chip *chip)
0948 {
0949     mv88e6xxx_reg_lock(chip);
0950     if (chip->info->ops->watchdog_ops->irq_free)
0951         chip->info->ops->watchdog_ops->irq_free(chip);
0952     mv88e6xxx_reg_unlock(chip);
0953 
0954     free_irq(chip->watchdog_irq, chip);
0955     irq_dispose_mapping(chip->watchdog_irq);
0956 }
0957 
0958 static int mv88e6xxx_g2_watchdog_setup(struct mv88e6xxx_chip *chip)
0959 {
0960     int err;
0961 
0962     chip->watchdog_irq = irq_find_mapping(chip->g2_irq.domain,
0963                           MV88E6XXX_G2_INT_SOURCE_WATCHDOG);
0964     if (chip->watchdog_irq < 0)
0965         return chip->watchdog_irq;
0966 
0967     snprintf(chip->watchdog_irq_name, sizeof(chip->watchdog_irq_name),
0968          "mv88e6xxx-%s-watchdog", dev_name(chip->dev));
0969 
0970     err = request_threaded_irq(chip->watchdog_irq, NULL,
0971                    mv88e6xxx_g2_watchdog_thread_fn,
0972                    IRQF_ONESHOT | IRQF_TRIGGER_FALLING,
0973                    chip->watchdog_irq_name, chip);
0974     if (err)
0975         return err;
0976 
0977     mv88e6xxx_reg_lock(chip);
0978     if (chip->info->ops->watchdog_ops->irq_setup)
0979         err = chip->info->ops->watchdog_ops->irq_setup(chip);
0980     mv88e6xxx_reg_unlock(chip);
0981 
0982     return err;
0983 }
0984 
0985 /* Offset 0x1D: Misc Register */
0986 
0987 static int mv88e6xxx_g2_misc_5_bit_port(struct mv88e6xxx_chip *chip,
0988                     bool port_5_bit)
0989 {
0990     u16 val;
0991     int err;
0992 
0993     err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_MISC, &val);
0994     if (err)
0995         return err;
0996 
0997     if (port_5_bit)
0998         val |= MV88E6XXX_G2_MISC_5_BIT_PORT;
0999     else
1000         val &= ~MV88E6XXX_G2_MISC_5_BIT_PORT;
1001 
1002     return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MISC, val);
1003 }
1004 
1005 int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
1006 {
1007     return mv88e6xxx_g2_misc_5_bit_port(chip, false);
1008 }
1009 
1010 static void mv88e6xxx_g2_irq_mask(struct irq_data *d)
1011 {
1012     struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1013     unsigned int n = d->hwirq;
1014 
1015     chip->g2_irq.masked |= (1 << n);
1016 }
1017 
1018 static void mv88e6xxx_g2_irq_unmask(struct irq_data *d)
1019 {
1020     struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1021     unsigned int n = d->hwirq;
1022 
1023     chip->g2_irq.masked &= ~(1 << n);
1024 }
1025 
1026 static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id)
1027 {
1028     struct mv88e6xxx_chip *chip = dev_id;
1029     unsigned int nhandled = 0;
1030     unsigned int sub_irq;
1031     unsigned int n;
1032     int err;
1033     u16 reg;
1034 
1035     mv88e6xxx_reg_lock(chip);
1036     err = mv88e6xxx_g2_int_source(chip, &reg);
1037     mv88e6xxx_reg_unlock(chip);
1038     if (err)
1039         goto out;
1040 
1041     for (n = 0; n < 16; ++n) {
1042         if (reg & (1 << n)) {
1043             sub_irq = irq_find_mapping(chip->g2_irq.domain, n);
1044             handle_nested_irq(sub_irq);
1045             ++nhandled;
1046         }
1047     }
1048 out:
1049     return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
1050 }
1051 
1052 static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d)
1053 {
1054     struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1055 
1056     mv88e6xxx_reg_lock(chip);
1057 }
1058 
1059 static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
1060 {
1061     struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
1062     int err;
1063 
1064     err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
1065     if (err)
1066         dev_err(chip->dev, "failed to mask interrupts\n");
1067 
1068     mv88e6xxx_reg_unlock(chip);
1069 }
1070 
1071 static const struct irq_chip mv88e6xxx_g2_irq_chip = {
1072     .name           = "mv88e6xxx-g2",
1073     .irq_mask       = mv88e6xxx_g2_irq_mask,
1074     .irq_unmask     = mv88e6xxx_g2_irq_unmask,
1075     .irq_bus_lock       = mv88e6xxx_g2_irq_bus_lock,
1076     .irq_bus_sync_unlock    = mv88e6xxx_g2_irq_bus_sync_unlock,
1077 };
1078 
1079 static int mv88e6xxx_g2_irq_domain_map(struct irq_domain *d,
1080                        unsigned int irq,
1081                        irq_hw_number_t hwirq)
1082 {
1083     struct mv88e6xxx_chip *chip = d->host_data;
1084 
1085     irq_set_chip_data(irq, d->host_data);
1086     irq_set_chip_and_handler(irq, &chip->g2_irq.chip, handle_level_irq);
1087     irq_set_noprobe(irq);
1088 
1089     return 0;
1090 }
1091 
1092 static const struct irq_domain_ops mv88e6xxx_g2_irq_domain_ops = {
1093     .map    = mv88e6xxx_g2_irq_domain_map,
1094     .xlate  = irq_domain_xlate_twocell,
1095 };
1096 
1097 void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
1098 {
1099     int irq, virq;
1100 
1101     mv88e6xxx_g2_watchdog_free(chip);
1102 
1103     free_irq(chip->device_irq, chip);
1104     irq_dispose_mapping(chip->device_irq);
1105 
1106     for (irq = 0; irq < 16; irq++) {
1107         virq = irq_find_mapping(chip->g2_irq.domain, irq);
1108         irq_dispose_mapping(virq);
1109     }
1110 
1111     irq_domain_remove(chip->g2_irq.domain);
1112 }
1113 
1114 int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
1115 {
1116     int err, irq, virq;
1117 
1118     chip->g2_irq.masked = ~0;
1119     mv88e6xxx_reg_lock(chip);
1120     err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
1121     mv88e6xxx_reg_unlock(chip);
1122     if (err)
1123         return err;
1124 
1125     chip->g2_irq.domain = irq_domain_add_simple(
1126         chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip);
1127     if (!chip->g2_irq.domain)
1128         return -ENOMEM;
1129 
1130     for (irq = 0; irq < 16; irq++)
1131         irq_create_mapping(chip->g2_irq.domain, irq);
1132 
1133     chip->g2_irq.chip = mv88e6xxx_g2_irq_chip;
1134 
1135     chip->device_irq = irq_find_mapping(chip->g1_irq.domain,
1136                         MV88E6XXX_G1_STS_IRQ_DEVICE);
1137     if (chip->device_irq < 0) {
1138         err = chip->device_irq;
1139         goto out;
1140     }
1141 
1142     snprintf(chip->device_irq_name, sizeof(chip->device_irq_name),
1143          "mv88e6xxx-%s-g2", dev_name(chip->dev));
1144 
1145     err = request_threaded_irq(chip->device_irq, NULL,
1146                    mv88e6xxx_g2_irq_thread_fn,
1147                    IRQF_ONESHOT, chip->device_irq_name, chip);
1148     if (err)
1149         goto out;
1150 
1151     return mv88e6xxx_g2_watchdog_setup(chip);
1152 
1153 out:
1154     for (irq = 0; irq < 16; irq++) {
1155         virq = irq_find_mapping(chip->g2_irq.domain, irq);
1156         irq_dispose_mapping(virq);
1157     }
1158 
1159     irq_domain_remove(chip->g2_irq.domain);
1160 
1161     return err;
1162 }
1163 
1164 int mv88e6xxx_g2_irq_mdio_setup(struct mv88e6xxx_chip *chip,
1165                 struct mii_bus *bus)
1166 {
1167     int phy, irq, err, err_phy;
1168 
1169     for (phy = 0; phy < chip->info->num_internal_phys; phy++) {
1170         irq = irq_find_mapping(chip->g2_irq.domain, phy);
1171         if (irq < 0) {
1172             err = irq;
1173             goto out;
1174         }
1175         bus->irq[chip->info->phy_base_addr + phy] = irq;
1176     }
1177     return 0;
1178 out:
1179     err_phy = phy;
1180 
1181     for (phy = 0; phy < err_phy; phy++)
1182         irq_dispose_mapping(bus->irq[phy]);
1183 
1184     return err;
1185 }
1186 
1187 void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
1188                 struct mii_bus *bus)
1189 {
1190     int phy;
1191 
1192     for (phy = 0; phy < chip->info->num_internal_phys; phy++)
1193         irq_dispose_mapping(bus->irq[phy]);
1194 }