]> www.infradead.org Git - users/hch/xfs.git/commitdiff
net: xilinx: axienet: Fix dangling multicast addresses
authorSean Anderson <sean.anderson@linux.dev>
Thu, 22 Aug 2024 15:40:56 +0000 (11:40 -0400)
committerJakub Kicinski <kuba@kernel.org>
Thu, 22 Aug 2024 20:03:56 +0000 (13:03 -0700)
If a multicast address is removed but there are still some multicast
addresses, that address would remain programmed into the frame filter.
Fix this by explicitly setting the enable bit for each filter.

Fixes: 8a3b7a252dca ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20240822154059.1066595-3-sean.anderson@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/xilinx/xilinx_axienet.h
drivers/net/ethernet/xilinx/xilinx_axienet_main.c

index c7d9221fafdcb1af0fc9d483177043f936fed626..09c9f9787180bf1dd9faedcdb337322c0211927b 100644 (file)
 #define XAE_UAW0_OFFSET                0x00000700 /* Unicast address word 0 */
 #define XAE_UAW1_OFFSET                0x00000704 /* Unicast address word 1 */
 #define XAE_FMI_OFFSET         0x00000708 /* Frame Filter Control */
+#define XAE_FFE_OFFSET         0x0000070C /* Frame Filter Enable */
 #define XAE_AF0_OFFSET         0x00000710 /* Address Filter 0 */
 #define XAE_AF1_OFFSET         0x00000714 /* Address Filter 1 */
 
index 163d052480071d626cd39939f999f53181c2a860..9aeb7b9f3ae408e2b843fc6d24c47fb04648b708 100644 (file)
@@ -432,7 +432,7 @@ static int netdev_set_mac_address(struct net_device *ndev, void *p)
  */
 static void axienet_set_multicast_list(struct net_device *ndev)
 {
-       int i;
+       int i = 0;
        u32 reg, af0reg, af1reg;
        struct axienet_local *lp = netdev_priv(ndev);
 
@@ -454,7 +454,6 @@ static void axienet_set_multicast_list(struct net_device *ndev)
                reg &= ~XAE_FMI_PM_MASK;
                axienet_iow(lp, XAE_FMI_OFFSET, reg);
 
-               i = 0;
                netdev_for_each_mc_addr(ha, ndev) {
                        if (i >= XAE_MULTICAST_CAM_TABLE_NUM)
                                break;
@@ -473,6 +472,7 @@ static void axienet_set_multicast_list(struct net_device *ndev)
                        axienet_iow(lp, XAE_FMI_OFFSET, reg);
                        axienet_iow(lp, XAE_AF0_OFFSET, af0reg);
                        axienet_iow(lp, XAE_AF1_OFFSET, af1reg);
+                       axienet_iow(lp, XAE_FFE_OFFSET, 1);
                        i++;
                }
        } else {
@@ -480,18 +480,15 @@ static void axienet_set_multicast_list(struct net_device *ndev)
                reg &= ~XAE_FMI_PM_MASK;
 
                axienet_iow(lp, XAE_FMI_OFFSET, reg);
-
-               for (i = 0; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) {
-                       reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00;
-                       reg |= i;
-
-                       axienet_iow(lp, XAE_FMI_OFFSET, reg);
-                       axienet_iow(lp, XAE_AF0_OFFSET, 0);
-                       axienet_iow(lp, XAE_AF1_OFFSET, 0);
-               }
-
                dev_info(&ndev->dev, "Promiscuous mode disabled.\n");
        }
+
+       for (; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) {
+               reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00;
+               reg |= i;
+               axienet_iow(lp, XAE_FMI_OFFSET, reg);
+               axienet_iow(lp, XAE_FFE_OFFSET, 0);
+       }
 }
 
 /**