net: stmmac: xgmac: Fix L3L4 filter count
authorRohan G Thomas <rohan.g.thomas@intel.com>
Mon, 17 Jul 2023 12:06:03 +0000 (20:06 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 19 Jul 2023 10:08:39 +0000 (11:08 +0100)
Get the exact count of L3L4 filters when the L3L4FNUM field of
HW_FEATURE1 register is >= 8. If L3L4FNUM < 8, then the number of L3L4
filters supported by XGMAC is equal to L3L4FNUM. From L3L4FNUM >= 8
the number of L3L4 filters goes on like 8, 16, 32, ... Current
maximum of L3L4FNUM = 10.

Also, fix the XGMAC_IDDR bitmask of L3L4_ADDR_CTRL register. IDDR
field starts from the 8th bit of the L3L4_ADDR_CTRL register. IDDR[3:0]
indicates the type of L3L4 filter register while IDDR[8:4] indicates
the filter number (0 to 31). So overall 9 bits are used for IDDR
(i.e. L3L4_ADDR_CTRL[16:8]) to address the registers of all the
filters. Currently, XGMAC_IDDR is GENMASK(15,8), causing issues
accessing L3L4 filters above 15 for those XGMACs configured with more
than 16 L3L4 filters.

Signed-off-by: Rohan G Thomas <rohan.g.thomas@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

index 1913385..153321f 100644 (file)
 #define XGMAC_DCS_SHIFT                        16
 #define XGMAC_ADDRx_LOW(x)             (0x00000304 + (x) * 0x8)
 #define XGMAC_L3L4_ADDR_CTRL           0x00000c00
-#define XGMAC_IDDR                     GENMASK(15, 8)
+#define XGMAC_IDDR                     GENMASK(16, 8)
 #define XGMAC_IDDR_SHIFT               8
 #define XGMAC_IDDR_FNUM                        4
 #define XGMAC_TT                       BIT(1)
index 070bd91..df5af52 100644 (file)
@@ -408,6 +408,16 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
        /* MAC HW feature 1 */
        hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
        dma_cap->l3l4fnum = (hw_cap & XGMAC_HWFEAT_L3L4FNUM) >> 27;
+       /* If L3L4FNUM < 8, then the number of L3L4 filters supported by
+        * XGMAC is equal to L3L4FNUM. From L3L4FNUM >= 8 the number of
+        * L3L4 filters goes on like 8, 16, 32, ... Current maximum of
+        * L3L4FNUM = 10.
+        */
+       if (dma_cap->l3l4fnum >= 8 && dma_cap->l3l4fnum <= 10)
+               dma_cap->l3l4fnum = 8 << (dma_cap->l3l4fnum - 8);
+       else if (dma_cap->l3l4fnum > 10)
+               dma_cap->l3l4fnum = 32;
+
        dma_cap->hash_tb_sz = (hw_cap & XGMAC_HWFEAT_HASHTBLSZ) >> 24;
        dma_cap->rssen = (hw_cap & XGMAC_HWFEAT_RSSEN) >> 20;
        dma_cap->tsoen = (hw_cap & XGMAC_HWFEAT_TSOEN) >> 18;