net: enetc: keep track of correct Tx BD count in enetc_map_tx_tso_buffs()
authorWei Fang <wei.fang@nxp.com>
Mon, 24 Feb 2025 11:12:45 +0000 (19:12 +0800)
committerJakub Kicinski <kuba@kernel.org>
Wed, 26 Feb 2025 03:10:58 +0000 (19:10 -0800)
When creating a TSO header, if the skb is VLAN tagged, the extended BD
will be used and the 'count' should be increased by 2 instead of 1.
Otherwise, when an error occurs, less tx_swbd will be freed than the
actual number.

Fixes: fb8629e2cbfc ("net: enetc: add support for software TSO")
Cc: stable@vger.kernel.org
Suggested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Wei Fang <wei.fang@nxp.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Link: https://patch.msgid.link/20250224111251.1061098-3-wei.fang@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/freescale/enetc/enetc.c

index 55ad31a5073e7eb23188ad0cd5e00d527b29b6a4..174db9e2ce8136e0e5b44d5fecef062229e9272d 100644 (file)
@@ -395,14 +395,15 @@ dma_err:
        return 0;
 }
 
-static void enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb,
-                                struct enetc_tx_swbd *tx_swbd,
-                                union enetc_tx_bd *txbd, int *i, int hdr_len,
-                                int data_len)
+static int enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb,
+                               struct enetc_tx_swbd *tx_swbd,
+                               union enetc_tx_bd *txbd, int *i, int hdr_len,
+                               int data_len)
 {
        union enetc_tx_bd txbd_tmp;
        u8 flags = 0, e_flags = 0;
        dma_addr_t addr;
+       int count = 1;
 
        enetc_clear_tx_bd(&txbd_tmp);
        addr = tx_ring->tso_headers_dma + *i * TSO_HEADER_SIZE;
@@ -445,7 +446,10 @@ static void enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb,
                /* Write the BD */
                txbd_tmp.ext.e_flags = e_flags;
                *txbd = txbd_tmp;
+               count++;
        }
+
+       return count;
 }
 
 static int enetc_map_tx_tso_data(struct enetc_bdr *tx_ring, struct sk_buff *skb,
@@ -802,9 +806,9 @@ static int enetc_map_tx_tso_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb
 
                /* compute the csum over the L4 header */
                csum = enetc_tso_hdr_csum(&tso, skb, hdr, hdr_len, &pos);
-               enetc_map_tx_tso_hdr(tx_ring, skb, tx_swbd, txbd, &i, hdr_len, data_len);
+               count += enetc_map_tx_tso_hdr(tx_ring, skb, tx_swbd, txbd,
+                                             &i, hdr_len, data_len);
                bd_data_num = 0;
-               count++;
 
                while (data_len > 0) {
                        int size;