Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Apr 2026 06:44:59 +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: a5bedb41e5d6 - main - bnxt_en: Add VF load path and PF/VF context differentiation
Message-ID:  <69f0576b.275f3.617c731d@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=a5bedb41e5d6b3680981f109c3e89fb5ffd8eee1

commit a5bedb41e5d6b3680981f109c3e89fb5ffd8eee1
Author:     Chandrakanth Patil <chandrakanth.patil@broadcom.com>
AuthorDate: 2026-03-31 16:59:01 +0000
Commit:     Sumit Saxena <ssaxena@FreeBSD.org>
CommitDate: 2026-04-28 06:21:46 +0000

    bnxt_en: Add VF load path and PF/VF context differentiation
    
    Teach the driver to distinguish a Physical Function from a Virtual
    Function at probe time and configure each appropriately.
    
    * Introduce bnxt_is_vf_device() to identify all known VF device IDs
      (NetXtreme-C/E Gen1-3, Thor1/2, Hyper-V variants).  Add corresponding
      PVID entries to bnxt_vendor_info_array.
    
    * Refactor the iflib shared context: rename bnxt_sctx_init to
      bnxt_sctx_template, add a Thor2-specific bnxt_sctx_template_p7, and
      build per-call PF/VF instances via bnxt_init_sctx_variants(); the VF
      instance carries IFLIB_IS_VF.  bnxt_register() selects the correct sctx.
    
    * bnxt_attach_pre(): replace the hard-coded NPAR/VF switch with
      bnxt_set_flags_by_devid(); on a VF call bnxt_approve_mac() to request
      PF approval for the firmware-assigned MAC address.
    
    * bnxt_hwrm_func_qcaps(): populate fw_fid and MAC for PF and VF contexts
      separately; for PF call iflib_set_mac() and record max_msix_vfs; for VF
      handle the case where the PF has not yet assigned a MAC.
    
    * bnxt_hwrm_func_qcfg(): populate the new alloc_* counters used by the VF
      resource configuration path; record registered_vfs for PF and VLAN/trust
      state for VF.
    
    * bnxt_init(): call bnxt_update_vf_mac() on VFs after each bring-up.
    
    MFC after:      1 month
    Reviewed by:    ssaxena
    Differential Revision: https://reviews.freebsd.org/D56198
---
 sys/dev/bnxt/bnxt_en/bnxt.h       |   1 +
 sys/dev/bnxt/bnxt_en/bnxt_hwrm.c  | 106 +++++++++++++++------
 sys/dev/bnxt/bnxt_en/bnxt_sriov.c |  62 ++++++++++++
 sys/dev/bnxt/bnxt_en/if_bnxt.c    | 193 ++++++++++++++++++++++++++++++--------
 4 files changed, 292 insertions(+), 70 deletions(-)

diff --git a/sys/dev/bnxt/bnxt_en/bnxt.h b/sys/dev/bnxt/bnxt_en/bnxt.h
index bae419d0eefe..4172e5e86b4f 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt.h
+++ b/sys/dev/bnxt/bnxt_en/bnxt.h
@@ -1397,5 +1397,6 @@ int bnxt_dcb_ieee_setapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app);
 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);
 
 #endif /* _BNXT_H */
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
index 2a79b418fe62..944824a1c182 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
+++ b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
@@ -1224,7 +1224,6 @@ bnxt_hwrm_func_qcaps(struct bnxt_softc *softc)
 	if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_GENERIC_STATS_SUPPORTED)
 		softc->fw_cap |= BNXT_FW_CAP_GENERIC_STATS;
 	func->fw_fid = le16toh(resp->fid);
-	memcpy(func->mac_addr, resp->mac_address, ETHER_ADDR_LEN);
 	func->max_rsscos_ctxs = le16toh(resp->max_rsscos_ctx);
 	func->max_cp_rings = le16toh(resp->max_cmpl_rings);
 	func->max_tx_rings = le16toh(resp->max_tx_rings);
