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: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20250213011240.1640031-9-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Somnath Kotur
2025-02-12 17:12:36 -08:00
committed by Jakub Kicinski
parent 4c8e612c9a
commit 6b6bf60fc9
2 changed files with 34 additions and 6 deletions
+32 -6
View File
@@ -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;
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_rx_ring;
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);
@@ -2410,6 +2410,8 @@ struct bnxt {
u8 max_q;
u8 num_tc;
u8 tph_mode;
unsigned int current_interval;
#define BNXT_TIMER_INTERVAL HZ