[PATCH net-next] net: stmmac: add tc-ets qdisc offload
Lorenzo Bianconi <[email protected]> Tue, 04 Aug 2026 20:17:35 +0200
| Newsgroups | gmane.linux.network,gmane.linux.ports.arm.kernel |
|---|---|
| Message-ID | <[email protected]> |
Implement offload of the tc-ets qdisc in the stmmac driver. The number of ETS bands cannot exceed the number of TX queues, and mixing strict priority bands (zero quanta) with weighted bands is rejected. When all bands are strict priority, the MTL scheduler is programmed with SP scheduling; otherwise the requested weights are applied to the TX queues and the scheduler is switched to DWRR. The TC_ETS_STATS command is accepted and handled. Export stmmac_set_tx_queue_weight() so the ETS path can reprogram queue weights, and wire TC_SETUP_QDISC_ETS into stmmac_setup_tc(). Signed-off-by: Lorenzo Bianconi <[email protected]> --- drivers/net/ethernet/stmicro/stmmac/hwif.h | 4 ++ drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 +- drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 69 +++++++++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h index 04dafec021b4..b70883a53b09 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h @@ -580,6 +580,8 @@ struct stmmac_tc_ops { struct tc_taprio_qopt_offload *qopt); int (*setup_etf)(struct stmmac_priv *priv, struct tc_etf_qopt_offload *qopt); + int (*setup_ets)(struct stmmac_priv *priv, + struct tc_ets_qopt_offload *qopt); int (*query_caps)(struct stmmac_priv *priv, struct tc_query_caps_base *base); int (*setup_mqprio)(struct stmmac_priv *priv, @@ -598,6 +600,8 @@ struct stmmac_tc_ops { stmmac_do_callback(__priv, tc, setup_taprio, __args) #define stmmac_tc_setup_etf(__priv, __args...) \ stmmac_do_callback(__priv, tc, setup_etf, __args) +#define stmmac_tc_setup_ets(__priv, __args...) \ + stmmac_do_callback(__priv, tc, setup_ets, __args) #define stmmac_tc_query_caps(__priv, __args...) \ stmmac_do_callback(__priv, tc, query_caps, __args) #define stmmac_tc_setup_mqprio(__priv, __args...) \ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 8ba8f03e1ce0..8ea6dd0c1697 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -394,6 +394,7 @@ enum stmmac_state { extern const struct dev_pm_ops stmmac_simple_pm_ops; +void stmmac_set_tx_queue_weight(struct stmmac_priv *priv); int stmmac_mdio_unregister(struct net_device *ndev); int stmmac_mdio_register(struct net_device *ndev); int stmmac_mdio_reset(struct mii_bus *mii); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 79b71466d5b0..404f4132f223 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3419,7 +3419,7 @@ static void stmmac_set_rings_length(struct stmmac_priv *priv) * @priv: driver private structure * Description: It is used for setting TX queues weight */ -static void stmmac_set_tx_queue_weight(struct stmmac_priv *priv) +void stmmac_set_tx_queue_weight(struct stmmac_priv *priv) { u8 tx_queues_count = priv->plat->tx_queues_to_use; u32 weight; @@ -6424,6 +6424,8 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type, return stmmac_tc_setup_taprio(priv, priv, type_data); case TC_SETUP_QDISC_ETF: return stmmac_tc_setup_etf(priv, priv, type_data); + case TC_SETUP_QDISC_ETS: + return stmmac_tc_setup_ets(priv, priv, type_data); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c index 14cabe76e53e..17be37e43bf8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c @@ -1210,6 +1210,73 @@ static int tc_setup_etf(struct stmmac_priv *priv, return 0; } +static int tc_setup_sp_sched(struct stmmac_priv *priv) +{ + struct plat_stmmacenet_data *pdata = priv->plat; + int i; + + for (i = 0; i < pdata->tx_queues_to_use; i++) + pdata->tx_queues_cfg[i].weight = 0; + stmmac_set_tx_queue_weight(priv); + + pdata->tx_sched_algorithm = MTL_TX_ALGORITHM_SP; + stmmac_prog_mtl_tx_algorithms(priv, priv->hw, + pdata->tx_sched_algorithm); + + return 0; +} + +static int tc_setup_ets_sched(struct stmmac_priv *priv, + struct tc_ets_qopt_offload *qopt) +{ + struct tc_ets_qopt_offload_replace_params *p = &qopt->replace_params; + struct plat_stmmacenet_data *pdata = priv->plat; + int i, nstrict = 0; + + if (p->bands > priv->plat->tx_queues_to_use) + return -EOPNOTSUPP; + + for (i = 0; i < p->bands; i++) { + if (!p->quanta[i]) + nstrict++; + } + + if (p->bands && nstrict) + return -EOPNOTSUPP; + + if (nstrict) { + tc_setup_sp_sched(priv); + } else { + for (i = 0; i < pdata->tx_queues_to_use; i++) { + if (i < p->bands) + pdata->tx_queues_cfg[i].weight = p->weights[i]; + else + pdata->tx_queues_cfg[i].weight = 0; + } + stmmac_set_tx_queue_weight(priv); + pdata->tx_sched_algorithm = MTL_TX_ALGORITHM_DWRR; + stmmac_prog_mtl_tx_algorithms(priv, priv->hw, + pdata->tx_sched_algorithm); + } + + return 0; +} + +static int tc_setup_ets(struct stmmac_priv *priv, + struct tc_ets_qopt_offload *qopt) +{ + switch (qopt->command) { + case TC_ETS_REPLACE: + return tc_setup_ets_sched(priv, qopt); + case TC_ETS_DESTROY: + return tc_setup_sp_sched(priv); + default: + return -EOPNOTSUPP; + } + + return 0; +} + static int tc_query_caps(struct stmmac_priv *priv, struct tc_query_caps_base *base) { @@ -1308,6 +1375,7 @@ const struct stmmac_tc_ops dwmac4_tc_ops = { .setup_cls = tc_setup_cls, .setup_taprio = tc_setup_taprio_without_fpe, .setup_etf = tc_setup_etf, + .setup_ets = tc_setup_ets, .query_caps = tc_query_caps, .setup_mqprio = tc_setup_mqprio_unimplemented, }; @@ -1319,6 +1387,7 @@ const struct stmmac_tc_ops dwmac510_tc_ops = { .setup_cls = tc_setup_cls, .setup_taprio = tc_setup_taprio, .setup_etf = tc_setup_etf, + .setup_ets = tc_setup_ets, .query_caps = tc_query_caps, .setup_mqprio = tc_setup_dwmac510_mqprio, }; --- base-commit: 828c4a5a9518117f9f7bdc445a7eeca85fc91bf8 change-id: 20260804-stmmac-ets-offload-cc936c99fdb1 Best regards, -- Lorenzo Bianconi <[email protected]>