]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bnxt_en: Mask the bd_cnt field in the TX BD properly
authorMichael Chan <michael.chan@broadcom.com>
Fri, 21 Mar 2025 21:16:38 +0000 (14:16 -0700)
committerJakub Kicinski <kuba@kernel.org>
Mon, 24 Mar 2025 21:24:17 +0000 (14:24 -0700)
The bd_cnt field in the TX BD specifies the total number of BDs for
the TX packet.  The bd_cnt field has 5 bits and the maximum number
supported is 32 with the value 0.

CONFIG_MAX_SKB_FRAGS can be modified and the total number of SKB
fragments can approach or exceed the maximum supported by the chip.
Add a macro to properly mask the bd_cnt field so that the value 32
will be properly masked and set to 0 in the bd_cnd field.

Without this patch, the out-of-range bd_cnt value will corrupt the
TX BD and may cause TX timeout.

The next patch will check for values exceeding 32.

Fixes: 3948b05950fd ("net: introduce a config option to tweak MAX_SKB_FRAGS")
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250321211639.3812992-2-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c

index 0ddc3d41e2d81934cea16e598ea5f14d6625fc67..158e9789c1f46845760a121223c7f422b4febdc4 100644 (file)
@@ -564,7 +564,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                        TX_BD_FLAGS_LHINT_512_AND_SMALLER |
                                        TX_BD_FLAGS_COAL_NOW |
                                        TX_BD_FLAGS_PACKET_END |
-                                       (2 << TX_BD_FLAGS_BD_CNT_SHIFT));
+                                       TX_BD_CNT(2));
 
                if (skb->ip_summed == CHECKSUM_PARTIAL)
                        tx_push1->tx_bd_hsize_lflags =
@@ -639,7 +639,7 @@ normal_tx:
 
        dma_unmap_addr_set(tx_buf, mapping, mapping);
        flags = (len << TX_BD_LEN_SHIFT) | TX_BD_TYPE_LONG_TX_BD |
-               ((last_frag + 2) << TX_BD_FLAGS_BD_CNT_SHIFT);
+               TX_BD_CNT(last_frag + 2);
 
        txbd->tx_bd_haddr = cpu_to_le64(mapping);
        txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, txr, prod, 2 + last_frag);
index 2373f423a523ecec5a8952ef218bd8e14092fa6f..3b4a044db73e3f14cee49a9cf92cd1d9195439d2 100644 (file)
@@ -82,6 +82,8 @@ struct tx_bd {
 #define TX_OPAQUE_PROD(bp, opq)        ((TX_OPAQUE_IDX(opq) + TX_OPAQUE_BDS(opq)) &\
                                 (bp)->tx_ring_mask)
 
+#define TX_BD_CNT(n)   (((n) << TX_BD_FLAGS_BD_CNT_SHIFT) & TX_BD_FLAGS_BD_CNT)
+
 struct tx_bd_ext {
        __le32 tx_bd_hsize_lflags;
        #define TX_BD_FLAGS_TCP_UDP_CHKSUM                      (1 << 0)
index 299822cacca48e8f12c89a7bf7de1ad1d163b4f4..d71bad3cfd6bd6a9044ac653df907487334e1d3b 100644 (file)
@@ -48,8 +48,7 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
                tx_buf->page = virt_to_head_page(xdp->data);
 
        txbd = &txr->tx_desc_ring[TX_RING(bp, prod)][TX_IDX(prod)];
-       flags = (len << TX_BD_LEN_SHIFT) |
-               ((num_frags + 1) << TX_BD_FLAGS_BD_CNT_SHIFT) |
+       flags = (len << TX_BD_LEN_SHIFT) | TX_BD_CNT(num_frags + 1) |
                bnxt_lhint_arr[len >> 9];
        txbd->tx_bd_len_flags_type = cpu_to_le32(flags);
        txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, txr, prod, 1 + num_frags);