Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Apr 2026 06:45:03 +0000
From:      Sumit Saxena <ssaxena@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Cc:        Chandrakanth Patil <chandrakanth.patil@broadcom.com>
Subject:   git: c972c5acbac4 - main - bnxt_en: VF ring reservation, HWRM registration, and PF-only operation guards
Message-ID:  <69f0576f.275f8.102c997@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by ssaxena:

URL: https://cgit.FreeBSD.org/src/commit/?id=c972c5acbac472a5dc797856f39f478862b6c6ea

commit c972c5acbac472a5dc797856f39f478862b6c6ea
Author:     Chandrakanth Patil <chandrakanth.patil@broadcom.com>
AuthorDate: 2026-04-02 23:04:45 +0000
Commit:     Sumit Saxena <ssaxena@FreeBSD.org>
CommitDate: 2026-04-28 06:35:09 +0000

    bnxt_en: VF ring reservation, HWRM registration, and PF-only operation guards
    
    VFs require separate HWRM commands for ring reservation and async
    completion ring setup, so a common PF/VF dispatcher is introduced and
    the async CR path is extended to handle both.  The PF must populate the
    VF request forwarding bitmap during driver registration so the firmware
    correctly forwards VF-originated HWRM commands.  VF reservation strategy
    and min-guaranteed capability flags are now parsed for correct resource
    partitioning, and PF-only operations (DCB, NVM, package version sysctl)
    are guarded against VF invocation.
    
    The short command buffer allocation is also reordered before the function
    reset to ensure extended HWRM messages are available when needed, a
    prerequisite uncovered during VF bring-up.
    
    MFC after:      1 month
    Reviewed by:    ssaxena
    Differential Revision: https://reviews.freebsd.org/D56232
---
 sys/dev/bnxt/bnxt_en/bnxt.h        |   1 +
 sys/dev/bnxt/bnxt_en/bnxt_dcb.c    |   3 ++
 sys/dev/bnxt/bnxt_en/bnxt_hwrm.c   | 105 ++++++++++++++++++++++++++++++++-----
 sys/dev/bnxt/bnxt_en/bnxt_hwrm.h   |   1 +
 sys/dev/bnxt/bnxt_en/bnxt_sysctl.c |   9 ++--
 sys/dev/bnxt/bnxt_en/if_bnxt.c     |  23 ++++++--
 6 files changed, 121 insertions(+), 21 deletions(-)

diff --git a/sys/dev/bnxt/bnxt_en/bnxt.h b/sys/dev/bnxt/bnxt_en/bnxt.h
index 4172e5e86b4f..6d00cd4d601d 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt.h
+++ b/sys/dev/bnxt/bnxt_en/bnxt.h
@@ -1398,5 +1398,6 @@ int bnxt_dcb_ieee_delapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app);
 int bnxt_dcb_ieee_listapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app,
     size_t nitems, int *num_inputs);
 void bnxt_set_flags_by_devid(struct bnxt_softc *softc);
