Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Nov 2022 22:55:58 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 58d84ef87094 - main - if_bnxt: Added support for mgmt interface for passthrough hwrms
Message-ID:  <202211042255.2A4MtwaN032819@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by imp:

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

commit 58d84ef87094691bf1ad9608964ec85f120cd34a
Author:     Sumit Saxena <sumit.saxena@broadcom.com>
AuthorDate: 2022-11-04 22:40:29 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2022-11-04 22:40:29 +0000

    if_bnxt: Added support for mgmt interface for passthrough hwrms
    
    Added support for application management interface. There are two types of commands supported:
    
    1. Firmware IOCTLs: These ioctls are meant for firmware
       consumption. Driver acts as a transport for these.
    2. Driver only IOCTLs: These ioctls are meant for driver
       consumption. Driver will serve these ioctls without sending them down
       to firmware.
    
    Reviewed by: imp
    Differential Revision: https://reviews.freebsd.org/D36448
---
 sys/conf/files            |   1 +
 sys/dev/bnxt/bnxt.h       |  13 ++
 sys/dev/bnxt/bnxt_hwrm.c  |  35 ++++-
 sys/dev/bnxt/bnxt_hwrm.h  |   2 +
 sys/dev/bnxt/bnxt_mgmt.c  | 373 ++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/bnxt/bnxt_mgmt.h  | 126 ++++++++++++++++
 sys/dev/bnxt/if_bnxt.c    |  43 +++++-
 sys/modules/bnxt/Makefile |   5 +-
 8 files changed, 592 insertions(+), 6 deletions(-)

diff --git a/sys/conf/files b/sys/conf/files
index e47f6577e39c..e8b2e02e79d9 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1376,6 +1376,7 @@ dev/bhnd/siba/siba_erom.c		optional siba bhnd
 dev/bhnd/siba/siba_subr.c		optional siba bhnd
 #
 dev/bnxt/bnxt_hwrm.c		optional bnxt iflib pci
+dev/bnxt/bnxt_mgmt.c		optional bnxt iflib pci
 dev/bnxt/bnxt_sysctl.c		optional bnxt iflib pci
 dev/bnxt/bnxt_txrx.c		optional bnxt iflib pci
 dev/bnxt/if_bnxt.c		optional bnxt iflib pci
diff --git a/sys/dev/bnxt/bnxt.h b/sys/dev/bnxt/bnxt.h
index 0d5824722b41..27abccc6b324 100644
--- a/sys/dev/bnxt/bnxt.h
+++ b/sys/dev/bnxt/bnxt.h
@@ -208,6 +208,7 @@ __FBSDID("$FreeBSD$");
 
 #define BNXT_MIN_FRAME_SIZE	52	/* Frames must be padded to this size for some A0 chips */
 
+extern char bnxt_driver_version[];
 typedef void (*bnxt_doorbell_tx)(void *, uint16_t idx);
 typedef void (*bnxt_doorbell_rx)(void *, uint16_t idx);
 typedef void (*bnxt_doorbell_rx_cq)(void *, bool);
