Hi Clement, On Wed, 2023-02-08 at 17:17 +0100, Clément Léger wrote: > EXTERNAL EMAIL: Do not click links or open attachments unless you > know the content is safe > > Add support for vlan operation (add, del, filtering) on the RZN1 > driver. The a5psw switch supports up to 32 VLAN IDs with filtering, > tagged/untagged VLANs and PVID for each ports. > > Signed-off-by: Clément Léger <clement.leger@xxxxxxxxxxx> > --- > drivers/net/dsa/rzn1_a5psw.c | 167 > +++++++++++++++++++++++++++++++++++ > drivers/net/dsa/rzn1_a5psw.h | 8 +- > 2 files changed, 172 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/dsa/rzn1_a5psw.c > b/drivers/net/dsa/rzn1_a5psw.c > index 0ce3948952db..de6b18ec647d 100644 > --- a/drivers/net/dsa/rzn1_a5psw.c > +++ b/drivers/net/dsa/rzn1_a5psw.c > @@ -583,6 +583,147 @@ static int a5psw_port_fdb_dump(struct > dsa_switch *ds, int port, > return ret; > } > > +static int a5psw_port_vlan_filtering(struct dsa_switch *ds, int > port, > + bool vlan_filtering, > + struct netlink_ext_ack *extack) > +{ > + u32 mask = BIT(port + A5PSW_VLAN_VERI_SHIFT) | > + BIT(port + A5PSW_VLAN_DISC_SHIFT); nit: if initialization of mask is separated from declaration may increase the readability. > + struct a5psw *a5psw = ds->priv; > + u32 val = 0; > + > + if (vlan_filtering) > + val = BIT(port + A5PSW_VLAN_VERI_SHIFT) | > + BIT(port + A5PSW_VLAN_DISC_SHIFT); > + > + a5psw_reg_rmw(a5psw, A5PSW_VLAN_VERIFY, mask, val); > + > + return 0; > +} > + > + > +static void a5psw_port_vlan_tagged_cfg(struct a5psw *a5psw, int > vlan_res_id, > + int port, bool set) > +{ > + u32 mask = A5PSW_VLAN_RES_WR_PORTMASK | > A5PSW_VLAN_RES_RD_TAGMASK | > + BIT(port); same here. > + u32 vlan_res_off = A5PSW_VLAN_RES(vlan_res_id); > + u32 val = A5PSW_VLAN_RES_WR_TAGMASK, reg; > + > + if (set) > + val |= BIT(port); > + > + /* Toggle tag mask read */ > + a5psw_reg_writel(a5psw, vlan_res_off, > A5PSW_VLAN_RES_RD_TAGMASK); > + reg = a5psw_reg_readl(a5psw, vlan_res_off); > + a5psw_reg_writel(a5psw, vlan_res_off, > A5PSW_VLAN_RES_RD_TAGMASK+static int a5psw_port_vlan_add(struct > dsa_switch *ds, int port, > > + const struct switchdev_obj_port_vlan > > *vlan, > > + struct netlink_ext_ack *extack) > > +{ > > + bool tagged = !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED); > > + bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; > > + struct a5psw *a5psw = ds->priv; > > + u16 vid = vlan->vid; > > + int vlan_res_id; > > + > > + dev_dbg(a5psw->dev, "Add VLAN %d on port %d, %s, %s\n", > > + vid, port, tagged ? "tagged" : "untagged", > > + pvid ? "PVID" : "no PVID"); > > + > > + vlan_res_id = a5psw_find_vlan_entry(a5psw, vid); > > + if (vlan_res_id < 0) { > > + vlan_res_id = a5psw_get_vlan_res_entry(a5psw, vid); > > + if (vlan_res_id < 0) > > + return -EINVAL; > > + } > > + > > + a5psw_port_vlan_cfg(a5psw, vlan_res_id, port, true); > > + if (tagged) > > + a5psw_port_vlan_tagged_cfg(a5psw, vlan_res_id, > port, > > true); > > + > > + if (pvid) { > > + a5psw_reg_rmw(a5psw, A5PSW_VLAN_IN_MODE_ENA, > > BIT(port), > > + BIT(port)); > > + a5psw_reg_writel(a5psw, A5PSW_SYSTEM_TAGINFO(port), > > vid); > > + } > > + > > + return 0; > > +} > > + >