]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/bnxt_re: Move the UAPI methods to a dedicated file
authorKalesh AP <kalesh-anakkur.purayil@broadcom.com>
Mon, 2 Mar 2026 11:00:31 +0000 (16:30 +0530)
committerJason Gunthorpe <jgg@nvidia.com>
Sun, 8 Mar 2026 10:20:25 +0000 (06:20 -0400)
This is in preparation for upcoming patches in the series.
Driver has to support additional UAPIs for some applications.
Moving current UAPI implementation to a new file, uapi.c.

Link: https://patch.msgid.link/r/20260302110036.36387-2-sriharsha.basavapatna@broadcom.com
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/bnxt_re/Makefile
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/ib_verbs.h
drivers/infiniband/hw/bnxt_re/uapi.c [new file with mode: 0644]

index f63417d2ccc644fc8e8403be664bc6eb5b9604b1..1533c079c9da17fafc97d50153e3ebda43eb2675 100644 (file)
@@ -5,4 +5,4 @@ obj-$(CONFIG_INFINIBAND_BNXT_RE) += bnxt_re.o
 bnxt_re-y := main.o ib_verbs.o \
             qplib_res.o qplib_rcfw.o   \
             qplib_sp.o qplib_fp.o  hw_counters.o       \
-            debugfs.o
+            debugfs.o uapi.o
index 62286a06db81681557356cff926a0c52989230b1..167fe414329d89c76d9c9963b924d9aef8f27393 100644 (file)
@@ -642,7 +642,7 @@ fail:
        return rc;
 }
 
-static struct bnxt_re_user_mmap_entry*
+struct bnxt_re_user_mmap_entry*
 bnxt_re_mmap_entry_insert(struct bnxt_re_ucontext *uctx, u64 mem_offset,
                          enum bnxt_re_mmap_flag mmap_flag, u64 *offset)
 {
@@ -4609,32 +4609,6 @@ int bnxt_re_destroy_flow(struct ib_flow *flow_id)
        return rc;
 }
 
