0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/bitfield.h>
0012
0013 #include "chip.h"
0014 #include "global1.h"
0015
0016 int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
0017 {
0018 int addr = chip->info->global1_addr;
0019
0020 return mv88e6xxx_read(chip, addr, reg, val);
0021 }
0022
0023 int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
0024 {
0025 int addr = chip->info->global1_addr;
0026
0027 return mv88e6xxx_write(chip, addr, reg, val);
0028 }
0029
0030 int mv88e6xxx_g1_wait_bit(struct mv88e6xxx_chip *chip, int reg, int
0031 bit, int val)
0032 {
0033 return mv88e6xxx_wait_bit(chip, chip->info->global1_addr, reg,
0034 bit, val);
0035 }
0036
0037 int mv88e6xxx_g1_wait_mask(struct mv88e6xxx_chip *chip, int reg,
0038 u16 mask, u16 val)
0039 {
0040 return mv88e6xxx_wait_mask(chip, chip->info->global1_addr, reg,
0041 mask, val);
0042 }
0043
0044
0045
0046 static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip *chip)
0047 {
0048 return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
0049 MV88E6185_G1_STS_PPU_STATE_MASK,
0050 MV88E6185_G1_STS_PPU_STATE_DISABLED);
0051 }
0052
0053 static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
0054 {
0055 return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
0056 MV88E6185_G1_STS_PPU_STATE_MASK,
0057 MV88E6185_G1_STS_PPU_STATE_POLLING);
0058 }
0059
0060 static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
0061 {
0062 int bit = __bf_shf(MV88E6352_G1_STS_PPU_STATE);
0063
0064 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
0065 }
0066
0067 static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip)
0068 {
0069 int bit = __bf_shf(MV88E6XXX_G1_STS_INIT_READY);
0070
0071
0072
0073
0074
0075 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
0076 }
0077
0078 void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip)
0079 {
0080 const unsigned long timeout = jiffies + 1 * HZ;
0081 u16 val;
0082 int err;
0083
0084
0085
0086
0087 while (time_before(jiffies, timeout)) {
0088 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val);
0089 if (err) {
0090 dev_err(chip->dev, "Error reading status");
0091 return;
0092 }
0093
0094
0095
0096
0097
0098
0099 if (val != 0xffff &&
0100 val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE))
0101 return;
0102
0103 usleep_range(1000, 2000);
0104 }
0105
0106 dev_err(chip->dev, "Timeout waiting for EEPROM done");
0107 }
0108
0109
0110
0111
0112
0113 int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
0114 {
0115 u16 reg;
0116 int err;
0117
0118 reg = (addr[0] << 8) | addr[1];
0119 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_01, reg);
0120 if (err)
0121 return err;
0122
0123 reg = (addr[2] << 8) | addr[3];
0124 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_23, reg);
0125 if (err)
0126 return err;
0127
0128 reg = (addr[4] << 8) | addr[5];
0129 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_MAC_45, reg);
0130 if (err)
0131 return err;
0132
0133 return 0;
0134 }
0135
0136
0137
0138 int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip)
0139 {
0140 u16 val;
0141 int err;
0142
0143
0144
0145
0146 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
0147 if (err)
0148 return err;
0149
0150 val |= MV88E6XXX_G1_CTL1_SW_RESET;
0151 val |= MV88E6XXX_G1_CTL1_PPU_ENABLE;
0152
0153 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
0154 if (err)
0155 return err;
0156
0157 err = mv88e6xxx_g1_wait_init_ready(chip);
0158 if (err)
0159 return err;
0160
0161 return mv88e6185_g1_wait_ppu_polling(chip);
0162 }
0163
0164 int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip)
0165 {
0166 u16 val;
0167 int err;
0168
0169
0170 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
0171 if (err)
0172 return err;
0173
0174 val |= MV88E6XXX_G1_CTL1_SW_RESET;
0175
0176 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
0177 if (err)
0178 return err;
0179
0180 return mv88e6xxx_g1_wait_init_ready(chip);
0181 }
0182
0183 int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip)
0184 {
0185 int err;
0186
0187 err = mv88e6250_g1_reset(chip);
0188 if (err)
0189 return err;
0190
0191 return mv88e6352_g1_wait_ppu_polling(chip);
0192 }
0193
0194 int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip)
0195 {
0196 u16 val;
0197 int err;
0198
0199 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
0200 if (err)
0201 return err;
0202
0203 val |= MV88E6XXX_G1_CTL1_PPU_ENABLE;
0204
0205 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
0206 if (err)
0207 return err;
0208
0209 return mv88e6185_g1_wait_ppu_polling(chip);
0210 }
0211
0212 int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip)
0213 {
0214 u16 val;
0215 int err;
0216
0217 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
0218 if (err)
0219 return err;
0220
0221 val &= ~MV88E6XXX_G1_CTL1_PPU_ENABLE;
0222
0223 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
0224 if (err)
0225 return err;
0226
0227 return mv88e6185_g1_wait_ppu_disabled(chip);
0228 }
0229
0230 int mv88e6185_g1_set_max_frame_size(struct mv88e6xxx_chip *chip, int mtu)
0231 {
0232 u16 val;
0233 int err;
0234
0235 mtu += ETH_HLEN + ETH_FCS_LEN;
0236
0237 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
0238 if (err)
0239 return err;
0240
0241 val &= ~MV88E6185_G1_CTL1_MAX_FRAME_1632;
0242
0243 if (mtu > 1518)
0244 val |= MV88E6185_G1_CTL1_MAX_FRAME_1632;
0245
0246 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
0247 }
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 int mv88e6085_g1_ip_pri_map(struct mv88e6xxx_chip *chip)
0260 {
0261 int err;
0262
0263
0264 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_0, 0x0000);
0265 if (err)
0266 return err;
0267
0268 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_1, 0x0000);
0269 if (err)
0270 return err;
0271
0272 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_2, 0x5555);
0273 if (err)
0274 return err;
0275
0276 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_3, 0x5555);
0277 if (err)
0278 return err;
0279
0280 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_4, 0xaaaa);
0281 if (err)
0282 return err;
0283
0284 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_5, 0xaaaa);
0285 if (err)
0286 return err;
0287
0288 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_6, 0xffff);
0289 if (err)
0290 return err;
0291
0292 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_7, 0xffff);
0293 if (err)
0294 return err;
0295
0296 return 0;
0297 }
0298
0299
0300
0301 int mv88e6085_g1_ieee_pri_map(struct mv88e6xxx_chip *chip)
0302 {
0303
0304 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IEEE_PRI, 0xfa41);
0305 }
0306
0307 int mv88e6250_g1_ieee_pri_map(struct mv88e6xxx_chip *chip)
0308 {
0309
0310 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IEEE_PRI, 0xfa50);
0311 }
0312
0313
0314
0315
0316 int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip,
0317 enum mv88e6xxx_egress_direction direction,
0318 int port)
0319 {
0320 u16 reg;
0321 int err;
0322
0323 err = mv88e6xxx_g1_read(chip, MV88E6185_G1_MONITOR_CTL, ®);
0324 if (err)
0325 return err;
0326
0327 switch (direction) {
0328 case MV88E6XXX_EGRESS_DIR_INGRESS:
0329 reg &= ~MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK;
0330 reg |= port <<
0331 __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK);
0332 break;
0333 case MV88E6XXX_EGRESS_DIR_EGRESS:
0334 reg &= ~MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK;
0335 reg |= port <<
0336 __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK);
0337 break;
0338 default:
0339 return -EINVAL;
0340 }
0341
0342 return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg);
0343 }
0344
0345
0346
0347
0348
0349 int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port)
0350 {
0351 u16 reg;
0352 int err;
0353
0354 err = mv88e6xxx_g1_read(chip, MV88E6185_G1_MONITOR_CTL, ®);
0355 if (err)
0356 return err;
0357
0358 reg &= ~MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK;
0359 reg |= port << __bf_shf(MV88E6185_G1_MONITOR_CTL_ARP_DEST_MASK);
0360
0361 return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg);
0362 }
0363
0364 static int mv88e6390_g1_monitor_write(struct mv88e6xxx_chip *chip,
0365 u16 pointer, u8 data)
0366 {
0367 u16 reg;
0368
0369 reg = MV88E6390_G1_MONITOR_MGMT_CTL_UPDATE | pointer | data;
0370
0371 return mv88e6xxx_g1_write(chip, MV88E6390_G1_MONITOR_MGMT_CTL, reg);
0372 }
0373
0374 int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip,
0375 enum mv88e6xxx_egress_direction direction,
0376 int port)
0377 {
0378 u16 ptr;
0379
0380 switch (direction) {
0381 case MV88E6XXX_EGRESS_DIR_INGRESS:
0382 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST;
0383 break;
0384 case MV88E6XXX_EGRESS_DIR_EGRESS:
0385 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST;
0386 break;
0387 default:
0388 return -EINVAL;
0389 }
0390
0391 return mv88e6390_g1_monitor_write(chip, ptr, port);
0392 }
0393
0394 int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port)
0395 {
0396 u16 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST;
0397
0398
0399
0400
0401 port |= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI;
0402
0403 return mv88e6390_g1_monitor_write(chip, ptr, port);
0404 }
0405
0406 int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
0407 {
0408 u16 ptr;
0409 int err;
0410
0411
0412 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200000XLO;
0413 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff);
0414 if (err)
0415 return err;
0416
0417
0418 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200000XHI;
0419 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff);
0420 if (err)
0421 return err;
0422
0423
0424 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200002XLO;
0425 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff);
0426 if (err)
0427 return err;
0428
0429
0430 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_0180C200002XHI;
0431 err = mv88e6390_g1_monitor_write(chip, ptr, 0xff);
0432 if (err)
0433 return err;
0434
0435 return 0;
0436 }
0437
0438
0439
0440 static int mv88e6xxx_g1_ctl2_mask(struct mv88e6xxx_chip *chip, u16 mask,
0441 u16 val)
0442 {
0443 u16 reg;
0444 int err;
0445
0446 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL2, ®);
0447 if (err)
0448 return err;
0449
0450 reg &= ~mask;
0451 reg |= val & mask;
0452
0453 return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2, reg);
0454 }
0455
0456 int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port)
0457 {
0458 const u16 mask = MV88E6185_G1_CTL2_CASCADE_PORT_MASK;
0459
0460 return mv88e6xxx_g1_ctl2_mask(chip, mask, port << __bf_shf(mask));
0461 }
0462
0463 int mv88e6085_g1_rmu_disable(struct mv88e6xxx_chip *chip)
0464 {
0465 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6085_G1_CTL2_P10RM |
0466 MV88E6085_G1_CTL2_RM_ENABLE, 0);
0467 }
0468
0469 int mv88e6352_g1_rmu_disable(struct mv88e6xxx_chip *chip)
0470 {
0471 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6352_G1_CTL2_RMU_MODE_MASK,
0472 MV88E6352_G1_CTL2_RMU_MODE_DISABLED);
0473 }
0474
0475 int mv88e6390_g1_rmu_disable(struct mv88e6xxx_chip *chip)
0476 {
0477 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6390_G1_CTL2_RMU_MODE_MASK,
0478 MV88E6390_G1_CTL2_RMU_MODE_DISABLED);
0479 }
0480
0481 int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
0482 {
0483 return mv88e6xxx_g1_ctl2_mask(chip, MV88E6390_G1_CTL2_HIST_MODE_MASK,
0484 MV88E6390_G1_CTL2_HIST_MODE_RX |
0485 MV88E6390_G1_CTL2_HIST_MODE_TX);
0486 }
0487
0488 int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip *chip, int index)
0489 {
0490 return mv88e6xxx_g1_ctl2_mask(chip,
0491 MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK,
0492 index);
0493 }
0494
0495
0496
0497 static int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip *chip)
0498 {
0499 int bit = __bf_shf(MV88E6XXX_G1_STATS_OP_BUSY);
0500
0501 return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STATS_OP, bit, 0);
0502 }
0503
0504 int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
0505 {
0506 u16 val;
0507 int err;
0508
0509 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &val);
0510 if (err)
0511 return err;
0512
0513 val |= MV88E6XXX_G1_STATS_OP_HIST_RX_TX;
0514
0515 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val);
0516
0517 return err;
0518 }
0519
0520 int mv88e6xxx_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
0521 {
0522 int err;
0523
0524
0525 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP,
0526 MV88E6XXX_G1_STATS_OP_BUSY |
0527 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT |
0528 MV88E6XXX_G1_STATS_OP_HIST_RX_TX | port);
0529 if (err)
0530 return err;
0531
0532
0533 return mv88e6xxx_g1_stats_wait(chip);
0534 }
0535
0536 int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
0537 {
0538 port = (port + 1) << 5;
0539
0540 return mv88e6xxx_g1_stats_snapshot(chip, port);
0541 }
0542
0543 int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port)
0544 {
0545 int err;
0546
0547 port = (port + 1) << 5;
0548
0549
0550 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP,
0551 MV88E6XXX_G1_STATS_OP_BUSY |
0552 MV88E6XXX_G1_STATS_OP_CAPTURE_PORT | port);
0553 if (err)
0554 return err;
0555
0556
0557 return mv88e6xxx_g1_stats_wait(chip);
0558 }
0559
0560 void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val)
0561 {
0562 u32 value;
0563 u16 reg;
0564 int err;
0565
0566 *val = 0;
0567
0568 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP,
0569 MV88E6XXX_G1_STATS_OP_BUSY |
0570 MV88E6XXX_G1_STATS_OP_READ_CAPTURED | stat);
0571 if (err)
0572 return;
0573
0574 err = mv88e6xxx_g1_stats_wait(chip);
0575 if (err)
0576 return;
0577
0578 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_COUNTER_32, ®);
0579 if (err)
0580 return;
0581
0582 value = reg << 16;
0583
0584 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_COUNTER_01, ®);
0585 if (err)
0586 return;
0587
0588 *val = value | reg;
0589 }
0590
0591 int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip *chip)
0592 {
0593 int err;
0594 u16 val;
0595
0596 err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &val);
0597 if (err)
0598 return err;
0599
0600
0601 val &= MV88E6XXX_G1_STATS_OP_HIST_RX_TX;
0602 val |= MV88E6XXX_G1_STATS_OP_BUSY | MV88E6XXX_G1_STATS_OP_FLUSH_ALL;
0603
0604 err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP, val);
0605 if (err)
0606 return err;
0607
0608
0609 return mv88e6xxx_g1_stats_wait(chip);
0610 }