bnxt_en: Reallocate RX completion ring for TPH support
authorSomnath Kotur <somnath.kotur@broadcom.com>
Thu, 13 Feb 2025 01:12:36 +0000 (17:12 -0800)
committerJakub Kicinski <kuba@kernel.org>
Sat, 15 Feb 2025 03:50:23 +0000 (19:50 -0800)
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>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h

index c6cf575af53f9e8ffbfdd260626fe745494ff555..04980718c2871048921885949d9a41c87090647b 100644 (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);
 
index db0be469a3dbdd25351bcef18f11b646ce34339f..4e20878e7714935f39985ca07ee5b217519e069d 100644 (file)
@@ -2410,6 +2410,8 @@ struct bnxt {
        u8                      max_q;
        u8                      num_tc;
 
+       u8                      tph_mode;
+
        unsigned int            current_interval;
 #define BNXT_TIMER_INTERVAL    HZ