[PATCH RFC net-next 7/9] net: stmmac: support custom XGMAC register layouts
Mohd Ayaan Anwar
mohd.anwar at oss.qualcomm.com
Tue Sep 22 18:07:33 PDT 2026
Some XGMAC integrations place their MTL queues and DMA channels at
different offsets from the standard register layout. Allow platform
data to override these addresses while retaining the standard layout by
default.
This follows the approach used by commit 33719b57f52e ("net: stmmac:
dwmac4: Allow platforms to specify some DMA/MTL offsets"). Qualcomm
XGMAC hardware similarly uses differently aligned queue and channel
registers.
Also allow platforms to override the timestamp register base.
Signed-off-by: Mohd Ayaan Anwar <mohd.anwar at oss.qualcomm.com>
---
drivers/net/ethernet/stmicro/stmmac/common.h | 1 +
.../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 2 +-
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 94 ++++++++++-----
.../net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 34 +++---
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 128 +++++++++++++--------
drivers/net/ethernet/stmicro/stmmac/hwif.c | 5 +-
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 5 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c | 15 ++-
include/linux/stmmac.h | 11 ++
9 files changed, 193 insertions(+), 102 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 1729fb29ece3853584bc27ed541413bcba88c695..c6387cecaf5d93ef10c45475a533bf1d0a4e0b45 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -622,6 +622,7 @@ struct mac_device_info {
const struct stmmac_mmc_ops *mmc;
const struct stmmac_est_ops *est;
const struct stmmac_vlan_ops *vlan;
+ const struct dwxgmac_addrs *dwxgmac_addrs;
struct dw_xpcs *xpcs;
struct phylink_pcs *phylink_pcs;
struct mii_regs mii; /* MII register Addresses */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index 1d7f0a57d28897005cdc1c5dcbd3c2f737a6c967..331ba38abae66f03b69c383b30762c9a09735a37 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -365,7 +365,7 @@ static int smtg_crosststamp(ktime_t *device, struct system_counterval_t *system,
};
num_snapshot = FIELD_GET(XGMAC_TIMESTAMP_ATSNS_MASK,
- readl(ioaddr + XGMAC_TIMESTAMP_STATUS));
+ readl(ioaddr + XGMAC_TIMESTAMP_STATUS(NULL)));
/* Repeat until the timestamps are from the FIFO last segment */
for (i = 0; i < num_snapshot; i++) {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index f8ab347f7b5b9e1b2df662785bb25cf875456088..22b476358a2028de862186c3d38295b2d48d87d6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -220,12 +220,21 @@
#define XGMAC_CT BIT(1)
#define XGMAC_OB BIT(0)
#define XGMAC_RSS_DATA 0x00000c8c
-#define XGMAC_TIMESTAMP_STATUS 0x00000d20
+
+/* Timestamp registers */
+#define XGMAC_TIMESTAMP_BASE_ADDR 0x00000d00
+
+static inline u32 xgmac_timestamp_base_addr(const struct dwxgmac_addrs *addrs)
+{
+ return addrs ? addrs->timestamp_base : XGMAC_TIMESTAMP_BASE_ADDR;
+}
+
+#define XGMAC_TIMESTAMP_STATUS(a) (xgmac_timestamp_base_addr(a) + 0x20)
#define XGMAC_TIMESTAMP_ATSNS_MASK GENMASK(29, 25)
#define XGMAC_TXTSC BIT(15)
-#define XGMAC_TXTIMESTAMP_NSEC 0x00000d30
+#define XGMAC_TXTIMESTAMP_NSEC(a) (xgmac_timestamp_base_addr(a) + 0x30)
#define XGMAC_TXTSSTSLO GENMASK(30, 0)
-#define XGMAC_TXTIMESTAMP_SEC 0x00000d34
+#define XGMAC_TXTIMESTAMP_SEC(a) (xgmac_timestamp_base_addr(a) + 0x34)
#define XGMAC_PPS_CONTROL 0x00000d70
#define XGMAC_PPS_MAXIDX(x) ((((x) + 1) * 8) - 1)
#define XGMAC_PPS_MINIDX(x) ((x) * 8)
@@ -285,37 +294,49 @@
#define XGMAC_MTL_ECC_INT_STATUS 0x000010cc
#define XGMAC_MTL_DPP_CONTROL 0x000010e0
#define XGMAC_DPP_DISABLE BIT(0)
-#define XGMAC_MTL_TXQ_OPMODE(x) (0x00001100 + (0x80 * (x)))
+
+/* MTL per-queue registers */
+#define XGMAC_MTL_CHAN_BASE_ADDR 0x00001100
+#define XGMAC_MTL_CHAN_OFFSET 0x80
+
+static inline u32
+xgmac_mtl_chanx_base_addr(const struct dwxgmac_addrs *addrs, u32 x)
+{
+ return addrs ? addrs->mtl_chan_base + x * addrs->mtl_chan_offset
+ : XGMAC_MTL_CHAN_BASE_ADDR + x * XGMAC_MTL_CHAN_OFFSET;
+}
+
+#define XGMAC_MTL_TXQ_OPMODE(a, x) xgmac_mtl_chanx_base_addr(a, x)
#define XGMAC_TQS GENMASK(25, 16)
#define XGMAC_Q2TCMAP GENMASK(10, 8)
#define XGMAC_TTC GENMASK(6, 4)
#define XGMAC_TXQEN GENMASK(3, 2)
#define XGMAC_TSF BIT(1)
-#define XGMAC_MTL_TCx_ETS_CONTROL(x) (0x00001110 + (0x80 * (x)))
-#define XGMAC_MTL_TCx_QUANTUM_WEIGHT(x) (0x00001118 + (0x80 * (x)))
-#define XGMAC_MTL_TCx_SENDSLOPE(x) (0x0000111c + (0x80 * (x)))
-#define XGMAC_MTL_TCx_HICREDIT(x) (0x00001120 + (0x80 * (x)))
-#define XGMAC_MTL_TCx_LOCREDIT(x) (0x00001124 + (0x80 * (x)))
+#define XGMAC_MTL_TCx_ETS_CONTROL(a, x) (xgmac_mtl_chanx_base_addr(a, x) + 0x10)
+#define XGMAC_MTL_TCx_QUANTUM_WEIGHT(a, x) (xgmac_mtl_chanx_base_addr(a, x) + 0x18)
+#define XGMAC_MTL_TCx_SENDSLOPE(a, x) (xgmac_mtl_chanx_base_addr(a, x) + 0x1c)
+#define XGMAC_MTL_TCx_HICREDIT(a, x) (xgmac_mtl_chanx_base_addr(a, x) + 0x20)
+#define XGMAC_MTL_TCx_LOCREDIT(a, x) (xgmac_mtl_chanx_base_addr(a, x) + 0x24)
#define XGMAC_CC BIT(3)
#define XGMAC_TSA GENMASK(1, 0)
#define XGMAC_SP (0x0 << 0)
#define XGMAC_CBS (0x1 << 0)
#define XGMAC_ETS (0x2 << 0)
-#define XGMAC_MTL_RXQ_OPMODE(x) (0x00001140 + (0x80 * (x)))
+#define XGMAC_MTL_RXQ_OPMODE(a, x) (xgmac_mtl_chanx_base_addr(a, x) + 0x40)
#define XGMAC_RQS GENMASK(25, 16)
#define XGMAC_EHFC BIT(7)
#define XGMAC_RSF BIT(5)
#define XGMAC_RTC GENMASK(1, 0)
-#define XGMAC_MTL_RXQ_FLOW_CONTROL(x) (0x00001150 + (0x80 * (x)))
+#define XGMAC_MTL_RXQ_FLOW_CONTROL(a, x) (xgmac_mtl_chanx_base_addr(a, x) + 0x50)
#define XGMAC_RFD GENMASK(31, 17)
#define XGMAC_RFA GENMASK(15, 1)
-#define XGMAC_MTL_QINTEN(x) (0x00001170 + (0x80 * (x)))
+#define XGMAC_MTL_QINTEN(a, x) (xgmac_mtl_chanx_base_addr(a, x) + 0x70)
#define XGMAC_RXOIE BIT(16)
-#define XGMAC_MTL_QINT_STATUS(x) (0x00001174 + (0x80 * (x)))
+#define XGMAC_MTL_QINT_STATUS(a, x) (xgmac_mtl_chanx_base_addr(a, x) + 0x74)
#define XGMAC_RXOVFIS BIT(16)
#define XGMAC_ABPSIS BIT(1)
#define XGMAC_TXUNFIS BIT(0)
-#define XGMAC_MAC_REGSIZE (XGMAC_MTL_QINT_STATUS(15) / 4)
+#define XGMAC_MAC_REGSIZE(a) (XGMAC_MTL_QINT_STATUS(a, 15) / 4)
/* DMA Registers */
#define XGMAC_DMA_MODE 0x00003000
@@ -353,28 +374,43 @@
#define XGMAC_TCEIE BIT(0)
#define XGMAC_DMA_ECC_INT_STATUS 0x0000306c
#define XGMAC_DMA_DPP_INT_STATUS 0x00003074
-#define XGMAC_DMA_CH_CONTROL(x) (0x00003100 + (0x80 * (x)))
+
+/* DMA per-channel registers */
+#define XGMAC_DMA_CHAN_BASE_ADDR 0x00003100
+#define XGMAC_DMA_CHAN_OFFSET 0x80
+
+static inline u32
+xgmac_dma_chanx_base_addr(const struct dwxgmac_addrs *addrs, u32 x)
+{
+ if (addrs && (x & 1))
+ return addrs->dma_odd_chan_base + x * addrs->dma_chan_offset;
+ if (addrs)
+ return addrs->dma_even_chan_base + x * addrs->dma_chan_offset;
+ return XGMAC_DMA_CHAN_BASE_ADDR + x * XGMAC_DMA_CHAN_OFFSET;
+}
+
+#define XGMAC_DMA_CH_CONTROL(a, x) (xgmac_dma_chanx_base_addr(a, x))
#define XGMAC_SPH BIT(24)
#define XGMAC_PBLx8 BIT(16)
-#define XGMAC_DMA_CH_TX_CONTROL(x) (0x00003104 + (0x80 * (x)))
+#define XGMAC_DMA_CH_TX_CONTROL(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x04)
#define XGMAC_EDSE BIT(28)
#define XGMAC_TxPBL GENMASK(21, 16)
#define XGMAC_TSE BIT(12)
#define XGMAC_OSP BIT(4)
#define XGMAC_TXST BIT(0)
-#define XGMAC_DMA_CH_RX_CONTROL(x) (0x00003108 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RX_CONTROL(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x08)
#define XGMAC_RxPBL GENMASK(21, 16)
#define XGMAC_RBSZ GENMASK(14, 1)
#define XGMAC_RXST BIT(0)
-#define XGMAC_DMA_CH_TxDESC_HADDR(x) (0x00003110 + (0x80 * (x)))
-#define XGMAC_DMA_CH_TxDESC_LADDR(x) (0x00003114 + (0x80 * (x)))
-#define XGMAC_DMA_CH_RxDESC_HADDR(x) (0x00003118 + (0x80 * (x)))
-#define XGMAC_DMA_CH_RxDESC_LADDR(x) (0x0000311c + (0x80 * (x)))
-#define XGMAC_DMA_CH_TxDESC_TAIL_LPTR(x) (0x00003124 + (0x80 * (x)))
-#define XGMAC_DMA_CH_RxDESC_TAIL_LPTR(x) (0x0000312c + (0x80 * (x)))
-#define XGMAC_DMA_CH_TxDESC_RING_LEN(x) (0x00003130 + (0x80 * (x)))
-#define XGMAC_DMA_CH_RxDESC_RING_LEN(x) (0x00003134 + (0x80 * (x)))
-#define XGMAC_DMA_CH_INT_EN(x) (0x00003138 + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_HADDR(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x10)
+#define XGMAC_DMA_CH_TxDESC_LADDR(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x14)
+#define XGMAC_DMA_CH_RxDESC_HADDR(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x18)
+#define XGMAC_DMA_CH_RxDESC_LADDR(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x1c)
+#define XGMAC_DMA_CH_TxDESC_TAIL_LPTR(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x24)
+#define XGMAC_DMA_CH_RxDESC_TAIL_LPTR(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x2c)
+#define XGMAC_DMA_CH_TxDESC_RING_LEN(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x30)
+#define XGMAC_DMA_CH_RxDESC_RING_LEN(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x34)
+#define XGMAC_DMA_CH_INT_EN(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x38)
#define XGMAC_NIE BIT(15)
#define XGMAC_AIE BIT(14)
#define XGMAC_RBUE BIT(7)
@@ -385,9 +421,9 @@
XGMAC_RIE | XGMAC_TIE)
#define XGMAC_DMA_INT_DEFAULT_RX (XGMAC_RIE)
#define XGMAC_DMA_INT_DEFAULT_TX (XGMAC_TIE)
-#define XGMAC_DMA_CH_Rx_WATCHDOG(x) (0x0000313c + (0x80 * (x)))
+#define XGMAC_DMA_CH_Rx_WATCHDOG(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x3c)
#define XGMAC_RWT GENMASK(7, 0)
-#define XGMAC_DMA_CH_STATUS(x) (0x00003160 + (0x80 * (x)))
+#define XGMAC_DMA_CH_STATUS(a, x) (xgmac_dma_chanx_base_addr(a, x) + 0x60)
#define XGMAC_NIS BIT(15)
#define XGMAC_AIS BIT(14)
#define XGMAC_FBE BIT(12)
@@ -396,7 +432,7 @@
#define XGMAC_TBU BIT(2)
#define XGMAC_TPS BIT(1)
#define XGMAC_TI BIT(0)
-#define XGMAC_REGSIZE ((0x0000317c + (0x80 * 15)) / 4)
+#define XGMAC_REGSIZE(a) ((xgmac_dma_chanx_base_addr(a, 15) + 0x7c) / 4)
#define XGMAC_DMA_STATUS_MSK_COMMON (XGMAC_NIS | XGMAC_AIS | XGMAC_FBE)
#define XGMAC_DMA_STATUS_MSK_RX (XGMAC_RBU | XGMAC_RI | \
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
index 1a88cbaed70ca18bbb714681569ede863f7130e5..d1099a1cf9ea56661e2beceeaa3f1938e51dfb3c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -234,11 +234,11 @@ static void dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info *hw,
/* Set ETS if desired */
for (i = 0; i < MTL_MAX_TX_QUEUES; i++) {
- value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(i));
+ value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(hw->dwxgmac_addrs, i));
value &= ~XGMAC_TSA;
if (ets)
value |= XGMAC_ETS;
- writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(i));
+ writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(hw->dwxgmac_addrs, i));
}
}
@@ -246,9 +246,10 @@ static void dwxgmac2_set_mtl_tx_queue_weight(struct stmmac_priv *priv,
struct mac_device_info *hw,
u32 weight, u32 queue)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
void __iomem *ioaddr = hw->pcsr;
- writel(weight, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue));
+ writel(weight, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(addrs, queue));
}
static void dwxgmac2_map_mtl_to_dma(struct mac_device_info *hw, u32 queue,
@@ -273,18 +274,19 @@ static void dwxgmac2_config_cbs(struct stmmac_priv *priv,
u32 send_slope, u32 idle_slope,
u32 high_credit, u32 low_credit, u32 queue)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
void __iomem *ioaddr = hw->pcsr;
u32 value;
- writel(send_slope, ioaddr + XGMAC_MTL_TCx_SENDSLOPE(queue));
- writel(idle_slope, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue));
- writel(high_credit, ioaddr + XGMAC_MTL_TCx_HICREDIT(queue));
- writel(low_credit, ioaddr + XGMAC_MTL_TCx_LOCREDIT(queue));
+ writel(send_slope, ioaddr + XGMAC_MTL_TCx_SENDSLOPE(addrs, queue));
+ writel(idle_slope, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(addrs, queue));
+ writel(high_credit, ioaddr + XGMAC_MTL_TCx_HICREDIT(addrs, queue));
+ writel(low_credit, ioaddr + XGMAC_MTL_TCx_LOCREDIT(addrs, queue));
- value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
+ value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(addrs, queue));
value &= ~XGMAC_TSA;
value |= XGMAC_CC | XGMAC_CBS;
- writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
+ writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(addrs, queue));
}
static void dwxgmac2_dump_regs(struct mac_device_info *hw, u32 *reg_space)
@@ -292,7 +294,7 @@ static void dwxgmac2_dump_regs(struct mac_device_info *hw, u32 *reg_space)
void __iomem *ioaddr = hw->pcsr;
int i;
- for (i = 0; i < XGMAC_MAC_REGSIZE; i++)
+ for (i = 0; i < XGMAC_MAC_REGSIZE(hw->dwxgmac_addrs); i++)
reg_space[i] = readl(ioaddr + i * 4);
}
@@ -336,18 +338,19 @@ static int dwxgmac2_host_irq_status(struct stmmac_priv *priv,
static int dwxgmac2_host_mtl_irq_status(struct stmmac_priv *priv,
struct mac_device_info *hw, u32 chan)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
void __iomem *ioaddr = hw->pcsr;
int ret = 0;
u32 status;
status = readl(ioaddr + XGMAC_MTL_INT_STATUS);
if (status & BIT(chan)) {
- u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan));
+ u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(addrs, chan));
if (chan_status & XGMAC_RXOVFIS)
ret |= CORE_IRQ_MTL_RX_OVERFLOW;
- writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan));
+ writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(addrs, chan));
}
return ret;
@@ -1143,14 +1146,15 @@ static int dwxgmac3_rxp_config(void __iomem *ioaddr,
static int dwxgmac2_get_mac_tx_timestamp(struct mac_device_info *hw, u64 *ts)
{
void __iomem *ioaddr = hw->pcsr;
+ const struct dwxgmac_addrs *addrs = hw->dwxgmac_addrs;
u32 value;
- if (readl_poll_timeout_atomic(ioaddr + XGMAC_TIMESTAMP_STATUS,
+ if (readl_poll_timeout_atomic(ioaddr + XGMAC_TIMESTAMP_STATUS(addrs),
value, value & XGMAC_TXTSC, 100, 10000))
return -EBUSY;
- *ts = readl(ioaddr + XGMAC_TXTIMESTAMP_NSEC) & XGMAC_TXTSSTSLO;
- *ts += readl(ioaddr + XGMAC_TXTIMESTAMP_SEC) * 1000000000ULL;
+ *ts = readl(ioaddr + XGMAC_TXTIMESTAMP_NSEC(addrs)) & XGMAC_TXTSSTSLO;
+ *ts += readl(ioaddr + XGMAC_TXTIMESTAMP_SEC(addrs)) * 1000000000ULL;
return 0;
}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
index ff83858ebc1f33aa8092a2d83018bd5f96b7eead..65d5e2a828076563a1c7368124ddda226bfffc7a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -47,13 +47,14 @@ static void dwxgmac2_dma_init_chan(struct stmmac_priv *priv,
void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg, u32 chan)
{
- u32 value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+ u32 value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(addrs, chan));
if (dma_cfg->pblx8)
value |= XGMAC_PBLx8;
- writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
- writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(addrs, chan));
+ writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(addrs, chan));
}
static void dwxgmac2_dma_init_rx_chan(struct stmmac_priv *priv,
@@ -61,15 +62,16 @@ static void dwxgmac2_dma_init_rx_chan(struct stmmac_priv *priv,
struct stmmac_dma_cfg *dma_cfg,
dma_addr_t phy, u32 chan)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
u32 rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
u32 value;
- value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+ value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(addrs, chan));
value = u32_replace_bits(value, rxpbl, XGMAC_RxPBL);
- writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(addrs, chan));
- writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chan));
- writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));
+ writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(addrs, chan));
+ writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(addrs, chan));
}
static void dwxgmac2_dma_init_tx_chan(struct stmmac_priv *priv,
@@ -77,15 +79,16 @@ static void dwxgmac2_dma_init_tx_chan(struct stmmac_priv *priv,
struct stmmac_dma_cfg *dma_cfg,
dma_addr_t phy, u32 chan)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
u32 txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
u32 value;
- value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+ value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan));
value = u32_replace_bits(value, txpbl, XGMAC_TxPBL);
- writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan));
- writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chan));
- writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));
+ writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(addrs, chan));
+ writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(addrs, chan));
}
static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
@@ -118,16 +121,18 @@ static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
static void dwxgmac2_dma_dump_regs(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 *reg_space)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
int i;
- for (i = (XGMAC_DMA_MODE / 4); i < XGMAC_REGSIZE; i++)
+ for (i = (XGMAC_DMA_MODE / 4); i < XGMAC_REGSIZE(addrs); i++)
reg_space[i] = readl(ioaddr + i * 4);
}
static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
int mode, u32 channel, int fifosz, u8 qmode)
{
- u32 value = readl(ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+ u32 value = readl(ioaddr + XGMAC_MTL_RXQ_OPMODE(addrs, channel));
unsigned int rqs = fifosz / 256 - 1;
unsigned int rtc;
@@ -149,7 +154,7 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
value = u32_replace_bits(value, rqs, XGMAC_RQS);
if ((fifosz >= 4096) && (qmode != MTL_QUEUE_AVB)) {
- u32 flow = readl(ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(channel));
+ u32 flow = readl(ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(addrs, channel));
unsigned int rfd, rfa;
value |= XGMAC_EHFC;
@@ -178,16 +183,17 @@ static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
flow = u32_replace_bits(flow, rfd, XGMAC_RFD);
flow = u32_replace_bits(flow, rfa, XGMAC_RFA);
- writel(flow, ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(channel));
+ writel(flow, ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(addrs, channel));
}
- writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+ writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(addrs, channel));
}
static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
int mode, u32 channel, int fifosz, u8 qmode)
{
- u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+ u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(addrs, channel));
unsigned int tqs = fifosz / 256 - 1;
unsigned int ttc, txqen;
@@ -225,45 +231,48 @@ static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
value = u32_replace_bits(value, txqen, XGMAC_TXQEN);
value = u32_replace_bits(value, tqs, XGMAC_TQS);
- writel(value, ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
+ writel(value, ioaddr + XGMAC_MTL_TXQ_OPMODE(addrs, channel));
}
static void dwxgmac2_enable_dma_irq(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 chan,
bool rx, bool tx)
{
- u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+ u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(addrs, chan));
if (rx)
value |= XGMAC_DMA_INT_DEFAULT_RX;
if (tx)
value |= XGMAC_DMA_INT_DEFAULT_TX;
- writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(addrs, chan));
}
static void dwxgmac2_disable_dma_irq(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 chan,
bool rx, bool tx)
{
- u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+ u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(addrs, chan));
if (rx)
value &= ~XGMAC_DMA_INT_DEFAULT_RX;
if (tx)
value &= ~XGMAC_DMA_INT_DEFAULT_TX;
- writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(addrs, chan));
}
static void dwxgmac2_dma_start_tx(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 chan)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
u32 value;
- value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+ value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan));
value |= XGMAC_TXST;
- writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan));
value = readl(ioaddr + XGMAC_TX_CONFIG);
value |= XGMAC_CONFIG_TE;
@@ -273,11 +282,12 @@ static void dwxgmac2_dma_start_tx(struct stmmac_priv *priv,
static void dwxgmac2_dma_stop_tx(struct stmmac_priv *priv, void __iomem *ioaddr,
u32 chan)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
u32 value;
- value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+ value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan));
value &= ~XGMAC_TXST;
- writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan));
value = readl(ioaddr + XGMAC_TX_CONFIG);
value &= ~XGMAC_CONFIG_TE;
@@ -287,11 +297,12 @@ static void dwxgmac2_dma_stop_tx(struct stmmac_priv *priv, void __iomem *ioaddr,
static void dwxgmac2_dma_start_rx(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 chan)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
u32 value;
- value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+ value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(addrs, chan));
value |= XGMAC_RXST;
- writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(addrs, chan));
value = readl(ioaddr + XGMAC_RX_CONFIG);
value |= XGMAC_CONFIG_RE;
@@ -301,11 +312,12 @@ static void dwxgmac2_dma_start_rx(struct stmmac_priv *priv,
static void dwxgmac2_dma_stop_rx(struct stmmac_priv *priv, void __iomem *ioaddr,
u32 chan)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
u32 value;
- value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+ value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(addrs, chan));
value &= ~XGMAC_RXST;
- writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(addrs, chan));
}
static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
@@ -314,8 +326,9 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
u32 dir)
{
struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
- u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
- u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+ u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(addrs, chan));
+ u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(addrs, chan));
int ret = 0;
if (dir == DMA_DIR_RX)
@@ -354,7 +367,7 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
}
/* Clear interrupts */
- writel(intr_en & intr_status, ioaddr + XGMAC_DMA_CH_STATUS(chan));
+ writel(intr_en & intr_status, ioaddr + XGMAC_DMA_CH_STATUS(addrs, chan));
return ret;
}
@@ -483,105 +496,120 @@ static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
static void dwxgmac2_rx_watchdog(struct stmmac_priv *priv, void __iomem *ioaddr,
u32 riwt, u32 queue)
{
- writel(riwt & XGMAC_RWT, ioaddr + XGMAC_DMA_CH_Rx_WATCHDOG(queue));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+
+ writel(riwt & XGMAC_RWT, ioaddr + XGMAC_DMA_CH_Rx_WATCHDOG(addrs, queue));
}
static void dwxgmac2_set_rx_ring_len(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 len, u32 chan)
{
- writel(len, ioaddr + XGMAC_DMA_CH_RxDESC_RING_LEN(chan));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+
+ writel(len, ioaddr + XGMAC_DMA_CH_RxDESC_RING_LEN(addrs, chan));
}
static void dwxgmac2_set_tx_ring_len(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 len, u32 chan)
{
- writel(len, ioaddr + XGMAC_DMA_CH_TxDESC_RING_LEN(chan));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+
+ writel(len, ioaddr + XGMAC_DMA_CH_TxDESC_RING_LEN(addrs, chan));
}
static void dwxgmac2_set_rx_tail_ptr(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 ptr, u32 chan)
{
- writel(ptr, ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(chan));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+
+ writel(ptr, ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(addrs, chan));
}
static void dwxgmac2_set_tx_tail_ptr(struct stmmac_priv *priv,
void __iomem *ioaddr, u32 ptr, u32 chan)
{
- writel(ptr, ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(chan));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+
+ writel(ptr, ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(addrs, chan));
}
static void dwxgmac2_enable_tso(struct stmmac_priv *priv, void __iomem *ioaddr,
bool en, u32 chan)
{
- u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+ u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan));
if (en)
value |= XGMAC_TSE;
else
value &= ~XGMAC_TSE;
- writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan));
}
static void dwxgmac2_qmode(struct stmmac_priv *priv, void __iomem *ioaddr,
u32 channel, u8 qmode)
{
- u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+ u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(addrs, channel));
u32 flow = readl(ioaddr + XGMAC_RX_FLOW_CTRL);
unsigned int txqen;
if (qmode != MTL_QUEUE_AVB) {
txqen = 0x2;
- writel(0, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(channel));
+ writel(0, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(addrs, channel));
} else {
txqen = 0x1;
writel(flow & (~XGMAC_RFE), ioaddr + XGMAC_RX_FLOW_CTRL);
}
value = u32_replace_bits(value, txqen, XGMAC_TXQEN);
- writel(value, ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
+ writel(value, ioaddr + XGMAC_MTL_TXQ_OPMODE(addrs, channel));
}
static void dwxgmac2_set_bfsize(struct stmmac_priv *priv, void __iomem *ioaddr,
int bfsize, u32 chan)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
u32 value;
- value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+ value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(addrs, chan));
value = u32_replace_bits(value, bfsize, XGMAC_RBSZ);
- writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(addrs, chan));
}
static void dwxgmac2_enable_sph(struct stmmac_priv *priv, void __iomem *ioaddr,
bool en, u32 chan)
{
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
u32 value = readl(ioaddr + XGMAC_RX_CONFIG);
value &= ~XGMAC_CONFIG_HDSMS;
value |= XGMAC_CONFIG_HDSMS_256; /* Segment max 256 bytes */
writel(value, ioaddr + XGMAC_RX_CONFIG);
- value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan));
+ value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(addrs, chan));
if (en)
value |= XGMAC_SPH;
else
value &= ~XGMAC_SPH;
- writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(addrs, chan));
}
static int dwxgmac2_enable_tbs(struct stmmac_priv *priv, void __iomem *ioaddr,
bool en, u32 chan)
{
- u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+ const struct dwxgmac_addrs *addrs = priv->plat->dwxgmac_addrs;
+ u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan));
if (en)
value |= XGMAC_EDSE;
else
value &= ~XGMAC_EDSE;
- writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+ writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan));
- value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)) & XGMAC_EDSE;
+ value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(addrs, chan)) & XGMAC_EDSE;
if (en && !value)
return -EIO;
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 265671170bf6e3856263fdcf99afbf3eac79a211..fdae241e5cf49a8d7a15aadb67d40700ab5b4429 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -368,8 +368,11 @@ int stmmac_hwif_init(struct stmmac_priv *priv)
mac->vlan = mac->vlan ? : entry->vlan;
priv->hw = mac;
+ mac->dwxgmac_addrs = priv->plat->dwxgmac_addrs;
priv->fpe_cfg.reg = entry->regs.fpe_reg;
- priv->ptpaddr = priv->ioaddr + entry->regs.ptp_off;
+ priv->ptpaddr = priv->ioaddr +
+ (priv->plat->dwxgmac_addrs ?
+ priv->plat->dwxgmac_addrs->timestamp_base : entry->regs.ptp_off);
priv->mmcaddr = priv->ioaddr + entry->regs.mmc_off;
memcpy(&priv->ptp_clock_ops, entry->ptp,
sizeof(struct ptp_clock_info));
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 1cf0f8820b337a0d7a9aa23c7d9b34e3f5616dad..82ce81fb6a18b66f2028a5a7784f0a3b9317b9bc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -351,8 +351,9 @@ static int stmmac_ethtool_get_regs_len(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
- if (priv->plat->core_type == DWMAC_CORE_XGMAC)
- return XGMAC_REGSIZE * 4;
+ if (priv->plat->core_type == DWMAC_CORE_XGMAC ||
+ priv->plat->core_type == DWMAC_CORE_25GMAC)
+ return XGMAC_REGSIZE(priv->plat->dwxgmac_addrs) * 4;
else if (priv->plat->core_type == DWMAC_CORE_GMAC4)
return GMAC4_REG_SPACE_SIZE;
return REG_SPACE_SIZE;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
index c889204a7aa5d2e74f7834ed1a22252e6c51ca36..1190b8854132915905773796f07503a9bf1446a0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
@@ -265,9 +265,12 @@ int dwxgmac3_fpe_map_preemption_class(struct net_device *ndev,
if (!num_tc) {
/* Restore default TC:Queue mapping */
for (u32 i = 0; i < priv->plat->tx_queues_to_use; i++) {
- val = readl(priv->ioaddr + XGMAC_MTL_TXQ_OPMODE(i));
+ val = readl(priv->ioaddr +
+ XGMAC_MTL_TXQ_OPMODE(priv->plat->dwxgmac_addrs,
+ i));
writel(u32_replace_bits(val, i, XGMAC_Q2TCMAP),
- priv->ioaddr + XGMAC_MTL_TXQ_OPMODE(i));
+ priv->ioaddr +
+ XGMAC_MTL_TXQ_OPMODE(priv->plat->dwxgmac_addrs, i));
}
}
@@ -288,9 +291,13 @@ int dwxgmac3_fpe_map_preemption_class(struct net_device *ndev,
preemptible_txqs |= GENMASK(offset + count - 1, offset);
for (u32 i = 0; i < count; i++) {
- val = readl(priv->ioaddr + XGMAC_MTL_TXQ_OPMODE(offset + i));
+ val = readl(priv->ioaddr +
+ XGMAC_MTL_TXQ_OPMODE(priv->plat->dwxgmac_addrs,
+ offset + i));
writel(u32_replace_bits(val, tc, XGMAC_Q2TCMAP),
- priv->ioaddr + XGMAC_MTL_TXQ_OPMODE(offset + i));
+ priv->ioaddr +
+ XGMAC_MTL_TXQ_OPMODE(priv->plat->dwxgmac_addrs,
+ offset + i));
}
}
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 00be2df63d2206a5865bd29333f2f3ba3442962a..5bb904030ef99ac91f66fabaa6c2159da1ec8811 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -188,6 +188,16 @@ struct dwmac4_addrs {
u32 mtl_low_cred_offset;
};
+/* Address layout for XGMAC MTL, DMA, and timestamp registers */
+struct dwxgmac_addrs {
+ u32 dma_even_chan_base;
+ u32 dma_odd_chan_base;
+ u32 dma_chan_offset;
+ u32 mtl_chan_base;
+ u32 mtl_chan_offset;
+ u32 timestamp_base;
+};
+
enum dwmac_core_type {
DWMAC_CORE_MAC100,
DWMAC_CORE_GMAC,
@@ -358,6 +368,7 @@ struct plat_stmmacenet_data {
int msi_rx_base_vec;
int msi_tx_base_vec;
const struct dwmac4_addrs *dwmac4_addrs;
+ const struct dwxgmac_addrs *dwxgmac_addrs;
unsigned int flags;
struct stmmac_dma_cfg __dma_cfg;
};
--
2.34.1
More information about the linux-arm-kernel
mailing list