On 1/30/19 2:28 PM, Vivien Didelot wrote: > Hi Florian, > > On Tue, 29 Jan 2019 16:55:43 -0800, Florian Fainelli <f.faine...@gmail.com> > wrote: > >> +static int dsa_slave_sync_unsync_mdb_addr(struct net_device *dev, >> + const unsigned char *addr, bool add) >> +{ >> + struct switchdev_obj_port_mdb mdb = { >> + .obj = { >> + .id = SWITCHDEV_OBJ_ID_HOST_MDB, >> + .flags = SWITCHDEV_F_DEFER, >> + }, >> + .vid = 0, >> + }; >> + int ret = -EOPNOTSUPP; > > Assignment unneeded here. > >> + >> + ether_addr_copy(mdb.addr, addr); >> + if (add) >> + ret = switchdev_port_obj_add(dev, &mdb.obj, NULL); >> + else >> + ret = switchdev_port_obj_del(dev, &mdb.obj); >> + >> + return ret; >> +} >> + >> +static int dsa_slave_sync_mdb_addr(struct net_device *dev, >> + const unsigned char *addr) >> +{ >> + return dsa_slave_sync_unsync_mdb_addr(dev, addr, true); >> +} >> + >> +static int dsa_slave_unsync_mdb_addr(struct net_device *dev, >> + const unsigned char *addr) >> +{ >> + return dsa_slave_sync_unsync_mdb_addr(dev, addr, false); >> +} > > This wrapper isn't necessary IMO. I'd go with something like: > > static int dsa_slave_sync(struct net_device *dev, const unsigned char *addr) > { > struct switchdev_obj_port_mdb mdb = { > .obj.id = SWITCHDEV_OBJ_ID_HOST_MDB, > .obj.flags = SWITCHDEV_F_DEFER, > }; > > ether_addr_copy(mdb.addr, addr); > > return switchdev_port_obj_add(dev, &mdb.obj, NULL); > } > > static int dsa_slave_unsync(struct net_device *dev, const unsigned char *addr) > { > struct switchdev_obj_port_mdb mdb = { > .obj.id = SWITCHDEV_OBJ_ID_HOST_MDB, > .obj.flags = SWITCHDEV_F_DEFER, > }; > > ether_addr_copy(mdb.addr, addr); > > return switchdev_port_obj_del(dev, &mdb.obj); > } > > We may eventually wrap this cryptic netdevery in: > > static int dsa_slave_mc_sync(struct net_device *dev) > { > return __hw_addr_sync_dev(&dev->mc, dev, dsa_slave_sync, > dsa_slave_unsync); > } > > static void dsa_slave_mc_unsync(struct net_device *dev) > { > __hw_addr_unsync_dev(&dev->mc, dev, dsa_slave_sync); > } > >> + >> static int dsa_slave_open(struct net_device *dev) >> { >> struct net_device *master = dsa_slave_to_master(dev); >> @@ -126,6 +159,8 @@ static int dsa_slave_close(struct net_device *dev) >> >> dev_mc_unsync(master, dev); >> dev_uc_unsync(master, dev); >> + __hw_addr_unsync_dev(&dev->mc, dev, dsa_slave_unsync_mdb_addr); >> + >> if (dev->flags & IFF_ALLMULTI) >> dev_set_allmulti(master, -1); >> if (dev->flags & IFF_PROMISC) >> @@ -150,7 +185,17 @@ static void dsa_slave_change_rx_flags(struct net_device >> *dev, int change) >> static void dsa_slave_set_rx_mode(struct net_device *dev) >> { >> struct net_device *master = dsa_slave_to_master(dev); >> + struct dsa_port *dp = dsa_slave_to_port(dev); >> >> + /* If the port is bridged, the bridge takes care of sending >> + * SWITCHDEV_OBJ_ID_HOST_MDB to program the host's MC filter >> + */ >> + if (netdev_mc_empty(dev) || dp->bridge_dev) >> + goto out; >> + >> + __hw_addr_sync_dev(&dev->mc, dev, dsa_slave_sync_mdb_addr, >> + dsa_slave_unsync_mdb_addr); > > And check the returned error code.
All good points, I have now incorporated your suggestions, thanks! -- Florian