Re: [PATCH RFC net-next 7/9] net: stmmac: support custom XGMAC register layouts

From: Lorenzo Bianconi

Date: Fri Sep 25 2026 - 08:24:06 EST


> 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@xxxxxxxxxxxxxxxx>

Hi Mohd,

Some nits inline.

Regards,
Lorenzo

> ---
> 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;
> +}

I think if we introduce a dma map even for default case these functions will be more
readable. What do you think?

> +
> +#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)

I guess the DWMAC_CORE_25GMAC is never defined, in fact I have the following
compilation error:

drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c:355:38: error: ‘DWMAC_CORE_25GMAC’ undeclared (first use in this function); did you mean ‘DWMAC_CORE_XGMAC’?


> + 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;

nit: what about union here?

> unsigned int flags;
> struct stmmac_dma_cfg __dma_cfg;
> };
>
> --
> 2.34.1
>

Attachment: signature.asc
Description: PGP signature