@@ -648,14 +649,25 @@ struct bnxt_hw_resc {
 
 #define BNXT_HWRM_MAX_REQ_LEN		(softc->hwrm_max_req_len)
 
+struct bnxt_softc_list {
+	SLIST_ENTRY(bnxt_softc_list) next;
+	struct bnxt_softc *softc;
+};
+
 struct bnxt_softc {
 	device_t	dev;
 	if_ctx_t	ctx;
 	if_softc_ctx_t	scctx;
 	if_shared_ctx_t	sctx;
+	uint32_t	domain;
+	uint32_t	bus;
+	uint32_t	slot;
+	uint32_t	function;
+	uint32_t	dev_fn;
 	struct ifmedia	*media;
 	struct bnxt_ctx_mem_info *ctx_mem;
 	struct bnxt_hw_resc hw_resc;
+	struct bnxt_softc_list list;
 
 	struct bnxt_bar_info	hwrm_bar;
 	struct bnxt_bar_info	doorbell_bar;
@@ -788,5 +800,6 @@ struct bnxt_filter_info {
 /* Function declarations */
 void bnxt_report_link(struct bnxt_softc *softc);
 bool bnxt_check_hwrm_version(struct bnxt_softc *softc);
+struct bnxt_softc *bnxt_find_dev(uint32_t domain, uint32_t bus, uint32_t dev_fn, char *name);
 
 #endif /* _BNXT_H */
diff --git a/sys/dev/bnxt/bnxt_hwrm.c b/sys/dev/bnxt/bnxt_hwrm.c
index 46dd8f34a6c5..c362e01a1f8b 100644
--- a/sys/dev/bnxt/bnxt_hwrm.c
+++ b/sys/dev/bnxt/bnxt_hwrm.c
@@ -540,6 +540,37 @@ hwrm_func_resc_qcaps_exit:
         return rc;
 }
 
+int
+bnxt_hwrm_passthrough(struct bnxt_softc *softc, void *req, uint32_t req_len,
+		void *resp, uint32_t resp_len, uint32_t app_timeout)
+{
+	int rc = 0;
+	void *output = (void *)softc->hwrm_cmd_resp.idi_vaddr;
+	struct input *input = req;
+	uint32_t old_timeo;
+
+	input->resp_addr = htole64(softc->hwrm_cmd_resp.idi_paddr);
+	BNXT_HWRM_LOCK(softc);
+	old_timeo = softc->hwrm_cmd_timeo;
+	if (input->req_type == HWRM_NVM_INSTALL_UPDATE) 
+		softc->hwrm_cmd_timeo = BNXT_NVM_TIMEO;
+	else
+		softc->hwrm_cmd_timeo = max(app_timeout, softc->hwrm_cmd_timeo);
+	rc = _hwrm_send_message(softc, req, req_len);
+	softc->hwrm_cmd_timeo = old_timeo;
+	if (rc) {
+		device_printf(softc->dev, "%s: %s command failed with rc: 0x%x\n",
+			      __FUNCTION__, GET_HWRM_REQ_TYPE(input->req_type), rc);
+		goto fail;
+	}
+
+	memcpy(resp, output, resp_len);
+fail:
+	BNXT_HWRM_UNLOCK(softc);
+	return rc;
+}
+
+
 int
 bnxt_hwrm_ver_get(struct bnxt_softc *softc)
 {
@@ -657,7 +688,6 @@ bnxt_hwrm_ver_get(struct bnxt_softc *softc)
 	softc->ver_info->chip_bond_id = resp->chip_bond_id;
 	softc->ver_info->chip_type = resp->chip_platform_type;
 
-
 	if (resp->hwrm_intf_maj_8b >= 1) {
 		softc->hwrm_max_req_len = le16toh(resp->max_req_win_len);
 		softc->hwrm_max_ext_req_len = le16toh(resp->max_ext_req_len);
@@ -666,8 +696,7 @@ bnxt_hwrm_ver_get(struct bnxt_softc *softc)
 	softc->hwrm_cmd_timeo = le16toh(resp->def_req_timeout);
 	if (!softc->hwrm_cmd_timeo)
 		softc->hwrm_cmd_timeo = DFLT_HWRM_CMD_TIMEOUT;
-
-
+	
 	dev_caps_cfg = le32toh(resp->dev_caps_cfg);
 	if ((dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) &&
 	    (dev_caps_cfg & HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_REQUIRED))
diff --git a/sys/dev/bnxt/bnxt_hwrm.h b/sys/dev/bnxt/bnxt_hwrm.h
index dde82c0aaff8..5e2be49b643d 100644
--- a/sys/dev/bnxt/bnxt_hwrm.h
+++ b/sys/dev/bnxt/bnxt_hwrm.h
@@ -129,4 +129,6 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt_softc *softc, bool all);
 int bnxt_hwrm_reserve_pf_rings (struct bnxt_softc *softc);
 void bnxt_hwrm_ring_info_get(struct bnxt_softc *softc, uint8_t ring_type,
                              uint32_t ring_id,  uint32_t *prod, uint32_t *);
+int bnxt_hwrm_passthrough(struct bnxt_softc *softc, void *req, uint32_t req_len,
+			  void *resp, uint32_t resp_len, uint32_t timeout);
 #endif
diff --git a/sys/dev/bnxt/bnxt_mgmt.c b/sys/dev/bnxt/bnxt_mgmt.c
new file mode 100644
index 000000000000..d54d7a2a2fe1
--- /dev/null
+++ b/sys/dev/bnxt/bnxt_mgmt.c
@@ -0,0 +1,373 @@
+/*
+ * Broadcom NetXtreme-C/E network driver.
+ *
+ * Copyright (c) 2022 Broadcom, All Rights Reserved.
+ * The term Broadcom refers to Broadcom Limited and/or its subsidiaries
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "bnxt_mgmt.h" 
+#include "bnxt.h"
+#include "bnxt_hwrm.h" 
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <sys/endian.h>
+#include <sys/lock.h>
+
+/* Function prototypes */
+static d_open_t      bnxt_mgmt_open;
+static d_close_t     bnxt_mgmt_close;
+static d_ioctl_t     bnxt_mgmt_ioctl;
+
+/* Character device entry points */
+static struct cdevsw bnxt_mgmt_cdevsw = {
+	.d_version = D_VERSION,
+	.d_open = bnxt_mgmt_open,
+	.d_close = bnxt_mgmt_close,
+	.d_ioctl = bnxt_mgmt_ioctl,
+	.d_name = "bnxt_mgmt",
+};
+
+/* Global vars */
+static struct cdev *bnxt_mgmt_dev;
+struct mtx		mgmt_lock;
+
+MALLOC_DEFINE(M_BNXT, "bnxt_mgmt_buffer", "buffer for bnxt_mgmt module");
+
+/*
+ * This function is called by the kld[un]load(2) system calls to
+ * determine what actions to take when a module is loaded or unloaded.
+ */
+static int
+bnxt_mgmt_loader(struct module *m, int what, void *arg)
+{
+	int error = 0;
+
+	switch (what) {
+	case MOD_LOAD:
+		error = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK,
+		    &bnxt_mgmt_dev,
+		    &bnxt_mgmt_cdevsw,
+		    0,
+		    UID_ROOT,
+		    GID_WHEEL,
+		    0600,
+		    "bnxt_mgmt");
+		if (error != 0) {
+			printf("%s: %s:%s:%d Failed to create the"
+			       "bnxt_mgmt device node\n", DRIVER_NAME,
+			       __FILE__, __FUNCTION__, __LINE__);
+			return (error);
+		}
+
+		mtx_init(&mgmt_lock, "BNXT MGMT Lock", NULL, MTX_DEF);
+
+		break;
+	case MOD_UNLOAD:
+		mtx_destroy(&mgmt_lock);
+		destroy_dev(bnxt_mgmt_dev);
+		break;
+	default:
+		error = EOPNOTSUPP;
+		break;
+	}
+
+	return (error);
+}
+
+static int
+bnxt_mgmt_process_hwrm(struct cdev *dev, u_long cmd, caddr_t data,
+		       int flag, struct thread *td)
+{
+	struct bnxt_softc *softc = NULL;
+	struct bnxt_mgmt_req mgmt_req = {};
+	struct bnxt_mgmt_fw_msg msg_temp, *msg, *msg2 = NULL;
+	struct iflib_dma_info dma_data = {};
+	void *user_ptr, *req, *resp;
+	int ret = 0;
+	uint16_t num_ind = 0;
+
+	memcpy(&user_ptr, data, sizeof(user_ptr));
+	if (copyin(user_ptr, &mgmt_req, sizeof(struct bnxt_mgmt_req))) {	
+		printf("%s: %s:%d Failed to copy data from user\n",
+			DRIVER_NAME, __FUNCTION__, __LINE__);
+		return -EFAULT;
+	}
+	softc = bnxt_find_dev(mgmt_req.hdr.domain, mgmt_req.hdr.bus,
+			      mgmt_req.hdr.devfn, NULL);
+	if (!softc) {
+		printf("%s: %s:%d unable to find softc reference\n",
+			DRIVER_NAME, __FUNCTION__, __LINE__);
+		return -ENODEV;
+	}
+
+	if (copyin((void*)mgmt_req.req.hreq, &msg_temp, sizeof(msg_temp))) {
+		device_printf(softc->dev, "%s:%d Failed to copy data from user\n",
+			      __FUNCTION__, __LINE__);
+		return -EFAULT;
+	}
+
+	if (msg_temp.len_req > BNXT_MGMT_MAX_HWRM_REQ_LENGTH ||
+			msg_temp.len_resp > BNXT_MGMT_MAX_HWRM_RESP_LENGTH) {
+		device_printf(softc->dev, "%s:%d Invalid length\n", 
+			      __FUNCTION__, __LINE__);
+		return -EINVAL;
+	}
+
+	if (msg_temp.num_dma_indications > 1) {
+		device_printf(softc->dev, "%s:%d Max num_dma_indications "
+			      "supported is 1 \n", __FUNCTION__, __LINE__);
+		return -EINVAL;
+	}
+
+	req = malloc(msg_temp.len_req, M_BNXT, M_WAITOK | M_ZERO);
+	if(!req) {
+		device_printf(softc->dev, "%s:%d Memory allocation failed",
+			      __FUNCTION__, __LINE__);
+		return -ENOMEM;
+	}
+	
+	resp = malloc(msg_temp.len_resp, M_BNXT, M_WAITOK | M_ZERO);
+	if(!resp) {
+		device_printf(softc->dev, "%s:%d Memory allocation failed",
+			      __FUNCTION__, __LINE__);
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	if (copyin((void *)msg_temp.usr_req, req, msg_temp.len_req)) {
+		device_printf(softc->dev, "%s:%d Failed to copy data from user\n",
+			      __FUNCTION__, __LINE__);
+		ret = -EFAULT;
+		goto end;
+	}
+
+	msg = &msg_temp;
+	num_ind = msg_temp.num_dma_indications;
+	if (num_ind) {
+		int size;
+		void *dma_ptr;
+		uint64_t *dmap;
+
+		size = sizeof(struct bnxt_mgmt_fw_msg) + 
+			     (num_ind * sizeof(struct dma_info));
+
+		msg2 = malloc(size, M_BNXT, M_WAITOK | M_ZERO);
+		if(!msg2) {
+			device_printf(softc->dev, "%s:%d Memory allocation failed",
+				      __FUNCTION__, __LINE__);
+			ret = -ENOMEM;
+			goto end;
+		}
+
+		if (copyin((void *)mgmt_req.req.hreq, msg2, size)) { 
+			device_printf(softc->dev, "%s:%d Failed to copy"
+				      "data from user\n", __FUNCTION__, __LINE__);
+			ret = -EFAULT;
+			goto end;
+		}
+		msg = msg2;
+		
+		ret = iflib_dma_alloc(softc->ctx, msg->dma[0].length, &dma_data,
+				    BUS_DMA_NOWAIT);
+		if (ret) {
+			device_printf(softc->dev, "%s:%d iflib_dma_alloc"
+				      "failed with ret = 0x%x\n", __FUNCTION__,
+				      __LINE__, ret);
+			ret = -ENOMEM;
+			goto end;
+		}
+
+		if (!(msg->dma[0].read_or_write)) {
+			if (copyin((void *)msg->dma[0].data, 
+				   dma_data.idi_vaddr, 
+				   msg->dma[0].length)) {
+				device_printf(softc->dev, "%s:%d Failed to copy"
+					      "data from user\n", __FUNCTION__,
+					      __LINE__);
+				ret = -EFAULT;
+				goto end;
+			}
+		}
+		dma_ptr = (void *) ((uint64_t) req + msg->dma[0].offset);
+		dmap = dma_ptr;
+		*dmap = htole64(dma_data.idi_paddr);
+	}
+   		
+	ret = bnxt_hwrm_passthrough(softc, req, msg->len_req, resp, msg->len_resp, msg->timeout);
+	if(ret)
+		goto end;
+	
+	if (num_ind) {
+		if ((msg->dma[0].read_or_write)) {
+			if (copyout(dma_data.idi_vaddr, 
+				    (void *)msg->dma[0].data, 
+				    msg->dma[0].length)) {
+				device_printf(softc->dev, "%s:%d Failed to copy data"
+					      "to user\n", __FUNCTION__, __LINE__);
+				ret = -EFAULT;
+				goto end;
+			}
+		}
+	}
+	
+	if (copyout(resp, (void *) msg->usr_resp, msg->len_resp)) {
+		device_printf(softc->dev, "%s:%d Failed to copy response to user\n",
+			      __FUNCTION__, __LINE__);
+		ret = -EFAULT;
+		goto end;
+	}
+
+end:
+	if (req)
+		free(req, M_BNXT);
+	if (resp)
+		free(resp, M_BNXT);
+	if (msg2)
+		free(msg2, M_BNXT);
+	if (dma_data.idi_paddr)
+		iflib_dma_free(&dma_data);
+	return ret;
+}
+
+static int
+bnxt_mgmt_get_dev_info(struct cdev *dev, u_long cmd, caddr_t data,
+		       int flag, struct thread *td)
+{
+	struct bnxt_softc *softc = NULL;
+	struct bnxt_dev_info dev_info;
+	void *user_ptr;
+	uint32_t dev_sn_lo, dev_sn_hi;
+	int dev_sn_offset = 0;
+	char dsn[16];
+	uint16_t lnk;
+	int capreg;
+
+	memcpy(&user_ptr, data, sizeof(user_ptr));
+	if (copyin(user_ptr, &dev_info, sizeof(dev_info))) {
+		printf("%s: %s:%d Failed to copy data from user\n",
+			DRIVER_NAME, __FUNCTION__, __LINE__);
+		return -EFAULT;
+	}
+	
+	softc = bnxt_find_dev(0, 0, 0, dev_info.nic_info.dev_name);
+	if (!softc) {
+		printf("%s: %s:%d unable to find softc reference\n",
+			DRIVER_NAME, __FUNCTION__, __LINE__);
+		return -ENODEV;
+	}
+
+	strncpy(dev_info.nic_info.driver_version, bnxt_driver_version, 64);
+	strncpy(dev_info.nic_info.driver_name, device_get_name(softc->dev), 64);
+	dev_info.pci_info.domain_no = softc->domain;
+	dev_info.pci_info.bus_no = softc->bus;
+	dev_info.pci_info.device_no = softc->slot;
+	dev_info.pci_info.function_no = softc->function;
+	dev_info.pci_info.vendor_id = pci_get_vendor(softc->dev);
+	dev_info.pci_info.device_id = pci_get_device(softc->dev);
+	dev_info.pci_info.sub_system_vendor_id = pci_get_subvendor(softc->dev);
+	dev_info.pci_info.sub_system_device_id = pci_get_subdevice(softc->dev);
+	dev_info.pci_info.revision = pci_read_config(softc->dev, PCIR_REVID, 1);
+	dev_info.pci_info.chip_rev_id = (dev_info.pci_info.device_id << 16);
+	dev_info.pci_info.chip_rev_id |= dev_info.pci_info.revision;
+	if (pci_find_extcap(softc->dev, PCIZ_SERNUM, &dev_sn_offset)) {
+		device_printf(softc->dev, "%s:%d device serial number is not found"
+			      "or not supported\n", __FUNCTION__, __LINE__);
+	} else {
+		dev_sn_lo = pci_read_config(softc->dev, dev_sn_offset + 4, 4);
+		dev_sn_hi = pci_read_config(softc->dev, dev_sn_offset + 8, 4);
+		snprintf(dsn, sizeof(dsn), "%02x%02x%02x%02x%02x%02x%02x%02x",
+			 (dev_sn_lo & 0x000000FF),
+			 (dev_sn_lo >> 8) & 0x0000FF,
+			 (dev_sn_lo >> 16) & 0x00FF,
+			 (dev_sn_lo >> 24 ) & 0xFF,
+			 (dev_sn_hi & 0x000000FF),
+			 (dev_sn_hi >> 8) & 0x0000FF,
+			 (dev_sn_hi >> 16) & 0x00FF,
+			 (dev_sn_hi >> 24 ) & 0xFF);
+		strncpy(dev_info.nic_info.device_serial_number, dsn, sizeof(dsn));
+	}
+	
+	if_t ifp = iflib_get_ifp(softc->ctx);
+	dev_info.nic_info.mtu = ifp->if_mtu;
+	memcpy(dev_info.nic_info.mac, softc->func.mac_addr, ETHER_ADDR_LEN);
+	
+	if (pci_find_cap(softc->dev, PCIY_EXPRESS, &capreg)) {
+		device_printf(softc->dev, "%s:%d pci link capability is not found"
+			      "or not supported\n", __FUNCTION__, __LINE__);
+	} else {
+		lnk = pci_read_config(softc->dev, capreg + PCIER_LINK_STA, 2);
+		dev_info.nic_info.pci_link_speed = (lnk & PCIEM_LINK_STA_SPEED);
+		dev_info.nic_info.pci_link_width = (lnk & PCIEM_LINK_STA_WIDTH) >> 4;
+	}
+	
+	if (copyout(&dev_info, user_ptr, sizeof(dev_info))) {
+		device_printf(softc->dev, "%s:%d Failed to copy data to user\n",
+			      __FUNCTION__, __LINE__);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*
+ * IOCTL entry point.
+ */
+static int
+bnxt_mgmt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
+		struct thread *td)
+{
+	int ret = 0;
+	
+	switch(cmd) {
+	case BNXT_MGMT_OPCODE_GET_DEV_INFO:
+		ret = bnxt_mgmt_get_dev_info(dev, cmd, data, flag, td);
+		break;
+	case BNXT_MGMT_OPCODE_PASSTHROUGH_HWRM:
+		mtx_lock(&mgmt_lock);
+		ret = bnxt_mgmt_process_hwrm(dev, cmd, data, flag, td); 
+		mtx_unlock(&mgmt_lock);
+		break;
+	default:
+		printf("%s: Unknown command 0x%lx\n", DRIVER_NAME, cmd);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;		
+}
+
+static int
+bnxt_mgmt_close(struct cdev *dev, int flags, int devtype, struct thread *td)
+{
+	return (0);
+}
+
+static int
+bnxt_mgmt_open(struct cdev *dev, int flags, int devtype, struct thread *td)
+{
+	return (0);
+}
+
+DEV_MODULE(bnxt_mgmt, bnxt_mgmt_loader, NULL);
+
diff --git a/sys/dev/bnxt/bnxt_mgmt.h b/sys/dev/bnxt/bnxt_mgmt.h
new file mode 100644
index 000000000000..f130ad386809
--- /dev/null
+++ b/sys/dev/bnxt/bnxt_mgmt.h
@@ -0,0 +1,126 @@
+/*
+ * Broadcom NetXtreme-C/E network driver.
+ *
+ * Copyright (c) 2022 Broadcom, All Rights Reserved.
+ * The term Broadcom refers to Broadcom Limited and/or its subsidiaries
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "bnxt.h"
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/param.h>
+#include <sys/module.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+
+
+#define	DRIVER_NAME				"if_bnxt"
+
+#define	BNXT_MGMT_OPCODE_GET_DEV_INFO		0x80000000
+#define	BNXT_MGMT_OPCODE_PASSTHROUGH_HWRM	0x80000001
+
+#define BNXT_MGMT_MAX_HWRM_REQ_LENGTH		HWRM_MAX_REQ_LEN
+#define BNXT_MGMT_MAX_HWRM_RESP_LENGTH		(512)
+
+struct bnxt_nic_info {
+#define BNXT_MAX_STR 64
+	char dev_name[BNXT_MAX_STR];
+	char driver_version[BNXT_MAX_STR];
+	char driver_name[BNXT_MAX_STR];
+	char device_serial_number[64];
+	uint32_t mtu;
+	uint8_t mac[ETHER_ADDR_LEN];
+	uint32_t pci_link_speed;
+	uint32_t pci_link_width;
+	uint32_t rsvd[4];
+} __packed;
+
+struct bnxt_pci_info {
+        uint16_t domain_no;
+        uint16_t bus_no;
+        uint16_t device_no;
+        uint16_t function_no;
+        uint16_t vendor_id;
+        uint16_t device_id;
+        uint16_t sub_system_vendor_id;
+        uint16_t sub_system_device_id;
+        uint16_t revision;
+        uint32_t chip_rev_id;
+	uint32_t rsvd[2];
+} __packed;
+
+struct bnxt_dev_info {
+        struct bnxt_nic_info nic_info; 
+        struct bnxt_pci_info pci_info;
+} __packed;
+
+struct dma_info {
+        uint64_t data;
+        uint32_t length;
+        uint16_t offset;
+        uint8_t read_or_write;
+        uint8_t unused;
+};
+
+struct bnxt_mgmt_fw_msg {
+        uint64_t usr_req;
+        uint64_t usr_resp;
+        uint32_t len_req;
+        uint32_t len_resp;
+        uint32_t timeout;
+        uint32_t num_dma_indications;
+        struct dma_info dma[0];
+};
+
+struct bnxt_mgmt_generic_msg {
+        uint8_t key;
+#define BNXT_LFC_KEY_DOMAIN_NO  1
+        uint8_t reserved[3];
+        uint32_t value;
+};
+
+enum bnxt_mgmt_req_type {
+        BNXT_MGMT_NVM_GET_VAR_REQ = 1,
+        BNXT_MGMT_NVM_SET_VAR_REQ,
+        BNXT_MGMT_NVM_FLUSH_REQ,
+        BNXT_MGMT_GENERIC_HWRM_REQ,
+};
+
+struct bnxt_mgmt_req_hdr {
+        uint32_t ver;
+	uint32_t domain;
+        uint32_t bus;
+        uint32_t devfn;
+        enum bnxt_mgmt_req_type req_type;
+};
+
+struct bnxt_mgmt_req {
+        struct bnxt_mgmt_req_hdr hdr;
+        union {
+            uint64_t hreq;
+        } req;
+};
+
diff --git a/sys/dev/bnxt/if_bnxt.c b/sys/dev/bnxt/if_bnxt.c
index 8b26b4d64436..d6cb4d613c96 100644
--- a/sys/dev/bnxt/if_bnxt.c
+++ b/sys/dev/bnxt/if_bnxt.c
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
 #include "bnxt_ioctl.h"
 #include "bnxt_sysctl.h"
 #include "hsi_struct_def.h"
+#include "bnxt_mgmt.h"
 
 /*
  * PCI Device ID Table
@@ -159,6 +160,9 @@ static pci_vendor_info_t bnxt_vendor_info_array[] =
  * Function prototypes
  */
 
+SLIST_HEAD(softc_list, bnxt_softc_list) pf_list;
+int bnxt_num_pfs = 0;
+
 static void *bnxt_register(device_t dev);
 
 /* Soft queue setup and teardown */
@@ -297,7 +301,7 @@ static driver_t bnxt_iflib_driver = {
  * iflib shared context
  */
 
-#define BNXT_DRIVER_VERSION	"1.0.0.2"
+#define BNXT_DRIVER_VERSION	"2.20.0.1"
 char bnxt_driver_version[] = BNXT_DRIVER_VERSION;
 extern struct if_txrx bnxt_txrx;
 static struct if_shared_ctx bnxt_sctx_init = {
@@ -1203,6 +1207,28 @@ static void bnxt_thor_db_nq(void *db_ptr, bool enable_irq)
 			BUS_SPACE_BARRIER_WRITE);
 }
 
+struct bnxt_softc *bnxt_find_dev(uint32_t domain, uint32_t bus, uint32_t dev_fn, char *dev_name)
+{
+	struct bnxt_softc_list *sc = NULL;
+
+	SLIST_FOREACH(sc, &pf_list, next) {
+		/* get the softc reference based on device name */
+		if (dev_name && !strncmp(dev_name, iflib_get_ifp(sc->softc->ctx)->if_xname, BNXT_MAX_STR)) {
+			return sc->softc;
+		}
+		/* get the softc reference based on domain,bus,device,function */
+		if (!dev_name &&
+		    (domain == sc->softc->domain) &&
+		    (bus == sc->softc->bus) &&
+		    (dev_fn == sc->softc->dev_fn)) {
+			return sc->softc;
+
+		}
+	}
+
+	return NULL;
+}
+
 /* Device setup and teardown */
 static int
 bnxt_attach_pre(if_ctx_t ctx)
@@ -1242,6 +1268,19 @@ bnxt_attach_pre(if_ctx_t ctx)
 		break;
 	}
 
+#define PCI_DEVFN(device, func) ((((device) & 0x1f) << 3) | ((func) & 0x07))
+	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);
+
+	if (bnxt_num_pfs == 0)
+		  SLIST_INIT(&pf_list);
+	bnxt_num_pfs++;
+	softc->list.softc = softc;
+	SLIST_INSERT_HEAD(&pf_list, &softc->list, next);
+
 	pci_enable_busmaster(softc->dev);
 
 	if (bnxt_pci_mapping(softc))
@@ -1575,6 +1614,8 @@ bnxt_detach(if_ctx_t ctx)
 	struct bnxt_vlan_tag *tmp;
 	int i;
 
+	SLIST_REMOVE(&pf_list, &softc->list, bnxt_softc_list, next);
+	bnxt_num_pfs--;
 	bnxt_wol_config(ctx);
 	bnxt_do_disable_intr(&softc->def_cp_ring);
 	bnxt_free_sysctl_ctx(softc);
diff --git a/sys/modules/bnxt/Makefile b/sys/modules/bnxt/Makefile
index 861a0b4c4d4a..f27e9934034e 100644
--- a/sys/modules/bnxt/Makefile
+++ b/sys/modules/bnxt/Makefile
@@ -6,8 +6,9 @@ KMOD    = if_bnxt
 SRCS    = device_if.h bus_if.h pci_if.h pci_iov_if.h ifdi_if.h
 SRCS	+= opt_inet.h opt_inet6.h opt_rss.h
 SRCS    += bnxt_txrx.c if_bnxt.c
-SRCS	+= bnxt_hwrm.c bnxt_hwrm.h
-SRCS	+= bnxt_sysctl.c bnxt_sysctl.h
+SRCS	+= bnxt_hwrm.c
+SRCS	+= bnxt_sysctl.c
+SRCS	+= bnxt_mgmt.c
 
 CFLAGS+= -DIFLIB
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202211042255.2A4MtwaN032819>