]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: stmmac: provide common stmmac_axi_blen_to_mask()
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Wed, 19 Nov 2025 10:23:25 +0000 (10:23 +0000)
committerJakub Kicinski <kuba@kernel.org>
Fri, 21 Nov 2025 01:57:40 +0000 (17:57 -0800)
Provide a common stmmac_axi_blen_to_mask() function to translate the
burst length array to the value for the AXI bus mode register, and use
it for dwmac, dwmac4 and dwxgmac2. Remove the now unnecessary
XGMAC_BLEN* definitions.

Note that stmmac_axi_blen_to_dma_mask() is coded to be more efficient
than the original three implementations, and verifies the contents of
the burst length array.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Link: https://patch.msgid.link/E1vLfLR-0000000FMav-0VL6@rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

index 3c6e7fe7b9999bb0035af9fba4fd4e70cfc6c8a5..49df46be366997170dbe5e89af8533cff4e672a0 100644 (file)
@@ -557,6 +557,9 @@ struct dma_features {
 #define DMA_AXI_BLEN16         BIT(3)
 #define DMA_AXI_BLEN8          BIT(2)
 #define DMA_AXI_BLEN4          BIT(1)
+#define DMA_AXI_BLEN_MASK      GENMASK(7, 1)
+
+void stmmac_axi_blen_to_mask(u32 *regval, const u32 *blen, size_t len);
 
 #define STMMAC_CHAIN_MODE      0x1
 #define STMMAC_RING_MODE       0x2
index 118a22406a2e939dfb6053ffb1d7fb774e6e218c..b6476a1bfeab01a921932562e08a50966add7a75 100644 (file)
@@ -19,7 +19,6 @@
 static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
 {
        u32 value = readl(ioaddr + DMA_AXI_BUS_MODE);
-       int i;
 
        pr_info("dwmac1000: Master AXI performs %s burst length\n",
                !(value & DMA_AXI_UNDEF) ? "fixed" : "any");
@@ -39,33 +38,11 @@ static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
 
        /* Depending on the UNDEF bit the Master AXI will perform any burst
         * length according to the BLEN programmed (by default all BLEN are
-        * set).
+        * set). Note that the UNDEF bit is readonly, and is the inverse of
+        * Bus Mode bit 16.
         */
-       for (i = 0; i < AXI_BLEN; i++) {
-               switch (axi->axi_blen[i]) {
-               case 256:
-                       value |= DMA_AXI_BLEN256;
-                       break;
-               case 128:
-                       value |= DMA_AXI_BLEN128;
-                       break;
-               case 64:
-                       value |= DMA_AXI_BLEN64;
-                       break;
-               case 32:
-                       value |= DMA_AXI_BLEN32;
-                       break;
-               case 16:
-                       value |= DMA_AXI_BLEN16;
-                       break;
-               case 8:
-                       value |= DMA_AXI_BLEN8;
-                       break;
-               case 4:
-                       value |= DMA_AXI_BLEN4;
-                       break;
-               }
-       }
+       stmmac_axi_blen_to_mask(&value, axi->axi_blen,
+                               ARRAY_SIZE(axi->axi_blen));
 
        writel(value, ioaddr + DMA_AXI_BUS_MODE);
 }
index d87a8b595e6a3b469a4ffbccc66df71939c6bd26..90d03c7b29f4c730ace1a89a0698227e3ee248af 100644 (file)
@@ -18,7 +18,6 @@
 static void dwmac4_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
 {
        u32 value = readl(ioaddr + DMA_SYS_BUS_MODE);
-       int i;
 
        pr_info("dwmac4: Master AXI performs %s burst length\n",
                (value & DMA_SYS_BUS_FB) ? "fixed" : "any");
@@ -38,33 +37,11 @@ static void dwmac4_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
 
        /* Depending on the UNDEF bit the Master AXI will perform any burst
         * length according to the BLEN programmed (by default all BLEN are
-        * set).
+        * set). Note that the UNDEF bit is readonly, and is the inverse of
+        * Bus Mode bit 16.
         */
-       for (i = 0; i < AXI_BLEN; i++) {
-               switch (axi->axi_blen[i]) {
-               case 256:
-                       value |= DMA_AXI_BLEN256;
-                       break;
-               case 128:
-                       value |= DMA_AXI_BLEN128;
-                       break;
-               case 64:
-                       value |= DMA_AXI_BLEN64;
-                       break;
-               case 32:
-                       value |= DMA_AXI_BLEN32;
-                       break;
-               case 16:
-                       value |= DMA_AXI_BLEN16;
-                       break;
-               case 8:
-                       value |= DMA_AXI_BLEN8;
-                       break;
-               case 4:
-                       value |= DMA_AXI_BLEN4;
-                       break;
-               }
-       }
+       stmmac_axi_blen_to_mask(&value, axi->axi_blen,
+                               ARRAY_SIZE(axi->axi_blen));
 
        writel(value, ioaddr + DMA_SYS_BUS_MODE);
 }
index dfcb7ce79e765d8991d199fba924152c1899dca7..f27126f055515b73f825295890e71c81aad4542f 100644 (file)
@@ -78,8 +78,6 @@
                                        DMA_AXI_BLEN16 | DMA_AXI_BLEN8 | \
                                        DMA_AXI_BLEN4)
 
-#define DMA_AXI_BURST_LEN_MASK         0x000000FE
-
 /* DMA TBS Control */
 #define DMA_TBS_FTOS                   GENMASK(31, 8)
 #define DMA_TBS_FTOV                   BIT(0)
