You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
5.5 KiB
148 lines
5.5 KiB
From af62980c29f1c626dd6b1c9869333c7a0ed21cb4 Mon Sep 17 00:00:00 2001
|
|
From: Igor Russkikh <irusskik@redhat.com>
|
|
Date: Fri, 6 Nov 2020 18:36:34 -0500
|
|
Subject: [PATCH 017/139] [netdrv] net: aquantia: correctly handle macvlan and
|
|
multicast coexistence
|
|
|
|
Message-id: <1604687916-15087-18-git-send-email-irusskik@redhat.com>
|
|
Patchwork-id: 338442
|
|
Patchwork-instance: patchwork
|
|
O-Subject: [RHEL8.4 BZ 1857861 017/139] net: aquantia: correctly handle macvlan and multicast coexistence
|
|
Bugzilla: 1857861
|
|
RH-Acked-by: David Arcari <darcari@redhat.com>
|
|
RH-Acked-by: John Linville <linville@redhat.com>
|
|
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
|
Bugzilla: http://bugzilla.redhat.com/1857861
|
|
|
|
commit 9f051db566da1e8110659ab4ab188af1c2510bb4
|
|
Author: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
|
|
Date: Fri Oct 11 13:45:23 2019 +0000
|
|
|
|
net: aquantia: correctly handle macvlan and multicast coexistence
|
|
|
|
macvlan and multicast handling is now mixed up.
|
|
The explicit issue is that macvlan interface gets broken (no traffic)
|
|
after clearing MULTICAST flag on the real interface.
|
|
|
|
We now do separate logic and consider both ALLMULTI and MULTICAST
|
|
flags on the device.
|
|
|
|
Fixes: 11ba961c9161 ("net: aquantia: Fix IFF_ALLMULTI flag functionality")
|
|
Signed-off-by: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
|
|
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
|
|
Signed-off-by: Igor Russkikh <irusskik@redhat.com>
|
|
|
|
Cc: David Arcari <darcari@redhat.com>
|
|
Cc: Igor Russkikh <irusskik@redhat.com>
|
|
Signed-off-by: Jan Stancek <jstancek@redhat.com>
|
|
---
|
|
drivers/net/ethernet/aquantia/atlantic/aq_main.c | 4 +--
|
|
drivers/net/ethernet/aquantia/atlantic/aq_nic.c | 32 +++++++++++-----------
|
|
.../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 7 +++--
|
|
3 files changed, 21 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_main.c b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
|
|
index b4a0fb281e69..bb65dd39f847 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_main.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_main.c
|
|
@@ -194,9 +194,7 @@ static void aq_ndev_set_multicast_settings(struct net_device *ndev)
|
|
{
|
|
struct aq_nic_s *aq_nic = netdev_priv(ndev);
|
|
|
|
- aq_nic_set_packet_filter(aq_nic, ndev->flags);
|
|
-
|
|
- aq_nic_set_multicast_list(aq_nic, ndev);
|
|
+ (void)aq_nic_set_multicast_list(aq_nic, ndev);
|
|
}
|
|
|
|
static int aq_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto,
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
index 8f66e7817811..2a18439b36fb 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
|
|
@@ -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);
|
|
}
|
|
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
|
|
index 3459fadb7ddd..2ad3fa6316ce 100644
|
|
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
|
|
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
|
|
@@ -818,14 +818,15 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,
|
|
cfg->is_vlan_force_promisc);
|
|
|
|
hw_atl_rpfl2multicast_flr_en_set(self,
|
|
- IS_FILTER_ENABLED(IFF_ALLMULTI), 0);
|
|
+ IS_FILTER_ENABLED(IFF_ALLMULTI) &&
|
|
+ IS_FILTER_ENABLED(IFF_MULTICAST), 0);
|
|
|
|
hw_atl_rpfl2_accept_all_mc_packets_set(self,
|
|
- IS_FILTER_ENABLED(IFF_ALLMULTI));
|
|
+ IS_FILTER_ENABLED(IFF_ALLMULTI) &&
|
|
+ IS_FILTER_ENABLED(IFF_MULTICAST));
|
|
|
|
hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST));
|
|
|
|
- cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST);
|
|
|
|
for (i = HW_ATL_B0_MAC_MIN; i < HW_ATL_B0_MAC_MAX; ++i)
|
|
hw_atl_rpfl2_uc_flr_en_set(self,
|
|
--
|
|
2.13.6
|
|
|