@@ -1235,6 +1234,7 @@ bnxt_hwrm_func_qcaps(struct bnxt_softc *softc)
 	func->max_l2_ctxs = le16toh(resp->max_l2_ctxs);
 	func->max_vnics = le16toh(resp->max_vnics);
 	func->max_stat_ctxs = le16toh(resp->max_stat_ctx);
+
 	if (BNXT_PF(softc)) {
 		struct bnxt_pf_info *pf = &softc->pf;
 
@@ -1247,10 +1247,40 @@ bnxt_hwrm_func_qcaps(struct bnxt_softc *softc)
 		pf->max_tx_wm_flows = le32toh(resp->max_tx_wm_flows);
 		pf->max_rx_em_flows = le32toh(resp->max_rx_em_flows);
 		pf->max_rx_wm_flows = le32toh(resp->max_rx_wm_flows);
-	}
-	if (!_is_valid_ether_addr(func->mac_addr)) {
-		device_printf(softc->dev, "Invalid ethernet address, generating random locally administered address\n");
-		get_random_ether_addr(func->mac_addr);
+
+		pf->fw_fid = le16toh(resp->fid);
+		memcpy(pf->mac_addr, resp->mac_address, ETHER_ADDR_LEN);
+		pf->max_msix_vfs = le16toh(resp->max_msix_vfs);
+		if (!_is_valid_ether_addr(pf->mac_addr)) {
+			device_printf(softc->dev, "Invalid PF ethernet address, generating random "
+				      "locally administered PF mac address\n");
+			get_random_ether_addr(pf->mac_addr);
+		}
+		iflib_set_mac(softc->ctx, pf->mac_addr);
+		memcpy(softc->func.mac_addr, pf->mac_addr, ETHER_ADDR_LEN);
+	} else {
+		struct bnxt_vf_info *vf = &softc->vf;
+
+		vf->fw_fid = le16toh(resp->fid);
+		memcpy(vf->mac_addr, resp->mac_address, ETHER_ADDR_LEN);
+		/* if PF has assigned a MAC -> use it. */
+		if (_is_valid_ether_addr(vf->mac_addr)) {
+			iflib_set_mac(softc->ctx, vf->mac_addr);
+			memcpy(softc->func.mac_addr, vf->mac_addr, ETHER_ADDR_LEN);
+		} else {
+			/* else PF has NOT assigned a MAC -> Generate one. */
+			uint8_t la_mac[ETHER_ADDR_LEN];
+			device_printf(softc->dev, "PF has not assigned a MAC address to VF, generating random "
+				      "locally administered VF mac address\n");
+			get_random_ether_addr(la_mac);
+
+			/* Set OS MAC and function MAC to LAA */
+			if (_is_valid_ether_addr(la_mac)) {
+				iflib_set_mac(softc->ctx, la_mac);
+				memcpy(softc->func.mac_addr, la_mac, ETHER_ADDR_LEN);
+				memcpy(vf->mac_addr, la_mac, ETHER_ADDR_LEN);
+			}
+		}
 	}
 
 fail:
@@ -1261,25 +1291,31 @@ fail:
 int
 bnxt_hwrm_func_qcfg(struct bnxt_softc *softc)
 {
-	struct hwrm_func_qcfg_input req = {0};
-	struct hwrm_func_qcfg_output *resp =
-		(void *)softc->hwrm_cmd_resp.idi_vaddr;
-	struct bnxt_func_qcfg *fn_qcfg = &softc->fn_qcfg;
+	int rc;
 	uint32_t min_db_offset = 0;
 	uint16_t flags;
-	int rc;
+        struct hwrm_func_qcfg_input req = {0};
+        struct hwrm_func_qcfg_output *resp =
+	    (void *)softc->hwrm_cmd_resp.idi_vaddr;
+	struct bnxt_func_qcfg *fn_qcfg = &softc->fn_qcfg;
 
 	bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FUNC_QCFG);
-	req.fid = htole16(0xffff);
+        req.fid = htole16(0xffff);
 	BNXT_HWRM_LOCK(softc);
 	rc = _hwrm_send_message(softc, &req, sizeof(req));
-	if (rc)
+        if (rc)
 		goto end;
 
