Commit 6b6bf60f authored by Somnath Kotur's avatar Somnath Kotur Committed by Jakub Kicinski
Browse files

bnxt_en: Reallocate RX completion ring for TPH support



In order to program the correct Steering Tag during an IRQ affinity
change, we need to free/re-allocate the RX completion ring during
queue_restart.  If TPH is enabled, call FW to free the Rx completion
ring and clear the ring entries in queue_stop().  Re-allocate it in
queue_start() if TPH is enabled.  Note that TPH mode is not enabled
in this patch and will be enabled later in the patch series.

While modifying bnxt_queue_start(), remove the unnecessary zeroing of
rxr->rx_next_cons.  It gets overwritten by the clone in
bnxt_queue_start().  Remove the rx_reset counter increment since
restart is not reset.  Add comment to clarify that the ring
allocations in queue_start should never fail.

Reviewed-by: default avatarMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Signed-off-by: default avatarSomnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20250213011240.1640031-9-michael.chan@broadcom.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 4c8e612c
Loading
Loading
Loading
Loading
+32 −6
Original line number Diff line number Diff line
@@ -7426,6 +7426,19 @@ static void bnxt_hwrm_cp_ring_free(struct bnxt *bp,
	ring->fw_ring_id = INVALID_HW_RING_ID;
}

static void bnxt_clear_one_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
{
	struct bnxt_ring_struct *ring = &cpr->cp_ring_struct;
	int i, size = ring->ring_mem.page_size;

	cpr->cp_raw_cons = 0;
	cpr->toggle = 0;

	for (i = 0; i < bp->cp_nr_pages; i++)
		if (cpr->cp_desc_ring[i])
			memset(cpr->cp_desc_ring[i], 0, size);
}

static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path)
{
	u32 type;
@@ -15623,7 +15636,6 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
{
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_rx_ring_info *rxr, *clone;
	struct bnxt_cp_ring_info *cpr;
	struct bnxt_vnic_info *vnic;
	int i, rc;

@@ -15642,20 +15654,27 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)

	bnxt_copy_rx_ring(bp, rxr, clone);

	/* All rings have been reserved and previously allocated.
	 * Reallocating with the same parameters should never fail.
	 */
	rc = bnxt_hwrm_rx_ring_alloc(bp, rxr);
	if (rc)
		return rc;
	rc = bnxt_hwrm_rx_agg_ring_alloc(bp, rxr);

	if (bp->tph_mode) {
		rc = bnxt_hwrm_cp_ring_alloc_p5(bp, rxr->rx_cpr);
		if (rc)
			goto err_free_hwrm_rx_ring;
	}

	rc = bnxt_hwrm_rx_agg_ring_alloc(bp, rxr);
	if (rc)
		goto err_free_hwrm_cp_ring;

	bnxt_db_write(bp, &rxr->rx_db, rxr->rx_prod);
	if (bp->flags & BNXT_FLAG_AGG_RINGS)
		bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod);

	cpr = &rxr->bnapi->cp_ring;
	cpr->sw_stats->rx.rx_resets++;

	for (i = 0; i <= BNXT_VNIC_NTUPLE; i++) {
		vnic = &bp->vnic_info[i];

@@ -15672,6 +15691,9 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)

	return 0;

err_free_hwrm_cp_ring:
	if (bp->tph_mode)
		bnxt_hwrm_cp_ring_free(bp, rxr->rx_cpr);
err_free_hwrm_rx_ring:
	bnxt_hwrm_rx_ring_free(bp, rxr, false);
	return rc;
@@ -15696,11 +15718,15 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx)
	cancel_work_sync(&rxr->bnapi->cp_ring.dim.work);
	bnxt_hwrm_rx_ring_free(bp, rxr, false);
	bnxt_hwrm_rx_agg_ring_free(bp, rxr, false);
	rxr->rx_next_cons = 0;
	page_pool_disable_direct_recycling(rxr->page_pool);
	if (bnxt_separate_head_pool())
		page_pool_disable_direct_recycling(rxr->head_pool);

	if (bp->tph_mode) {
		bnxt_hwrm_cp_ring_free(bp, rxr->rx_cpr);
		bnxt_clear_one_cp_ring(bp, rxr->rx_cpr);
	}

	memcpy(qmem, rxr, sizeof(*rxr));
	bnxt_init_rx_ring_struct(bp, qmem);

+2 −0
Original line number Diff line number Diff line
@@ -2410,6 +2410,8 @@ struct bnxt {
	u8			max_q;
	u8			num_tc;

	u8			tph_mode;

	unsigned int		current_interval;
#define BNXT_TIMER_INTERVAL	HZ