From f685ed0a3ac7e1f32a16b5eb0db14be201519473 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Wed, 9 Apr 2025 16:20:38 +0300 Subject: 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 --- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 9 +++++++++ 2 files changed, 10 insertions(+) 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)); } -- cgit v1.2.3