diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index 1ad7bcd1d421..81cd4a906038 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c @@ -133,6 +133,9 @@ struct dsa_switch_driver mv88e6123_switch_driver = { .set_eeprom = mv88e6xxx_set_eeprom, .get_regs_len = mv88e6xxx_get_regs_len, .get_regs = mv88e6xxx_get_regs, + .port_bridge_join = mv88e6xxx_port_bridge_join, + .port_bridge_leave = mv88e6xxx_port_bridge_leave, + .port_stp_state_set = mv88e6xxx_port_stp_state_set, }; MODULE_ALIAS("platform:mv88e6123"); diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 3fb06af74db3..5d252445e543 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -168,6 +168,7 @@ struct dsa_switch_driver mv88e6131_switch_driver = { .adjust_link = mv88e6xxx_adjust_link, .port_bridge_join = mv88e6xxx_port_bridge_join, .port_bridge_leave = mv88e6xxx_port_bridge_leave, + .port_stp_state_set = mv88e6xxx_port_stp_state_set, .port_vlan_filtering = mv88e6xxx_port_vlan_filtering, .port_vlan_prepare = mv88e6xxx_port_vlan_prepare, .port_vlan_add = mv88e6xxx_port_vlan_add, diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index c28ad83ee74d..f02738eaf541 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c @@ -1369,6 +1369,9 @@ void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int stp_state; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_PORTSTATE)) + return; + switch (state) { case BR_STATE_DISABLED: stp_state = PORT_CONTROL_STATE_DISABLED; @@ -2430,6 +2433,9 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); int i, err = 0; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE)) + return -EOPNOTSUPP; + mutex_lock(&ps->smi_mutex); /* Assign the bridge and remap each port's VLANTable */ @@ -2454,6 +2460,9 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port) struct net_device *bridge = ps->ports[port].bridge_dev; int i; + if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_VLANTABLE)) + return; + mutex_lock(&ps->smi_mutex); /* Unassign the bridge and remap each port's VLANTable */ diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index b99e0905992a..d15e0b3dffd3 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -360,6 +360,11 @@ enum mv88e6xxx_cap { */ MV88E6XXX_CAP_EEPROM, + /* Port State Filtering for 802.1D Spanning Tree. + * See PORT_CONTROL_STATE_* values in the PORT_CONTROL register. + */ + MV88E6XXX_CAP_PORTSTATE, + /* PHY Polling Unit. * See GLOBAL_CONTROL_PPU_ENABLE and GLOBAL_STATUS_PPU_POLLING. */ @@ -383,50 +388,67 @@ enum mv88e6xxx_cap { */ MV88E6XXX_CAP_TEMP, MV88E6XXX_CAP_TEMP_LIMIT, + + /* In-chip Port Based VLANs. + * Each port VLANTable register (see PORT_BASE_VLAN) is used to restrict + * the output (or egress) ports to which it is allowed to send frames. + */ + MV88E6XXX_CAP_VLANTABLE, }; /* Bitmask of capabilities */ #define MV88E6XXX_FLAG_EEE BIT(MV88E6XXX_CAP_EEE) #define MV88E6XXX_FLAG_EEPROM BIT(MV88E6XXX_CAP_EEPROM) +#define MV88E6XXX_FLAG_PORTSTATE BIT(MV88E6XXX_CAP_PORTSTATE) #define MV88E6XXX_FLAG_PPU BIT(MV88E6XXX_CAP_PPU) #define MV88E6XXX_FLAG_SMI_PHY BIT(MV88E6XXX_CAP_SMI_PHY) #define MV88E6XXX_FLAG_SWITCH_MAC BIT(MV88E6XXX_CAP_SWITCH_MAC_WOL_WOF) #define MV88E6XXX_FLAG_TEMP BIT(MV88E6XXX_CAP_TEMP) #define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT) +#define MV88E6XXX_FLAG_VLANTABLE BIT(MV88E6XXX_CAP_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6095 \ - MV88E6XXX_FLAG_PPU + (MV88E6XXX_FLAG_PPU | \ + MV88E6XXX_FLAG_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6097 \ - MV88E6XXX_FLAG_PPU + (MV88E6XXX_FLAG_PPU | \ + MV88E6XXX_FLAG_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6165 \ (MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP) #define MV88E6XXX_FLAGS_FAMILY_6185 \ - MV88E6XXX_FLAG_PPU + (MV88E6XXX_FLAG_PPU | \ + MV88E6XXX_FLAG_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6320 \ (MV88E6XXX_FLAG_EEE | \ MV88E6XXX_FLAG_EEPROM | \ + MV88E6XXX_FLAG_PORTSTATE | \ MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ - MV88E6XXX_FLAG_TEMP_LIMIT) + MV88E6XXX_FLAG_TEMP_LIMIT | \ + MV88E6XXX_FLAG_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6351 \ - (MV88E6XXX_FLAG_SMI_PHY | \ + (MV88E6XXX_FLAG_PORTSTATE | \ + MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ - MV88E6XXX_FLAG_TEMP) + MV88E6XXX_FLAG_TEMP | \ + MV88E6XXX_FLAG_VLANTABLE) #define MV88E6XXX_FLAGS_FAMILY_6352 \ (MV88E6XXX_FLAG_EEE | \ MV88E6XXX_FLAG_EEPROM | \ - MV88E6XXX_FLAG_SMI_PHY | \ + MV88E6XXX_FLAG_PORTSTATE | \ + MV88E6XXX_FLAG_SMI_PHY | \ MV88E6XXX_FLAG_SWITCH_MAC | \ MV88E6XXX_FLAG_TEMP | \ - MV88E6XXX_FLAG_TEMP_LIMIT) + MV88E6XXX_FLAG_TEMP_LIMIT | \ + MV88E6XXX_FLAG_VLANTABLE) struct mv88e6xxx_info { enum mv88e6xxx_family family;