On 8/19/2019 5:00 PM, Vladimir Oltean wrote:
> The bridge core assumes that enabling/disabling vlan_filtering will
> translate into the simple toggling of a flag for switchdev drivers.
> 
> That is clearly not the case for sja1105, which alters the VLAN table
> and the pvids in order to obtain port separation in standalone mode.
> 
> So, since the bridge will not call any vlan operation through switchdev
> after enabling vlan_filtering, we need to ensure we're in a functional
> state ourselves.
> 
> Hence read the pvid that the bridge is aware of, and program that into
> our ports.

That is arguably applicable with DSA at large and not just specifically
for tag_8021q.c no? Is there a reason why you are not seeking to solve
this on a more global scale?

> 
> Signed-off-by: Vladimir Oltean <olte...@gmail.com>
> ---
>  net/dsa/tag_8021q.c | 32 +++++++++++++++++++++++++++++++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
> 
> diff --git a/net/dsa/tag_8021q.c b/net/dsa/tag_8021q.c
> index 67a1bc635a7b..6423beb1efcd 100644
> --- a/net/dsa/tag_8021q.c
> +++ b/net/dsa/tag_8021q.c
> @@ -93,6 +93,33 @@ int dsa_8021q_rx_source_port(u16 vid)
>  }
>  EXPORT_SYMBOL_GPL(dsa_8021q_rx_source_port);
>  
> +static int dsa_port_restore_pvid(struct dsa_switch *ds, int port)
> +{
> +     struct bridge_vlan_info vinfo;
> +     struct net_device *slave;
> +     u16 pvid;
> +     int err;
> +
> +     if (!dsa_is_user_port(ds, port))
> +             return 0;
> +
> +     slave = ds->ports[port].slave;
> +
> +     err = br_vlan_get_pvid(slave, &pvid);
> +     if (err < 0) {
> +             dev_err(ds->dev, "Couldn't determine bridge PVID\n");
> +             return err;
> +     }
> +
> +     err = br_vlan_get_info(slave, pvid, &vinfo);
> +     if (err < 0) {
> +             dev_err(ds->dev, "Couldn't determine PVID attributes\n");
> +             return err;
> +     }
> +
> +     return dsa_port_vid_add(&ds->ports[port], pvid, vinfo.flags);
> +}
> +
>  /* RX VLAN tagging (left) and TX VLAN tagging (right) setup shown for a 
> single
>   * front-panel switch port (here swp0).
>   *
> @@ -223,7 +250,10 @@ int dsa_port_setup_8021q_tagging(struct dsa_switch *ds, 
> int port, bool enabled)
>               return err;
>       }
>  
> -     return 0;
> +     if (!enabled)
> +             err = dsa_port_restore_pvid(ds, port);
> +
> +     return err;
>  }
>  EXPORT_SYMBOL_GPL(dsa_port_setup_8021q_tagging);
>  
> 

-- 
Florian

Reply via email to