Commit d7417ee9 authored by David S. Miller's avatar David S. Miller

Merge branch 'mv88e6xxx-offload-bridge-flags'

Tobias Waldekranz says:

====================
net: dsa: mv88e6xxx: Offload bridge port flags

Add support for offloading learning and broadcast flooding flags. With
this in place, mv88e6xx supports offloading of all bridge port flags
that are currently supported by the bridge.

Broadcast flooding is somewhat awkward to control as there is no
per-port bit for this like there is for unknown unicast and unknown
multicast. Instead we have to update the ATU entry for the broadcast
address for all currently used FIDs.

v2 -> v3:
  - Only return a netdev from dsa_port_to_bridge_port if the port is
    currently bridged (Vladimir & Florian)

v1 -> v2:
  - Ensure that mv88e6xxx_vtu_get handles VID 0 (Vladimir)
  - Fixed off-by-one in mv88e6xxx_port_set_assoc_vector (Vladimir)
  - Fast age all entries on port when disabling learning (Vladimir)
  - Correctly detect bridge flags on LAG ports (Vladimir)
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 44b958a6 8d1d8298
This diff is collapsed.
...@@ -1309,6 +1309,27 @@ int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port) ...@@ -1309,6 +1309,27 @@ int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
0x0001); 0x0001);
} }
/* Offset 0x0B: Port Association Vector */
int mv88e6xxx_port_set_assoc_vector(struct mv88e6xxx_chip *chip, int port,
u16 pav)
{
u16 reg, mask;
int err;
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
&reg);
if (err)
return err;
mask = mv88e6xxx_port_mask(chip);
reg &= ~mask;
reg |= pav & mask;
return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
reg);
}
/* Offset 0x0C: Port ATU Control */ /* Offset 0x0C: Port ATU Control */
int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port) int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port)
......
...@@ -407,6 +407,8 @@ int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port, ...@@ -407,6 +407,8 @@ int mv88e6165_port_set_jumbo_size(struct mv88e6xxx_chip *chip, int port,
size_t size); size_t size);
int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port); int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port);
int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port); int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port);
int mv88e6xxx_port_set_assoc_vector(struct mv88e6xxx_chip *chip, int port,
u16 pav);
int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, int mv88e6097_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
u8 out); u8 out);
int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in, int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
......
...@@ -493,6 +493,20 @@ static inline bool dsa_port_is_vlan_filtering(const struct dsa_port *dp) ...@@ -493,6 +493,20 @@ static inline bool dsa_port_is_vlan_filtering(const struct dsa_port *dp)
return dp->vlan_filtering; return dp->vlan_filtering;
} }
static inline
struct net_device *dsa_port_to_bridge_port(const struct dsa_port *dp)
{
if (!dp->bridge_dev)
return NULL;
if (dp->lag_dev)
return dp->lag_dev;
else if (dp->hsr_dev)
return dp->hsr_dev;
return dp->slave;
}
typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid, typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,
bool is_static, void *data); bool is_static, void *data);
struct dsa_switch_ops { struct dsa_switch_ops {
......
...@@ -233,19 +233,7 @@ extern const struct phylink_mac_ops dsa_port_phylink_mac_ops; ...@@ -233,19 +233,7 @@ extern const struct phylink_mac_ops dsa_port_phylink_mac_ops;
static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp, static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp,
struct net_device *dev) struct net_device *dev)
{ {
/* Switchdev offloading can be configured on: */ return dsa_port_to_bridge_port(dp) == dev;
if (dev == dp->slave)
/* DSA ports directly connected to a bridge, and event
* was emitted for the ports themselves.
*/
return true;
if (dp->lag_dev == dev)
/* DSA ports connected to a bridge via a LAG */
return true;
return false;
} }
static inline bool dsa_port_offloads_bridge(struct dsa_port *dp, static inline bool dsa_port_offloads_bridge(struct dsa_port *dp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment