diff options
| author | Serge Semin <fancer.lancer@gmail.com> | 2025-04-09 16:20:38 +0300 |
|---|---|---|
| committer | Serge Semin <fancer.lancer@gmail.com> | 2026-08-13 20:35:09 +0300 |
| commit | f685ed0a3ac7e1f32a16b5eb0db14be201519473 (patch) | |
| tree | 29ad35643a8ceebca9fec2cecf85017d8a005331 | |
| parent | 3c449f1bfdeca7713316f15fbac70ab1fd0b4156 (diff) | |
| download | linux-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.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 9 |
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)); } |