+int bnxt_hwrm_reserve_rings(struct bnxt_softc *softc);
 
 #endif /* _BNXT_H */
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_dcb.c b/sys/dev/bnxt/bnxt_en/bnxt_dcb.c
index e0643f200021..d169be6e5c7b 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt_dcb.c
+++ b/sys/dev/bnxt/bnxt_en/bnxt_dcb.c
@@ -326,6 +326,9 @@ bnxt_hwrm_get_dcbx_app(struct bnxt_softc *softc, struct bnxt_dcb_app *app,
 	if (softc->hwrm_spec_code < 0x10601)
 		return 0;
 
+	if (BNXT_VF(softc))
+		return 0;
+
 	bnxt_hwrm_cmd_hdr_init(softc, &get, HWRM_FW_GET_STRUCTURED_DATA);
 
 	n = BNXT_IEEE_8021QAZ_MAX_TCS;
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
index 944824a1c182..b89a44e4677b 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
+++ b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
@@ -79,6 +79,14 @@ long bnxt_rx_pkts_pri_arr_base_off[] = {BNXT_RX_STATS_PRI_ENTRIES(rx_packets)};
 long bnxt_tx_bytes_pri_arr_base_off[] = {BNXT_TX_STATS_PRI_ENTRIES(tx_bytes)};
 long bnxt_tx_pkts_pri_arr_base_off[] = {BNXT_TX_STATS_PRI_ENTRIES(tx_packets)};
 
+uint16_t bnxt_vf_req_snif[] = {
+	HWRM_FUNC_CFG,
+	HWRM_FUNC_VF_CFG,
+	HWRM_PORT_PHY_QCFG,
+	HWRM_CFA_L2_FILTER_ALLOC,
+	HWRM_OEM_CMD,
+};
+
 static int
 bnxt_hwrm_err_map(uint16_t err)
 {
@@ -757,9 +765,21 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt_softc *softc, bool all)
 	hw_resc->max_stat_ctxs = le16toh(resp->max_stat_ctx);
 
 	if (BNXT_CHIP_P5_PLUS(softc)) {
-		hw_resc->max_nqs = le16toh(resp->max_msix);
+		hw_resc->max_nqs = hw_resc->max_irqs = le16toh(resp->max_msix);
 		hw_resc->max_hw_ring_grps = hw_resc->max_rx_rings;
 	}
+	
+	if (BNXT_PF(softc)) {
+		struct bnxt_pf_info *pf = &softc->pf;
+
+		pf->vf_resv_strategy = le16toh(resp->vf_reservation_strategy);
+		if (pf->vf_resv_strategy > BNXT_VF_RESV_STRATEGY_MINIMAL_STATIC)
+			pf->vf_resv_strategy = BNXT_VF_RESV_STRATEGY_MAXIMAL;
+
+		if (resp->flags &
+		    htole16(FUNC_RESOURCE_QCAPS_RESP_FLAGS_MIN_GUARANTEED))
+			softc->fw_cap |= BNXT_FW_CAP_VF_RES_MIN_GUARANTEED;
+	}
 
 hwrm_func_resc_qcaps_exit:
 	BNXT_HWRM_UNLOCK(softc);
@@ -1054,6 +1074,26 @@ int bnxt_hwrm_func_drv_rgtr(struct bnxt_softc *bp, unsigned long *bmap, int bmap
 	req.os_type = htole16(HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD);
 
 	if (BNXT_PF(bp)) {
+		u32 data[8];
+		int i;
+
+		memset(data, 0, sizeof(data));
+		for (i = 0; i < ARRAY_SIZE(bnxt_vf_req_snif); i++) {
+			u16 cmd = bnxt_vf_req_snif[i];
+			unsigned int bit, idx;
+
+			if ((bp->fw_cap & BNXT_FW_CAP_LINK_ADMIN) &&
+			    (cmd == HWRM_PORT_PHY_QCFG))
+				continue;
+
+			idx = cmd / 32;
+			bit = cmd % 32;
+			data[idx] |= 1 << bit;
+		}
+
+		for (i = 0; i < 8; i++)
+			req.vf_req_fwd[i] = cpu_to_le32(data[i]);
+
 		req.enables |=
 			htole32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_REQ_FWD);
 	}
@@ -2299,25 +2339,63 @@ bnxt_hwrm_reserve_pf_rings(struct bnxt_softc *softc)
 	return hwrm_send_message(softc, &req, sizeof(req));
 }
 
+#define BNXT_VF_MAX_L2_CTX      4
+int bnxt_hwrm_reserve_vf_rings(struct bnxt_softc *softc)
+{
+	struct hwrm_func_vf_cfg_input req = {0};
+
+	bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_VF_CFG);
+
+	req.enables |= htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS);
+	req.enables |= htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_CMPL_RINGS);
+	req.enables |= htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_TX_RINGS);
+	req.enables |= htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_RX_RINGS);
+	req.enables |= htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_VNICS);
+	req.enables |= htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_STAT_CTXS);
+	req.enables |= htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_L2_CTXS);
+	req.num_rsscos_ctxs = htole16(0x8);
+	req.num_cmpl_rings = htole16(BNXT_MAX_NUM_QUEUES * 2);
+	req.num_tx_rings = htole16(BNXT_MAX_NUM_QUEUES);
+	req.num_rx_rings = htole16(BNXT_MAX_NUM_QUEUES);
+	req.num_vnics = htole16(BNXT_MAX_NUM_QUEUES);
+	req.num_stat_ctxs = htole16(BNXT_MAX_NUM_QUEUES * 2);
+	req.num_l2_ctxs = htole16(BNXT_VF_MAX_L2_CTX);
+
+	return hwrm_send_message(softc, &req, sizeof(req));
+}
+
 int
 bnxt_cfg_async_cr(struct bnxt_softc *softc)
 {
 	int rc = 0;
-	struct hwrm_func_cfg_input req = {0};
 
-	if (!BNXT_PF(softc))
-		return 0;
+	if (BNXT_PF(softc)) {
+		struct hwrm_func_cfg_input req = {0};
 
-	bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG);
+		bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_CFG);
 
-	req.fid = htole16(0xffff);
-	req.enables = htole32(HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
-	if (BNXT_CHIP_P5_PLUS(softc))
-		req.async_event_cr = htole16(softc->nq_rings[0].ring.phys_id);
-	else
-		req.async_event_cr = htole16(softc->def_cp_ring.ring.phys_id);
+		req.fid = htole16(0xffff);
+		req.enables = htole32(HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+		if (BNXT_CHIP_P5_PLUS(softc))
+			req.async_event_cr = htole16(softc->nq_rings[0].ring.phys_id);
+		else
+			req.async_event_cr = htole16(softc->def_cp_ring.ring.phys_id);
 
-	rc = hwrm_send_message(softc, &req, sizeof(req));
+		rc = hwrm_send_message(softc, &req, sizeof(req));
+	} else {
+		/* VF needs to configure async event completion ring using HWRM_FUNC_VF_CFG */
+		struct hwrm_func_vf_cfg_input req = {0};
+
+		bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_VF_CFG);
+
+		req.enables = htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+		if (BNXT_CHIP_P5_PLUS(softc))
+			req.async_event_cr = htole16(softc->nq_rings[0].ring.phys_id);
+		else
+			req.async_event_cr = htole16(softc->def_cp_ring.ring.phys_id);
+
+		rc = hwrm_send_message(softc, &req, sizeof(req));
+	}
 
 	return rc;
 }