-static struct bnxt_re_cq *bnxt_re_search_for_cq(struct bnxt_re_dev *rdev, u32 cq_id)
-{
-       struct bnxt_re_cq *cq = NULL, *tmp_cq;
-
-       hash_for_each_possible(rdev->cq_hash, tmp_cq, hash_entry, cq_id) {
-               if (tmp_cq->qplib_cq.id == cq_id) {
-                       cq = tmp_cq;
-                       break;
-               }
-       }
-       return cq;
-}
-
-static struct bnxt_re_srq *bnxt_re_search_for_srq(struct bnxt_re_dev *rdev, u32 srq_id)
-{
-       struct bnxt_re_srq *srq = NULL, *tmp_srq;
-
-       hash_for_each_possible(rdev->srq_hash, tmp_srq, hash_entry, srq_id) {
-               if (tmp_srq->qplib_srq.id == srq_id) {
-                       srq = tmp_srq;
-                       break;
-               }
-       }
-       return srq;
-}
-
 /* Helper function to mmap the virtual memory from user app */
 int bnxt_re_mmap(struct ib_ucontext *ib_uctx, struct vm_area_struct *vma)
 {
@@ -4737,280 +4711,3 @@ int bnxt_re_process_mad(struct ib_device *ibdev, int mad_flags,
        ret |= IB_MAD_RESULT_REPLY;
        return ret;
 }
-
-static int UVERBS_HANDLER(BNXT_RE_METHOD_NOTIFY_DRV)(struct uverbs_attr_bundle *attrs)
-{
-       struct bnxt_re_ucontext *uctx;
-
-       uctx = container_of(ib_uverbs_get_ucontext(attrs), struct bnxt_re_ucontext, ib_uctx);
-       bnxt_re_pacing_alert(uctx->rdev);
-       return 0;
-}
-
-static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *attrs)
-{
-       struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, BNXT_RE_ALLOC_PAGE_HANDLE);
-       enum bnxt_re_alloc_page_type alloc_type;
-       struct bnxt_re_user_mmap_entry *entry;
-       enum bnxt_re_mmap_flag mmap_flag;
-       struct bnxt_qplib_chip_ctx *cctx;
-       struct bnxt_re_ucontext *uctx;
-       struct bnxt_re_dev *rdev;
-       u64 mmap_offset;
-       u32 length;
-       u32 dpi;
-       u64 addr;
-       int err;
-
-       uctx = container_of(ib_uverbs_get_ucontext(attrs), struct bnxt_re_ucontext, ib_uctx);
-       if (IS_ERR(uctx))
-               return PTR_ERR(uctx);
-
-       err = uverbs_get_const(&alloc_type, attrs, BNXT_RE_ALLOC_PAGE_TYPE);
-       if (err)
-               return err;
-
-       rdev = uctx->rdev;
-       cctx = rdev->chip_ctx;
-
-       switch (alloc_type) {
-       case BNXT_RE_ALLOC_WC_PAGE:
-               if (cctx->modes.db_push)  {
-                       if (bnxt_qplib_alloc_dpi(&rdev->qplib_res, &uctx->wcdpi,
-                                                uctx, BNXT_QPLIB_DPI_TYPE_WC))
-                               return -ENOMEM;
-                       length = PAGE_SIZE;
-                       dpi = uctx->wcdpi.dpi;
-                       addr = (u64)uctx->wcdpi.umdbr;
-                       mmap_flag = BNXT_RE_MMAP_WC_DB;
-               } else {
-                       return -EINVAL;
-               }
-
-               break;
-       case BNXT_RE_ALLOC_DBR_BAR_PAGE:
-               length = PAGE_SIZE;
-               addr = (u64)rdev->pacing.dbr_bar_addr;
-               mmap_flag = BNXT_RE_MMAP_DBR_BAR;
-               break;
-
-       case BNXT_RE_ALLOC_DBR_PAGE:
-               length = PAGE_SIZE;
-               addr = (u64)rdev->pacing.dbr_page;
-               mmap_flag = BNXT_RE_MMAP_DBR_PAGE;
-               break;
-
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mmap_offset);
-       if (!entry)
-               return -ENOMEM;
-
-       uobj->object = entry;
-       uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_PAGE_HANDLE);
-       err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_MMAP_OFFSET,
-                            &mmap_offset, sizeof(mmap_offset));
-       if (err)
-               return err;
-
-       err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_MMAP_LENGTH,
-                            &length, sizeof(length));
-       if (err)
-               return err;
-
-       err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_DPI,
-                            &dpi, sizeof(dpi));
-       if (err)
-               return err;
-
-       return 0;
-}
-
-static int alloc_page_obj_cleanup(struct ib_uobject *uobject,
-                                 enum rdma_remove_reason why,
-                           struct uverbs_attr_bundle *attrs)
-{
-       struct  bnxt_re_user_mmap_entry *entry = uobject->object;
-       struct bnxt_re_ucontext *uctx = entry->uctx;
-
-       switch (entry->mmap_flag) {
-       case BNXT_RE_MMAP_WC_DB:
-               if (uctx && uctx->wcdpi.dbr) {
-                       struct bnxt_re_dev *rdev = uctx->rdev;
-
-                       bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->wcdpi);
-                       uctx->wcdpi.dbr = NULL;
-               }
-               break;
-       case BNXT_RE_MMAP_DBR_BAR:
-       case BNXT_RE_MMAP_DBR_PAGE:
-               break;
-       default:
-               goto exit;
-       }
-       rdma_user_mmap_entry_remove(&entry->rdma_entry);
-exit:
-       return 0;
-}
-
-DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_ALLOC_PAGE,
-                           UVERBS_ATTR_IDR(BNXT_RE_ALLOC_PAGE_HANDLE,
-                                           BNXT_RE_OBJECT_ALLOC_PAGE,
-                                           UVERBS_ACCESS_NEW,
-                                           UA_MANDATORY),
-                           UVERBS_ATTR_CONST_IN(BNXT_RE_ALLOC_PAGE_TYPE,
-                                                enum bnxt_re_alloc_page_type,
-                                                UA_MANDATORY),
-                           UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_MMAP_OFFSET,
-                                               UVERBS_ATTR_TYPE(u64),
-                                               UA_MANDATORY),
-                           UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_MMAP_LENGTH,
-                                               UVERBS_ATTR_TYPE(u32),
-                                               UA_MANDATORY),
-                           UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_DPI,
-                                               UVERBS_ATTR_TYPE(u32),
-                                               UA_MANDATORY));
-
-DECLARE_UVERBS_NAMED_METHOD_DESTROY(BNXT_RE_METHOD_DESTROY_PAGE,
-                                   UVERBS_ATTR_IDR(BNXT_RE_DESTROY_PAGE_HANDLE,
-                                                   BNXT_RE_OBJECT_ALLOC_PAGE,
-                                                   UVERBS_ACCESS_DESTROY,
-                                                   UA_MANDATORY));
-
-DECLARE_UVERBS_NAMED_OBJECT(BNXT_RE_OBJECT_ALLOC_PAGE,
-                           UVERBS_TYPE_ALLOC_IDR(alloc_page_obj_cleanup),
-                           &UVERBS_METHOD(BNXT_RE_METHOD_ALLOC_PAGE),
-                           &UVERBS_METHOD(BNXT_RE_METHOD_DESTROY_PAGE));
-
-DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_NOTIFY_DRV);
-
-DECLARE_UVERBS_GLOBAL_METHODS(BNXT_RE_OBJECT_NOTIFY_DRV,
-                             &UVERBS_METHOD(BNXT_RE_METHOD_NOTIFY_DRV));
-
-/* Toggle MEM */
-static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bundle *attrs)
-{
-       struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, BNXT_RE_TOGGLE_MEM_HANDLE);
-       enum bnxt_re_mmap_flag mmap_flag = BNXT_RE_MMAP_TOGGLE_PAGE;
-       enum bnxt_re_get_toggle_mem_type res_type;
-       struct bnxt_re_user_mmap_entry *entry;
-       struct bnxt_re_ucontext *uctx;
-       struct ib_ucontext *ib_uctx;
-       struct bnxt_re_dev *rdev;
-       struct bnxt_re_srq *srq;
-       u32 length = PAGE_SIZE;
-       struct bnxt_re_cq *cq;
-       u64 mem_offset;
-       u32 offset = 0;
-       u64 addr = 0;
-       u32 res_id;
-       int err;
-
-       ib_uctx = ib_uverbs_get_ucontext(attrs);
-       if (IS_ERR(ib_uctx))
-               return PTR_ERR(ib_uctx);
-
-       err = uverbs_get_const(&res_type, attrs, BNXT_RE_TOGGLE_MEM_TYPE);
-       if (err)
-               return err;
-
-       uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx);
-       rdev = uctx->rdev;
-       err = uverbs_copy_from(&res_id, attrs, BNXT_RE_TOGGLE_MEM_RES_ID);
-       if (err)
-               return err;
-
-       switch (res_type) {
-       case BNXT_RE_CQ_TOGGLE_MEM:
-               cq = bnxt_re_search_for_cq(rdev, res_id);
-               if (!cq)
-                       return -EINVAL;
-
-               addr = (u64)cq->uctx_cq_page;
-               break;
-       case BNXT_RE_SRQ_TOGGLE_MEM:
-               srq = bnxt_re_search_for_srq(rdev, res_id);
-               if (!srq)
-                       return -EINVAL;
-
-               addr = (u64)srq->uctx_srq_page;
-               break;
-
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mem_offset);
-       if (!entry)
-               return -ENOMEM;
-
-       uobj->object = entry;
-       uverbs_finalize_uobj_create(attrs, BNXT_RE_TOGGLE_MEM_HANDLE);
-       err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_PAGE,
-                            &mem_offset, sizeof(mem_offset));
-       if (err)
-               return err;
-
-       err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_LENGTH,
-                            &length, sizeof(length));
-       if (err)
-               return err;
-
-       err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_OFFSET,
-                            &offset, sizeof(offset));
-       if (err)
-               return err;
-
-       return 0;
-}
-
-static int get_toggle_mem_obj_cleanup(struct ib_uobject *uobject,
-                                     enum rdma_remove_reason why,
-                                     struct uverbs_attr_bundle *attrs)
-{
-       struct  bnxt_re_user_mmap_entry *entry = uobject->object;
-
-       rdma_user_mmap_entry_remove(&entry->rdma_entry);
-       return 0;
-}
-
-DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM,
-                           UVERBS_ATTR_IDR(BNXT_RE_TOGGLE_MEM_HANDLE,
-                                           BNXT_RE_OBJECT_GET_TOGGLE_MEM,
-                                           UVERBS_ACCESS_NEW,
-                                           UA_MANDATORY),
-                           UVERBS_ATTR_CONST_IN(BNXT_RE_TOGGLE_MEM_TYPE,
-                                                enum bnxt_re_get_toggle_mem_type,
-                                                UA_MANDATORY),
-                           UVERBS_ATTR_PTR_IN(BNXT_RE_TOGGLE_MEM_RES_ID,
-                                              UVERBS_ATTR_TYPE(u32),
-                                              UA_MANDATORY),
-                           UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_PAGE,
-                                               UVERBS_ATTR_TYPE(u64),
-                                               UA_MANDATORY),
-                           UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_OFFSET,
-                                               UVERBS_ATTR_TYPE(u32),
-                                               UA_MANDATORY),
-                           UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_LENGTH,
-                                               UVERBS_ATTR_TYPE(u32),
-                                               UA_MANDATORY));
-
-DECLARE_UVERBS_NAMED_METHOD_DESTROY(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM,
-                                   UVERBS_ATTR_IDR(BNXT_RE_RELEASE_TOGGLE_MEM_HANDLE,
-                                                   BNXT_RE_OBJECT_GET_TOGGLE_MEM,
-                                                   UVERBS_ACCESS_DESTROY,
-                                                   UA_MANDATORY));
-
-DECLARE_UVERBS_NAMED_OBJECT(BNXT_RE_OBJECT_GET_TOGGLE_MEM,
-                           UVERBS_TYPE_ALLOC_IDR(get_toggle_mem_obj_cleanup),
-                           &UVERBS_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM),
-                           &UVERBS_METHOD(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM));
-
-const struct uapi_definition bnxt_re_uapi_defs[] = {
-       UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_ALLOC_PAGE),
-       UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_NOTIFY_DRV),
-       UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_GET_TOGGLE_MEM),
-       {}
-};
index 76ba9ab04d5ce44f826793252bacd6645a02df94..a11f56730a31c5b8cabd90df2ae3ba760c65b8d1 100644 (file)
@@ -293,4 +293,7 @@ static inline u32 __to_ib_port_num(u16 port_id)
 
 unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp);
 void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags);
