[PATCH net-next v4 3/5] bnge: add bnge_for_each_open_nq() iterator

From: Bhargava Marreddy

Date: Wed Nov 11 2026 - 14:07:54 EST


Add BNGE_FIRST_OPEN_NQ and bnge_for_each_open_nq(), and use them in the
loops that will need to skip the NQ that is created at probe once it is
split out. The "open" NQs are those whose IRQs and firmware rings are
created in ndo_open() and destroyed in ndo_stop(), i.e., all NQs from
index BNGE_FIRST_OPEN_NQ on.

The loops over the Completion Rings (CP rings), per-NQ stats, and NAPI
registration (init/del) are intentionally left alone to cover all NQs
(including NQ0), as NQ0's completion structures and NAPI registration
remain tied to open/stop. The bnapi allocation and NAPI enable/disable
loops are converted here; NQ0's NAPI enable/disable is handled
separately by a later patch in this series.

In bnge_hwrm_ring_free(), split the NQ free out of the completion ring
loop so that it can use the iterator, mirroring bnge_hwrm_ring_alloc().
This changes the order of the firmware commands: previously each NQ was
freed right after its own completion rings, now all completion rings
are freed first and all NQs after. Each completion ring is still freed
before the NQ it belongs to.

BNGE_FIRST_OPEN_NQ is 0 for now, i.e., every NQ is an open NQ, so the
macro expands to the loops it replaces. Apart from the firmware command
order above, no functional change.