@@ -2391,6 +2469,9 @@ bnxt_hwrm_nvm_find_dir_entry(struct bnxt_softc *softc, uint16_t type,
 	    (void *)softc->hwrm_cmd_resp.idi_vaddr;
 	int	rc = 0;
 	uint32_t old_timeo;
+	
+	if (BNXT_VF(softc))
+		return 0;
 
 	MPASS(ordinal);
 
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.h b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.h
index 126cad977c82..b10981d9d53f 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.h
+++ b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.h
@@ -141,4 +141,5 @@ int bnxt_hwrm_passthrough(struct bnxt_softc *softc, void *req, uint32_t req_len,
 int	_hwrm_send_message(struct bnxt_softc *, void *, uint32_t);
 int	hwrm_send_message(struct bnxt_softc *, void *, uint32_t);
 void	bnxt_hwrm_cmd_hdr_init(struct bnxt_softc *, void *, uint16_t);
+int bnxt_hwrm_reserve_vf_rings (struct bnxt_softc *softc);
 #endif
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c b/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c
index 51438e657546..741cba4588aa 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c
+++ b/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c
@@ -1219,10 +1219,11 @@ bnxt_create_ver_sysctls(struct bnxt_softc *softc)
 	    "chip_type", CTLFLAG_RD, vi->chip_type > MAX_CHIP_TYPE ?
 	    bnxt_chip_type[MAX_CHIP_TYPE] : bnxt_chip_type[vi->chip_type], 0,
 	    "RoCE firmware name");
-	SYSCTL_ADD_PROC(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
-	    "package_ver", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
-	    softc, 0, bnxt_package_ver_sysctl, "A",
-	    "currently installed package version");
+	if (!BNXT_VF(softc))
+		SYSCTL_ADD_PROC(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "package_ver", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+		    softc, 0, bnxt_package_ver_sysctl, "A",
+		    "currently installed package version");
 	SYSCTL_ADD_PROC(&vi->ver_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
 	    "hwrm_min_ver", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
 	    softc, 0, bnxt_hwrm_min_ver_sysctl, "A",
diff --git a/sys/dev/bnxt/bnxt_en/if_bnxt.c b/sys/dev/bnxt/bnxt_en/if_bnxt.c
index b48c28f002d8..80ca53db4782 100644
--- a/sys/dev/bnxt/bnxt_en/if_bnxt.c
+++ b/sys/dev/bnxt/bnxt_en/if_bnxt.c
@@ -2197,7 +2197,8 @@ static int bnxt_open(struct bnxt_softc *bp)
 	}
 
 	if (BNXT_CHIP_P5_PLUS(bp))
-		bnxt_hwrm_reserve_pf_rings(bp);
+		bnxt_hwrm_reserve_rings(bp);
+	
 	/* Get the current configuration of this function */
 	rc = bnxt_hwrm_func_qcfg(bp);
 	if (rc) {
@@ -2435,6 +2436,16 @@ static void bnxt_sp_task(struct work_struct *work)
 	clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
 }
 
+int
+bnxt_hwrm_reserve_rings(struct bnxt_softc *softc)
+{
+	if (BNXT_PF(softc))
+		return bnxt_hwrm_reserve_pf_rings(softc);
+
+	else
+		return bnxt_hwrm_reserve_vf_rings(softc);
+}
+
 /* Device setup and teardown */
 static int
 bnxt_attach_pre(if_ctx_t ctx)
@@ -2510,15 +2521,15 @@ bnxt_attach_pre(if_ctx_t ctx)
 		goto ver_fail;
 	}
 
-	/* Now perform a function reset */
-	rc = bnxt_hwrm_func_reset(softc);
-
 	if ((softc->flags & BNXT_FLAG_SHORT_CMD) ||
 	    softc->hwrm_max_ext_req_len > BNXT_HWRM_MAX_REQ_LEN) {
 		rc = bnxt_alloc_hwrm_short_cmd_req(softc);
 		if (rc)
 			goto hwrm_short_cmd_alloc_fail;
 	}
+	
+	/* Now perform a function reset */
+	rc = bnxt_hwrm_func_reset(softc);
 
 	if ((softc->ver_info->chip_num == BCM57508) ||
 	    (softc->ver_info->chip_num == BCM57504) ||
@@ -2670,8 +2681,10 @@ bnxt_attach_pre(if_ctx_t ctx)
 
 	/* Get the queue config */
 	bnxt_get_wol_settings(softc);
+
 	if (BNXT_CHIP_P5_PLUS(softc))
-		bnxt_hwrm_reserve_pf_rings(softc);
+		bnxt_hwrm_reserve_rings(softc);
+
 	rc = bnxt_hwrm_func_qcfg(softc);
 	if (rc) {
 		device_printf(softc->dev, "attach: hwrm func qcfg failed\n");


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f0576f.275f8.102c997>