]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/net/ethernet/aquantia/atlantic/aq_nic.c
net: aquantia: correctly handle macvlan and multicast coexistence
[linux.git] / drivers / net / ethernet / aquantia / atlantic / aq_nic.c
index 8f66e781781182e553c53ba73fde92581de21ee7..2a18439b36fbe5975116d1ae4ddeb6975bf62e5d 100644 (file)
@@ -631,9 +631,12 @@ int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags)
 
 int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev)
 {
-       unsigned int packet_filter = self->packet_filter;
+       const struct aq_hw_ops *hw_ops = self->aq_hw_ops;
+       struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
+       unsigned int packet_filter = ndev->flags;
        struct netdev_hw_addr *ha = NULL;
        unsigned int i = 0U;
+       int err = 0;
 
        self->mc_list.count = 0;
        if (netdev_uc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) {
@@ -641,29 +644,26 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev)
        } else {
                netdev_for_each_uc_addr(ha, ndev) {
                        ether_addr_copy(self->mc_list.ar[i++], ha->addr);
-
-                       if (i >= AQ_HW_MULTICAST_ADDRESS_MAX)
-                               break;
                }
        }
 
-       if (i + netdev_mc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) {
-               packet_filter |= IFF_ALLMULTI;
-       } else {
-               netdev_for_each_mc_addr(ha, ndev) {
-                       ether_addr_copy(self->mc_list.ar[i++], ha->addr);
-
-                       if (i >= AQ_HW_MULTICAST_ADDRESS_MAX)
-                               break;
+       cfg->is_mc_list_enabled = !!(packet_filter & IFF_MULTICAST);
+       if (cfg->is_mc_list_enabled) {
+               if (i + netdev_mc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) {
+                       packet_filter |= IFF_ALLMULTI;
+               } else {
+                       netdev_for_each_mc_addr(ha, ndev) {
+                               ether_addr_copy(self->mc_list.ar[i++],
+                                               ha->addr);
+                       }
                }
        }
 
        if (i > 0 && i <= AQ_HW_MULTICAST_ADDRESS_MAX) {
-               packet_filter |= IFF_MULTICAST;
                self->mc_list.count = i;
-               self->aq_hw_ops->hw_multicast_list_set(self->aq_hw,
-                                                      self->mc_list.ar,
-                                                      self->mc_list.count);
+               err = hw_ops->hw_multicast_list_set(self->aq_hw,
+                                                   self->mc_list.ar,
+                                                   self->mc_list.count);
        }
        return aq_nic_set_packet_filter(self, packet_filter);
 }