mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
To: Mohd Ayaan Anwar <mohd.anwar@oss.qualcomm.com>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Serge Semin <fancer.lancer@gmail.com>,
	Andrew Lunn <andrew@lunn.ch>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	Richard Cochran <richardcochran@gmail.com>,
	Bjorn Andersson <andersson@kernel.org>,
	Konrad Dybcio <konradybcio@kernel.org>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>,
	Giuseppe Cavallaro <peppe.cavallaro@st.com>,
	Jose Abreu <joabreu@synopsys.com>,
	Maxime Chevallier <maxime.chevallier@bootlin.com>,
	Maxime Coquelin <mcoquelin.stm32@gmail.com>,
	netdev@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
	linux-stm32@st-md-mailman.stormreply.com,
	linux-arm-kernel@lists.infradead.org,
	Shawn Guo <shengchao.guo@oss.qualcomm.com>,
	Zhangfei Gao <zhangfei.gao@oss.qualcomm.com>,
	Jitendra Vegiraju <jitendra.vegiraju@broadcom.com>
Subject: Re: [PATCH RFC net-next 7/9] net: stmmac: support custom XGMAC register layouts
Date: Fri, 25 Sep 2026 14:22:12 +0200	[thread overview]
Message-ID: <arZnc5AWGz7xuQCq@lore-desk> (raw)
In-Reply-To: <20260923-qcom_xpcs_nord_emac-v1-7-4b1c682af70f@oss.qualcomm.com>

[-- Attachment #1: Type: text/plain, Size: 35999 bytes --]

> 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@oss.qualcomm.com>

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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

  reply	other threads:[~2026-09-25 12:22 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-23  1:07 [PATCH RFC net-next 0/9] net: introduce Qualcomm XPCS support and add Nord Ethernet plumbing Mohd Ayaan Anwar
2026-09-23  1:07 ` [PATCH RFC net-next 1/9] dt-bindings: net: pcs: add Qualcomm Nord XPCS Mohd Ayaan Anwar
2026-09-23  1:07 ` [PATCH RFC net-next 2/9] net: pcs: xpcs: add USXGMII Clause 37 autoneg support Mohd Ayaan Anwar
2026-09-23 13:31   ` Mohd Ayaan Anwar
2026-09-23  1:07 ` [PATCH RFC net-next 3/9] net: pcs: xpcs: add custom platform register accessors Mohd Ayaan Anwar
2026-09-23 12:18   ` Andrew Lunn
2026-09-23 12:37     ` Mohd Ayaan Anwar
2026-09-25 10:18   ` Lorenzo Bianconi
2026-09-23  1:07 ` [PATCH RFC net-next 4/9] net: pcs: xpcs: add Qualcomm Nord platform support Mohd Ayaan Anwar
2026-09-23 12:07   ` Andrew Lunn
2026-09-23 12:57     ` Mohd Ayaan Anwar
2026-09-25 10:37   ` Lorenzo Bianconi
2026-09-23  1:07 ` [PATCH RFC net-next 5/9] net: pcs: xpcs: initialize runtime PM as suspended Mohd Ayaan Anwar
2026-09-25 11:03   ` Lorenzo Bianconi
2026-09-23  1:07 ` [PATCH RFC net-next 6/9] dt-bindings: net: qcom,ethqos: add Qualcomm Nord Mohd Ayaan Anwar
2026-09-23  1:07 ` [PATCH RFC net-next 7/9] net: stmmac: support custom XGMAC register layouts Mohd Ayaan Anwar
2026-09-25 12:22   ` Lorenzo Bianconi [this message]
2026-09-23  1:07 ` [PATCH RFC net-next 8/9] net: stmmac: qcom-ethqos: support external PCS Mohd Ayaan Anwar
2026-09-23  1:07 ` [PATCH RFC net-next 9/9] net: stmmac: qcom-ethqos: add Qualcomm Nord support Mohd Ayaan Anwar
2026-09-25 13:02   ` Lorenzo Bianconi
2026-09-23  8:49 ` [PATCH 0/3] Nord ethernet followup Zhangfei Gao
2026-09-23  8:49   ` [PATCH 1/3] net: stmmac: support low-speed USXGMII validation Zhangfei Gao
2026-09-23 12:58     ` Andrew Lunn
2026-09-24 10:39       ` Zhangfei Gao
2026-09-24 14:22         ` Andrew Lunn
2026-09-23 13:09     ` Andrew Lunn
2026-09-24 11:12       ` Zhangfei Gao
2026-09-23  8:49   ` [PATCH 2/3] net: stmmac: qcom-ethqos: configure USXGMII rates Zhangfei Gao
2026-09-23  8:49   ` [PATCH 3/3] net: stmmac: fix 10/100 support and MDIO for DW25GMAC Zhangfei Gao
2026-09-23 12:50   ` [PATCH 0/3] Nord ethernet followup Andrew Lunn
2026-09-24 11:18     ` Zhangfei Gao
2026-09-23  8:50 ` [PATCH RFC net-next 0/9] net: introduce Qualcomm XPCS support and add Nord Ethernet plumbing Zhangfei Gao
2026-09-23 15:15   ` Andrew Lunn
2026-09-23  9:41 ` Maxime Chevallier
2026-09-23 10:43   ` Mohd Ayaan Anwar
2026-09-23 13:17     ` Coia Prant
2026-09-23 14:03       ` Mohd Ayaan Anwar
2026-09-24  5:54         ` Coia Prant
2026-09-23 18:35       ` Andrew Lunn
2026-09-24  5:25         ` Coia Prant
2026-09-23 18:40       ` Andrew Lunn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=arZnc5AWGz7xuQCq@lore-desk \
    --to=lorenzo.bianconi@oss.qualcomm.com \
    --cc=alexandre.torgue@foss.st.com \
    --cc=andersson@kernel.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=andrew@lunn.ch \
    --cc=conor+dt@kernel.org \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=edumazet@google.com \
    --cc=fancer.lancer@gmail.com \
    --cc=hkallweit1@gmail.com \
    --cc=jitendra.vegiraju@broadcom.com \
    --cc=joabreu@synopsys.com \
    --cc=konradybcio@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-stm32@st-md-mailman.stormreply.com \
    --cc=linux@armlinux.org.uk \
    --cc=maxime.chevallier@bootlin.com \
    --cc=mcoquelin.stm32@gmail.com \
    --cc=mohd.anwar@oss.qualcomm.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=peppe.cavallaro@st.com \
    --cc=richardcochran@gmail.com \
    --cc=robh@kernel.org \
    --cc=shengchao.guo@oss.qualcomm.com \
    --cc=zhangfei.gao@oss.qualcomm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®