[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250923121704.00000eb7@huawei.com>
Date: Tue, 23 Sep 2025 12:17:04 +0100
From: Jonathan Cameron <jonathan.cameron@...wei.com>
To: Pavan Chebbi <pavan.chebbi@...adcom.com>
CC: <jgg@...pe.ca>, <michael.chan@...adcom.com>, <dave.jiang@...el.com>,
<saeedm@...dia.com>, <davem@...emloft.net>, <corbet@....net>,
<edumazet@...gle.com>, <gospo@...adcom.com>, <kuba@...nel.org>,
<netdev@...r.kernel.org>, <pabeni@...hat.com>, <andrew+netdev@...n.ch>,
<selvin.xavier@...adcom.com>, <leon@...nel.org>,
<kalesh-anakkur.purayil@...adcom.com>
Subject: Re: [PATCH net-next v2 5/6] bnxt_fwctl: Add bnxt fwctl device
On Tue, 23 Sep 2025 02:58:24 -0700
Pavan Chebbi <pavan.chebbi@...adcom.com> wrote:
> Create bnxt_fwctl device. This will bind to bnxt's aux device.
> On the upper edge, it will register with the fwctl subsystem.
> It will make use of bnxt's ULP functions to send FW commands.
>
> Reviewed-by: Andy Gospodarek <gospo@...adcom.com>
> Signed-off-by: Pavan Chebbi <pavan.chebbi@...adcom.com>
I'm failing to find where this driver applies the fwctl_rpc_scope
to commands issued. I suppose maybe they are all entirely safe
non invasive requests for data?
That scope stuff is probably the most important thing that fwctl
provides so all drivers need to deal with it.
Thanks,
Jonathan
> --- /dev/null
> +++ b/drivers/fwctl/bnxt/main.c
> @@ -0,0 +1,297 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2025, Broadcom Corporation
> + *
This blank line doesn't add anything.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/auxiliary_bus.h>
> +#include <linux/slab.h>
> +#include <linux/pci.h>
Is there anything pci specific in here? I'd check all the includes
to ensure they follow (approx) include what you used iwyu principles.
> +#include <linux/fwctl.h>
> +#include <uapi/fwctl/fwctl.h>
> +#include <uapi/fwctl/bnxt.h>
> +#include <linux/bnxt/common.h>
> +#include <linux/bnxt/ulp.h>
> +static bool bnxtctl_validate_rpc(struct bnxt_en_dev *edev,
> + struct bnxt_fw_msg *hwrm_in)
> +{
> + struct input *req = (struct input *)hwrm_in->msg;
> +
> + mutex_lock(&edev->en_dev_lock);
Neater if you use guard()
> + if (edev->flags & BNXT_EN_FLAG_ULP_STOPPED) {
> + mutex_unlock(&edev->en_dev_lock);
> + return false;
> + }
> + mutex_unlock(&edev->en_dev_lock);
> +
> + if (le16_to_cpu(req->req_type) <= HWRM_LAST)
> + return true;
> +
> + return false;
I was kind of expecting something called validate_rpc to do
the scope checks that we see in other drivers.
e.g. mlx5ctl_validate_rpc()
> +}
> +
> +static void *bnxtctl_fw_rpc(struct fwctl_uctx *uctx,
> + enum fwctl_rpc_scope scope,
> + void *in, size_t in_len, size_t *out_len)
> +{
> + struct bnxtctl_dev *bnxtctl =
> + container_of(uctx->fwctl, struct bnxtctl_dev, fwctl);
> + struct bnxt_aux_priv *bnxt_aux_priv = bnxtctl->aux_priv;
> + struct fwctl_dma_info_bnxt *dma_buf = NULL;
> + struct device *dev = &uctx->fwctl->dev;
> + struct fwctl_rpc_bnxt *msg = in;
> + struct bnxt_fw_msg rpc_in;
> + int i, rc, err = 0;
> + int dma_buf_size;
> +
> + rpc_in.msg = kzalloc(msg->req_len, GFP_KERNEL);
> + if (!rpc_in.msg) {
> + err = -ENOMEM;
> + goto err_out;
Nothing to clean up at this point, so returning here would be simpler.
> + }
> + if (copy_from_user(rpc_in.msg, u64_to_user_ptr(msg->req),
> + msg->req_len)) {
> + dev_dbg(dev, "Failed to copy in_payload from user\n");
> + err = -EFAULT;
> + goto err_out;
> + }
> +
> + if (!bnxtctl_validate_rpc(bnxt_aux_priv->edev, &rpc_in))
> + return ERR_PTR(-EPERM);
> +
> + rpc_in.msg_len = msg->req_len;
> + rpc_in.resp = kzalloc(*out_len, GFP_KERNEL);
> + if (!rpc_in.resp) {
> + err = -ENOMEM;
> + goto err_out;
> + }
> +
> + rpc_in.resp_max_len = *out_len;
> + if (!msg->timeout)
> + rpc_in.timeout = DFLT_HWRM_CMD_TIMEOUT;
> + else
> + rpc_in.timeout = msg->timeout;
> +
> + if (msg->num_dma) {
> + if (msg->num_dma > MAX_NUM_DMA_INDICATIONS) {
> + dev_err(dev, "DMA buffers exceed the number supported\n");
> + err = -EINVAL;
> + goto err_out;
> + }
> + dma_buf_size = msg->num_dma * sizeof(*dma_buf);
kcalloc probably more appropriate given it looks like an array.
> + dma_buf = kzalloc(dma_buf_size, GFP_KERNEL);
> + if (!dma_buf) {
> + dev_err(dev, "Failed to allocate dma buffers\n");
> + err = -ENOMEM;
General (growing) convention is don't bother printing messages on memory
failure as the allocator is very noisy if this happen away.
> + goto err_out;
> + }
> +
> + if (copy_from_user(dma_buf, u64_to_user_ptr(msg->payload),
> + dma_buf_size)) {
> + dev_dbg(dev, "Failed to copy payload from user\n");
> + err = -EFAULT;
> + goto err_out;
> + }
> +
> + rc = bnxt_fw_setup_input_dma(bnxtctl, dev, msg->num_dma,
> + dma_buf, &rpc_in);
> + if (rc) {
> + err = -EIO;
> + goto err_out;
> + }
> + }
> +
> + rc = bnxt_send_msg(bnxt_aux_priv->edev, &rpc_in);
> + if (rc) {
> + err = -EIO;
> + goto err_out;
> + }
> +
> + for (i = 0; i < msg->num_dma; i++) {
> + if (dma_buf[i].read_from_device) {
> + if (copy_to_user(u64_to_user_ptr(dma_buf[i].data),
> + bnxtctl->dma_virt_addr[i],
> + dma_buf[i].len)) {
> + dev_dbg(dev, "Failed to copy resp to user\n");
> + err = -EFAULT;
> + }
> + }
> + }
> + for (i = 0; i < msg->num_dma; i++)
> + dma_free_coherent(dev->parent, dma_buf[i].len,
> + bnxtctl->dma_virt_addr[i],
> + bnxtctl->dma_addr[i]);
> +
> +err_out:
> + kfree(dma_buf);
> + kfree(rpc_in.msg);
> +
> + if (err)
> + return ERR_PTR(err);
> +
> + return rpc_in.resp;
> +}
> +
> +static const struct fwctl_ops bnxtctl_ops = {
> + .device_type = FWCTL_DEVICE_TYPE_BNXT,
> + .uctx_size = sizeof(struct bnxtctl_uctx),
> + .open_uctx = bnxtctl_open_uctx,
> + .close_uctx = bnxtctl_close_uctx,
> + .info = bnxtctl_info,
> + .fw_rpc = bnxtctl_fw_rpc,
> +};
...
> +static const struct auxiliary_device_id bnxtctl_id_table[] = {
> + { .name = "bnxt_en.fwctl", },
> + {},
No need for trailing comma.
> +};
> +MODULE_DEVICE_TABLE(auxiliary, bnxtctl_id_table);
> diff --git a/include/uapi/fwctl/bnxt.h b/include/uapi/fwctl/bnxt.h
> new file mode 100644
> index 000000000000..cf8f2b80f3de
> --- /dev/null
> +++ b/include/uapi/fwctl/bnxt.h
> @@ -0,0 +1,63 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +/*
> + * Copyright (c) 2025, Broadcom Corporation
> + *
Trivial, blank line here adds nothing useful.
> + */
> +
> +#ifndef _UAPI_FWCTL_BNXT_H_
> +#define _UAPI_FWCTL_BNXT_H_
> +
> +#include <linux/types.h>
> +
> +#define MAX_DMA_MEM_SIZE 0x10000 /*64K*/
> +#define DFLT_HWRM_CMD_TIMEOUT 500
Powered by blists - more mailing lists