summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2025-04-09 16:20:38 +0300
committerSerge Semin <fancer.lancer@gmail.com>2026-08-13 20:35:09 +0300
commitf685ed0a3ac7e1f32a16b5eb0db14be201519473 (patch)
tree29ad35643a8ceebca9fec2cecf85017d8a005331
parent3c449f1bfdeca7713316f15fbac70ab1fd0b4156 (diff)
downloadlinux-f685ed0a3ac7e1f32a16b5eb0db14be201519473.tar.gz
linux-f685ed0a3ac7e1f32a16b5eb0db14be201519473.zip
net: stmmac: vlan: Prevent redundant desc allocation for VLAN tags
Both DW GMAC4 and DW XGMAC HW-manuals claim that the VLAN tags specified via the context descriptors are stored in the DMA-engine and re-used on the next packet marked as VLAN tagged: > The VLAN Tag IDs and MSS values, provided by the application in a > context descriptor with their corresponding Valid bits set, are stored > internally by the DMA. When the outer or inner VLAN tag is provided > with the Valid bit set, the DMA always passes the last valid VLAN tag to > the MTL. The application cannot invalidate the valid VLAN tag stored by > the DMA. The VLAN tag is inserted or replaced based on the control > inputs provided for the packet. Thus it's redundant to allocate the context DMA-descriptor each time a VLAN tagged packet is transmitted in case if it' tag has already been stored by the DMA-engine of the respective queue. Let's cache the VLAN tag then and skip the allocation if a frame with the same tag is specified. This shall improve the xfer performance and reduce the DMA-descriptors consumption rate. Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c9
2 files changed, 10 insertions, 0 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index b1188d897936..7ac58e01d846 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -119,6 +119,7 @@ struct stmmac_tx_queue {
dma_addr_t dma_tx_phy;
dma_addr_t tx_tail_addr;
u32 mss;
+ u16 tci;
u16 ttc;
};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 1a6d2f6335b5..9dad81d3ffea 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4406,6 +4406,13 @@ static bool stmmac_vlan_insert(struct stmmac_priv *priv, struct sk_buff *skb,
tag = skb_vlan_tag_get(skb);
+ /* The previously set outer VLAN Tag is stored in the DMA-engine.
+ * Skip setting it again if it is the same is in the previous xfers.
+ * Note TPID is selected by the activated Tx CTAG/STAG feature.
+ */
+ if (tx_q->tci == tag)
+ return true;
+
if (tx_q->tbs & STMMAC_TBS_AVAIL)
p = &tx_q->dma_entx[tx_q->cur_tx].basic;
else
@@ -4416,6 +4423,7 @@ static bool stmmac_vlan_insert(struct stmmac_priv *priv, struct sk_buff *skb,
stmmac_set_tx_owner(priv, p);
tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
+ tx_q->tci = tag;
return true;
}
@@ -9025,6 +9033,7 @@ static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue)
tx_q->cur_tx = 0;
tx_q->dirty_tx = 0;
tx_q->mss = 0;
+ tx_q->tci = 0;
netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue));
}