Commit 52abc724 authored by Furong Xu's avatar Furong Xu Committed by Guo Mengqi
Browse files

net: stmmac: xgmac: fix handling of DPP safety error for DMA channels

stable inclusion
from stable-v5.10.210
commit 2fc45a4631ac7837a5c497cb4f7e2115d950fc37
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9DNZK

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2fc45a4631ac7837a5c497cb4f7e2115d950fc37



--------------------------------

[ Upstream commit 46eba193d04f8bd717e525eb4110f3c46c12aec3 ]

Commit 56e58d6c ("net: stmmac: Implement Safety Features in
XGMAC core") checks and reports safety errors, but leaves the
Data Path Parity Errors for each channel in DMA unhandled at all, lead to
a storm of interrupt.
Fix it by checking and clearing the DMA_DPP_Interrupt_Status register.

Fixes: 56e58d6c ("net: stmmac: Implement Safety Features in XGMAC core")
Signed-off-by: default avatarFurong Xu <0x1207@gmail.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarWang Hai <wanghai38@huawei.com>

[Backport] net: stmmac: xgmac: use #define for string constants

stable inclusion
from stable-v5.10.210
commit 78115a3473b1f91818077860ef74c2f55ca11720
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9DNZK

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=78115a3473b1f91818077860ef74c2f55ca11720



--------------------------------

commit 1692b9775e745f84b69dc8ad0075b0855a43db4e upstream.

The cited commit introduces and uses the string constants dpp_tx_err and
dpp_rx_err. These are assigned to constant fields of the array
dwxgmac3_error_desc.

It has been reported that on GCC 6 and 7.5.0 this results in warnings
such as:

  .../dwxgmac2_core.c:836:20: error: initialiser element is not constant
   { true, "TDPES0", dpp_tx_err },

I have been able to reproduce this using: GCC 7.5.0, 8.4.0, 9.4.0 and 10.5.0.
But not GCC 13.2.0.

So it seems this effects older compilers but not newer ones.
As Jon points out in his report, the minimum compiler supported by
the kernel is GCC 5.1, so it does seem that this ought to be fixed.

It is not clear to me what combination of 'const', if any, would address
this problem.  So this patch takes of using #defines for the string
constants

Compile tested only.

Fixes: 46eba193d04f ("net: stmmac: xgmac: fix handling of DPP safety error for DMA channels")
Reported-by: default avatarJon Hunter <jonathanh@nvidia.com>
Closes: https://lore.kernel.org/netdev/c25eb595-8d91-40ea-9f52-efa15ebafdbc@nvidia.com/


Reported-by: default avatarkernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202402081135.lAxxBXHk-lkp@intel.com/


Signed-off-by: default avatarSimon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20240208-xgmac-const-v1-1-e69a1eeabfc8@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarWang Hai <wanghai38@huawei.com>
parent 1df0d53c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@ struct stmmac_safety_stats {
	unsigned long mac_errors[32];
	unsigned long mtl_errors[32];
	unsigned long dma_errors[32];
	unsigned long dma_dpp_errors[32];
};

/* Number of fields in Safety Stats */
+3 −0
Original line number Diff line number Diff line
@@ -282,6 +282,8 @@
#define XGMAC_RXCEIE			BIT(4)
#define XGMAC_TXCEIE			BIT(0)
#define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
#define XGMAC_MTL_DPP_CONTROL		0x000010e0
#define XGMAC_DDPP_DISABLE		BIT(0)
#define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
#define XGMAC_TQS			GENMASK(25, 16)
#define XGMAC_TQS_SHIFT			16
@@ -364,6 +366,7 @@
#define XGMAC_DCEIE			BIT(1)
#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)))
#define XGMAC_SPH			BIT(24)
#define XGMAC_PBLx8			BIT(16)
+57 −1
Original line number Diff line number Diff line
@@ -788,6 +788,44 @@ static const struct dwxgmac3_error_desc dwxgmac3_dma_errors[32]= {
	{ false, "UNKNOWN", "Unknown Error" }, /* 31 */
};

#define DPP_RX_ERR "Read Rx Descriptor Parity checker Error"
#define DPP_TX_ERR "Read Tx Descriptor Parity checker Error"

static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = {
	{ true, "TDPES0", DPP_TX_ERR },
	{ true, "TDPES1", DPP_TX_ERR },
	{ true, "TDPES2", DPP_TX_ERR },
	{ true, "TDPES3", DPP_TX_ERR },
	{ true, "TDPES4", DPP_TX_ERR },
	{ true, "TDPES5", DPP_TX_ERR },
	{ true, "TDPES6", DPP_TX_ERR },
	{ true, "TDPES7", DPP_TX_ERR },
	{ true, "TDPES8", DPP_TX_ERR },
	{ true, "TDPES9", DPP_TX_ERR },
	{ true, "TDPES10", DPP_TX_ERR },
	{ true, "TDPES11", DPP_TX_ERR },
	{ true, "TDPES12", DPP_TX_ERR },
	{ true, "TDPES13", DPP_TX_ERR },
	{ true, "TDPES14", DPP_TX_ERR },
	{ true, "TDPES15", DPP_TX_ERR },
	{ true, "RDPES0", DPP_RX_ERR },
	{ true, "RDPES1", DPP_RX_ERR },
	{ true, "RDPES2", DPP_RX_ERR },
	{ true, "RDPES3", DPP_RX_ERR },
	{ true, "RDPES4", DPP_RX_ERR },
	{ true, "RDPES5", DPP_RX_ERR },
	{ true, "RDPES6", DPP_RX_ERR },
	{ true, "RDPES7", DPP_RX_ERR },
	{ true, "RDPES8", DPP_RX_ERR },
	{ true, "RDPES9", DPP_RX_ERR },
	{ true, "RDPES10", DPP_RX_ERR },
	{ true, "RDPES11", DPP_RX_ERR },
	{ true, "RDPES12", DPP_RX_ERR },
	{ true, "RDPES13", DPP_RX_ERR },
	{ true, "RDPES14", DPP_RX_ERR },
	{ true, "RDPES15", DPP_RX_ERR },
};

static void dwxgmac3_handle_dma_err(struct net_device *ndev,
				    void __iomem *ioaddr, bool correctable,
				    struct stmmac_safety_stats *stats)
@@ -799,6 +837,13 @@ static void dwxgmac3_handle_dma_err(struct net_device *ndev,

	dwxgmac3_log_error(ndev, value, correctable, "DMA",
			   dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats);

	value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS);
	writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS);

	dwxgmac3_log_error(ndev, value, false, "DMA_DPP",
			   dwxgmac3_dma_dpp_errors,
			   STAT_OFF(dma_dpp_errors), stats);
}

static int dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp)
@@ -835,6 +880,12 @@ static int dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp)
	value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */
	writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL);

	/* 5. Enable Data Path Parity Protection */
	value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL);
	/* already enabled by default, explicit enable it again */
	value &= ~XGMAC_DDPP_DISABLE;
	writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL);

	return 0;
}

@@ -868,7 +919,11 @@ static int dwxgmac3_safety_feat_irq_status(struct net_device *ndev,
		ret |= !corr;
	}

	err = dma & (XGMAC_DEUIS | XGMAC_DECIS);
	/* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in
	 * DMA_Safety_Interrupt_Status, so we handle DMA Data Path
	 * Parity Errors here
	 */
	err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS);
	corr = dma & XGMAC_DECIS;
	if (err) {
		dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats);
@@ -884,6 +939,7 @@ static const struct dwxgmac3_error {
	{ dwxgmac3_mac_errors },
	{ dwxgmac3_mtl_errors },
	{ dwxgmac3_dma_errors },
	{ dwxgmac3_dma_dpp_errors },
};

static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats,