Commit e69880cb authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'bnxt_en-3-bug-fixes'

Michael Chan says:

====================
bnxt_en: 3 bug fixes

The first one fixes a memory corruption issue that can happen when
FW resources change during ifdown with TCs created.  The next two
fix FW resource reservation logic for TX rings and stats context.
====================

Link: https://patch.msgid.link/20250825175927.459987-1-michael.chan@broadcom.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d9b0ca13 b4fc8faa
Loading
Loading
Loading
Loading
+30 −6
Original line number Diff line number Diff line
@@ -8016,7 +8016,8 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
	}
	rx_rings = min_t(int, rx_rings, hwr.grp);
	hwr.cp = min_t(int, hwr.cp, bp->cp_nr_rings);
	if (hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
	if (bnxt_ulp_registered(bp->edev) &&
	    hwr.stat > bnxt_get_ulp_stat_ctxs(bp))
		hwr.stat -= bnxt_get_ulp_stat_ctxs(bp);
	hwr.cp = min_t(int, hwr.cp, hwr.stat);
	rc = bnxt_trim_rings(bp, &rx_rings, &hwr.tx, hwr.cp, sh);
@@ -8024,6 +8025,11 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
		hwr.rx = rx_rings << 1;
	tx_cp = bnxt_num_tx_to_cp(bp, hwr.tx);
	hwr.cp = sh ? max_t(int, tx_cp, rx_rings) : tx_cp + rx_rings;
	if (hwr.tx != bp->tx_nr_rings) {
		netdev_warn(bp->dev,
			    "Able to reserve only %d out of %d requested TX rings\n",
			    hwr.tx, bp->tx_nr_rings);
	}
	bp->tx_nr_rings = hwr.tx;

	/* If we cannot reserve all the RX rings, reset the RSS map only
@@ -12851,6 +12857,17 @@ static int bnxt_set_xps_mapping(struct bnxt *bp)
	return rc;
}

static int bnxt_tx_nr_rings(struct bnxt *bp)
{
	return bp->num_tc ? bp->tx_nr_rings_per_tc * bp->num_tc :
			    bp->tx_nr_rings_per_tc;
}

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 int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
{
	int rc = 0;
@@ -12868,6 +12885,13 @@ 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;
	}
	rc = bnxt_alloc_mem(bp, irq_re_init);
	if (rc) {
		netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
@@ -16325,7 +16349,7 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
	bp->cp_nr_rings = min_t(int, bp->tx_nr_rings_per_tc, bp->rx_nr_rings);
	bp->rx_nr_rings = bp->cp_nr_rings;
	bp->tx_nr_rings_per_tc = bp->cp_nr_rings;
	bp->tx_nr_rings = bp->tx_nr_rings_per_tc;
	bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
}

static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
@@ -16357,7 +16381,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool 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 = bp->tx_nr_rings_per_tc;
	bp->tx_nr_rings = bnxt_tx_nr_rings(bp);

	avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
	if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
@@ -16370,7 +16394,7 @@ 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 = bp->tx_nr_rings;
	bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
	if (sh)
		bnxt_trim_dflt_sh_rings(bp);

@@ -16379,7 +16403,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
		rc = __bnxt_reserve_rings(bp);
		if (rc && rc != -ENODEV)
			netdev_warn(bp->dev, "2nd rings reservation failed.\n");
		bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
		bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
	}
	if (BNXT_CHIP_TYPE_NITRO_A0(bp)) {
		bp->rx_nr_rings++;
@@ -16413,7 +16437,7 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp)
	if (rc)
		goto init_dflt_ring_err;

	bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
	bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);

	bnxt_set_dflt_rfs(bp);