]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: atlantic: better loopback mode handling
authorNikita Danilov <ndanilov@marvell.com>
Fri, 14 Feb 2020 15:44:54 +0000 (18:44 +0300)
committerDavid S. Miller <davem@davemloft.net>
Mon, 17 Feb 2020 03:03:39 +0000 (19:03 -0800)
Add checks to not enable multiple loopback modes simultaneously,
It was also discovered that for dma loopback to function correctly
promisc mode should be enabled on device.

Fixes: ea4b4d7fc106 ("net: atlantic: loopback tests via private flags")
Signed-off-by: Nikita Danilov <ndanilov@marvell.com>
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Dmitry Bogdanov <dbogdanov@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c

index a1f99bef4a683286bda9c141f9fed6e7953b68b0..7b55633d2cb939d23f08cb442e380cc215464115 100644 (file)
@@ -722,6 +722,11 @@ static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
        if (flags & ~AQ_PRIV_FLAGS_MASK)
                return -EOPNOTSUPP;
 
+       if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) {
+               netdev_info(ndev, "Can't enable more than one loopback simultaneously\n");
+               return -EINVAL;
+       }
+
        cfg->priv_flags = flags;
 
        if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
index 9acdb3fbb750dd0ce0bada33786b3f142c88b83b..d20d91cdece861adeb0b45c44a69a8140cb048e4 100644 (file)
@@ -885,13 +885,16 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,
 {
        struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
        unsigned int i = 0U;
+       u32 vlan_promisc;
+       u32 l2_promisc;
 
-       hw_atl_rpfl2promiscuous_mode_en_set(self,
-                                           IS_FILTER_ENABLED(IFF_PROMISC));
+       l2_promisc = IS_FILTER_ENABLED(IFF_PROMISC) ||
+                    !!(cfg->priv_flags & BIT(AQ_HW_LOOPBACK_DMA_NET));
+       vlan_promisc = l2_promisc || cfg->is_vlan_force_promisc;
 
-       hw_atl_rpf_vlan_prom_mode_en_set(self,
-                                    IS_FILTER_ENABLED(IFF_PROMISC) ||
-                                    cfg->is_vlan_force_promisc);
+       hw_atl_rpfl2promiscuous_mode_en_set(self, l2_promisc);
+
+       hw_atl_rpf_vlan_prom_mode_en_set(self, vlan_promisc);
 
        hw_atl_rpfl2multicast_flr_en_set(self,
                                         IS_FILTER_ENABLED(IFF_ALLMULTI) &&