git: 9d87ca8b9f60 - main - if_bnxt: Add support for HWRM passthrough with multiple DMA buffers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 15 Jun 2026 11:35:38 UTC
The branch main has been updated by ssaxena:
URL: https://cgit.FreeBSD.org/src/commit/?id=9d87ca8b9f60bdec0bbc1733920df250a08beb0c
commit 9d87ca8b9f60bdec0bbc1733920df250a08beb0c
Author: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
AuthorDate: 2026-06-15 09:49:40 +0000
Commit: Sumit Saxena <ssaxena@FreeBSD.org>
CommitDate: 2026-06-15 11:34:12 +0000
if_bnxt: Add support for HWRM passthrough with multiple DMA buffers
Added support for HWRM passthrough commands with multiple DMA buffers.
Also, changed the mgmt_lock to sleepable exclusive lock.
MFC after: 2 weeks
Reviewed by: gallatin, ssaxena
Differential Revision: https://reviews.freebsd.org/D56686
---
sys/dev/bnxt/bnxt_en/bnxt.h | 3 ++
sys/dev/bnxt/bnxt_en/bnxt_mgmt.c | 96 ++++++++++++++++++++++++----------------
2 files changed, 60 insertions(+), 39 deletions(-)
diff --git a/sys/dev/bnxt/bnxt_en/bnxt.h b/sys/dev/bnxt/bnxt_en/bnxt.h
index dfbf1d8f03d3..7e58139f1ab6 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt.h
+++ b/sys/dev/bnxt/bnxt_en/bnxt.h
@@ -1397,6 +1397,9 @@ struct bnxt_softc {
struct mtx log_lock; /* logging ops lock */
struct callout time_sync_callout;
struct bnxt_bs_trace_info bs_trace[BNXT_CTX_TRACE_BUF_COUNT];
+
+#define MAX_NUM_DMA_INDICATIONS 10
+ struct iflib_dma_info mgmt_dma_data[MAX_NUM_DMA_INDICATIONS];
};
struct bnxt_filter_info {
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c b/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c
index 0a12bea17ead..edf50ac1432f 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c
+++ b/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c
@@ -52,7 +52,7 @@ static struct cdevsw bnxt_mgmt_cdevsw = {
/* Global vars */
static struct cdev *bnxt_mgmt_dev;
-struct mtx mgmt_lock;
+struct sx mgmt_lock;
MALLOC_DEFINE(M_BNXT, "bnxt_mgmt_buffer", "buffer for bnxt_mgmt module");
@@ -439,11 +439,11 @@ bnxt_mgmt_loader(struct module *m, int what, void *arg)
return (error);
}
- mtx_init(&mgmt_lock, "BNXT MGMT Lock", NULL, MTX_DEF);
+ sx_init(&mgmt_lock, "BNXT MGMT Lock");
break;
case MOD_UNLOAD:
- mtx_destroy(&mgmt_lock);
+ sx_destroy(&mgmt_lock);
destroy_dev(bnxt_mgmt_dev);
break;
default:
@@ -526,9 +526,8 @@ bnxt_mgmt_process_hwrm(struct cdev *dev, u_long cmd, caddr_t data,
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;
+ int ret = 0, num_allocated = 0, i;
uint16_t num_ind = 0;
memcpy(&user_ptr, data, sizeof(user_ptr));
@@ -558,9 +557,10 @@ bnxt_mgmt_process_hwrm(struct cdev *dev, u_long cmd, caddr_t data,
return -EINVAL;
}
- if (msg_temp.num_dma_indications > 1) {
+ if (msg_temp.num_dma_indications > MAX_NUM_DMA_INDICATIONS) {
device_printf(softc->dev, "%s:%d Max num_dma_indications "
- "supported is 1\n", __func__, __LINE__);
+ "supported is %d\n", __func__, __LINE__,
+ MAX_NUM_DMA_INDICATIONS);
return -EINVAL;
}
@@ -594,43 +594,58 @@ bnxt_mgmt_process_hwrm(struct cdev *dev, u_long cmd, caddr_t data,
}
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", __func__,
- __LINE__, ret);
- ret = -ENOMEM;
- goto end;
- }
+ for (i = 0; i < num_ind; i++) {
- 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", __func__,
- __LINE__);
- ret = -EFAULT;
+ if (msg->dma[i].length == 0) {
+ device_printf(softc->dev,
+ "%s:%d i:%d Invalid DMA memory length\n",
+ __func__, __LINE__, i);
+ ret = -ENOMEM;
+ goto end;
+ }
+
+ memset(&softc->mgmt_dma_data[i], 0, sizeof(struct iflib_dma_info));
+
+ ret = iflib_dma_alloc(softc->ctx, msg->dma[i].length, &softc->mgmt_dma_data[i],
+ BUS_DMA_WAITOK);
+ if (ret) {
+ device_printf(softc->dev,
+ "%s:%d iflib_dma_alloc failed with ret = 0x%x\n",
+ __func__, __LINE__, ret);
+ ret = -ENOMEM;
goto end;
}
+
+ num_allocated++;
+ if (!(msg->dma[i].read_or_write)) {
+ if (copyin((void *)msg->dma[i].data,
+ softc->mgmt_dma_data[i].idi_vaddr,
+ msg->dma[i].length)) {
+ device_printf(softc->dev,
+ "%s:%d Failed to copy data from user\n",
+ __func__, __LINE__);
+ ret = -EFAULT;
+ goto end;
+ }
+ }
+ dma_ptr = (void *) ((uint64_t) req + msg->dma[i].offset);
+ dmap = dma_ptr;
+ *dmap = htole64(softc->mgmt_dma_data[i].idi_paddr);
}
- 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)
+ 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", __func__, __LINE__);
+ for (i = 0; i < num_ind; i++) {
+ if ((msg->dma[i].read_or_write)) {
+ if (copyout(softc->mgmt_dma_data[i].idi_vaddr,
+ (void *)msg->dma[i].data,
+ msg->dma[i].length)) {
+ device_printf(softc->dev,
+ "%s:%d Failed to copy data to user\n",
+ __func__, __LINE__);
ret = -EFAULT;
goto end;
}
@@ -651,8 +666,11 @@ end:
free(resp, M_BNXT);
if (msg2)
free(msg2, M_BNXT);
- if (dma_data.idi_paddr)
- iflib_dma_free(&dma_data);
+ if (num_allocated) {
+ for (i = 0; i < num_allocated; i++)
+ if (softc->mgmt_dma_data[i].idi_paddr)
+ iflib_dma_free(&softc->mgmt_dma_data[i]);
+ }
return ret;
}
@@ -828,9 +846,9 @@ bnxt_mgmt_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
break;
case IO_BNXT_MGMT_OPCODE_PASSTHROUGH_HWRM:
case IOW_BNXT_MGMT_OPCODE_PASSTHROUGH_HWRM:
- mtx_lock(&mgmt_lock);
+ sx_xlock(&mgmt_lock);
ret = bnxt_mgmt_process_hwrm(dev, cmd, data, flag, td);
- mtx_unlock(&mgmt_lock);
+ sx_xunlock(&mgmt_lock);
break;
case IO_BNXT_MGMT_OPCODE_DCB_OPS:
case IOW_BNXT_MGMT_OPCODE_DCB_OPS: