diff options
author | Vladimir Oltean <vladimir.oltean@nxp.com> | 2021-02-12 16:15:55 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-02-13 02:08:04 +0100 |
commit | e18f4c18ab5b0dd47caaf8377c2e36d66f632a8c (patch) | |
tree | a89ff5e705df268b0035f9d8611f7cb408ff8b83 /drivers/net/ethernet/ti/cpsw_switchdev.c | |
parent | net: dsa: configure better brport flags when ports leave the bridge (diff) | |
download | linux-e18f4c18ab5b0dd47caaf8377c2e36d66f632a8c.tar.xz linux-e18f4c18ab5b0dd47caaf8377c2e36d66f632a8c.zip |
net: switchdev: pass flags and mask to both {PRE_,}BRIDGE_FLAGS attributes
This switchdev attribute offers a counterproductive API for a driver
writer, because although br_switchdev_set_port_flag gets passed a
"flags" and a "mask", those are passed piecemeal to the driver, so while
the PRE_BRIDGE_FLAGS listener knows what changed because it has the
"mask", the BRIDGE_FLAGS listener doesn't, because it only has the final
value. But certain drivers can offload only certain combinations of
settings, like for example they cannot change unicast flooding
independently of multicast flooding - they must be both on or both off.
The way the information is passed to switchdev makes drivers not
expressive enough, and unable to reject this request ahead of time, in
the PRE_BRIDGE_FLAGS notifier, so they are forced to reject it during
the deferred BRIDGE_FLAGS attribute, where the rejection is currently
ignored.
This patch also changes drivers to make use of the "mask" field for edge
detection when possible.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/ti/cpsw_switchdev.c')
-rw-r--r-- | drivers/net/ethernet/ti/cpsw_switchdev.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/net/ethernet/ti/cpsw_switchdev.c b/drivers/net/ethernet/ti/cpsw_switchdev.c index 13524cbaa8b6..a72bb570756f 100644 --- a/drivers/net/ethernet/ti/cpsw_switchdev.c +++ b/drivers/net/ethernet/ti/cpsw_switchdev.c @@ -57,26 +57,30 @@ static int cpsw_port_stp_state_set(struct cpsw_priv *priv, u8 state) static int cpsw_port_attr_br_flags_set(struct cpsw_priv *priv, struct net_device *orig_dev, - unsigned long brport_flags) + struct switchdev_brport_flags flags) { struct cpsw_common *cpsw = priv->cpsw; - bool unreg_mcast_add = false; - if (brport_flags & BR_MCAST_FLOOD) - unreg_mcast_add = true; - dev_dbg(priv->dev, "BR_MCAST_FLOOD: %d port %u\n", - unreg_mcast_add, priv->emac_port); + if (flags.mask & BR_MCAST_FLOOD) { + bool unreg_mcast_add = false; - cpsw_ale_set_unreg_mcast(cpsw->ale, BIT(priv->emac_port), - unreg_mcast_add); + if (flags.val & BR_MCAST_FLOOD) + unreg_mcast_add = true; + + dev_dbg(priv->dev, "BR_MCAST_FLOOD: %d port %u\n", + unreg_mcast_add, priv->emac_port); + + cpsw_ale_set_unreg_mcast(cpsw->ale, BIT(priv->emac_port), + unreg_mcast_add); + } return 0; } static int cpsw_port_attr_br_flags_pre_set(struct net_device *netdev, - unsigned long flags) + struct switchdev_brport_flags flags) { - if (flags & ~(BR_LEARNING | BR_MCAST_FLOOD)) + if (flags.mask & ~(BR_LEARNING | BR_MCAST_FLOOD)) return -EINVAL; return 0; |