diff options
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/port.c')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/port.c | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index 8875784c4718..548a956637ee 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c @@ -3,7 +3,8 @@ * * Copyright (c) 2008 Marvell Semiconductor * - * Copyright (c) 2016 Vivien Didelot <vivien.didelot@savoirfairelinux.com> + * Copyright (c) 2016-2017 Savoir-faire Linux Inc. + * Vivien Didelot <vivien.didelot@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -497,8 +498,8 @@ int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port, return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg); } -int mv88e6085_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port, - bool on) +static int mv88e6185_port_set_forward_unknown(struct mv88e6xxx_chip *chip, + int port, bool unicast) { int err; u16 reg; @@ -507,7 +508,7 @@ int mv88e6085_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port, if (err) return err; - if (on) + if (unicast) reg |= PORT_CONTROL_FORWARD_UNKNOWN; else reg &= ~PORT_CONTROL_FORWARD_UNKNOWN; @@ -515,8 +516,8 @@ int mv88e6085_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port, return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg); } -int mv88e6351_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port, - bool on) +int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port, + bool unicast, bool multicast) { int err; u16 reg; @@ -525,21 +526,45 @@ int mv88e6351_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port, if (err) return err; - if (on) - reg |= PORT_CONTROL_EGRESS_ALL_UNKNOWN_DA; + reg &= ~PORT_CONTROL_EGRESS_FLOODS_MASK; + + if (unicast && multicast) + reg |= PORT_CONTROL_EGRESS_FLOODS_ALL_UNKNOWN_DA; + else if (unicast) + reg |= PORT_CONTROL_EGRESS_FLOODS_NO_UNKNOWN_MC_DA; + else if (multicast) + reg |= PORT_CONTROL_EGRESS_FLOODS_NO_UNKNOWN_UC_DA; else - reg &= ~PORT_CONTROL_EGRESS_ALL_UNKNOWN_DA; + reg |= PORT_CONTROL_EGRESS_FLOODS_NO_UNKNOWN_DA; return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg); } /* Offset 0x05: Port Control 1 */ +int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port, + bool message_port) +{ + u16 val; + int err; + + err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_1, &val); + if (err) + return err; + + if (message_port) + val |= PORT_CONTROL_1_MESSAGE_PORT; + else + val &= ~PORT_CONTROL_1_MESSAGE_PORT; + + return mv88e6xxx_port_write(chip, port, PORT_CONTROL_1, val); +} + /* Offset 0x06: Port Based VLAN Map */ int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map) { - const u16 mask = GENMASK(mv88e6xxx_num_ports(chip) - 1, 0); + const u16 mask = mv88e6xxx_port_mask(chip); u16 reg; int err; @@ -672,8 +697,8 @@ static const char * const mv88e6xxx_port_8021q_mode_names[] = { [PORT_CONTROL_2_8021Q_SECURE] = "Secure", }; -int mv88e6095_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port, - bool on) +static int mv88e6185_port_set_default_forward(struct mv88e6xxx_chip *chip, + int port, bool multicast) { int err; u16 reg; @@ -682,14 +707,26 @@ int mv88e6095_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port, if (err) return err; - if (on) - reg |= PORT_CONTROL_2_FORWARD_UNKNOWN; + if (multicast) + reg |= PORT_CONTROL_2_DEFAULT_FORWARD; else - reg &= ~PORT_CONTROL_2_FORWARD_UNKNOWN; + reg &= ~PORT_CONTROL_2_DEFAULT_FORWARD; return mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg); } +int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port, + bool unicast, bool multicast) +{ + int err; + + err = mv88e6185_port_set_forward_unknown(chip, port, unicast); + if (err) + return err; + + return mv88e6185_port_set_default_forward(chip, port, multicast); +} + int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port, int upstream_port) { @@ -769,6 +806,20 @@ int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port) return mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL, 0x0001); } +/* Offset 0x0C: Port ATU Control */ + +int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port) +{ + return mv88e6xxx_port_write(chip, port, PORT_ATU_CONTROL, 0); +} + +/* Offset 0x0D: (Priority) Override Register */ + +int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port) +{ + return mv88e6xxx_port_write(chip, port, PORT_PRI_OVERRIDE, 0); +} + /* Offset 0x0f: Port Ether type */ int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port, |