-	fn_qcfg->alloc_completion_rings = le16toh(resp->alloc_cmpl_rings);
 	fn_qcfg->alloc_tx_rings = le16toh(resp->alloc_tx_rings);
 	fn_qcfg->alloc_rx_rings = le16toh(resp->alloc_rx_rings);
+	fn_qcfg->alloc_completion_rings = le16toh(resp->alloc_cmpl_rings);
 	fn_qcfg->alloc_vnics = le16toh(resp->alloc_vnics);
+	fn_qcfg->alloc_rss_ctx = le16toh(resp->alloc_rsscos_ctx);
+	fn_qcfg->alloc_l2_ctx = le16toh(resp->alloc_l2_ctx);
+	fn_qcfg->alloc_vfs = le16toh(resp->alloc_vfs);
+	fn_qcfg->alloc_hw_ring_grps = le16toh(resp->alloc_hw_ring_grps);
+	fn_qcfg->alloc_stat_ctx = le16toh(resp->alloc_stat_ctx);
+	fn_qcfg->alloc_msix = le16toh(resp->alloc_msix);
 
 	switch (resp->port_partition_type) {
 	case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0:
@@ -1291,22 +1327,34 @@ bnxt_hwrm_func_qcfg(struct bnxt_softc *softc)
 	}
 
 	flags = le16toh(resp->flags);
-	if (flags & (HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED |
-		     HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_LLDP_AGENT_ENABLED)) {
-		softc->fw_cap |= BNXT_FW_CAP_LLDP_AGENT;
-		if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED)
-			softc->fw_cap |= BNXT_FW_CAP_DCBX_AGENT;
-	}
-	if (BNXT_PF(softc) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_HOST))
-		softc->flags |= BNXT_FLAG_MULTI_HOST;
-	if (BNXT_PF(softc) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_ROOT))
-		softc->flags |= BNXT_FLAG_MULTI_ROOT;
-	if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_SECURE_MODE_ENABLED)
-		softc->fw_cap |= BNXT_FW_CAP_SECURE_MODE;
-	if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_RING_MONITOR_ENABLED)
-		softc->fw_cap |= BNXT_FW_CAP_RING_MONITOR;
-	if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_ENABLE_RDMA_SRIOV)
-		softc->fw_cap |= BNXT_FW_CAP_ENABLE_RDMA_SRIOV;
+
+	if (BNXT_VF(softc)) {
+		struct bnxt_vf_info *vf = &softc->vf;
+
+		vf->vlan = le16toh(resp->vlan) & BNXT_VLAN_VID_MASK;
+		if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_TRUSTED_VF)
+			vf->flags |= BNXT_VF_TRUST;
+		else
+			vf->flags &= ~BNXT_VF_TRUST;
+	} else
+		softc->pf.registered_vfs = le16toh(resp->registered_vfs);
+
+        if (flags & (HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED |
+                     HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_LLDP_AGENT_ENABLED)) {
+                softc->fw_cap |= BNXT_FW_CAP_LLDP_AGENT;
+                if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED)
+                        softc->fw_cap |= BNXT_FW_CAP_DCBX_AGENT;
+        }
+        if (BNXT_PF(softc) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_HOST))
+                softc->flags |= BNXT_FLAG_MULTI_HOST;
+        if (BNXT_PF(softc) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_ROOT))
+                softc->flags |= BNXT_FLAG_MULTI_ROOT;
+        if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_SECURE_MODE_ENABLED)
+                softc->fw_cap |= BNXT_FW_CAP_SECURE_MODE;
+        if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_RING_MONITOR_ENABLED)
+                softc->fw_cap |= BNXT_FW_CAP_RING_MONITOR;
+        if (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_ENABLE_RDMA_SRIOV)
+                softc->fw_cap |= BNXT_FW_CAP_ENABLE_RDMA_SRIOV;
 
 	if (softc->db_size)
 		goto end;
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_sriov.c b/sys/dev/bnxt/bnxt_en/bnxt_sriov.c
index b2a65c044cee..0ca1881514c2 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt_sriov.c
+++ b/sys/dev/bnxt/bnxt_en/bnxt_sriov.c
@@ -212,6 +212,68 @@ static int bnxt_set_vf_params(struct bnxt_softc *softc, int vf_id)
 	return rc;
 }
 
