0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/bitfield.h>
0012 #include <linux/if_bridge.h>
0013 #include <linux/phy.h>
0014 #include <linux/phylink.h>
0015
0016 #include "chip.h"
0017 #include "global2.h"
0018 #include "port.h"
0019 #include "serdes.h"
0020
0021 int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
0022 u16 *val)
0023 {
0024 int addr = chip->info->port_base_addr + port;
0025
0026 return mv88e6xxx_read(chip, addr, reg, val);
0027 }
0028
0029 int mv88e6xxx_port_wait_bit(struct mv88e6xxx_chip *chip, int port, int reg,
0030 int bit, int val)
0031 {
0032 int addr = chip->info->port_base_addr + port;
0033
0034 return mv88e6xxx_wait_bit(chip, addr, reg, bit, val);
0035 }
0036
0037 int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
0038 u16 val)
0039 {
0040 int addr = chip->info->port_base_addr + port;
0041
0042 return mv88e6xxx_write(chip, addr, reg, val);
0043 }
0044
0045
0046
0047
0048
0049
0050 int mv88e6185_port_set_pause(struct mv88e6xxx_chip *chip, int port,
0051 int pause)
0052 {
0053 u16 reg;
0054 int err;
0055
0056 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
0057 if (err)
0058 return err;
0059
0060 if (pause)
0061 reg |= MV88E6XXX_PORT_STS_MY_PAUSE;
0062 else
0063 reg &= ~MV88E6XXX_PORT_STS_MY_PAUSE;
0064
0065 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
0066 }
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
0078 phy_interface_t mode)
0079 {
0080 u16 reg;
0081 int err;
0082
0083 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
0084 if (err)
0085 return err;
0086
0087 reg &= ~(MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
0088 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK);
0089
0090 switch (mode) {
0091 case PHY_INTERFACE_MODE_RGMII_RXID:
0092 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK;
0093 break;
0094 case PHY_INTERFACE_MODE_RGMII_TXID:
0095 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
0096 break;
0097 case PHY_INTERFACE_MODE_RGMII_ID:
0098 reg |= MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK |
0099 MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK;
0100 break;
0101 case PHY_INTERFACE_MODE_RGMII:
0102 break;
0103 default:
0104 return 0;
0105 }
0106
0107 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
0108 if (err)
0109 return err;
0110
0111 dev_dbg(chip->dev, "p%d: delay RXCLK %s, TXCLK %s\n", port,
0112 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK ? "yes" : "no",
0113 reg & MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK ? "yes" : "no");
0114
0115 return 0;
0116 }
0117
0118 int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
0119 phy_interface_t mode)
0120 {
0121 if (port < 5)
0122 return -EOPNOTSUPP;
0123
0124 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
0125 }
0126
0127 int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
0128 phy_interface_t mode)
0129 {
0130 if (port != 0)
0131 return -EOPNOTSUPP;
0132
0133 return mv88e6xxx_port_set_rgmii_delay(chip, port, mode);
0134 }
0135
0136 int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link)
0137 {
0138 u16 reg;
0139 int err;
0140
0141 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
0142 if (err)
0143 return err;
0144
0145 reg &= ~(MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
0146 MV88E6XXX_PORT_MAC_CTL_LINK_UP);
0147
0148 switch (link) {
0149 case LINK_FORCED_DOWN:
0150 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK;
0151 break;
0152 case LINK_FORCED_UP:
0153 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_LINK |
0154 MV88E6XXX_PORT_MAC_CTL_LINK_UP;
0155 break;
0156 case LINK_UNFORCED:
0157
0158 break;
0159 default:
0160 return -EINVAL;
0161 }
0162
0163 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
0164 if (err)
0165 return err;
0166
0167 dev_dbg(chip->dev, "p%d: %s link %s\n", port,
0168 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_LINK ? "Force" : "Unforce",
0169 reg & MV88E6XXX_PORT_MAC_CTL_LINK_UP ? "up" : "down");
0170
0171 return 0;
0172 }
0173
0174 int mv88e6xxx_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup)
0175 {
0176 const struct mv88e6xxx_ops *ops = chip->info->ops;
0177 int err = 0;
0178 int link;
0179
0180 if (isup)
0181 link = LINK_FORCED_UP;
0182 else
0183 link = LINK_FORCED_DOWN;
0184
0185 if (ops->port_set_link)
0186 err = ops->port_set_link(chip, port, link);
0187
0188 return err;
0189 }
0190
0191 int mv88e6185_port_sync_link(struct mv88e6xxx_chip *chip, int port, unsigned int mode, bool isup)
0192 {
0193 const struct mv88e6xxx_ops *ops = chip->info->ops;
0194 int err = 0;
0195 int link;
0196
0197 if (mode == MLO_AN_INBAND)
0198 link = LINK_UNFORCED;
0199 else if (isup)
0200 link = LINK_FORCED_UP;
0201 else
0202 link = LINK_FORCED_DOWN;
0203
0204 if (ops->port_set_link)
0205 err = ops->port_set_link(chip, port, link);
0206
0207 return err;
0208 }
0209
0210 static int mv88e6xxx_port_set_speed_duplex(struct mv88e6xxx_chip *chip,
0211 int port, int speed, bool alt_bit,
0212 bool force_bit, int duplex)
0213 {
0214 u16 reg, ctrl;
0215 int err;
0216
0217 switch (speed) {
0218 case 10:
0219 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
0220 break;
0221 case 100:
0222 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
0223 break;
0224 case 200:
0225 if (alt_bit)
0226 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
0227 MV88E6390_PORT_MAC_CTL_ALTSPEED;
0228 else
0229 ctrl = MV88E6065_PORT_MAC_CTL_SPEED_200;
0230 break;
0231 case 1000:
0232 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
0233 break;
0234 case 2500:
0235 if (alt_bit)
0236 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
0237 MV88E6390_PORT_MAC_CTL_ALTSPEED;
0238 else
0239 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000;
0240 break;
0241 case 10000:
0242
0243 case SPEED_UNFORCED:
0244 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
0245 break;
0246 default:
0247 return -EOPNOTSUPP;
0248 }
0249
0250 switch (duplex) {
0251 case DUPLEX_HALF:
0252 ctrl |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
0253 break;
0254 case DUPLEX_FULL:
0255 ctrl |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
0256 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
0257 break;
0258 case DUPLEX_UNFORCED:
0259
0260 break;
0261 default:
0262 return -EOPNOTSUPP;
0263 }
0264
0265 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
0266 if (err)
0267 return err;
0268
0269 reg &= ~(MV88E6XXX_PORT_MAC_CTL_SPEED_MASK |
0270 MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
0271 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL);
0272
0273 if (alt_bit)
0274 reg &= ~MV88E6390_PORT_MAC_CTL_ALTSPEED;
0275 if (force_bit) {
0276 reg &= ~MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
0277 if (speed != SPEED_UNFORCED)
0278 ctrl |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
0279 }
0280 reg |= ctrl;
0281
0282 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
0283 if (err)
0284 return err;
0285
0286 if (speed != SPEED_UNFORCED)
0287 dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
0288 else
0289 dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
0290 dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
0291 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
0292 reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
0293
0294 return 0;
0295 }
0296
0297
0298 int mv88e6185_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
0299 int speed, int duplex)
0300 {
0301 if (speed == 200 || speed > 1000)
0302 return -EOPNOTSUPP;
0303
0304 return mv88e6xxx_port_set_speed_duplex(chip, port, speed, false, false,
0305 duplex);
0306 }
0307
0308
0309 int mv88e6250_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
0310 int speed, int duplex)
0311 {
0312 if (speed > 100)
0313 return -EOPNOTSUPP;
0314
0315 return mv88e6xxx_port_set_speed_duplex(chip, port, speed, false, false,
0316 duplex);
0317 }
0318
0319
0320 int mv88e6341_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
0321 int speed, int duplex)
0322 {
0323 if (speed > 2500)
0324 return -EOPNOTSUPP;
0325
0326 if (speed == 200 && port != 0)
0327 return -EOPNOTSUPP;
0328
0329 if (speed == 2500 && port < 5)
0330 return -EOPNOTSUPP;
0331
0332 return mv88e6xxx_port_set_speed_duplex(chip, port, speed, !port, true,
0333 duplex);
0334 }
0335
0336 phy_interface_t mv88e6341_port_max_speed_mode(int port)
0337 {
0338 if (port == 5)
0339 return PHY_INTERFACE_MODE_2500BASEX;
0340
0341 return PHY_INTERFACE_MODE_NA;
0342 }
0343
0344
0345 int mv88e6352_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
0346 int speed, int duplex)
0347 {
0348 if (speed > 1000)
0349 return -EOPNOTSUPP;
0350
0351 if (speed == 200 && port < 5)
0352 return -EOPNOTSUPP;
0353
0354 return mv88e6xxx_port_set_speed_duplex(chip, port, speed, true, false,
0355 duplex);
0356 }
0357
0358
0359 int mv88e6390_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
0360 int speed, int duplex)
0361 {
0362 if (speed > 2500)
0363 return -EOPNOTSUPP;
0364
0365 if (speed == 200 && port != 0)
0366 return -EOPNOTSUPP;
0367
0368 if (speed == 2500 && port < 9)
0369 return -EOPNOTSUPP;
0370
0371 return mv88e6xxx_port_set_speed_duplex(chip, port, speed, true, true,
0372 duplex);
0373 }
0374
0375 phy_interface_t mv88e6390_port_max_speed_mode(int port)
0376 {
0377 if (port == 9 || port == 10)
0378 return PHY_INTERFACE_MODE_2500BASEX;
0379
0380 return PHY_INTERFACE_MODE_NA;
0381 }
0382
0383
0384 int mv88e6390x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
0385 int speed, int duplex)
0386 {
0387 if (speed == 200 && port != 0)
0388 return -EOPNOTSUPP;
0389
0390 if (speed >= 2500 && port < 9)
0391 return -EOPNOTSUPP;
0392
0393 return mv88e6xxx_port_set_speed_duplex(chip, port, speed, true, true,
0394 duplex);
0395 }
0396
0397 phy_interface_t mv88e6390x_port_max_speed_mode(int port)
0398 {
0399 if (port == 9 || port == 10)
0400 return PHY_INTERFACE_MODE_XAUI;
0401
0402 return PHY_INTERFACE_MODE_NA;
0403 }
0404
0405
0406
0407
0408
0409 int mv88e6393x_port_set_speed_duplex(struct mv88e6xxx_chip *chip, int port,
0410 int speed, int duplex)
0411 {
0412 u16 reg, ctrl;
0413 int err;
0414
0415 if (speed == 200 && port != 0)
0416 return -EOPNOTSUPP;
0417
0418 if (speed >= 2500 && port > 0 && port < 9)
0419 return -EOPNOTSUPP;
0420
0421 switch (speed) {
0422 case 10:
0423 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_10;
0424 break;
0425 case 100:
0426 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100;
0427 break;
0428 case 200:
0429 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_100 |
0430 MV88E6390_PORT_MAC_CTL_ALTSPEED;
0431 break;
0432 case 1000:
0433 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000;
0434 break;
0435 case 2500:
0436 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_1000 |
0437 MV88E6390_PORT_MAC_CTL_ALTSPEED;
0438 break;
0439 case 5000:
0440 ctrl = MV88E6390_PORT_MAC_CTL_SPEED_10000 |
0441 MV88E6390_PORT_MAC_CTL_ALTSPEED;
0442 break;
0443 case 10000:
0444 case SPEED_UNFORCED:
0445 ctrl = MV88E6XXX_PORT_MAC_CTL_SPEED_UNFORCED;
0446 break;
0447 default:
0448 return -EOPNOTSUPP;
0449 }
0450
0451 switch (duplex) {
0452 case DUPLEX_HALF:
0453 ctrl |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX;
0454 break;
0455 case DUPLEX_FULL:
0456 ctrl |= MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX |
0457 MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL;
0458 break;
0459 case DUPLEX_UNFORCED:
0460
0461 break;
0462 default:
0463 return -EOPNOTSUPP;
0464 }
0465
0466 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
0467 if (err)
0468 return err;
0469
0470 reg &= ~(MV88E6XXX_PORT_MAC_CTL_SPEED_MASK |
0471 MV88E6390_PORT_MAC_CTL_ALTSPEED |
0472 MV88E6390_PORT_MAC_CTL_FORCE_SPEED);
0473
0474 if (speed != SPEED_UNFORCED)
0475 reg |= MV88E6390_PORT_MAC_CTL_FORCE_SPEED;
0476
0477 reg |= ctrl;
0478
0479 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
0480 if (err)
0481 return err;
0482
0483 if (speed != SPEED_UNFORCED)
0484 dev_dbg(chip->dev, "p%d: Speed set to %d Mbps\n", port, speed);
0485 else
0486 dev_dbg(chip->dev, "p%d: Speed unforced\n", port);
0487 dev_dbg(chip->dev, "p%d: %s %s duplex\n", port,
0488 reg & MV88E6XXX_PORT_MAC_CTL_FORCE_DUPLEX ? "Force" : "Unforce",
0489 reg & MV88E6XXX_PORT_MAC_CTL_DUPLEX_FULL ? "full" : "half");
0490
0491 return 0;
0492 }
0493
0494 phy_interface_t mv88e6393x_port_max_speed_mode(int port)
0495 {
0496 if (port == 0 || port == 9 || port == 10)
0497 return PHY_INTERFACE_MODE_10GBASER;
0498
0499 return PHY_INTERFACE_MODE_NA;
0500 }
0501
0502 static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
0503 phy_interface_t mode, bool force)
0504 {
0505 u16 cmode;
0506 int lane;
0507 u16 reg;
0508 int err;
0509
0510
0511
0512
0513 if (mode == PHY_INTERFACE_MODE_NA)
0514 mode = PHY_INTERFACE_MODE_1000BASEX;
0515
0516 switch (mode) {
0517 case PHY_INTERFACE_MODE_RMII:
0518 cmode = MV88E6XXX_PORT_STS_CMODE_RMII;
0519 break;
0520 case PHY_INTERFACE_MODE_1000BASEX:
0521 cmode = MV88E6XXX_PORT_STS_CMODE_1000BASEX;
0522 break;
0523 case PHY_INTERFACE_MODE_SGMII:
0524 cmode = MV88E6XXX_PORT_STS_CMODE_SGMII;
0525 break;
0526 case PHY_INTERFACE_MODE_2500BASEX:
0527 cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
0528 break;
0529 case PHY_INTERFACE_MODE_5GBASER:
0530 cmode = MV88E6393X_PORT_STS_CMODE_5GBASER;
0531 break;
0532 case PHY_INTERFACE_MODE_XGMII:
0533 case PHY_INTERFACE_MODE_XAUI:
0534 cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
0535 break;
0536 case PHY_INTERFACE_MODE_RXAUI:
0537 cmode = MV88E6XXX_PORT_STS_CMODE_RXAUI;
0538 break;
0539 case PHY_INTERFACE_MODE_10GBASER:
0540 cmode = MV88E6393X_PORT_STS_CMODE_10GBASER;
0541 break;
0542 default:
0543 cmode = 0;
0544 }
0545
0546
0547 if (cmode == chip->ports[port].cmode && !force)
0548 return 0;
0549
0550 lane = mv88e6xxx_serdes_get_lane(chip, port);
0551 if (lane >= 0) {
0552 if (chip->ports[port].serdes_irq) {
0553 err = mv88e6xxx_serdes_irq_disable(chip, port, lane);
0554 if (err)
0555 return err;
0556 }
0557
0558 err = mv88e6xxx_serdes_power_down(chip, port, lane);
0559 if (err)
0560 return err;
0561 }
0562
0563 chip->ports[port].cmode = 0;
0564
0565 if (cmode) {
0566 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
0567 if (err)
0568 return err;
0569
0570 reg &= ~MV88E6XXX_PORT_STS_CMODE_MASK;
0571 reg |= cmode;
0572
0573 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
0574 if (err)
0575 return err;
0576
0577 chip->ports[port].cmode = cmode;
0578
0579 lane = mv88e6xxx_serdes_get_lane(chip, port);
0580 if (lane == -ENODEV)
0581 return 0;
0582 if (lane < 0)
0583 return lane;
0584
0585 err = mv88e6xxx_serdes_power_up(chip, port, lane);
0586 if (err)
0587 return err;
0588
0589 if (chip->ports[port].serdes_irq) {
0590 err = mv88e6xxx_serdes_irq_enable(chip, port, lane);
0591 if (err)
0592 return err;
0593 }
0594 }
0595
0596 return 0;
0597 }
0598
0599 int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
0600 phy_interface_t mode)
0601 {
0602 if (port != 9 && port != 10)
0603 return -EOPNOTSUPP;
0604
0605 return mv88e6xxx_port_set_cmode(chip, port, mode, false);
0606 }
0607
0608 int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
0609 phy_interface_t mode)
0610 {
0611 if (port != 9 && port != 10)
0612 return -EOPNOTSUPP;
0613
0614 switch (mode) {
0615 case PHY_INTERFACE_MODE_NA:
0616 return 0;
0617 case PHY_INTERFACE_MODE_XGMII:
0618 case PHY_INTERFACE_MODE_XAUI:
0619 case PHY_INTERFACE_MODE_RXAUI:
0620 return -EINVAL;
0621 default:
0622 break;
0623 }
0624
0625 return mv88e6xxx_port_set_cmode(chip, port, mode, false);
0626 }
0627
0628 int mv88e6393x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
0629 phy_interface_t mode)
0630 {
0631 int err;
0632 u16 reg;
0633
0634 if (port != 0 && port != 9 && port != 10)
0635 return -EOPNOTSUPP;
0636
0637
0638 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, ®);
0639 if (err)
0640 return err;
0641
0642 reg &= ~MV88E6XXX_PORT_MAC_CTL_EEE;
0643 reg |= MV88E6XXX_PORT_MAC_CTL_FORCE_EEE;
0644 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_MAC_CTL, reg);
0645 if (err)
0646 return err;
0647
0648 return mv88e6xxx_port_set_cmode(chip, port, mode, false);
0649 }
0650
0651 static int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip,
0652 int port)
0653 {
0654 int err, addr;
0655 u16 reg, bits;
0656
0657 if (port != 5)
0658 return -EOPNOTSUPP;
0659
0660 addr = chip->info->port_base_addr + port;
0661
0662 err = mv88e6xxx_port_hidden_read(chip, 0x7, addr, 0, ®);
0663 if (err)
0664 return err;
0665
0666 bits = MV88E6341_PORT_RESERVED_1A_FORCE_CMODE |
0667 MV88E6341_PORT_RESERVED_1A_SGMII_AN;
0668
0669 if ((reg & bits) == bits)
0670 return 0;
0671
0672 reg |= bits;
0673 return mv88e6xxx_port_hidden_write(chip, 0x7, addr, 0, reg);
0674 }
0675
0676 int mv88e6341_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
0677 phy_interface_t mode)
0678 {
0679 int err;
0680
0681 if (port != 5)
0682 return -EOPNOTSUPP;
0683
0684 switch (mode) {
0685 case PHY_INTERFACE_MODE_NA:
0686 return 0;
0687 case PHY_INTERFACE_MODE_XGMII:
0688 case PHY_INTERFACE_MODE_XAUI:
0689 case PHY_INTERFACE_MODE_RXAUI:
0690 return -EINVAL;
0691 default:
0692 break;
0693 }
0694
0695 err = mv88e6341_port_set_cmode_writable(chip, port);
0696 if (err)
0697 return err;
0698
0699 return mv88e6xxx_port_set_cmode(chip, port, mode, true);
0700 }
0701
0702 int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
0703 {
0704 int err;
0705 u16 reg;
0706
0707 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
0708 if (err)
0709 return err;
0710
0711 *cmode = reg & MV88E6185_PORT_STS_CMODE_MASK;
0712
0713 return 0;
0714 }
0715
0716 int mv88e6352_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
0717 {
0718 int err;
0719 u16 reg;
0720
0721 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
0722 if (err)
0723 return err;
0724
0725 *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
0726
0727 return 0;
0728 }
0729
0730
0731
0732
0733
0734
0735
0736 int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
0737 u8 out)
0738 {
0739 return mv88e6xxx_port_write(chip, port, MV88E6097_PORT_JAM_CTL,
0740 out << 8 | in);
0741 }
0742
0743 int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
0744 u8 out)
0745 {
0746 int err;
0747
0748 err = mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
0749 MV88E6390_PORT_FLOW_CTL_UPDATE |
0750 MV88E6390_PORT_FLOW_CTL_LIMIT_IN | in);
0751 if (err)
0752 return err;
0753
0754 return mv88e6xxx_port_write(chip, port, MV88E6390_PORT_FLOW_CTL,
0755 MV88E6390_PORT_FLOW_CTL_UPDATE |
0756 MV88E6390_PORT_FLOW_CTL_LIMIT_OUT | out);
0757 }
0758
0759
0760
0761 static const char * const mv88e6xxx_port_state_names[] = {
0762 [MV88E6XXX_PORT_CTL0_STATE_DISABLED] = "Disabled",
0763 [MV88E6XXX_PORT_CTL0_STATE_BLOCKING] = "Blocking/Listening",
0764 [MV88E6XXX_PORT_CTL0_STATE_LEARNING] = "Learning",
0765 [MV88E6XXX_PORT_CTL0_STATE_FORWARDING] = "Forwarding",
0766 };
0767
0768 int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
0769 {
0770 u16 reg;
0771 int err;
0772
0773 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
0774 if (err)
0775 return err;
0776
0777 reg &= ~MV88E6XXX_PORT_CTL0_STATE_MASK;
0778
0779 switch (state) {
0780 case BR_STATE_DISABLED:
0781 state = MV88E6XXX_PORT_CTL0_STATE_DISABLED;
0782 break;
0783 case BR_STATE_BLOCKING:
0784 case BR_STATE_LISTENING:
0785 state = MV88E6XXX_PORT_CTL0_STATE_BLOCKING;
0786 break;
0787 case BR_STATE_LEARNING:
0788 state = MV88E6XXX_PORT_CTL0_STATE_LEARNING;
0789 break;
0790 case BR_STATE_FORWARDING:
0791 state = MV88E6XXX_PORT_CTL0_STATE_FORWARDING;
0792 break;
0793 default:
0794 return -EINVAL;
0795 }
0796
0797 reg |= state;
0798
0799 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
0800 if (err)
0801 return err;
0802
0803 dev_dbg(chip->dev, "p%d: PortState set to %s\n", port,
0804 mv88e6xxx_port_state_names[state]);
0805
0806 return 0;
0807 }
0808
0809 int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
0810 enum mv88e6xxx_egress_mode mode)
0811 {
0812 int err;
0813 u16 reg;
0814
0815 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
0816 if (err)
0817 return err;
0818
0819 reg &= ~MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK;
0820
0821 switch (mode) {
0822 case MV88E6XXX_EGRESS_MODE_UNMODIFIED:
0823 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED;
0824 break;
0825 case MV88E6XXX_EGRESS_MODE_UNTAGGED:
0826 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED;
0827 break;
0828 case MV88E6XXX_EGRESS_MODE_TAGGED:
0829 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_TAGGED;
0830 break;
0831 case MV88E6XXX_EGRESS_MODE_ETHERTYPE:
0832 reg |= MV88E6XXX_PORT_CTL0_EGRESS_MODE_ETHER_TYPE_DSA;
0833 break;
0834 default:
0835 return -EINVAL;
0836 }
0837
0838 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
0839 }
0840
0841 int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
0842 enum mv88e6xxx_frame_mode mode)
0843 {
0844 int err;
0845 u16 reg;
0846
0847 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
0848 if (err)
0849 return err;
0850
0851 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
0852
0853 switch (mode) {
0854 case MV88E6XXX_FRAME_MODE_NORMAL:
0855 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
0856 break;
0857 case MV88E6XXX_FRAME_MODE_DSA:
0858 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
0859 break;
0860 default:
0861 return -EINVAL;
0862 }
0863
0864 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
0865 }
0866
0867 int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
0868 enum mv88e6xxx_frame_mode mode)
0869 {
0870 int err;
0871 u16 reg;
0872
0873 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
0874 if (err)
0875 return err;
0876
0877 reg &= ~MV88E6XXX_PORT_CTL0_FRAME_MODE_MASK;
0878
0879 switch (mode) {
0880 case MV88E6XXX_FRAME_MODE_NORMAL:
0881 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_NORMAL;
0882 break;
0883 case MV88E6XXX_FRAME_MODE_DSA:
0884 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_DSA;
0885 break;
0886 case MV88E6XXX_FRAME_MODE_PROVIDER:
0887 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_PROVIDER;
0888 break;
0889 case MV88E6XXX_FRAME_MODE_ETHERTYPE:
0890 reg |= MV88E6XXX_PORT_CTL0_FRAME_MODE_ETHER_TYPE_DSA;
0891 break;
0892 default:
0893 return -EINVAL;
0894 }
0895
0896 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
0897 }
0898
0899 int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip,
0900 int port, bool unicast)
0901 {
0902 int err;
0903 u16 reg;
0904
0905 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
0906 if (err)
0907 return err;
0908
0909 if (unicast)
0910 reg |= MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
0911 else
0912 reg &= ~MV88E6185_PORT_CTL0_FORWARD_UNKNOWN;
0913
0914 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
0915 }
0916
0917 int mv88e6352_port_set_ucast_flood(struct mv88e6xxx_chip *chip, int port,
0918 bool unicast)
0919 {
0920 int err;
0921 u16 reg;
0922
0923 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
0924 if (err)
0925 return err;
0926
0927 if (unicast)
0928 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_UC;
0929 else
0930 reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_UC;
0931
0932 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
0933 }
0934
0935 int mv88e6352_port_set_mcast_flood(struct mv88e6xxx_chip *chip, int port,
0936 bool multicast)
0937 {
0938 int err;
0939 u16 reg;
0940
0941 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
0942 if (err)
0943 return err;
0944
0945 if (multicast)
0946 reg |= MV88E6352_PORT_CTL0_EGRESS_FLOODS_MC;
0947 else
0948 reg &= ~MV88E6352_PORT_CTL0_EGRESS_FLOODS_MC;
0949
0950 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
0951 }
0952
0953
0954
0955 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,
0956 bool message_port)
0957 {
0958 u16 val;
0959 int err;
0960
0961 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
0962 if (err)
0963 return err;
0964
0965 if (message_port)
0966 val |= MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
0967 else
0968 val &= ~MV88E6XXX_PORT_CTL1_MESSAGE_PORT;
0969
0970 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
0971 }
0972
0973 int mv88e6xxx_port_set_trunk(struct mv88e6xxx_chip *chip, int port,
0974 bool trunk, u8 id)
0975 {
0976 u16 val;
0977 int err;
0978
0979 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1, &val);
0980 if (err)
0981 return err;
0982
0983 val &= ~MV88E6XXX_PORT_CTL1_TRUNK_ID_MASK;
0984
0985 if (trunk)
0986 val |= MV88E6XXX_PORT_CTL1_TRUNK_PORT |
0987 (id << MV88E6XXX_PORT_CTL1_TRUNK_ID_SHIFT);
0988 else
0989 val &= ~MV88E6XXX_PORT_CTL1_TRUNK_PORT;
0990
0991 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1, val);
0992 }
0993
0994
0995
0996 int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
0997 {
0998 const u16 mask = mv88e6xxx_port_mask(chip);
0999 u16 reg;
1000 int err;
1001
1002 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
1003 if (err)
1004 return err;
1005
1006 reg &= ~mask;
1007 reg |= map & mask;
1008
1009 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
1010 if (err)
1011 return err;
1012
1013 dev_dbg(chip->dev, "p%d: VLANTable set to %.3x\n", port, map);
1014
1015 return 0;
1016 }
1017
1018 int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid)
1019 {
1020 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
1021 u16 reg;
1022 int err;
1023
1024
1025 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
1026 if (err)
1027 return err;
1028
1029 *fid = (reg & 0xf000) >> 12;
1030
1031
1032 if (upper_mask) {
1033 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
1034 ®);
1035 if (err)
1036 return err;
1037
1038 *fid |= (reg & upper_mask) << 4;
1039 }
1040
1041 return 0;
1042 }
1043
1044 int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid)
1045 {
1046 const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4;
1047 u16 reg;
1048 int err;
1049
1050 if (fid >= mv88e6xxx_num_databases(chip))
1051 return -EINVAL;
1052
1053
1054 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, ®);
1055 if (err)
1056 return err;
1057
1058 reg &= 0x0fff;
1059 reg |= (fid & 0x000f) << 12;
1060
1061 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_BASE_VLAN, reg);
1062 if (err)
1063 return err;
1064
1065
1066 if (upper_mask) {
1067 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
1068 ®);
1069 if (err)
1070 return err;
1071
1072 reg &= ~upper_mask;
1073 reg |= (fid >> 4) & upper_mask;
1074
1075 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL1,
1076 reg);
1077 if (err)
1078 return err;
1079 }
1080
1081 dev_dbg(chip->dev, "p%d: FID set to %u\n", port, fid);
1082
1083 return 0;
1084 }
1085
1086
1087
1088 int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid)
1089 {
1090 u16 reg;
1091 int err;
1092
1093 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
1094 ®);
1095 if (err)
1096 return err;
1097
1098 *pvid = reg & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
1099
1100 return 0;
1101 }
1102
1103 int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid)
1104 {
1105 u16 reg;
1106 int err;
1107
1108 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
1109 ®);
1110 if (err)
1111 return err;
1112
1113 reg &= ~MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
1114 reg |= pvid & MV88E6XXX_PORT_DEFAULT_VLAN_MASK;
1115
1116 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_DEFAULT_VLAN,
1117 reg);
1118 if (err)
1119 return err;
1120
1121 dev_dbg(chip->dev, "p%d: DefaultVID set to %u\n", port, pvid);
1122
1123 return 0;
1124 }
1125
1126
1127
1128 static const char * const mv88e6xxx_port_8021q_mode_names[] = {
1129 [MV88E6XXX_PORT_CTL2_8021Q_MODE_DISABLED] = "Disabled",
1130 [MV88E6XXX_PORT_CTL2_8021Q_MODE_FALLBACK] = "Fallback",
1131 [MV88E6XXX_PORT_CTL2_8021Q_MODE_CHECK] = "Check",
1132 [MV88E6XXX_PORT_CTL2_8021Q_MODE_SECURE] = "Secure",
1133 };
1134
1135 int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip,
1136 int port, bool multicast)
1137 {
1138 int err;
1139 u16 reg;
1140
1141 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
1142 if (err)
1143 return err;
1144
1145 if (multicast)
1146 reg |= MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
1147 else
1148 reg &= ~MV88E6XXX_PORT_CTL2_DEFAULT_FORWARD;
1149
1150 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1151 }
1152
1153 int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
1154 int upstream_port)
1155 {
1156 int err;
1157 u16 reg;
1158
1159 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
1160 if (err)
1161 return err;
1162
1163 reg &= ~MV88E6095_PORT_CTL2_CPU_PORT_MASK;
1164 reg |= upstream_port;
1165
1166 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1167 }
1168
1169 int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
1170 enum mv88e6xxx_egress_direction direction,
1171 bool mirror)
1172 {
1173 bool *mirror_port;
1174 u16 reg;
1175 u16 bit;
1176 int err;
1177
1178 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
1179 if (err)
1180 return err;
1181
1182 switch (direction) {
1183 case MV88E6XXX_EGRESS_DIR_INGRESS:
1184 bit = MV88E6XXX_PORT_CTL2_INGRESS_MONITOR;
1185 mirror_port = &chip->ports[port].mirror_ingress;
1186 break;
1187 case MV88E6XXX_EGRESS_DIR_EGRESS:
1188 bit = MV88E6XXX_PORT_CTL2_EGRESS_MONITOR;
1189 mirror_port = &chip->ports[port].mirror_egress;
1190 break;
1191 default:
1192 return -EINVAL;
1193 }
1194
1195 reg &= ~bit;
1196 if (mirror)
1197 reg |= bit;
1198
1199 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1200 if (!err)
1201 *mirror_port = mirror;
1202
1203 return err;
1204 }
1205
1206 int mv88e6xxx_port_set_lock(struct mv88e6xxx_chip *chip, int port,
1207 bool locked)
1208 {
1209 u16 reg;
1210 int err;
1211
1212 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, ®);
1213 if (err)
1214 return err;
1215
1216 reg &= ~MV88E6XXX_PORT_CTL0_SA_FILT_MASK;
1217 if (locked)
1218 reg |= MV88E6XXX_PORT_CTL0_SA_FILT_DROP_ON_LOCK;
1219
1220 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
1221 if (err)
1222 return err;
1223
1224 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, ®);
1225 if (err)
1226 return err;
1227
1228 reg &= ~MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT;
1229 if (locked)
1230 reg |= MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT;
1231
1232 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, reg);
1233 }
1234
1235 int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
1236 u16 mode)
1237 {
1238 u16 reg;
1239 int err;
1240
1241 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
1242 if (err)
1243 return err;
1244
1245 reg &= ~MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
1246 reg |= mode & MV88E6XXX_PORT_CTL2_8021Q_MODE_MASK;
1247
1248 err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1249 if (err)
1250 return err;
1251
1252 dev_dbg(chip->dev, "p%d: 802.1QMode set to %s\n", port,
1253 mv88e6xxx_port_8021q_mode_names[mode]);
1254
1255 return 0;
1256 }
1257
1258 int mv88e6xxx_port_drop_untagged(struct mv88e6xxx_chip *chip, int port,
1259 bool drop_untagged)
1260 {
1261 u16 old, new;
1262 int err;
1263
1264 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &old);
1265 if (err)
1266 return err;
1267
1268 if (drop_untagged)
1269 new = old | MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED;
1270 else
1271 new = old & ~MV88E6XXX_PORT_CTL2_DISCARD_UNTAGGED;
1272
1273 if (new == old)
1274 return 0;
1275
1276 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, new);
1277 }
1278
1279 int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port, bool map)
1280 {
1281 u16 reg;
1282 int err;
1283
1284 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
1285 if (err)
1286 return err;
1287
1288 if (map)
1289 reg |= MV88E6XXX_PORT_CTL2_MAP_DA;
1290 else
1291 reg &= ~MV88E6XXX_PORT_CTL2_MAP_DA;
1292
1293 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1294 }
1295
1296 int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
1297 size_t size)
1298 {
1299 u16 reg;
1300 int err;
1301
1302 size += VLAN_ETH_HLEN + ETH_FCS_LEN;
1303
1304 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, ®);
1305 if (err)
1306 return err;
1307
1308 reg &= ~MV88E6XXX_PORT_CTL2_JUMBO_MODE_MASK;
1309
1310 if (size <= 1522)
1311 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_1522;
1312 else if (size <= 2048)
1313 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_2048;
1314 else if (size <= 10240)
1315 reg |= MV88E6XXX_PORT_CTL2_JUMBO_MODE_10240;
1316 else
1317 return -ERANGE;
1318
1319 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
1320 }
1321
1322
1323
1324 int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1325 {
1326 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1327 0x0000);
1328 }
1329
1330 int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
1331 {
1332 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_EGRESS_RATE_CTL1,
1333 0x0001);
1334 }
1335
1336
1337
1338 int mv88e6xxx_port_set_assoc_vector(struct mv88e6xxx_chip *chip, int port,
1339 u16 pav)
1340 {
1341 u16 reg, mask;
1342 int err;
1343
1344 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
1345 ®);
1346 if (err)
1347 return err;
1348
1349 mask = mv88e6xxx_port_mask(chip);
1350 reg &= ~mask;
1351 reg |= pav & mask;
1352
1353 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
1354 reg);
1355 }
1356
1357
1358
1359 int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
1360 {
1361 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ATU_CTL, 0);
1362 }
1363
1364
1365
1366 int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port)
1367 {
1368 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_PRI_OVERRIDE, 0);
1369 }
1370
1371
1372
1373 static int mv88e6393x_port_policy_read(struct mv88e6xxx_chip *chip, int port,
1374 u16 pointer, u8 *data)
1375 {
1376 u16 reg;
1377 int err;
1378
1379 err = mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_POLICY_MGMT_CTL,
1380 pointer);
1381 if (err)
1382 return err;
1383
1384 err = mv88e6xxx_port_read(chip, port, MV88E6393X_PORT_POLICY_MGMT_CTL,
1385 ®);
1386 if (err)
1387 return err;
1388
1389 *data = reg;
1390
1391 return 0;
1392 }
1393
1394 static int mv88e6393x_port_policy_write(struct mv88e6xxx_chip *chip, int port,
1395 u16 pointer, u8 data)
1396 {
1397 u16 reg;
1398
1399 reg = MV88E6393X_PORT_POLICY_MGMT_CTL_UPDATE | pointer | data;
1400
1401 return mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_POLICY_MGMT_CTL,
1402 reg);
1403 }
1404
1405 static int mv88e6393x_port_policy_write_all(struct mv88e6xxx_chip *chip,
1406 u16 pointer, u8 data)
1407 {
1408 int err, port;
1409
1410 for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
1411 if (dsa_is_unused_port(chip->ds, port))
1412 continue;
1413
1414 err = mv88e6393x_port_policy_write(chip, port, pointer, data);
1415 if (err)
1416 return err;
1417 }
1418
1419 return 0;
1420 }
1421
1422 int mv88e6393x_set_egress_port(struct mv88e6xxx_chip *chip,
1423 enum mv88e6xxx_egress_direction direction,
1424 int port)
1425 {
1426 u16 ptr;
1427 int err;
1428
1429 switch (direction) {
1430 case MV88E6XXX_EGRESS_DIR_INGRESS:
1431 ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_INGRESS_DEST;
1432 err = mv88e6393x_port_policy_write_all(chip, ptr, port);
1433 if (err)
1434 return err;
1435 break;
1436 case MV88E6XXX_EGRESS_DIR_EGRESS:
1437 ptr = MV88E6393X_G2_EGRESS_MONITOR_DEST;
1438 err = mv88e6xxx_g2_write(chip, ptr, port);
1439 if (err)
1440 return err;
1441 break;
1442 }
1443
1444 return 0;
1445 }
1446
1447 int mv88e6393x_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
1448 int upstream_port)
1449 {
1450 u16 ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_CPU_DEST;
1451 u8 data = MV88E6393X_PORT_POLICY_MGMT_CTL_CPU_DEST_MGMTPRI |
1452 upstream_port;
1453
1454 return mv88e6393x_port_policy_write(chip, port, ptr, data);
1455 }
1456
1457 int mv88e6393x_port_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
1458 {
1459 u16 ptr;
1460 int err;
1461
1462
1463
1464
1465
1466 ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000000XLO;
1467 err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
1468 if (err)
1469 return err;
1470
1471 ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000000XHI;
1472 err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
1473 if (err)
1474 return err;
1475
1476 ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000002XLO;
1477 err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
1478 if (err)
1479 return err;
1480
1481 ptr = MV88E6393X_PORT_POLICY_MGMT_CTL_PTR_01C280000002XHI;
1482 err = mv88e6393x_port_policy_write_all(chip, ptr, 0xff);
1483 if (err)
1484 return err;
1485
1486 return 0;
1487 }
1488
1489
1490
1491 static int mv88e6393x_port_epc_wait_ready(struct mv88e6xxx_chip *chip, int port)
1492 {
1493 int bit = __bf_shf(MV88E6393X_PORT_EPC_CMD_BUSY);
1494
1495 return mv88e6xxx_port_wait_bit(chip, port, MV88E6393X_PORT_EPC_CMD, bit, 0);
1496 }
1497
1498
1499
1500 int mv88e6393x_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
1501 u16 etype)
1502 {
1503 u16 val;
1504 int err;
1505
1506 err = mv88e6393x_port_epc_wait_ready(chip, port);
1507 if (err)
1508 return err;
1509
1510 err = mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_EPC_DATA, etype);
1511 if (err)
1512 return err;
1513
1514 val = MV88E6393X_PORT_EPC_CMD_BUSY |
1515 MV88E6393X_PORT_EPC_CMD_WRITE |
1516 MV88E6393X_PORT_EPC_INDEX_PORT_ETYPE;
1517
1518 return mv88e6xxx_port_write(chip, port, MV88E6393X_PORT_EPC_CMD, val);
1519 }
1520
1521
1522
1523 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
1524 u16 etype)
1525 {
1526 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ETH_TYPE, etype);
1527 }
1528
1529
1530
1531
1532
1533 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1534 {
1535 int err;
1536
1537
1538 err = mv88e6xxx_port_write(chip, port,
1539 MV88E6095_PORT_IEEE_PRIO_REMAP_0123,
1540 0x3210);
1541 if (err)
1542 return err;
1543
1544 return mv88e6xxx_port_write(chip, port,
1545 MV88E6095_PORT_IEEE_PRIO_REMAP_4567,
1546 0x7654);
1547 }
1548
1549 static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
1550 int port, u16 table, u8 ptr, u16 data)
1551 {
1552 u16 reg;
1553
1554 reg = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE | table |
1555 (ptr << __bf_shf(MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_PTR_MASK)) |
1556 (data & MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_DATA_MASK);
1557
1558 return mv88e6xxx_port_write(chip, port,
1559 MV88E6390_PORT_IEEE_PRIO_MAP_TABLE, reg);
1560 }
1561
1562 int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1563 {
1564 int err, i;
1565 u16 table;
1566
1567 for (i = 0; i <= 7; i++) {
1568 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP;
1569 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i,
1570 (i | i << 4));
1571 if (err)
1572 return err;
1573
1574 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP;
1575 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1576 if (err)
1577 return err;
1578
1579 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP;
1580 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1581 if (err)
1582 return err;
1583
1584 table = MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP;
1585 err = mv88e6xxx_port_ieeepmt_write(chip, port, table, i, i);
1586 if (err)
1587 return err;
1588 }
1589
1590 return 0;
1591 }
1592
1593
1594
1595 static int
1596 mv88e6xxx_port_policy_mapping_get_pos(enum mv88e6xxx_policy_mapping mapping,
1597 enum mv88e6xxx_policy_action action,
1598 u16 *mask, u16 *val, int *shift)
1599 {
1600 switch (mapping) {
1601 case MV88E6XXX_POLICY_MAPPING_DA:
1602 *shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_DA_MASK);
1603 *mask = MV88E6XXX_PORT_POLICY_CTL_DA_MASK;
1604 break;
1605 case MV88E6XXX_POLICY_MAPPING_SA:
1606 *shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_SA_MASK);
1607 *mask = MV88E6XXX_PORT_POLICY_CTL_SA_MASK;
1608 break;
1609 case MV88E6XXX_POLICY_MAPPING_VTU:
1610 *shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VTU_MASK);
1611 *mask = MV88E6XXX_PORT_POLICY_CTL_VTU_MASK;
1612 break;
1613 case MV88E6XXX_POLICY_MAPPING_ETYPE:
1614 *shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK);
1615 *mask = MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK;
1616 break;
1617 case MV88E6XXX_POLICY_MAPPING_PPPOE:
1618 *shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK);
1619 *mask = MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK;
1620 break;
1621 case MV88E6XXX_POLICY_MAPPING_VBAS:
1622 *shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK);
1623 *mask = MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK;
1624 break;
1625 case MV88E6XXX_POLICY_MAPPING_OPT82:
1626 *shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK);
1627 *mask = MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK;
1628 break;
1629 case MV88E6XXX_POLICY_MAPPING_UDP:
1630 *shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_UDP_MASK);
1631 *mask = MV88E6XXX_PORT_POLICY_CTL_UDP_MASK;
1632 break;
1633 default:
1634 return -EOPNOTSUPP;
1635 }
1636
1637 switch (action) {
1638 case MV88E6XXX_POLICY_ACTION_NORMAL:
1639 *val = MV88E6XXX_PORT_POLICY_CTL_NORMAL;
1640 break;
1641 case MV88E6XXX_POLICY_ACTION_MIRROR:
1642 *val = MV88E6XXX_PORT_POLICY_CTL_MIRROR;
1643 break;
1644 case MV88E6XXX_POLICY_ACTION_TRAP:
1645 *val = MV88E6XXX_PORT_POLICY_CTL_TRAP;
1646 break;
1647 case MV88E6XXX_POLICY_ACTION_DISCARD:
1648 *val = MV88E6XXX_PORT_POLICY_CTL_DISCARD;
1649 break;
1650 default:
1651 return -EOPNOTSUPP;
1652 }
1653
1654 return 0;
1655 }
1656
1657 int mv88e6352_port_set_policy(struct mv88e6xxx_chip *chip, int port,
1658 enum mv88e6xxx_policy_mapping mapping,
1659 enum mv88e6xxx_policy_action action)
1660 {
1661 u16 reg, mask, val;
1662 int shift;
1663 int err;
1664
1665 err = mv88e6xxx_port_policy_mapping_get_pos(mapping, action, &mask,
1666 &val, &shift);
1667 if (err)
1668 return err;
1669
1670 err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_POLICY_CTL, ®);
1671 if (err)
1672 return err;
1673
1674 reg &= ~mask;
1675 reg |= (val << shift) & mask;
1676
1677 return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_POLICY_CTL, reg);
1678 }
1679
1680 int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port,
1681 enum mv88e6xxx_policy_mapping mapping,
1682 enum mv88e6xxx_policy_action action)
1683 {
1684 u16 mask, val;
1685 int shift;
1686 int err;
1687 u16 ptr;
1688 u8 reg;
1689
1690 err = mv88e6xxx_port_policy_mapping_get_pos(mapping, action, &mask,
1691 &val, &shift);
1692 if (err)
1693 return err;
1694
1695
1696
1697
1698
1699
1700 ptr = shift / 8;
1701 shift %= 8;
1702 mask >>= ptr * 8;
1703
1704 err = mv88e6393x_port_policy_read(chip, port, ptr, ®);
1705 if (err)
1706 return err;
1707
1708 reg &= ~mask;
1709 reg |= (val << shift) & mask;
1710
1711 return mv88e6393x_port_policy_write(chip, port, ptr, reg);
1712 }