On Mon, Feb 08, 2021 at 01:21:37AM +0200, Vladimir Oltean wrote:
> From: Vladimir Oltean <vladimir.olt...@nxp.com>
> 
> There does not appear to be any strong reason why
> br_switchdev_set_port_flag issues a separate notification for checking
> the supported brport flags rather than just attempting to apply them and
> propagating the error if that fails.
> 
> However, there is a reason why this switchdev API is counterproductive
> for a driver writer, and that is 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. This means that "edge detection" needs to be
> done by each individual BRIDGE_FLAGS listener by XOR-ing the old and the
> new flags, which in turn means that copying the flags into a driver
> private variable is strictly necessary.
> 
> This can be solved by passing the "flags" and the "value" together into
> a single switchdev attribute, and it also reduces some boilerplate in
> the drivers that offload this.
> 
> Signed-off-by: Vladimir Oltean <vladimir.olt...@nxp.com>
> ---
>  drivers/net/dsa/b53/b53_common.c              | 16 ++++-------
>  drivers/net/dsa/mv88e6xxx/chip.c              | 17 ++++-------
>  .../marvell/prestera/prestera_switchdev.c     | 16 +++++------
>  .../mellanox/mlxsw/spectrum_switchdev.c       | 28 ++++++-------------
>  drivers/net/ethernet/rocker/rocker_main.c     | 24 +++-------------
>  drivers/net/ethernet/ti/cpsw_switchdev.c      | 20 ++++---------
>  drivers/staging/fsl-dpaa2/ethsw/ethsw.c       | 22 ++++-----------
>  include/net/dsa.h                             |  4 +--
>  include/net/switchdev.h                       |  8 ++++--
>  net/bridge/br_switchdev.c                     | 19 ++++---------
>  net/dsa/dsa_priv.h                            |  4 +--
>  net/dsa/port.c                                | 15 ++--------
>  net/dsa/slave.c                               |  3 --
>  13 files changed, 58 insertions(+), 138 deletions(-)
> 

(..)

> --- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
> +++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
> @@ -908,28 +908,22 @@ static int dpaa2_switch_port_attr_stp_state_set(struct 
> net_device *netdev,
>       return dpaa2_switch_port_set_stp_state(port_priv, state);
>  }
>  
> -static int dpaa2_switch_port_attr_br_flags_pre_set(struct net_device *netdev,
> -                                                unsigned long flags)
> -{
> -     if (flags & ~(BR_LEARNING | BR_FLOOD))
> -             return -EINVAL;
> -
> -     return 0;
> -}
> -
>  static int dpaa2_switch_port_attr_br_flags_set(struct net_device *netdev,
> -                                            unsigned long flags)
> +                                            struct switchdev_brport_flags 
> val)
>  {
>       struct ethsw_port_priv *port_priv = netdev_priv(netdev);
>       int err = 0;
>  
> +     if (val.mask & ~(BR_LEARNING | BR_FLOOD))
> +             return -EINVAL;
> +
>       /* Learning is enabled per switch */
>       err = dpaa2_switch_set_learning(port_priv->ethsw_data,
> -                                     !!(flags & BR_LEARNING));
> +                                     !!(val.flags & BR_LEARNING));
>       if (err)
>               goto exit;
>  
> -     err = dpaa2_switch_port_set_flood(port_priv, !!(flags & BR_FLOOD));
> +     err = dpaa2_switch_port_set_flood(port_priv, !!(val.flags & BR_FLOOD));


Could you also check the mask to see if the flag needs to be actually changed?

> --- a/include/net/dsa.h
> +++ b/include/net/dsa.h
> @@ -621,10 +621,8 @@ struct dsa_switch_ops {
>       void    (*port_stp_state_set)(struct dsa_switch *ds, int port,
>                                     u8 state);
>       void    (*port_fast_age)(struct dsa_switch *ds, int port);
> -     int     (*port_pre_bridge_flags)(struct dsa_switch *ds, int port,
> -                                      unsigned long mask);
>       int     (*port_bridge_flags)(struct dsa_switch *ds, int port,
> -                                  unsigned long flags);
> +                                  struct switchdev_brport_flags val);
>       int     (*port_set_mrouter)(struct dsa_switch *ds, int port,
>                                   bool mrouter);
>  

In the previous patch you add the .port_pre_bridge_flags()
dsa_switch_ops only to remove it here. Couldn't these two patches be in
reverse order so that there is no need to actually add the callback in
the first place?

Ioana

Reply via email to