+int bnxt_approve_mac(struct bnxt_softc *sc)
+{
+
+	struct hwrm_func_vf_cfg_input req = (struct hwrm_func_vf_cfg_input){0};
+	struct bnxt_vf_info *vf = &sc->vf;
+	u8 *mac = vf->mac_addr;
+	int rc = 0;
+
+	if (!BNXT_VF(sc))
+		return EOPNOTSUPP;
+
+	bnxt_hwrm_cmd_hdr_init(sc, &req, HWRM_FUNC_VF_CFG);
+	req.enables = htole32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+	memcpy(req.dflt_mac_addr, mac, ETHER_ADDR_LEN);
+
+	BNXT_HWRM_LOCK(sc);
+	rc = _hwrm_send_message(sc, &req, sizeof(req));
+	BNXT_HWRM_UNLOCK(sc);
+
+	if (rc) {
+		device_printf(sc->dev,
+		"VF MAC %02x:%02x:%02x:%02x:%02x:%02x not approved by PF (rc=%d)\n",
+		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], rc);
+		return EADDRNOTAVAIL;
+	}
+	return rc;
+}
+
+void
+bnxt_update_vf_mac(struct bnxt_softc *sc)
+{
+	int rc = 0;
+	struct hwrm_func_qcaps_input req = {0};
+	struct hwrm_func_qcaps_output *resp =
+	    (void *)sc->hwrm_cmd_resp.idi_vaddr;
+	bool inform_pf = false;
+
+	bnxt_hwrm_cmd_hdr_init(sc, &req, HWRM_FUNC_QCAPS);
+	req.fid = htole16(0xffff);
+
+	BNXT_HWRM_LOCK(sc);
+	rc = _hwrm_send_message(sc, &req, sizeof(req));
+	if (rc)
+		goto update_vf_mac_exit;
+
+	if (!ether_addr_equal(resp->mac_address, sc->vf.mac_addr)) {
+		memcpy(sc->vf.mac_addr, resp->mac_address, ETHER_ADDR_LEN);
+		if (!is_valid_ether_addr(sc->vf.mac_addr))
+			inform_pf = true;
+	}
+
+	if (is_valid_ether_addr(sc->vf.mac_addr)) {
+		iflib_set_mac(sc->ctx, sc->vf.mac_addr);
+		memcpy(sc->func.mac_addr, sc->vf.mac_addr, ETHER_ADDR_LEN);
+	}
+
+update_vf_mac_exit:
+	BNXT_HWRM_UNLOCK(sc);
+	if (inform_pf)
+		bnxt_approve_mac(sc);
+}
+
 static int
 bnxt_hwrm_func_vf_resc_cfg(struct bnxt_softc *softc, int num_vfs, bool reset)
 {
diff --git a/sys/dev/bnxt/bnxt_en/if_bnxt.c b/sys/dev/bnxt/bnxt_en/if_bnxt.c
index b9fb7fb8a7e4..9226ea85a34a 100644
--- a/sys/dev/bnxt/bnxt_en/if_bnxt.c
+++ b/sys/dev/bnxt/bnxt_en/if_bnxt.c
@@ -168,6 +168,20 @@ static const pci_vendor_info_t bnxt_vendor_info_array[] =
 	"Broadcom NetXtreme-E Ethernet Virtual Function"),
     PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF3,
 	"Broadcom NetXtreme-E Ethernet Virtual Function"),
+    PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF4,
+	"Broadcom NetXtreme-E Ethernet Virtual Function"),
+    PVID(BROADCOM_VENDOR_ID, NETXTREME_E_VF5,
+	"Broadcom NetXtreme-E Ethernet Virtual Function"),
+    PVID(BROADCOM_VENDOR_ID, NETXTREME_E_P5_VF1,
+	"Broadcom BCM5750X NetXtreme-E Ethernet Virtual Function"),
+    PVID(BROADCOM_VENDOR_ID, NETXTREME_E_P5_VF2,
+	"Broadcom BCM5750X NetXtreme-E Ethernet Virtual Function"),
+    PVID(BROADCOM_VENDOR_ID, NETXTREME_E_P5_VF_HV1,
+	"Broadcom NetXtreme-C Virtual Function for Hyper-V"),
+    PVID(BROADCOM_VENDOR_ID, NETXTREME_E_P5_VF_HV2,
+	"Broadcom NetXtreme-C Virtual Function for Hyper-V"),
+    PVID(BROADCOM_VENDOR_ID, NETXTREME_E_P7_VF,
+	"Broadcom BCM5760X Virtual Function"),
     /* required last entry */
 
     PVID_END
