0001
0002
0003
0004
0005
0006
0007
0008
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
0037
0038 static int mv88e6xxx_g2_int_source(struct mv88e6xxx_chip *chip, u16 *src)
0039 {
0040
0041 return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_INT_SRC, src);
0042 }
0043
0044
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
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
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
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
0090
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
0104
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
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
0120
0121
0122
0123 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_DEVICE_MAPPING,
0124 MV88E6XXX_G2_DEVICE_MAPPING_UPDATE | val);
0125 }
0126
0127
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
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
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
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
0176
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
0213
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
0229
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
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
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
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
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
0339
0340
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
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
0611
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;
0643
0644 if (c45)
0645 cmd |= MV88E6XXX_G2_SMI_PHY_CMD_MODE_45;
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
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
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
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
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
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
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, ®);
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, ®);
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, ®);
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, ®);
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, ®);
0908
0909 dev_info(chip->dev, "Watchdog history: 0x%04x",
0910 reg & MV88E6390_G2_WDOG_CTL_DATA_MASK);
0911
0912
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
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, ®);
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 }