Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Marvell 88E6xxx Switch Port 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/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 /* Offset 0x00: MAC (or PCS or Physical) Status Register
0046  *
0047  * For most devices, this is read only. However the 6185 has the MyPause
0048  * bit read/write.
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, &reg);
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 /* Offset 0x01: MAC (or PCS or Physical) Control Register
0069  *
0070  * Link, Duplex and Flow Control have one force bit, one value bit.
0071  *
0072  * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value.
0073  * Alternative values require the 200BASE (or AltSpeed) bit 12 set.
0074  * Newer chips need a ForcedSpd bit 13 set to consider the value.
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, &reg);
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, &reg);
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         /* normal link detection */
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         /* all bits set, fall through... */
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         /* normal duplex detection */
0260         break;
0261     default:
0262         return -EOPNOTSUPP;
0263     }
0264 
0265     err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
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 /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */
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 /* Support 10, 100 Mbps (e.g. 88E6250 family) */
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 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6341) */
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 /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */
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 /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */
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 /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */
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 /* Support 10, 100, 200, 1000, 2500, 5000, 10000 Mbps (e.g. 88E6393X)
0406  * Function mv88e6xxx_port_set_speed_duplex() can't be used as the register
0407  * values for speeds 2500 & 5000 conflict.
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         /* normal duplex detection */
0461         break;
0462     default:
0463         return -EOPNOTSUPP;
0464     }
0465 
0466     err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
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     /* Default to a slow mode, so freeing up SERDES interfaces for
0511      * other ports which might use them for SFPs.
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     /* cmode doesn't change, nothing to do for us unless forced */
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, &reg);
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     /* mv88e6393x errata 4.5: EEE should be disabled on SERDES ports */
0638     err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_MAC_CTL, &reg);
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, &reg);
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, &reg);
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, &reg);
0722     if (err)
0723         return err;
0724 
0725     *cmode = reg & MV88E6XXX_PORT_STS_CMODE_MASK;
0726 
0727     return 0;
0728 }
0729 
0730 /* Offset 0x02: Jamming Control
0731  *
0732  * Do not limit the period of time that this port can be paused for by
0733  * the remote end or the period of time that this port can pause the
0734  * remote end.
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 /* Offset 0x04: Port Control Register */
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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 /* Offset 0x05: Port Control 1 */
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 /* Offset 0x06: Port Based VLAN Map */
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, &reg);
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     /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
1025     err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
1026     if (err)
1027         return err;
1028 
1029     *fid = (reg & 0xf000) >> 12;
1030 
1031     /* Port's default FID upper bits are located in reg 0x05, offset 0 */
1032     if (upper_mask) {
1033         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
1034                       &reg);
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     /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */
1054     err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_BASE_VLAN, &reg);
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     /* Port's default FID upper bits are located in reg 0x05, offset 0 */
1066     if (upper_mask) {
1067         err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL1,
1068                       &reg);
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 /* Offset 0x07: Default Port VLAN ID & Priority */
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                   &reg);
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                   &reg);
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 /* Offset 0x08: Port Control 2 Register */
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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, &reg);
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 /* Offset 0x09: Port Rate Control */
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 /* Offset 0x0B: Port Association Vector */
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                   &reg);
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 /* Offset 0x0C: Port ATU Control */
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 /* Offset 0x0D: (Priority) Override Register */
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 /* Offset 0x0E: Policy & MGMT Control Register for FAMILY 6191X 6193X 6393X */
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                   &reg);
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     /* Consider the frames with reserved multicast destination
1463      * addresses matching 01:80:c2:00:00:00 and
1464      * 01:80:c2:00:00:02 as MGMT.
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 /* Offset 0x10 & 0x11: EPC */
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 /* Port Ether type for 6393X family */
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 /* Offset 0x0f: Port Ether type */
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 /* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
1530  * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
1531  */
1532 
1533 int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
1534 {
1535     int err;
1536 
1537     /* Use a direct priority mapping for all IEEE tagged frames */
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 /* Offset 0x0E: Policy Control Register */
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, &reg);
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     /* The 16-bit Port Policy CTL register from older chips is on 6393x
1696      * changed to Port Policy MGMT CTL, which can access more data, but
1697      * indirectly. The original 16-bit value is divided into two 8-bit
1698      * registers.
1699      */
1700     ptr = shift / 8;
1701     shift %= 8;
1702     mask >>= ptr * 8;
1703 
1704     err = mv88e6393x_port_policy_read(chip, port, ptr, &reg);
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 }