summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2025-05-21 21:26:38 +0300
committerSerge Semin <fancer.lancer@gmail.com>2026-08-13 20:31:11 +0300
commitcc45abee5b7c9c146dc7cf032d81ab6792b84cca (patch)
treec67fb20c746650bd2b9b96e31cc2bb4089b9f0b2
parent2f68514ead4e12cb242ebbb73d093a61cb984cd3 (diff)
downloadlinux-cc45abee5b7c9c146dc7cf032d81ab6792b84cca.tar.gz
linux-cc45abee5b7c9c146dc7cf032d81ab6792b84cca.zip
net: stmmac: Fully disable TSO if required
Currently even if the NETIF_F_TSO and NETIF_F_TSO6 features are disabled the TSO engine will be actually left enabled for the DW QoS Ether and DW XGMAC IP-cores since the DMA_CH(#i)_TX_Control.TSE flag will be left set. This makes the TSO feature toggling incomplete and at the very least slows down the outbound packets handling a little bit. Let's fix that by clearing the denoted flag in the ndo_set_features() callback. Besides as the commit 5e6038b88a57 ("net: stmmac: fix TSO and TBS feature enabling during driver open") correctly noted the TBS and TSO features are mutually exclusive and can't be both simultaneously enabled on the same channel. Thus let's convert the code handling these features enable/disable to imply that requirement. Fixes: f748be531d70 ("stmmac: support new GMAC4") Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index eee665c43db8..d78d2756a517 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3756,19 +3756,6 @@ static int stmmac_hw_setup(struct net_device *dev)
/* set TX and RX rings length */
stmmac_set_rings_length(priv);
- /* Enable TSO */
- if (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) {
- for (chan = 0; chan < tx_cnt; chan++) {
- struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
-
- /* TSO and TBS cannot co-exist */
- if (tx_q->tbs & STMMAC_TBS_AVAIL)
- continue;
-
- stmmac_enable_tso(priv, priv->ioaddr, 1, chan);
- }
- }
-
/* Enable Split Header */
sph_en = (priv->hw->rx_csum > 0) && priv->sph_active;
for (chan = 0; chan < rx_cnt; chan++)
@@ -3779,12 +3766,15 @@ static int stmmac_hw_setup(struct net_device *dev)
if (priv->dma_cap.vlins)
stmmac_enable_vlan(priv, priv->hw, STMMAC_VLAN_INSERT);
- /* TBS */
+ /* Enable TSO and/or TBS */
for (chan = 0; chan < tx_cnt; chan++) {
struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
- int enable = tx_q->tbs & STMMAC_TBS_AVAIL;
- stmmac_enable_tbs(priv, priv->ioaddr, enable, chan);
+ /* TSO and TBS cannot co-exist */
+ if (tx_q->tbs & STMMAC_TBS_AVAIL)
+ stmmac_enable_tbs(priv, priv->ioaddr, true, chan);
+ else if (dev->features & (NETIF_F_TSO | NETIF_F_TSO6))
+ stmmac_enable_tso(priv, priv->ioaddr, true, chan);
}
/* Configure real RX and TX queues */
@@ -6207,6 +6197,7 @@ static int stmmac_set_features(struct net_device *netdev,
netdev_features_t features)
{
struct stmmac_priv *priv = netdev_priv(netdev);
+ u32 chan;
/* Keep the COE Type in case of csum is supporting */
if (features & NETIF_F_RXCSUM)
@@ -6218,9 +6209,16 @@ static int stmmac_set_features(struct net_device *netdev,
*/
stmmac_rx_ipc(priv, priv->hw);
+ for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) {
+ struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
+ bool tso_en = !(tx_q->tbs & STMMAC_TBS_AVAIL) &&
+ features & (NETIF_F_TSO | NETIF_F_TSO6);
+
+ stmmac_enable_tso(priv, priv->ioaddr, tso_en, chan);
+ }
+
if (priv->sph_capable) {
bool sph_en = (priv->hw->rx_csum > 0) && priv->sph_active;
- u32 chan;
for (chan = 0; chan < priv->plat->rx_queues_to_use; chan++)
stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan);