bnxt_en: Put the TX producer information in the TX BD opaque field
authorMichael Chan <michael.chan@broadcom.com>
Tue, 14 Nov 2023 00:16:09 +0000 (16:16 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 15 Nov 2023 10:07:39 +0000 (10:07 +0000)
Currently, the opaque field in the TX BD is only used for debugging.
The TX completion logic relies on getting one TX completion for each
packet and they always complete in order.

Improve this scheme by putting the producer information (ring index plus
number of BDs for the packet) in the opaque field.  This way, we can
handle TX completion processing by looking at the last TX completion
instead of counting the number of completions.

Since we no longer need to count the exact number of completions, we can
optimize xmit_more by disabling TX completion when the xmit_more
condition is true.  This will be done in later patches.

This patch is only initializing the opaque field in the TX BD and is
not changing the driver's TX completion logic yet.

Reviewed-by: Andy Gospodarek <gospo@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c

index d0359b569afeb17e3ef1340bac5b3645636af237..669ea945d3cd74a5f57d59a67cd0a62a77871c6a 100644 (file)
@@ -432,8 +432,6 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        txbd = &txr->tx_desc_ring[TX_RING(prod)][TX_IDX(prod)];
 
-       txbd->tx_bd_opaque = prod;
-
        tx_buf = &txr->tx_buf_ring[prod];
        tx_buf->skb = skb;
        tx_buf->nr_frags = last_frag;
@@ -519,7 +517,9 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
                txbd->tx_bd_len_flags_type = tx_push->tx_bd_len_flags_type;
                txbd->tx_bd_haddr = txr->data_mapping;
+               txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, prod, 2);
                prod = NEXT_TX(prod);
+               tx_push->tx_bd_opaque = txbd->tx_bd_opaque;
                txbd = &txr->tx_desc_ring[TX_RING(prod)][TX_IDX(prod)];
                memcpy(txbd, tx_push1, sizeof(*txbd));
                prod = NEXT_TX(prod);
@@ -562,6 +562,7 @@ normal_tx:
                ((last_frag + 2) << TX_BD_FLAGS_BD_CNT_SHIFT);
 
        txbd->tx_bd_haddr = cpu_to_le64(mapping);
+       txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, prod, 2 + last_frag);
 
        prod = NEXT_TX(prod);
        txbd1 = (struct tx_bd_ext *)
index e702dbc3e6b131d1bf622be3ae781201a9f8e5f3..c7895e7d78d5d6663f00b148622c58662aa8b0bb 100644 (file)
@@ -61,6 +61,13 @@ struct tx_bd {
        __le64 tx_bd_haddr;
 } __packed;
 
+#define TX_OPAQUE_IDX_MASK     0x0000ffff
+#define TX_OPAQUE_BDS_MASK     0x00ff0000
+#define TX_OPAQUE_BDS_SHIFT    16
+
+#define SET_TX_OPAQUE(bp, idx, bds)                                    \
+       (((bds) << TX_OPAQUE_BDS_SHIFT) | ((idx) & (bp)->tx_ring_mask))
+
 struct tx_bd_ext {
        __le32 tx_bd_hsize_lflags;
        #define TX_BD_FLAGS_TCP_UDP_CHKSUM                      (1 << 0)
index 96f5ca778c67d609ffa3530fa5508704e0b8e98f..3e5144aafb0c61940ca132c842e513ca487869d6 100644 (file)
@@ -52,7 +52,7 @@ struct bnxt_sw_tx_bd *bnxt_xmit_bd(struct bnxt *bp,
                ((num_frags + 1) << TX_BD_FLAGS_BD_CNT_SHIFT) |
                bnxt_lhint_arr[len >> 9];
        txbd->tx_bd_len_flags_type = cpu_to_le32(flags);
-       txbd->tx_bd_opaque = prod;
+       txbd->tx_bd_opaque = SET_TX_OPAQUE(bp, prod, 1 + num_frags);
        txbd->tx_bd_haddr = cpu_to_le64(mapping);
 
        /* now let us fill up the frags into the next buffers */