index 967a735e9a0bd50d3440becd1c8208ab6bcc8752..d1c149f7a3dd9e472b237101666e11878707f0f2 100644 (file)
@@ -77,8 +77,6 @@ static inline u32 dma_chan_base_addr(u32 base, u32 chan)
 
 #define DMA_AXI_UNDEF          BIT(0)
 
-#define DMA_AXI_BURST_LEN_MASK 0x000000FE
-
 #define DMA_CUR_TX_BUF_ADDR    0x00001050      /* Current Host Tx Buffer */
 #define DMA_CUR_RX_BUF_ADDR    0x00001054      /* Current Host Rx Buffer */
 #define DMA_HW_FEATURE         0x00001058      /* HW Feature Register */
index 16c6d03fc929f1a25512e1c76f39829af2fceb25..fecda3034d368d765b4f4874abe1e13ee99844d0 100644 (file)
 #define XGMAC_LPI_XIT_PKT              BIT(14)
 #define XGMAC_AAL                      DMA_AXI_AAL
 #define XGMAC_EAME                     BIT(11)
-#define XGMAC_BLEN                     GENMASK(7, 1)
-#define XGMAC_BLEN256                  DMA_AXI_BLEN256
-#define XGMAC_BLEN128                  DMA_AXI_BLEN128
-#define XGMAC_BLEN64                   DMA_AXI_BLEN64
-#define XGMAC_BLEN32                   DMA_AXI_BLEN32
-#define XGMAC_BLEN16                   DMA_AXI_BLEN16
-#define XGMAC_BLEN8                    DMA_AXI_BLEN8
-#define XGMAC_BLEN4                    DMA_AXI_BLEN4
+/* XGMAC_BLEN* are now defined as DMA_AXI_BLEN* in common.h */
 #define XGMAC_UNDEF                    BIT(0)
 #define XGMAC_TX_EDMA_CTRL             0x00003040
 #define XGMAC_TDPS                     GENMASK(29, 0)
index 4d6bb995d8d84cd31b8c552036a647281de06fbb..8a2cb6ca9588eec9531b456e36eb6f480f5efd9e 100644 (file)
@@ -84,7 +84,6 @@ static void dwxgmac2_dma_init_tx_chan(struct stmmac_priv *priv,
 static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
 {
        u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
-       int i;
 
        if (axi->axi_lpi_en)
                value |= XGMAC_EN_LPI;
@@ -102,32 +101,13 @@ static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
        if (!axi->axi_fb)
                value |= XGMAC_UNDEF;
 
-       value &= ~XGMAC_BLEN;
-       for (i = 0; i < AXI_BLEN; i++) {
-               switch (axi->axi_blen[i]) {
-               case 256:
-                       value |= XGMAC_BLEN256;
-                       break;
-               case 128:
-                       value |= XGMAC_BLEN128;
-                       break;
-               case 64:
-                       value |= XGMAC_BLEN64;
-                       break;
-               case 32:
-                       value |= XGMAC_BLEN32;
-                       break;
-               case 16:
-                       value |= XGMAC_BLEN16;
-                       break;
-               case 8:
-                       value |= XGMAC_BLEN8;
-                       break;
-               case 4:
-                       value |= XGMAC_BLEN4;
-                       break;
-               }
-       }
+       /* Depending on the UNDEF bit the Master AXI will perform any burst
+        * length according to the BLEN programmed (by default all BLEN are
+        * set). Note that the UNDEF bit is readonly, and is the inverse of
+        * Bus Mode bit 16.
+        */
+       stmmac_axi_blen_to_mask(&value, axi->axi_blen,
+                               ARRAY_SIZE(axi->axi_blen));
 
        writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
        writel(XGMAC_TDPS, ioaddr + XGMAC_TX_EDMA_CTRL);
index e9c3c18b9fc1045aee7ec7ab71849e93838545cd..0b1e571f70f0e48289c011e69625c6e34bcb3ed4 100644 (file)
@@ -189,6 +189,43 @@ int stmmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i,
 }
 EXPORT_SYMBOL_GPL(stmmac_set_clk_tx_rate);
 
+/**
+ * stmmac_axi_blen_to_mask() - convert a burst length array to reg value
+ * @regval: pointer to a u32 for the resulting register value
+ * @blen: pointer to an array of u32 containing the burst length values in bytes
+ * @len: the number of entries in the @blen array
+ */
+void stmmac_axi_blen_to_mask(u32 *regval, const u32 *blen, size_t len)
+{
+       size_t i;
+       u32 val;
+
+       for (val = i = 0; i < len; i++) {
+               u32 burst = blen[i];
+
+               /* Burst values of zero must be skipped. */
+               if (!burst)
+                       continue;
+
+               /* The valid range for the burst length is 4 to 256 inclusive,
+                * and it must be a power of two.
+                */
+               if (burst < 4 || burst > 256 || !is_power_of_2(burst)) {
+                       pr_err("stmmac: invalid burst length %u at index %zu\n",
+                              burst, i);
+                       continue;
+               }
+
+               /* Since burst is a power of two, and the register field starts
+                * with burst = 4, shift right by two bits so bit 0 of the field
+                * corresponds with the minimum value.
+                */
+               val |= burst >> 2;
+       }
+
+       u32p_replace_bits(regval, val, DMA_AXI_BLEN_MASK);
+}
+
 /**
  * stmmac_verify_args - verify the driver parameters.
  * Description: it checks the driver parameters and set a default in case of