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
This commit is contained in:
Sumit Saxena 2022-11-04 16:40:29 -06:00 committed by Warner Losh
parent 2ed061f08d
commit 58d84ef870
8 changed files with 592 additions and 6 deletions

View File

@ -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

View File

@ -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 */

View File

@ -540,6 +540,37 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt_softc *softc, bool all)
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))

View File

@ -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

373
sys/dev/bnxt/bnxt_mgmt.c Normal file
View File

@ -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);

126
sys/dev/bnxt/bnxt_mgmt.h Normal file
View File

@ -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;
};

View File

@ -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);

View File

@ -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