diff options
author | Igor Russkikh <Igor.Russkikh@aquantia.com> | 2017-08-28 14:52:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-08-29 18:11:44 -0400 |
commit | b21f502f84be082fb63cca8e7ab6eb8f7ee88024 (patch) | |
tree | 44fb2a3f0c48a1a32ab7266e8c785eadf37d2566 | |
parent | bd8ed4415ff8584ccdd1f61c8d7279dc1f9e623e (diff) |
net:ethernet:aquantia: Fix for multicast filter handling.
Since the HW supports up to 32 multicast filters we should
track count of multicast filters to avoid overflow.
If we attempt to add >32 multicast filter - just set NETIF_ALLMULTI flag
instead.
Fixes: 94f6c9e4cdf6 ("net: ethernet: aquantia: Support for NIC-specific code")
Signed-off-by: Igor Russkikh <Igor.Russkikh@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c index dce17a5b82b1..6ac9e2602d6d 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c | |||
@@ -669,11 +669,26 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev) | |||
669 | netdev_for_each_mc_addr(ha, ndev) { | 669 | netdev_for_each_mc_addr(ha, ndev) { |
670 | ether_addr_copy(self->mc_list.ar[i++], ha->addr); | 670 | ether_addr_copy(self->mc_list.ar[i++], ha->addr); |
671 | ++self->mc_list.count; | 671 | ++self->mc_list.count; |
672 | |||
673 | if (i >= AQ_CFG_MULTICAST_ADDRESS_MAX) | ||
674 | break; | ||
672 | } | 675 | } |
673 | 676 | ||
674 | return self->aq_hw_ops.hw_multicast_list_set(self->aq_hw, | 677 | if (i >= AQ_CFG_MULTICAST_ADDRESS_MAX) { |
678 | /* Number of filters is too big: atlantic does not support this. | ||
679 | * Force all multi filter to support this. | ||
680 | * With this we disable all UC filters and setup "all pass" | ||
681 | * multicast mask | ||
682 | */ | ||
683 | self->packet_filter |= IFF_ALLMULTI; | ||
684 | self->aq_hw->aq_nic_cfg->mc_list_count = 0; | ||
685 | return self->aq_hw_ops.hw_packet_filter_set(self->aq_hw, | ||
686 | self->packet_filter); | ||
687 | } else { | ||
688 | return self->aq_hw_ops.hw_multicast_list_set(self->aq_hw, | ||
675 | self->mc_list.ar, | 689 | self->mc_list.ar, |
676 | self->mc_list.count); | 690 | self->mc_list.count); |
691 | } | ||
677 | } | 692 | } |
678 | 693 | ||
679 | int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu) | 694 | int aq_nic_set_mtu(struct aq_nic_s *self, int new_mtu) |