@@ -364,14 +378,19 @@ static driver_t bnxt_iflib_driver = {
 /*
  * iflib shared context
  */
-
 #define BNXT_DRIVER_VERSION	"230.0.133.0"
 const char bnxt_driver_version[] = BNXT_DRIVER_VERSION;
+
+static char drv_version_msg[] =
+		"Broadcom NetXtreme-C/E Ethernet Driver if_bnxt" \
+		" v" BNXT_DRIVER_VERSION;
+
 extern struct if_txrx bnxt_txrx;
-static struct if_shared_ctx bnxt_sctx_init = {
+
+static struct if_shared_ctx bnxt_sctx_template = {
 	.isc_magic = IFLIB_MAGIC,
 	.isc_driver = &bnxt_iflib_driver,
-	.isc_nfl = 2,				// Number of Free Lists
+	.isc_nfl = 2,
 	.isc_flags = IFLIB_HAS_RXCQ | IFLIB_HAS_TXCQ | IFLIB_NEED_ETHER_PAD,
 	.isc_q_align = PAGE_SIZE,
 	.isc_tx_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
@@ -380,28 +399,117 @@ static struct if_shared_ctx bnxt_sctx_init = {
 	.isc_tso_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
 	.isc_rx_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
 	.isc_rx_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
-
-	// Only use a single segment to avoid page size constraints
 	.isc_rx_nsegments = 1,
 	.isc_ntxqs = 3,
 	.isc_nrxqs = 3,
 	.isc_nrxd_min = {16, 16, 16},
 	.isc_nrxd_default = {PAGE_SIZE / sizeof(struct cmpl_base) * 8,
-	    PAGE_SIZE / sizeof(struct rx_prod_pkt_bd),
-	    PAGE_SIZE / sizeof(struct rx_prod_pkt_bd)},
+			     PAGE_SIZE / sizeof(struct rx_prod_pkt_bd),
+			     PAGE_SIZE / sizeof(struct rx_prod_pkt_bd)},
 	.isc_nrxd_max = {BNXT_MAX_RXD, BNXT_MAX_RXD, BNXT_MAX_RXD},
 	.isc_ntxd_min = {16, 16, 16},
 	.isc_ntxd_default = {PAGE_SIZE / sizeof(struct cmpl_base) * 2,
-	    PAGE_SIZE / sizeof(struct tx_bd_short),
-	    /* NQ depth 4096 */
-	    PAGE_SIZE / sizeof(struct cmpl_base) * 16},
+			     PAGE_SIZE / sizeof(struct tx_bd_short),
+			     PAGE_SIZE / sizeof(struct cmpl_base) * 16},
 	.isc_ntxd_max = {BNXT_MAX_TXD, BNXT_MAX_TXD, BNXT_MAX_TXD},
+	.isc_vendor_info = bnxt_vendor_info_array,
+	.isc_driver_version = bnxt_driver_version,
+};
 
-	.isc_admin_intrcnt = BNXT_ROCE_IRQ_COUNT,
+static struct if_shared_ctx bnxt_sctx_template_p7 = {
+	.isc_magic = IFLIB_MAGIC,
+	.isc_driver = &bnxt_iflib_driver,
+	.isc_nfl = 2,
+	.isc_flags = IFLIB_HAS_RXCQ | IFLIB_HAS_TXCQ | IFLIB_NEED_ETHER_PAD,
+	.isc_q_align = PAGE_SIZE,
+	.isc_tx_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
+	.isc_tx_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
+	.isc_tso_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
+	.isc_tso_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
+	.isc_rx_maxsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
+	.isc_rx_maxsegsize = BNXT_TSO_SIZE + sizeof(struct ether_vlan_header),
+	.isc_rx_nsegments = 1,
+	.isc_ntxqs = 3,
+	.isc_nrxqs = 3,
+	.isc_nrxd_min = {16, 16, 16},
+	.isc_nrxd_default = {PAGE_SIZE / sizeof(struct cmpl_base) * 8,
+			     PAGE_SIZE / sizeof(struct rx_prod_pkt_bd),
+			     PAGE_SIZE / sizeof(struct rx_prod_pkt_bd)},
+	.isc_nrxd_max = {BNXT_MAX_RXD, BNXT_MAX_RXD, BNXT_MAX_RXD},
+	.isc_ntxd_min = {128, 128, 128},
+	.isc_ntxd_default = {PAGE_SIZE / sizeof(struct cmpl_base) * 2,
+			     PAGE_SIZE / sizeof(struct tx_bd_short),
+			     PAGE_SIZE / sizeof(struct cmpl_base) * 16},
+	.isc_ntxd_max = {BNXT_MAX_TXD, BNXT_MAX_TXD, BNXT_MAX_TXD},
 	.isc_vendor_info = bnxt_vendor_info_array,
 	.isc_driver_version = bnxt_driver_version,
 };
 
+static struct if_shared_ctx bnxt_sctx_pf_init;
+static struct if_shared_ctx bnxt_sctx_vf_init;
+static bool sctx_initialized = false;
+
+static inline void
+bnxt_init_sctx_variants(uint16_t device_id)
+{
+    if (device_id == BCM57608)
+	bnxt_sctx_pf_init = bnxt_sctx_template_p7;
+    else
+	bnxt_sctx_pf_init = bnxt_sctx_template;
+
+    bnxt_sctx_pf_init.isc_admin_intrcnt = BNXT_ROCE_IRQ_COUNT;
+
+    bnxt_sctx_vf_init = bnxt_sctx_template;
+    bnxt_sctx_vf_init.isc_flags |= IFLIB_IS_VF;
+}
+
+static inline bool
+bnxt_is_vf_device(uint16_t device_id)
+{
+	switch (device_id) {
+	case NETXTREME_C_VF1:
+	case NETXTREME_C_VF2:
+	case NETXTREME_C_VF3:
+	case NETXTREME_E_VF1:
+	case NETXTREME_E_VF2:
+	case NETXTREME_E_VF3:
+	case NETXTREME_E_VF4:
+	case NETXTREME_E_VF5:
+	case NETXTREME_E_P5_VF1:
+	case NETXTREME_E_P5_VF2:
+	case NETXTREME_E_P5_VF_HV1:
+	case NETXTREME_E_P5_VF_HV2:
+	case NETXTREME_E_P7_VF:
+		return true;
+	default:
+		return false;
+	}
+}
+
+void
+bnxt_set_flags_by_devid(struct bnxt_softc *softc)
+{
+	uint16_t device_id = pci_get_device(softc->dev);
+
+	if (bnxt_is_vf_device(device_id))
+		softc->flags |= BNXT_FLAG_VF;
+
+	switch (device_id) {
+	case BCM57402_NPAR:
+	case BCM57404_NPAR:
+	case BCM57406_NPAR:
+	case BCM57407_NPAR:
+	case BCM57412_NPAR1:
+	case BCM57412_NPAR2:
+	case BCM57414_NPAR1:
+	case BCM57414_NPAR2:
+	case BCM57416_NPAR1:
+	case BCM57416_NPAR2:
+		softc->flags |= BNXT_FLAG_NPAR;
+		break;
+	}
+}
+
 #define PCI_SUBSYSTEM_ID	0x2e
 static struct workqueue_struct *bnxt_pf_wq;
 
@@ -414,7 +522,23 @@ extern void bnxt_destroy_irq(struct bnxt_softc *softc);
 static void *
 bnxt_register(device_t dev)
 {
-	return (&bnxt_sctx_init);
+	uint16_t vendor_id = pci_get_vendor(dev);
+	uint16_t device_id = pci_get_device(dev);
+
+	if (vendor_id != BROADCOM_VENDOR_ID)
+		return NULL;
+
+	if (!sctx_initialized) {
+		printf("if_bnxt: %s\n", drv_version_msg);
+		sctx_initialized = true;
+	}
+
+	bnxt_init_sctx_variants(device_id);
+
+	if (bnxt_is_vf_device(device_id))
+		return &bnxt_sctx_vf_init;
+
+	return &bnxt_sctx_pf_init;
 }
 
 static void
@@ -2317,38 +2441,14 @@ bnxt_attach_pre(if_ctx_t ctx)
 	softc->scctx = iflib_get_softc_ctx(ctx);
 	softc->sctx = iflib_get_sctx(ctx);
 	scctx = softc->scctx;
-
-	/* TODO: Better way of detecting NPAR/VF is needed */
-	switch (pci_get_device(softc->dev)) {
-	case BCM57402_NPAR:
-	case BCM57404_NPAR:
-	case BCM57406_NPAR:
-	case BCM57407_NPAR:
-	case BCM57412_NPAR1:
-	case BCM57412_NPAR2:
-	case BCM57414_NPAR1:
-	case BCM57414_NPAR2:
-	case BCM57416_NPAR1:
-	case BCM57416_NPAR2:
-	case BCM57504_NPAR:
-		softc->flags |= BNXT_FLAG_NPAR;
-		break;
-	case NETXTREME_C_VF1:
-	case NETXTREME_C_VF2:
-	case NETXTREME_C_VF3:
-	case NETXTREME_E_VF1:
-	case NETXTREME_E_VF2:
-	case NETXTREME_E_VF3:
-		softc->flags |= BNXT_FLAG_VF;
-		break;
-	}
-
 	softc->domain = pci_get_domain(softc->dev);
 	softc->bus = pci_get_bus(softc->dev);
 	softc->slot = pci_get_slot(softc->dev);
 	softc->function = pci_get_function(softc->dev);
 	softc->dev_fn = PCI_DEVFN(softc->slot, softc->function);
 
+	bnxt_set_flags_by_devid(softc);
+
 	if (bnxt_num_pfs == 0)
 		  SLIST_INIT(&pf_list);
 	bnxt_num_pfs++;
@@ -2505,6 +2605,15 @@ bnxt_attach_pre(if_ctx_t ctx)
 	if (rc)
 		goto failed;
 
+	/* Inform PF to approve MAC as default VF MAC. */
+	if (BNXT_VF(softc)) {
+		rc = bnxt_approve_mac(softc);
+		if (rc) {
+			device_printf(softc->dev, "attach: bnxt_approve_mac failed\n");
+			goto failed;
+		}
+	}
+
 	/*
 	 * Register the driver with the FW
 	 * Register the async events with the FW
@@ -2531,8 +2640,6 @@ bnxt_attach_pre(if_ctx_t ctx)
 		goto failed;
 	}
 
-	iflib_set_mac(ctx, softc->func.mac_addr);
-
 	scctx->isc_txrx = &bnxt_txrx;
 	scctx->isc_tx_csum_flags = (CSUM_IP | CSUM_TCP | CSUM_UDP |
 	    CSUM_TCP_IPV6 | CSUM_UDP_IPV6 | CSUM_TSO);
@@ -3141,6 +3248,10 @@ skip_def_cp_ring:
 			goto fail;
 	}
 
+	/* Inform PF to approve MAC as default VF MAC. */
+	if (BNXT_VF(softc))
+		bnxt_update_vf_mac(softc);
+
 	/* And now set the default CP / NQ ring for the async */
 	rc = bnxt_cfg_async_cr(softc);
 	if (rc)
@@ -5339,4 +5450,4 @@ bnxt_get_wol_settings(struct bnxt_softc *softc)
 	do {
 		wol_handle = bnxt_hwrm_get_wol_fltrs(softc, wol_handle);
 	} while (wol_handle && wol_handle != BNXT_NO_MORE_WOL_FILTERS);
-}
\ No newline at end of file
+}


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f0576b.275f3.617c731d>