Merge branch 'bnxt_en-bug-fixes'

Michael Chan says:

====================
bnxt_en: Bug fixes

The first patch is a refactor patch needed by the second patch to
fix XDP ring initialization during FW reset.  The third patch
fixes an issue related to stats context reservation for RoCE.
====================

Link: https://patch.msgid.link/20260331065138.948205-1-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-04-01 20:13:00 -07:00
commit 9351edf65c
4 changed files with 52 additions and 27 deletions

View File

@ -8045,6 +8045,8 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
ulp_msix = bnxt_get_avail_msix(bp, bp->ulp_num_msix_want);
if (!ulp_msix)
bnxt_set_ulp_stat_ctxs(bp, 0);
else
bnxt_set_dflt_ulp_stat_ctxs(bp);
if (ulp_msix > bp->ulp_num_msix_want)
ulp_msix = bp->ulp_num_msix_want;
@ -12992,6 +12994,21 @@ static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings;
}
static void bnxt_set_xdp_tx_rings(struct bnxt *bp)
{
bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
bp->tx_nr_rings += bp->tx_nr_rings_xdp;
}
static void bnxt_adj_tx_rings(struct bnxt *bp)
{
/* Make adjustments if reserved TX rings are less than requested */
bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
if (bp->tx_nr_rings_xdp)
bnxt_set_xdp_tx_rings(bp);
}
static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
{
int rc = 0;
@ -13009,13 +13026,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
if (rc)
return rc;
/* Make adjustments if reserved TX rings are less than requested */
bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
if (bp->tx_nr_rings_xdp) {
bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
bp->tx_nr_rings += bp->tx_nr_rings_xdp;
}
bnxt_adj_tx_rings(bp);
rc = bnxt_alloc_mem(bp, irq_re_init);
if (rc) {
netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
@ -15436,11 +15447,19 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
void bnxt_set_cp_rings(struct bnxt *bp, bool sh)
{
int tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
tx_cp + bp->rx_nr_rings;
}
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
{
struct bnxt *bp = netdev_priv(dev);
bool sh = false;
int rc, tx_cp;
int rc;
if (tc > bp->max_tc) {
netdev_err(dev, "Too many traffic classes requested: %d. Max supported is %d.\n",
@ -15473,9 +15492,7 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
bp->num_tc = 0;
}
bp->tx_nr_rings += bp->tx_nr_rings_xdp;
tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
tx_cp + bp->rx_nr_rings;
bnxt_set_cp_rings(bp, sh);
if (netif_running(bp->dev))
return bnxt_open_nic(bp, true, false);
@ -16525,6 +16542,19 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
}
static void bnxt_adj_dflt_rings(struct bnxt *bp, bool sh)
{
if (sh)
bnxt_trim_dflt_sh_rings(bp);
else
bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
if (sh && READ_ONCE(bp->xdp_prog)) {
bnxt_set_xdp_tx_rings(bp);
bnxt_set_cp_rings(bp, true);
}
}
static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
{
int dflt_rings, max_rx_rings, max_tx_rings, rc;
@ -16550,11 +16580,8 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
return rc;
bp->rx_nr_rings = min_t(int, dflt_rings, max_rx_rings);
bp->tx_nr_rings_per_tc = min_t(int, dflt_rings, max_tx_rings);
if (sh)
bnxt_trim_dflt_sh_rings(bp);
else
bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
bnxt_adj_dflt_rings(bp, sh);
avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
@ -16567,16 +16594,17 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
rc = __bnxt_reserve_rings(bp);
if (rc && rc != -ENODEV)
netdev_warn(bp->dev, "Unable to reserve tx rings\n");
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
bnxt_adj_tx_rings(bp);
if (sh)
bnxt_trim_dflt_sh_rings(bp);
bnxt_adj_dflt_rings(bp, true);
/* Rings may have been trimmed, re-reserve the trimmed rings. */
if (bnxt_need_reserve_rings(bp)) {
rc = __bnxt_reserve_rings(bp);
if (rc && rc != -ENODEV)
netdev_warn(bp->dev, "2nd rings reservation failed.\n");
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
bnxt_adj_tx_rings(bp);
}
if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
bp->rx_nr_rings++;
@ -16610,7 +16638,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
if (rc)
goto init_dflt_ring_err;
bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
bnxt_adj_tx_rings(bp);
bnxt_set_dflt_rfs(bp);

View File

@ -2985,6 +2985,7 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
int tx_xdp);
int bnxt_fw_init_one(struct bnxt *bp);
bool bnxt_hwrm_reset_permitted(struct bnxt *bp);
void bnxt_set_cp_rings(struct bnxt *bp, bool sh);
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
struct bnxt_ntuple_filter *bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp,
struct bnxt_ntuple_filter *fltr, u32 idx);

View File

@ -945,7 +945,6 @@ static int bnxt_set_channels(struct net_device *dev,
bool sh = false;
int tx_xdp = 0;
int rc = 0;
int tx_cp;
if (channel->other_count)
return -EINVAL;
@ -1013,9 +1012,7 @@ static int bnxt_set_channels(struct net_device *dev,
if (tcs > 1)
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tcs + tx_xdp;
tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
tx_cp + bp->rx_nr_rings;
bnxt_set_cp_rings(bp, sh);
/* After changing number of rx channels, update NTUPLE feature. */
netdev_update_features(dev);

View File

@ -384,7 +384,7 @@ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
{
struct net_device *dev = bp->dev;
int tx_xdp = 0, tx_cp, rc, tc;
int tx_xdp = 0, rc, tc;
struct bpf_prog *old;
netdev_assert_locked(dev);
@ -431,8 +431,7 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
}
bp->tx_nr_rings_xdp = tx_xdp;
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
bp->cp_nr_rings = max_t(int, tx_cp, bp->rx_nr_rings);
bnxt_set_cp_rings(bp, true);
bnxt_set_tpa_flags(bp);
bnxt_set_ring_params(bp);