+struct bnxt_re_user_mmap_entry*
+bnxt_re_mmap_entry_insert(struct bnxt_re_ucontext *uctx, u64 mem_offset,
+                         enum bnxt_re_mmap_flag mmap_flag, u64 *offset);
 #endif /* __BNXT_RE_IB_VERBS_H__ */
diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
new file mode 100644 (file)
index 0000000..0145882
--- /dev/null
@@ -0,0 +1,339 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * Copyright (c) 2025, Broadcom. All rights reserved.  The term
+ * Broadcom refers to Broadcom Limited and/or its subsidiaries.
+ *
+ * Description: uapi interpreter
+ */
+
+#include <rdma/ib_addr.h>
+#include <rdma/uverbs_types.h>
+#include <rdma/uverbs_std_types.h>
+#include <rdma/ib_user_ioctl_cmds.h>
+#define UVERBS_MODULE_NAME bnxt_re
+#include <rdma/uverbs_named_ioctl.h>
+#include <rdma/bnxt_re-abi.h>
+
+#include "roce_hsi.h"
+#include "qplib_res.h"
+#include "qplib_sp.h"
+#include "qplib_fp.h"
+#include "qplib_rcfw.h"
+#include "bnxt_re.h"
+#include "ib_verbs.h"
+
+static struct bnxt_re_cq *bnxt_re_search_for_cq(struct bnxt_re_dev *rdev, u32 cq_id)
+{
+       struct bnxt_re_cq *cq = NULL, *tmp_cq;
+
+       hash_for_each_possible(rdev->cq_hash, tmp_cq, hash_entry, cq_id) {
+               if (tmp_cq->qplib_cq.id == cq_id) {
+                       cq = tmp_cq;
+                       break;
+               }
+       }
+       return cq;
+}
+
+static struct bnxt_re_srq *bnxt_re_search_for_srq(struct bnxt_re_dev *rdev, u32 srq_id)
+{
+       struct bnxt_re_srq *srq = NULL, *tmp_srq;
+
+       hash_for_each_possible(rdev->srq_hash, tmp_srq, hash_entry, srq_id) {
+               if (tmp_srq->qplib_srq.id == srq_id) {
+                       srq = tmp_srq;
+                       break;
+               }
+       }
+       return srq;
+}
+
+static int UVERBS_HANDLER(BNXT_RE_METHOD_NOTIFY_DRV)(struct uverbs_attr_bundle *attrs)
+{
+       struct bnxt_re_ucontext *uctx;
+       struct ib_ucontext *ib_uctx;
+
+       ib_uctx = ib_uverbs_get_ucontext(attrs);
+       if (IS_ERR(ib_uctx))
+               return PTR_ERR(ib_uctx);
+
+       uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx);
+       if (IS_ERR(uctx))
+               return PTR_ERR(uctx);
+
+       bnxt_re_pacing_alert(uctx->rdev);
+       return 0;
+}
+
+static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *attrs)
+{
+       struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, BNXT_RE_ALLOC_PAGE_HANDLE);
+       enum bnxt_re_alloc_page_type alloc_type;
+       struct bnxt_re_user_mmap_entry *entry;
+       enum bnxt_re_mmap_flag mmap_flag;
+       struct bnxt_qplib_chip_ctx *cctx;
+       struct bnxt_re_ucontext *uctx;
+       struct ib_ucontext *ib_uctx;
+       struct bnxt_re_dev *rdev;
+       u64 mmap_offset;
+       u32 length;
+       u32 dpi;
+       u64 addr;
+       int err;
+
+       ib_uctx = ib_uverbs_get_ucontext(attrs);
+       if (IS_ERR(ib_uctx))
+               return PTR_ERR(ib_uctx);
+
+       uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx);
+       if (IS_ERR(uctx))
+               return PTR_ERR(uctx);
+
+       err = uverbs_get_const(&alloc_type, attrs, BNXT_RE_ALLOC_PAGE_TYPE);
+       if (err)
+               return err;
+
+       rdev = uctx->rdev;
+       cctx = rdev->chip_ctx;
+
+       switch (alloc_type) {
+       case BNXT_RE_ALLOC_WC_PAGE:
+               if (cctx->modes.db_push)  {
+                       if (bnxt_qplib_alloc_dpi(&rdev->qplib_res, &uctx->wcdpi,
+                                                uctx, BNXT_QPLIB_DPI_TYPE_WC))
+                               return -ENOMEM;
+                       length = PAGE_SIZE;
+                       dpi = uctx->wcdpi.dpi;
+                       addr = (u64)uctx->wcdpi.umdbr;
+                       mmap_flag = BNXT_RE_MMAP_WC_DB;
+               } else {
+                       return -EINVAL;
+               }
+
+               break;
+       case BNXT_RE_ALLOC_DBR_BAR_PAGE:
+               length = PAGE_SIZE;
+               addr = (u64)rdev->pacing.dbr_bar_addr;
+               mmap_flag = BNXT_RE_MMAP_DBR_BAR;
+               break;
+
+       case BNXT_RE_ALLOC_DBR_PAGE:
+               length = PAGE_SIZE;
+               addr = (u64)rdev->pacing.dbr_page;
+               mmap_flag = BNXT_RE_MMAP_DBR_PAGE;
+               break;
+
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mmap_offset);
+       if (!entry)
+               return -ENOMEM;
+
+       uobj->object = entry;
+       uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_PAGE_HANDLE);
+       err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_MMAP_OFFSET,
+                            &mmap_offset, sizeof(mmap_offset));
+       if (err)
+               return err;
+
+       err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_MMAP_LENGTH,
+                            &length, sizeof(length));
+       if (err)
+               return err;
+
+       err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_DPI,
+                            &dpi, sizeof(dpi));
+       if (err)
+               return err;
+
+       return 0;
+}
+
+static int alloc_page_obj_cleanup(struct ib_uobject *uobject,
+                                 enum rdma_remove_reason why,
+                           struct uverbs_attr_bundle *attrs)
+{
+       struct  bnxt_re_user_mmap_entry *entry = uobject->object;
+       struct bnxt_re_ucontext *uctx = entry->uctx;
+
+       switch (entry->mmap_flag) {
+       case BNXT_RE_MMAP_WC_DB:
+               if (uctx && uctx->wcdpi.dbr) {
+                       struct bnxt_re_dev *rdev = uctx->rdev;
+
+                       bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->wcdpi);
+                       uctx->wcdpi.dbr = NULL;
+               }
+               break;
+       case BNXT_RE_MMAP_DBR_BAR:
+       case BNXT_RE_MMAP_DBR_PAGE:
+               break;
+       default:
+               goto exit;
+       }
+       rdma_user_mmap_entry_remove(&entry->rdma_entry);
+exit:
+       return 0;
+}
+
+DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_ALLOC_PAGE,
+                           UVERBS_ATTR_IDR(BNXT_RE_ALLOC_PAGE_HANDLE,
+                                           BNXT_RE_OBJECT_ALLOC_PAGE,
+                                           UVERBS_ACCESS_NEW,
+                                           UA_MANDATORY),
+                           UVERBS_ATTR_CONST_IN(BNXT_RE_ALLOC_PAGE_TYPE,
+                                                enum bnxt_re_alloc_page_type,
+                                                UA_MANDATORY),
+                           UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_MMAP_OFFSET,
+                                               UVERBS_ATTR_TYPE(u64),
+                                               UA_MANDATORY),
+                           UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_MMAP_LENGTH,
+                                               UVERBS_ATTR_TYPE(u32),
+                                               UA_MANDATORY),
+                           UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_DPI,
+                                               UVERBS_ATTR_TYPE(u32),
+                                               UA_MANDATORY));
+
+DECLARE_UVERBS_NAMED_METHOD_DESTROY(BNXT_RE_METHOD_DESTROY_PAGE,
+                                   UVERBS_ATTR_IDR(BNXT_RE_DESTROY_PAGE_HANDLE,
+                                                   BNXT_RE_OBJECT_ALLOC_PAGE,
+                                                   UVERBS_ACCESS_DESTROY,
+                                                   UA_MANDATORY));
+
+DECLARE_UVERBS_NAMED_OBJECT(BNXT_RE_OBJECT_ALLOC_PAGE,
+                           UVERBS_TYPE_ALLOC_IDR(alloc_page_obj_cleanup),
+                           &UVERBS_METHOD(BNXT_RE_METHOD_ALLOC_PAGE),
+                           &UVERBS_METHOD(BNXT_RE_METHOD_DESTROY_PAGE));
+
+DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_NOTIFY_DRV);
+
+DECLARE_UVERBS_GLOBAL_METHODS(BNXT_RE_OBJECT_NOTIFY_DRV,
+                             &UVERBS_METHOD(BNXT_RE_METHOD_NOTIFY_DRV));
+
+/* Toggle MEM */
+static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bundle *attrs)
+{
+       struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, BNXT_RE_TOGGLE_MEM_HANDLE);
+       enum bnxt_re_mmap_flag mmap_flag = BNXT_RE_MMAP_TOGGLE_PAGE;
+       enum bnxt_re_get_toggle_mem_type res_type;
+       struct bnxt_re_user_mmap_entry *entry;
+       struct bnxt_re_ucontext *uctx;
+       struct ib_ucontext *ib_uctx;
+       struct bnxt_re_dev *rdev;
+       struct bnxt_re_srq *srq;
+       u32 length = PAGE_SIZE;
+       struct bnxt_re_cq *cq;
+       u64 mem_offset;
+       u32 offset = 0;
+       u64 addr = 0;
+       u32 res_id;
+       int err;
+
+       ib_uctx = ib_uverbs_get_ucontext(attrs);
+       if (IS_ERR(ib_uctx))
+               return PTR_ERR(ib_uctx);
+
+       err = uverbs_get_const(&res_type, attrs, BNXT_RE_TOGGLE_MEM_TYPE);
+       if (err)
+               return err;
+
+       uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx);
+       rdev = uctx->rdev;
+       err = uverbs_copy_from(&res_id, attrs, BNXT_RE_TOGGLE_MEM_RES_ID);
+       if (err)
+               return err;
+
+       switch (res_type) {
+       case BNXT_RE_CQ_TOGGLE_MEM:
+               cq = bnxt_re_search_for_cq(rdev, res_id);
+               if (!cq)
+                       return -EINVAL;
+
+               addr = (u64)cq->uctx_cq_page;
+               break;
+       case BNXT_RE_SRQ_TOGGLE_MEM:
+               srq = bnxt_re_search_for_srq(rdev, res_id);
+               if (!srq)
+                       return -EINVAL;
+
+               addr = (u64)srq->uctx_srq_page;
+               break;
+
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mem_offset);
+       if (!entry)
+               return -ENOMEM;
+
+       uobj->object = entry;
+       uverbs_finalize_uobj_create(attrs, BNXT_RE_TOGGLE_MEM_HANDLE);
+       err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_PAGE,
+                            &mem_offset, sizeof(mem_offset));
+       if (err)
+               return err;
+
+       err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_LENGTH,
+                            &length, sizeof(length));
+       if (err)
+               return err;
+
+       err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_OFFSET,
+                            &offset, sizeof(offset));
+       if (err)
+               return err;
+
+       return 0;
+}
+
+static int get_toggle_mem_obj_cleanup(struct ib_uobject *uobject,
+                                     enum rdma_remove_reason why,
+                                     struct uverbs_attr_bundle *attrs)
+{
+       struct  bnxt_re_user_mmap_entry *entry = uobject->object;
+
+       rdma_user_mmap_entry_remove(&entry->rdma_entry);
+       return 0;
+}
+
+DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM,
+                           UVERBS_ATTR_IDR(BNXT_RE_TOGGLE_MEM_HANDLE,
+                                           BNXT_RE_OBJECT_GET_TOGGLE_MEM,
+                                           UVERBS_ACCESS_NEW,
+                                           UA_MANDATORY),
+                           UVERBS_ATTR_CONST_IN(BNXT_RE_TOGGLE_MEM_TYPE,
+                                                enum bnxt_re_get_toggle_mem_type,
+                                                UA_MANDATORY),
+                           UVERBS_ATTR_PTR_IN(BNXT_RE_TOGGLE_MEM_RES_ID,
+                                              UVERBS_ATTR_TYPE(u32),
+                                              UA_MANDATORY),
+                           UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_PAGE,
+                                               UVERBS_ATTR_TYPE(u64),
+                                               UA_MANDATORY),
+                           UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_OFFSET,
+                                               UVERBS_ATTR_TYPE(u32),
+                                               UA_MANDATORY),
+                           UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_LENGTH,
+                                               UVERBS_ATTR_TYPE(u32),
+                                               UA_MANDATORY));
+
+DECLARE_UVERBS_NAMED_METHOD_DESTROY(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM,
+                                   UVERBS_ATTR_IDR(BNXT_RE_RELEASE_TOGGLE_MEM_HANDLE,
+                                                   BNXT_RE_OBJECT_GET_TOGGLE_MEM,
+                                                   UVERBS_ACCESS_DESTROY,
+                                                   UA_MANDATORY));
+
+DECLARE_UVERBS_NAMED_OBJECT(BNXT_RE_OBJECT_GET_TOGGLE_MEM,
+                           UVERBS_TYPE_ALLOC_IDR(get_toggle_mem_obj_cleanup),
+                           &UVERBS_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM),
+                           &UVERBS_METHOD(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM));
+
+const struct uapi_definition bnxt_re_uapi_defs[] = {
+       UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_ALLOC_PAGE),
+       UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_NOTIFY_DRV),
+       UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_GET_TOGGLE_MEM),
+       {}
+};