]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/bng_re: Register and get the resources from bnge driver
authorSiva Reddy Kallam <siva.kallam@broadcom.com>
Mon, 17 Nov 2025 17:11:21 +0000 (17:11 +0000)
committerLeon Romanovsky <leon@kernel.org>
Mon, 24 Nov 2025 07:58:29 +0000 (02:58 -0500)
Register and get the basic required resources from bnge driver.

Signed-off-by: Siva Reddy Kallam <siva.kallam@broadcom.com>
Link: https://patch.msgid.link/20251117171136.128193-4-siva.kallam@broadcom.com
Reviewed-by: Usman Ansari <usman.ansari@broadcom.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/hw/bng_re/bng_dev.c
drivers/infiniband/hw/bng_re/bng_re.h
drivers/infiniband/hw/bng_re/bng_res.h [new file with mode: 0644]

index a4388a87d8288f65155f4ac19033b20258a7633e..77d33c8758371716f3700090b32c7ef7b034a8b1 100644 (file)
@@ -7,8 +7,10 @@
 
 #include <rdma/ib_verbs.h>
 
+#include "bng_res.h"
 #include "bng_re.h"
 #include "bnge.h"
+#include "bnge_hwrm.h"
 #include "bnge_auxr.h"
 
 MODULE_AUTHOR("Siva Reddy Kallam <siva.kallam@broadcom.com>");
@@ -36,6 +38,144 @@ static struct bng_re_dev *bng_re_dev_add(struct auxiliary_device *adev,
        return rdev;
 }
 
+
+static int bng_re_register_netdev(struct bng_re_dev *rdev)
+{
+       struct bnge_auxr_dev *aux_dev;
+
+       aux_dev = rdev->aux_dev;
+       return bnge_register_dev(aux_dev, rdev->adev);
+}
+
+static void bng_re_destroy_chip_ctx(struct bng_re_dev *rdev)
+{
+       struct bng_re_chip_ctx *chip_ctx;
+
+       if (!rdev->chip_ctx)
+               return;
+
+       chip_ctx = rdev->chip_ctx;
+       rdev->chip_ctx = NULL;
+       kfree(chip_ctx);
+}
+
+static int bng_re_setup_chip_ctx(struct bng_re_dev *rdev)
+{
+       struct bng_re_chip_ctx *chip_ctx;
+       struct bnge_auxr_dev *aux_dev;
+
+       aux_dev = rdev->aux_dev;
+
+       chip_ctx = kzalloc(sizeof(*chip_ctx), GFP_KERNEL);
+       if (!chip_ctx)
+               return -ENOMEM;
+       chip_ctx->chip_num = aux_dev->chip_num;
+       chip_ctx->hw_stats_size = aux_dev->hw_ring_stats_size;
+
+       rdev->chip_ctx = chip_ctx;
+
+       return 0;
+}
+
+static void bng_re_init_hwrm_hdr(struct input *hdr, u16 opcd)
+{
+       hdr->req_type = cpu_to_le16(opcd);
+       hdr->cmpl_ring = cpu_to_le16(-1);
+       hdr->target_id = cpu_to_le16(-1);
+}
+
+static void bng_re_fill_fw_msg(struct bnge_fw_msg *fw_msg, void *msg,
+                              int msg_len, void *resp, int resp_max_len,
+                              int timeout)
+{
+       fw_msg->msg = msg;
+       fw_msg->msg_len = msg_len;
+       fw_msg->resp = resp;
+       fw_msg->resp_max_len = resp_max_len;
+       fw_msg->timeout = timeout;
+}
+
+static void bng_re_query_hwrm_version(struct bng_re_dev *rdev)
+{
+       struct bnge_auxr_dev *aux_dev = rdev->aux_dev;
+       struct hwrm_ver_get_output ver_get_resp = {};
+       struct hwrm_ver_get_input ver_get_req = {};
+       struct bng_re_chip_ctx *cctx;
+       struct bnge_fw_msg fw_msg = {};
+       int rc;
+
+       bng_re_init_hwrm_hdr((void *)&ver_get_req, HWRM_VER_GET);
+       ver_get_req.hwrm_intf_maj = HWRM_VERSION_MAJOR;
+       ver_get_req.hwrm_intf_min = HWRM_VERSION_MINOR;
+       ver_get_req.hwrm_intf_upd = HWRM_VERSION_UPDATE;
+       bng_re_fill_fw_msg(&fw_msg, (void *)&ver_get_req, sizeof(ver_get_req),
+                           (void *)&ver_get_resp, sizeof(ver_get_resp),
+                           BNGE_DFLT_HWRM_CMD_TIMEOUT);
+       rc = bnge_send_msg(aux_dev, &fw_msg);
+       if (rc) {
+               ibdev_err(&rdev->ibdev, "Failed to query HW version, rc = 0x%x",
+                         rc);
+               return;
+       }
+
+       cctx = rdev->chip_ctx;
+       cctx->hwrm_intf_ver =
+               (u64)le16_to_cpu(ver_get_resp.hwrm_intf_major) << 48 |
+               (u64)le16_to_cpu(ver_get_resp.hwrm_intf_minor) << 32 |
+               (u64)le16_to_cpu(ver_get_resp.hwrm_intf_build) << 16 |
+               le16_to_cpu(ver_get_resp.hwrm_intf_patch);
+
+       cctx->hwrm_cmd_max_timeout = le16_to_cpu(ver_get_resp.max_req_timeout);
+
+       if (!cctx->hwrm_cmd_max_timeout)
+               cctx->hwrm_cmd_max_timeout = BNG_ROCE_FW_MAX_TIMEOUT;
+}
+
+static int bng_re_dev_init(struct bng_re_dev *rdev)
+{
+       int rc;
+
+       /* Registered a new RoCE device instance to netdev */
+       rc = bng_re_register_netdev(rdev);
+       if (rc) {
+               ibdev_err(&rdev->ibdev,
+                               "Failed to register with netedev: %#x\n", rc);
+               return -EINVAL;
+       }
+
+       set_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
+
+       if (rdev->aux_dev->auxr_info->msix_requested < BNG_RE_MIN_MSIX) {
+               ibdev_err(&rdev->ibdev,
+                         "RoCE requires minimum 2 MSI-X vectors, but only %d reserved\n",
+                         rdev->aux_dev->auxr_info->msix_requested);
+               bnge_unregister_dev(rdev->aux_dev);
+               clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
+               return -EINVAL;
+       }
+       ibdev_dbg(&rdev->ibdev, "Got %d MSI-X vectors\n",
+                 rdev->aux_dev->auxr_info->msix_requested);
+
+       rc = bng_re_setup_chip_ctx(rdev);
+       if (rc) {
+               bnge_unregister_dev(rdev->aux_dev);
+               clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
+               ibdev_err(&rdev->ibdev, "Failed to get chip context\n");
+               return -EINVAL;
+       }
+
+       bng_re_query_hwrm_version(rdev);
+
+       return 0;
+}
+
+static void bng_re_dev_uninit(struct bng_re_dev *rdev)
+{
+       bng_re_destroy_chip_ctx(rdev);
+       if (test_and_clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags))
+               bnge_unregister_dev(rdev->aux_dev);
+}
+
 static int bng_re_add_device(struct auxiliary_device *adev)
 {
        struct bnge_auxr_priv *auxr_priv =
@@ -54,7 +194,14 @@ static int bng_re_add_device(struct auxiliary_device *adev)
 
        dev_info->rdev = rdev;
 
+       rc = bng_re_dev_init(rdev);
+       if (rc)
+               goto re_dev_dealloc;
+
        return 0;
+
+re_dev_dealloc:
+       ib_dealloc_device(&rdev->ibdev);
 exit:
        return rc;
 }
