From: Nazim Amirul The preemptive MAC in DWMAC is always enabled, meaning DWMAC is always ready to receive preemptive mPackets. Initialize pmac_enabled to true at init time and reject attempts to disable it via ethtool set_mm. Also add a missing fpesel capability check in stmmac_set_mm() to return -EOPNOTSUPP early on hardware without FPE support. Signed-off-by: Rohan G Thomas Signed-off-by: Nazim Amirul Reviewed-by: Maxime Chevallier --- v2: No changes. Collect Reviewed-by from Maxime Chevallier. drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 7 +++++++ drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c | 5 +++++ 2 files changed, 12 insertions(+) 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..2f880c5e35b0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c @@ -176,6 +176,11 @@ void stmmac_fpe_init(struct stmmac_priv *priv) if ((!priv->fpe_cfg.reg || !priv->hw->mac->fpe_map_preemption_class) && priv->dma_cap.fpesel) dev_info(priv->device, "FPE is not supported by driver.\n"); + + /* The preemptive MAC in DWMAC is always enabled, so initialize + * pmac_enabled to true to reflect the hardware state. + */ + priv->fpe_cfg.mmsv.pmac_enabled = true; } int stmmac_fpe_get_add_frag_size(struct stmmac_priv *priv) -- 2.43.7 From: Nazim Amirul When FPE is not supported by the driver, stmmac_fpe_init() prints a warning but falls through into the pmac_enabled initialization, which should only be reached on supported hardware. Add the missing return to prevent this. Signed-off-by: Rohan G Thomas Signed-off-by: Nazim Amirul Reviewed-by: Maxime Chevallier --- v2: No changes. Collect Reviewed-by from Maxime Chevallier. drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c index 2f880c5e35b0..3436e962a238 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c @@ -174,8 +174,10 @@ 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, so initialize * pmac_enabled to true to reflect the hardware state. -- 2.43.7 From: Nazim Amirul The Frame Preemption Residue Queue (fprq) controls which Rx queue receives residual preemptive mPackets from the pmac. This is a pmac concern, not a TX concern, so move its configuration from stmmac_fpe_configure_tx() to stmmac_fpe_configure_pmac() where it logically belongs. Keep the open-coded mask/shift update rather than u32_replace_bits(), since fprq_mask is not a compile-time constant. Signed-off-by: Rohan G Thomas Signed-off-by: Nazim Amirul Reviewed-by: Maxime Chevallier --- v2: Drop u32_replace_bits(); fprq_mask is not a compile-time constant and triggered __bad_mask on x86. Keep open-coded mask/shift. Collect Reviewed-by from Maxime Chevallier. .../net/ethernet/stmicro/stmmac/stmmac_fpe.c | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c index 3436e962a238..55b4df3c677b 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; } -- 2.43.7