diff mbox series

[net,1/2] net: stmmac: fix taprio schedule configuration

Message ID 20210112172457.20539-1-yannick.vignon@oss.nxp.com
State Superseded
Headers show
Series [net,1/2] net: stmmac: fix taprio schedule configuration | expand

Commit Message

Yannick Vignon Jan. 12, 2021, 5:24 p.m. UTC
From: Yannick Vignon <yannick.vignon@nxp.com>

When configuring a 802.1Qbv schedule through the tc taprio qdisc on an NXP
i.MX8MPlus device, the effective cycle time differed from the requested one
by N*96ns, with N number of entries in the Qbv Gate Control List. This is
because the driver was adding a 96ns margin to each interval of the GCL,
apparently to account for the IPG. The problem was observed on NXP
i.MX8MPlus devices but likely affected all devices relying on the same
configuration callback (dwmac 4.00, 4.10, 5.10 variants).

Fix the issue by removing the margins, and simply setup the MAC with the
provided cycle time value. This is the behavior expected by the user-space
API, as altering the Qbv schedule timings would break standards conformance.
This is also the behavior of several other Ethernet MAC implementations
supporting taprio, including the dwxgmac variant of stmmac.

Signed-off-by: Yannick Vignon <yannick.vignon@nxp.com>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 52 ++------------------
 1 file changed, 4 insertions(+), 48 deletions(-)

Comments

Jakub Kicinski Jan. 13, 2021, 2:29 a.m. UTC | #1
On Tue, 12 Jan 2021 18:24:56 +0100 Yannick Vignon wrote:
> From: Yannick Vignon <yannick.vignon@nxp.com>

> 

> When configuring a 802.1Qbv schedule through the tc taprio qdisc on an NXP

> i.MX8MPlus device, the effective cycle time differed from the requested one

> by N*96ns, with N number of entries in the Qbv Gate Control List. This is

> because the driver was adding a 96ns margin to each interval of the GCL,

> apparently to account for the IPG. The problem was observed on NXP

> i.MX8MPlus devices but likely affected all devices relying on the same

> configuration callback (dwmac 4.00, 4.10, 5.10 variants).

> 

> Fix the issue by removing the margins, and simply setup the MAC with the

> provided cycle time value. This is the behavior expected by the user-space

> API, as altering the Qbv schedule timings would break standards conformance.

> This is also the behavior of several other Ethernet MAC implementations

> supporting taprio, including the dwxgmac variant of stmmac.

> 

> Signed-off-by: Yannick Vignon <yannick.vignon@nxp.com>


Thanks for the patches, could you repost and include appropriate Fixes
tags?

https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes

> +	u32 ctrl;

> 	int i, ret = 0x0;


Please keep the variable declaration lines sorted longest to shortest
in both patches.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
index 03e79a677c8b..cdef27bb7b6c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
@@ -568,68 +568,24 @@  static int dwmac5_est_write(void __iomem *ioaddr, u32 reg, u32 val, bool gcl)
 int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg,
 			 unsigned int ptp_rate)
 {
-	u32 speed, total_offset, offset, ctrl, ctr_low;
-	u32 extcfg = readl(ioaddr + GMAC_EXT_CONFIG);
-	u32 mac_cfg = readl(ioaddr + GMAC_CONFIG);
+	u32 ctrl;
 	int i, ret = 0x0;
-	u64 total_ctr;
-
-	if (extcfg & GMAC_CONFIG_EIPG_EN) {
-		offset = (extcfg & GMAC_CONFIG_EIPG) >> GMAC_CONFIG_EIPG_SHIFT;
-		offset = 104 + (offset * 8);
-	} else {
-		offset = (mac_cfg & GMAC_CONFIG_IPG) >> GMAC_CONFIG_IPG_SHIFT;
-		offset = 96 - (offset * 8);
-	}
-
-	speed = mac_cfg & (GMAC_CONFIG_PS | GMAC_CONFIG_FES);
-	speed = speed >> GMAC_CONFIG_FES_SHIFT;
-
-	switch (speed) {
-	case 0x0:
-		offset = offset * 1000; /* 1G */
-		break;
-	case 0x1:
-		offset = offset * 400; /* 2.5G */
-		break;
-	case 0x2:
-		offset = offset * 100000; /* 10M */
-		break;
-	case 0x3:
-		offset = offset * 10000; /* 100M */
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	offset = offset / 1000;
 
 	ret |= dwmac5_est_write(ioaddr, BTR_LOW, cfg->btr[0], false);
 	ret |= dwmac5_est_write(ioaddr, BTR_HIGH, cfg->btr[1], false);
 	ret |= dwmac5_est_write(ioaddr, TER, cfg->ter, false);
 	ret |= dwmac5_est_write(ioaddr, LLR, cfg->gcl_size, false);
+	ret |= dwmac5_est_write(ioaddr, CTR_LOW, cfg->ctr[0], false);
+	ret |= dwmac5_est_write(ioaddr, CTR_HIGH, cfg->ctr[1], false);
 	if (ret)
 		return ret;
 
-	total_offset = 0;
 	for (i = 0; i < cfg->gcl_size; i++) {
-		ret = dwmac5_est_write(ioaddr, i, cfg->gcl[i] + offset, true);
+		ret = dwmac5_est_write(ioaddr, i, cfg->gcl[i], true);
 		if (ret)
 			return ret;
-
-		total_offset += offset;
 	}
 
-	total_ctr = cfg->ctr[0] + cfg->ctr[1] * 1000000000ULL;
-	total_ctr += total_offset;
-
-	ctr_low = do_div(total_ctr, 1000000000);
-
-	ret |= dwmac5_est_write(ioaddr, CTR_LOW, ctr_low, false);
-	ret |= dwmac5_est_write(ioaddr, CTR_HIGH, total_ctr, false);
-	if (ret)
-		return ret;
-
 	ctrl = readl(ioaddr + MTL_EST_CONTROL);
 	ctrl &= ~PTOV;
 	ctrl |= ((1000000000 / ptp_rate) * 6) << PTOV_SHIFT;