linux/drivers/net/ethernet/broadcom/bnxt/bnxt_gso.h
Joe Damato 87550ba2dc net: bnxt: Add SW GSO completion and teardown support
Update __bnxt_tx_int and bnxt_free_one_tx_ring_skbs to handle SW GSO
segments:

- MID segments: adjust tx_pkts/tx_bytes accounting and skip skb free
  (the skb is shared across all segments and freed only once)

- LAST segments: call tso_dma_map_complete() to tear down the IOVA
  mapping if one was used. On the fallback path, payload DMA unmapping
  is handled by the existing per-BD dma_unmap_len walk.

Both MID and LAST completions advance tx_inline_cons to release the
segment's inline header slot back to the ring.

is_sw_gso is initialized to zero, so the new code paths are not run.

Add logic for feature advertisement and guardrails for ring sizing.

Suggested-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260408230607.2019402-9-joe@dama.to
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-12 10:54:32 -07:00

47 lines
1.4 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Broadcom NetXtreme-C/E network driver.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*/
#ifndef BNXT_GSO_H
#define BNXT_GSO_H
/* Maximum segments the stack may send in a single SW USO skb.
* This caps gso_max_segs for NICs without HW USO support.
*/
#define BNXT_SW_USO_MAX_SEGS 64
/* Worst-case TX descriptors consumed by one SW USO packet:
* Each segment: 1 long BD + 1 ext BD + payload BDs.
* Total payload BDs across all segs <= num_segs + nr_frags (each frag
* boundary crossing adds at most 1 extra BD).
* So: 3 * max_segs + MAX_SKB_FRAGS + 1 = 3 * 64 + 17 + 1 = 210.
*/
#define BNXT_SW_USO_MAX_DESCS (3 * BNXT_SW_USO_MAX_SEGS + MAX_SKB_FRAGS + 1)
static inline u16 bnxt_inline_avail(struct bnxt_tx_ring_info *txr)
{
return BNXT_SW_USO_MAX_SEGS -
(u16)(txr->tx_inline_prod - READ_ONCE(txr->tx_inline_cons));
}
static inline int bnxt_min_tx_desc_cnt(struct bnxt *bp,
netdev_features_t features)
{
if (!(bp->flags & BNXT_FLAG_UDP_GSO_CAP) &&
(features & NETIF_F_GSO_UDP_L4))
return BNXT_SW_USO_MAX_DESCS;
return BNXT_MIN_TX_DESC_CNT;
}
netdev_tx_t bnxt_sw_udp_gso_xmit(struct bnxt *bp,
struct bnxt_tx_ring_info *txr,
struct netdev_queue *txq,
struct sk_buff *skb);
#endif