[PATCH net-next] net: stmmac: fpe: Keep pmac always enabled
From: <hidden>
Date: 2026-07-27 05:13:19
Also in:
linux-arm-kernel, lkml
Subsystem:
networking drivers, stmmac ethernet driver, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Maxime Chevallier, Linus Torvalds
From: Nazim Amirul <redacted> The preemptive MAC in DWMAC is always enabled, meaning DWMAC is always ready to receive preemptive mPackets. Keep pmac_enabled true at init time and reject attempts to disable it via ethtool set_mm. The FPE residual queue (fprq) controls which Rx queue receives residual preemptive mPackets from the pmac. Move its configuration from stmmac_fpe_configure_tx() to stmmac_fpe_configure_pmac() where it logically belongs. Also add a missing return in stmmac_fpe_init() so that the pmac_enabled initialization is not reached on hardware where FPE is not supported by the driver. Signed-off-by: Rohan G Thomas <redacted> Signed-off-by: Nazim Amirul <redacted> --- .../ethernet/stmicro/stmmac/stmmac_ethtool.c | 7 ++++ .../net/ethernet/stmicro/stmmac/stmmac_fpe.c | 34 ++++++++++++------- 2 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 92585d27ab88..8ebdd249e5c8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c@@ -1064,6 +1064,13 @@ static int stmmac_set_mm(struct net_device *ndev, struct ethtool_mm_cfg *cfg, if (err) return err; + if (!priv->dma_cap.fpesel) + return -EOPNOTSUPP; + + /* DWMAC always have preemptible MAC enabled */ + if (!cfg->pmac_enabled) + return -EINVAL; + stmmac_fpe_set_add_frag_size(priv, frag_size); ethtool_mmsv_set_mm(&priv->fpe_cfg.mmsv, cfg);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
index c54c70224351..2bfa84ad04a6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c@@ -47,20 +47,13 @@ static void stmmac_fpe_configure_tx(struct ethtool_mmsv *mmsv, bool tx_enable) struct stmmac_fpe_cfg *cfg = container_of(mmsv, struct stmmac_fpe_cfg, mmsv); struct stmmac_priv *priv = container_of(cfg, struct stmmac_priv, fpe_cfg); const struct stmmac_fpe_reg *reg = cfg->reg; - u32 num_rxq = priv->plat->rx_queues_to_use; void __iomem *ioaddr = priv->ioaddr; - u32 value; - if (tx_enable) { + if (tx_enable) cfg->fpe_csr = STMMAC_MAC_FPE_CTRL_STS_EFPE; - value = readl(ioaddr + reg->rxq_ctrl1_reg); - value &= ~reg->fprq_mask; - /* Keep this SHIFT, FIELD_PREP() expects a constant mask :-/ */ - value |= (num_rxq - 1) << __ffs(reg->fprq_mask); - writel(value, ioaddr + reg->rxq_ctrl1_reg); - } else { + else cfg->fpe_csr = 0; - } + writel(cfg->fpe_csr, ioaddr + reg->mac_fpe_reg); }
@@ -68,10 +61,11 @@ static void stmmac_fpe_configure_pmac(struct ethtool_mmsv *mmsv, bool pmac_enabl { struct stmmac_fpe_cfg *cfg = container_of(mmsv, struct stmmac_fpe_cfg, mmsv); struct stmmac_priv *priv = container_of(cfg, struct stmmac_priv, fpe_cfg); + u32 num_rxq = priv->plat->rx_queues_to_use; const struct stmmac_fpe_reg *reg = cfg->reg; void __iomem *ioaddr = priv->ioaddr; unsigned long flags; - u32 value; + u32 value, value_2; spin_lock_irqsave(&priv->hw->irq_ctrl_lock, flags); value = readl(ioaddr + reg->int_en_reg);
@@ -83,6 +77,14 @@ static void stmmac_fpe_configure_pmac(struct ethtool_mmsv *mmsv, bool pmac_enabl value |= reg->int_en_bit; } + /* Frame Preemption Residue Queue is the Rx Queue to which + * residual preemptive mPackets must be forwarded from the pmac. + */ + value_2 = readl(ioaddr + reg->rxq_ctrl1_reg); + value_2 &= ~reg->fprq_mask; + /* Keep this SHIFT, FIELD_PREP() expects a constant mask :-/ */ + value_2 |= (num_rxq - 1) << __ffs(reg->fprq_mask); + writel(value_2, ioaddr + reg->rxq_ctrl1_reg); } else { value &= ~reg->int_en_bit; }
@@ -174,8 +176,16 @@ void stmmac_fpe_init(struct stmmac_priv *priv) &stmmac_mmsv_ops); if ((!priv->fpe_cfg.reg || !priv->hw->mac->fpe_map_preemption_class) && - priv->dma_cap.fpesel) + priv->dma_cap.fpesel) { dev_info(priv->device, "FPE is not supported by driver.\n"); + return; + } + + /* The preemptive mac in DWMAC is always enabled, that means DWMAC is + * ready to receive preemptive mPackets always. So keep pmac_enabled + * true. pmac_enabled = false is not valid. + */ + priv->fpe_cfg.mmsv.pmac_enabled = true; } int stmmac_fpe_get_add_frag_size(struct stmmac_priv *priv)
--
2.43.7