Signed-off-by: Bhargava Marreddy <bhargava.marreddy@xxxxxxxxxxxx>
Reviewed-by: Dharmender Garg <dharmender.garg@xxxxxxxxxxxx>
Reviewed-by: Kumar Mudide <kumar.mudide@xxxxxxxxxxxx>
Reviewed-by: Ramakrishna Koduri <ramakrishna.koduri@xxxxxxxxxxxx>
Reviewed-by: Vikas Gupta <vikas.gupta@xxxxxxxxxxxx>
---
drivers/net/ethernet/broadcom/bnge/bnge.h | 8 ++++++
.../net/ethernet/broadcom/bnge/bnge_netdev.c | 25 +++++++++++--------
2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnge/bnge.h b/drivers/net/ethernet/broadcom/bnge/bnge.h
index e76ba4e063bb..5cc08177ff86 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge.h
+++ b/drivers/net/ethernet/broadcom/bnge/bnge.h
@@ -238,6 +238,14 @@ struct bnge_dev {
#define bnge_warn(bd, fmt, ...) bnge_log(warn, bd, fmt, ##__VA_ARGS__)
#define bnge_dbg(bd, fmt, ...) bnge_log(dbg, bd, fmt, ##__VA_ARGS__)

+/* Index of the first NQ created in ndo_open() and destroyed in ndo_stop();
+ * lower NQs live from probe to remove.
+ */
+#define BNGE_FIRST_OPEN_NQ 0
+
+#define bnge_for_each_open_nq(i, bd) \
+ for ((i) = BNGE_FIRST_OPEN_NQ; (i) < (bd)->nq_nr_rings; (i)++)
+
static inline bool bnge_is_roce_en(struct bnge_dev *bd)
{
return bd->flags & BNGE_EN_ROCE;
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
index d95c3c1469da..197a9032bbeb 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
@@ -549,7 +549,7 @@ static void bnge_free_nqs(struct bnge_net *bn)
struct bnge_dev *bd = bn->bd;
int i;

- for (i = 0; i < bd->nq_nr_rings; i++)
+ bnge_for_each_open_nq(i, bd)
bnge_free_nq(bn, bn->bnapi[i]);
}

@@ -563,7 +563,7 @@ static int bnge_alloc_nqs(struct bnge_net *bn)
* so every NQ gets a distinct irq_tbl index.
*/
aux_msix = bnge_aux_get_msix(bd);
- for (i = 0; i < bd->nq_nr_rings; i++) {
+ bnge_for_each_open_nq(i, bd) {
rc = bnge_alloc_nq(bn, bn->bnapi[i], aux_msix);
if (rc)
goto err_free_nqs;
@@ -571,7 +571,7 @@ static int bnge_alloc_nqs(struct bnge_net *bn)
return 0;

err_free_nqs:
- while (--i >= 0)
+ while (--i >= BNGE_FIRST_OPEN_NQ)
bnge_free_nq(bn, bn->bnapi[i]);
return rc;
}
@@ -1255,10 +1255,11 @@ static int bnge_alloc_core(struct bnge_net *bn)

bn->bnapi = bnapi;
bnapi += arr_size;
- for (i = 0; i < bd->nq_nr_rings; i++, bnapi += size) {
+ bnge_for_each_open_nq(i, bd) {
bn->bnapi[i] = bnapi;
bn->bnapi[i]->index = i;
bn->bnapi[i]->bn = bn;
+ bnapi += size;
}

bn->rx_ring = kzalloc_objs(struct bnge_rx_ring_info, bd->rx_nr_rings);
@@ -1976,7 +1977,7 @@ static int bnge_hwrm_ring_alloc(struct bnge_net *bn)
int i, rc = 0;

agg_rings = !!(bnge_is_agg_reqd(bd));
- for (i = 0; i < bd->nq_nr_rings; i++) {
+ bnge_for_each_open_nq(i, bd) {
struct bnge_napi *bnapi = bn->bnapi[i];
struct bnge_ring_struct *ring = &bnapi->nq_ring.ring_struct;

@@ -2432,7 +2433,7 @@ static void bnge_enable_int(struct bnge_net *bn)
struct bnge_dev *bd = bn->bd;
int i;

- for (i = 0; i < bd->nq_nr_rings; i++) {
+ bnge_for_each_open_nq(i, bd) {
struct bnge_napi *bnapi = bn->bnapi[i];
struct bnge_nq_ring_info *nqr;

@@ -2449,7 +2450,7 @@ static void bnge_disable_napi(struct bnge_net *bn)
if (test_and_set_bit(BNGE_STATE_NAPI_DISABLED, &bn->state))
return;

- for (i = 0; i < bd->nq_nr_rings; i++) {
+ bnge_for_each_open_nq(i, bd) {
struct bnge_napi *bnapi = bn->bnapi[i];

napi_disable_locked(&bnapi->napi);
@@ -2462,7 +2463,7 @@ static void bnge_enable_napi(struct bnge_net *bn)
int i;

clear_bit(BNGE_STATE_NAPI_DISABLED, &bn->state);
- for (i = 0; i < bd->nq_nr_rings; i++) {
+ bnge_for_each_open_nq(i, bd) {
struct bnge_napi *bnapi = bn->bnapi[i];

bnapi->in_reset = false;
@@ -2615,7 +2616,9 @@ static void bnge_hwrm_ring_free(struct bnge_net *bn, bool close_path)

for (j = 0; j < nqr->cp_ring_count && nqr->cp_ring_arr; j++)
bnge_hwrm_cp_ring_free(bn, &nqr->cp_ring_arr[j]);
+ }

+ bnge_for_each_open_nq(i, bd) {
bnge_hwrm_nq_free(bn, bn->bnapi[i]);
bn->grp_info[i].nq_fw_ring_id = INVALID_HW_RING_ID;
}
@@ -2628,7 +2631,7 @@ static void bnge_setup_msix(struct bnge_net *bn)
int len, i;

len = sizeof(bd->irq_tbl[0].name);
- for (i = 0; i < bd->nq_nr_rings; i++) {
+ bnge_for_each_open_nq(i, bd) {
int map_idx = bnge_cp_num_to_irq_num(bn, i);
char *attr;

@@ -2713,7 +2716,7 @@ static void bnge_free_irq(struct bnge_net *bn)
struct bnge_dev *bd = bn->bd;
int i;

- for (i = 0; i < bd->nq_nr_rings; i++)
+ bnge_for_each_open_nq(i, bd)
bnge_nq_free_irq(bn, bn->bnapi[i]);
}

@@ -2727,7 +2730,7 @@ static int bnge_request_irq(struct bnge_net *bn)
netdev_err(bn->netdev, "bnge_setup_interrupts err: %d\n", rc);
return rc;
}
- for (i = 0; i < bd->nq_nr_rings; i++) {
+ bnge_for_each_open_nq(i, bd) {
rc = bnge_nq_request_irq(bn, bn->bnapi[i]);
if (rc)
goto err_free_irq;
--
2.47.3