summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2025-11-20 17:57:42 -0800
committerJakub Kicinski <kuba@kernel.org>2025-11-20 17:57:42 -0800
commit22eaa206fcacc54e8bc0487c7667883df9200e57 (patch)
treefd05203fae0a1062729e51a5eb7eb3e4d04bff02
parentf15bcd071913dfa754cabb85e9fff4eded4e35b2 (diff)
parentefd3c8cc52bb9583183ebb83c8c55b23bf97cb2f (diff)
downloadlinux-next-22eaa206fcacc54e8bc0487c7667883df9200e57.tar.gz
linux-next-22eaa206fcacc54e8bc0487c7667883df9200e57.zip
Merge branch 'net-stmmac-simplify-axi_blen-handling'
Russell King says: ==================== net: stmmac: simplify axi_blen handling stmmac's axi_blen (burst length) handling is very verbose and unnecessary. Firstly, the burst length register bitfield is the same across all dwmac cores, so we can use common definitions for these bits which platform glue can use. We end up with platform glue: - filling in the axi_blen[] array with the decimal burst lengths, e.g. dwmac-intel.c, etc - decoding a bitmap into burst lengths for this array, e.g. dwmac-dwc-qos-eth.c Other cases read the array from DT, placing it into the axi_blen array, and converting later to the register bitfield. This series removes all this complexity, ultimately ending up with platform glue providing the register value containing the burst length bitfield directly. Where necessary, platform glue calls stmmac_axi_blen_to_mask() to convert a decimal array (e.g. from DT) to the register value. This also means that stmmac_axi_blen_to_mask() can issue a diagnostic message at probe time if the burst length is incorrect. ==================== Link: https://patch.msgid.link/aR2aaDs6rqfu32B-@shell.armlinux.org.uk Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h13
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c28
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c5
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c30
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c30
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h11
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h13
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h11
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c33
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c38
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c4
-rw-r--r--include/linux/stmmac.h2
13 files changed, 78 insertions, 146 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 7395bbb94aea..49df46be3669 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -548,6 +548,19 @@ struct dma_features {
#define LPI_CTRL_STATUS_TLPIEX BIT(1) /* Transmit LPI Exit */
#define LPI_CTRL_STATUS_TLPIEN BIT(0) /* Transmit LPI Entry */
+/* Common definitions for AXI Master Bus Mode */
+#define DMA_AXI_AAL BIT(12)
+#define DMA_AXI_BLEN256 BIT(7)
+#define DMA_AXI_BLEN128 BIT(6)
+#define DMA_AXI_BLEN64 BIT(5)
+#define DMA_AXI_BLEN32 BIT(4)
+#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
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
index c7cd6497d42d..d043bad4a862 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c
@@ -38,8 +38,6 @@ static int dwc_eth_dwmac_config_dt(struct platform_device *pdev,
{
struct device *dev = &pdev->dev;
u32 burst_map = 0;
- u32 bit_index = 0;
- u32 a_index = 0;
if (!plat_dat->axi) {
plat_dat->axi = devm_kzalloc(&pdev->dev,
@@ -83,30 +81,8 @@ static int dwc_eth_dwmac_config_dt(struct platform_device *pdev,
}
device_property_read_u32(dev, "snps,burst-map", &burst_map);
- /* converts burst-map bitmask to burst array */
- for (bit_index = 0; bit_index < 7; bit_index++) {
- if (burst_map & (1 << bit_index)) {
- switch (bit_index) {
- case 0:
- plat_dat->axi->axi_blen[a_index] = 4; break;
- case 1:
- plat_dat->axi->axi_blen[a_index] = 8; break;
- case 2:
- plat_dat->axi->axi_blen[a_index] = 16; break;
- case 3:
- plat_dat->axi->axi_blen[a_index] = 32; break;
- case 4:
- plat_dat->axi->axi_blen[a_index] = 64; break;
- case 5:
- plat_dat->axi->axi_blen[a_index] = 128; break;
- case 6:
- plat_dat->axi->axi_blen[a_index] = 256; break;
- default:
- break;
- }
- a_index++;
- }
- }
+ plat_dat->axi->axi_blen_regval = FIELD_PREP(DMA_AXI_BLEN_MASK,
+ burst_map);
/* dwc-qos needs GMAC4, AAL, TSO and PMT */
plat_dat->core_type = DWMAC_CORE_GMAC4;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 8938e7a59925..aad1be1ec4c1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -650,9 +650,8 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
plat->axi->axi_xit_frm = 0;
plat->axi->axi_wr_osr_lmt = 1;
plat->axi->axi_rd_osr_lmt = 1;
- plat->axi->axi_blen[0] = 4;
- plat->axi->axi_blen[1] = 8;
- plat->axi->axi_blen[2] = 16;
+ plat->axi->axi_blen_regval = DMA_AXI_BLEN4 | DMA_AXI_BLEN8 |
+ DMA_AXI_BLEN16;
plat->ptp_max_adj = plat->clk_ptp_rate;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 118a22406a2e..6d9b8fac3c6d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -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,10 @@ 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;
- }
- }
+ value = (value & ~DMA_AXI_BLEN_MASK) | axi->axi_blen_regval;
writel(value, ioaddr + DMA_AXI_BUS_MODE);
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index d87a8b595e6a..7b513324cfb0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -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,10 @@ 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;
- }
- }
+ value = (value & ~DMA_AXI_BLEN_MASK) | axi->axi_blen_regval;
writel(value, ioaddr + DMA_SYS_BUS_MODE);
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
index 4f980dcd3958..f27126f05551 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
@@ -69,15 +69,8 @@
#define DMA_SYS_BUS_MB BIT(14)
#define DMA_AXI_1KBBE BIT(13)
-#define DMA_SYS_BUS_AAL BIT(12)
+#define DMA_SYS_BUS_AAL DMA_AXI_AAL
#define DMA_SYS_BUS_EAME BIT(11)
-#define DMA_AXI_BLEN256 BIT(7)
-#define DMA_AXI_BLEN128 BIT(6)
-#define DMA_AXI_BLEN64 BIT(5)
-#define DMA_AXI_BLEN32 BIT(4)
-#define DMA_AXI_BLEN16 BIT(3)
-#define DMA_AXI_BLEN8 BIT(2)
-#define DMA_AXI_BLEN4 BIT(1)
#define DMA_SYS_BUS_FB BIT(0)
#define DMA_BURST_LEN_DEFAULT (DMA_AXI_BLEN256 | DMA_AXI_BLEN128 | \
@@ -85,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)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 5d9c18f5bbf5..d1c149f7a3dd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -68,23 +68,14 @@ static inline u32 dma_chan_base_addr(u32 base, u32 chan)
#define DMA_AXI_OSR_MAX 0xf
#define DMA_AXI_MAX_OSR_LIMIT ((DMA_AXI_OSR_MAX << DMA_AXI_WR_OSR_LMT_SHIFT) | \
(DMA_AXI_OSR_MAX << DMA_AXI_RD_OSR_LMT_SHIFT))
-#define DMA_AXI_1KBBE BIT(13)
-#define DMA_AXI_AAL BIT(12)
-#define DMA_AXI_BLEN256 BIT(7)
-#define DMA_AXI_BLEN128 BIT(6)
-#define DMA_AXI_BLEN64 BIT(5)
-#define DMA_AXI_BLEN32 BIT(4)
-#define DMA_AXI_BLEN16 BIT(3)
-#define DMA_AXI_BLEN8 BIT(2)
-#define DMA_AXI_BLEN4 BIT(1)
#define DMA_BURST_LEN_DEFAULT (DMA_AXI_BLEN256 | DMA_AXI_BLEN128 | \
DMA_AXI_BLEN64 | DMA_AXI_BLEN32 | \
DMA_AXI_BLEN16 | DMA_AXI_BLEN8 | \
DMA_AXI_BLEN4)
-#define DMA_AXI_UNDEF BIT(0)
+#define DMA_AXI_1KBBE BIT(13)
-#define DMA_AXI_BURST_LEN_MASK 0x000000FE
+#define DMA_AXI_UNDEF BIT(0)
#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */
#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index e48cfa05000c..fecda3034d36 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -338,16 +338,9 @@
#define XGMAC_RD_OSR_LMT_SHIFT 16
#define XGMAC_EN_LPI BIT(15)
#define XGMAC_LPI_XIT_PKT BIT(14)
-#define XGMAC_AAL BIT(12)
+#define XGMAC_AAL DMA_AXI_AAL
#define XGMAC_EAME BIT(11)
-#define XGMAC_BLEN GENMASK(7, 1)
-#define XGMAC_BLEN256 BIT(7)
-#define XGMAC_BLEN128 BIT(6)
-#define XGMAC_BLEN64 BIT(5)
-#define XGMAC_BLEN32 BIT(4)
-#define XGMAC_BLEN16 BIT(3)
-#define XGMAC_BLEN8 BIT(2)
-#define XGMAC_BLEN4 BIT(1)
+/* 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)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
index 4d6bb995d8d8..cc1bdc0975d5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -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,12 @@ 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.
+ */
+ value = (value & ~DMA_AXI_BLEN_MASK) | axi->axi_blen_regval;
writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
writel(XGMAC_TDPS, ioaddr + XGMAC_TX_EDMA_CTRL);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e9c3c18b9fc1..b1aa236d8051 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -190,6 +190,44 @@ 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;
+ }
+
+ *regval = FIELD_PREP(DMA_AXI_BLEN_MASK, val);
+}
+EXPORT_SYMBOL_GPL(stmmac_axi_blen_to_mask);
+
+/**
* stmmac_verify_args - verify the driver parameters.
* Description: it checks the driver parameters and set a default in case of
* errors.
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index 2fd4660838bb..afb1c53ca6f8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -92,10 +92,8 @@ static int snps_gmac5_default_data(struct pci_dev *pdev,
plat->axi->axi_rd_osr_lmt = 31;
plat->axi->axi_fb = false;
- plat->axi->axi_blen[0] = 4;
- plat->axi->axi_blen[1] = 8;
- plat->axi->axi_blen[2] = 16;
- plat->axi->axi_blen[3] = 32;
+ plat->axi->axi_blen_regval = DMA_AXI_BLEN4 | DMA_AXI_BLEN8 |
+ DMA_AXI_BLEN16 | DMA_AXI_BLEN32;
return 0;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 9015b7f80d1b..8979a50b5507 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -95,6 +95,7 @@ static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
{
struct device_node *np;
struct stmmac_axi *axi;
+ u32 axi_blen[AXI_BLEN];
np = of_parse_phandle(pdev->dev.of_node, "snps,axi-config", 0);
if (!np)
@@ -117,7 +118,8 @@ static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
axi->axi_wr_osr_lmt = 1;
if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt))
axi->axi_rd_osr_lmt = 1;
- of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
+ of_property_read_u32_array(np, "snps,blen", axi_blen, AXI_BLEN);
+ stmmac_axi_blen_to_mask(&axi->axi_blen_regval, axi_blen, AXI_BLEN);
of_node_put(np);
return axi;
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 673b068fdadf..f1054b9c2d8a 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -113,7 +113,7 @@ struct stmmac_axi {
u32 axi_wr_osr_lmt;
u32 axi_rd_osr_lmt;
bool axi_kbbe;
- u32 axi_blen[AXI_BLEN];
+ u32 axi_blen_regval;
bool axi_fb;
bool axi_mb;
bool axi_rb;