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

Reply via email to