@@ -63,6 +210,7 @@ exit:
 static void bng_re_remove_device(struct bng_re_dev *rdev,
                                 struct auxiliary_device *aux_dev)
 {
+       bng_re_dev_uninit(rdev);
        ib_dealloc_device(&rdev->ibdev);
 }
 
@@ -86,6 +234,7 @@ static int bng_re_probe(struct auxiliary_device *adev,
        rc = bng_re_add_device(adev);
        if (rc)
                kfree(en_info);
+
        return rc;
 }
 
index 5341ffe22724bde3018cc130988cbdca0175607e..f31eec133fa10928c882667f5fa7dc084a246561 100644 (file)
@@ -10,6 +10,8 @@
 
 #define        rdev_to_dev(rdev)       ((rdev) ? (&(rdev)->ibdev.dev) : NULL)
 
+#define BNG_RE_MIN_MSIX                2
+
 struct bng_re_en_dev_info {
        struct bng_re_dev *rdev;
        struct bnge_auxr_dev *auxr_dev;
@@ -17,9 +19,12 @@ struct bng_re_en_dev_info {
 
 struct bng_re_dev {
        struct ib_device                ibdev;
+       unsigned long                   flags;
+#define BNG_RE_FLAG_NETDEV_REGISTERED          0
        struct net_device               *netdev;
        struct auxiliary_device         *adev;
        struct bnge_auxr_dev            *aux_dev;
+       struct bng_re_chip_ctx          *chip_ctx;
        int                             fn_id;
 };
 
diff --git a/drivers/infiniband/hw/bng_re/bng_res.h b/drivers/infiniband/hw/bng_re/bng_res.h
new file mode 100644 (file)
index 0000000..d648334
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (c) 2025 Broadcom.
+
+#ifndef __BNG_RES_H__
+#define __BNG_RES_H__
+
+#define BNG_ROCE_FW_MAX_TIMEOUT        60
+
+struct bng_re_chip_ctx {
+       u16     chip_num;
+       u16     hw_stats_size;
+       u64     hwrm_intf_ver;
+       u16     hwrm_cmd_max_timeout;
+};
+
+#endif