Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

RDMA/bnxt_re: Move the UAPI methods to a dedicated file

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>

authored by

Kalesh AP and committed by
Jason Gunthorpe
eee62684 613713f2

+344 -305
+1 -1
drivers/infiniband/hw/bnxt_re/Makefile
··· 5 5 bnxt_re-y := main.o ib_verbs.o \ 6 6 qplib_res.o qplib_rcfw.o \ 7 7 qplib_sp.o qplib_fp.o hw_counters.o \ 8 - debugfs.o 8 + debugfs.o uapi.o
+1 -304
drivers/infiniband/hw/bnxt_re/ib_verbs.c
··· 642 642 return rc; 643 643 } 644 644 645 - static struct bnxt_re_user_mmap_entry* 645 + struct bnxt_re_user_mmap_entry* 646 646 bnxt_re_mmap_entry_insert(struct bnxt_re_ucontext *uctx, u64 mem_offset, 647 647 enum bnxt_re_mmap_flag mmap_flag, u64 *offset) 648 648 { ··· 4609 4609 return rc; 4610 4610 } 4611 4611 4612 - static struct bnxt_re_cq *bnxt_re_search_for_cq(struct bnxt_re_dev *rdev, u32 cq_id) 4613 - { 4614 - struct bnxt_re_cq *cq = NULL, *tmp_cq; 4615 - 4616 - hash_for_each_possible(rdev->cq_hash, tmp_cq, hash_entry, cq_id) { 4617 - if (tmp_cq->qplib_cq.id == cq_id) { 4618 - cq = tmp_cq; 4619 - break; 4620 - } 4621 - } 4622 - return cq; 4623 - } 4624 - 4625 - static struct bnxt_re_srq *bnxt_re_search_for_srq(struct bnxt_re_dev *rdev, u32 srq_id) 4626 - { 4627 - struct bnxt_re_srq *srq = NULL, *tmp_srq; 4628 - 4629 - hash_for_each_possible(rdev->srq_hash, tmp_srq, hash_entry, srq_id) { 4630 - if (tmp_srq->qplib_srq.id == srq_id) { 4631 - srq = tmp_srq; 4632 - break; 4633 - } 4634 - } 4635 - return srq; 4636 - } 4637 - 4638 4612 /* Helper function to mmap the virtual memory from user app */ 4639 4613 int bnxt_re_mmap(struct ib_ucontext *ib_uctx, struct vm_area_struct *vma) 4640 4614 { ··· 4711 4737 ret |= IB_MAD_RESULT_REPLY; 4712 4738 return ret; 4713 4739 } 4714 - 4715 - static int UVERBS_HANDLER(BNXT_RE_METHOD_NOTIFY_DRV)(struct uverbs_attr_bundle *attrs) 4716 - { 4717 - struct bnxt_re_ucontext *uctx; 4718 - 4719 - uctx = container_of(ib_uverbs_get_ucontext(attrs), struct bnxt_re_ucontext, ib_uctx); 4720 - bnxt_re_pacing_alert(uctx->rdev); 4721 - return 0; 4722 - } 4723 - 4724 - static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *attrs) 4725 - { 4726 - struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, BNXT_RE_ALLOC_PAGE_HANDLE); 4727 - enum bnxt_re_alloc_page_type alloc_type; 4728 - struct bnxt_re_user_mmap_entry *entry; 4729 - enum bnxt_re_mmap_flag mmap_flag; 4730 - struct bnxt_qplib_chip_ctx *cctx; 4731 - struct bnxt_re_ucontext *uctx; 4732 - struct bnxt_re_dev *rdev; 4733 - u64 mmap_offset; 4734 - u32 length; 4735 - u32 dpi; 4736 - u64 addr; 4737 - int err; 4738 - 4739 - uctx = container_of(ib_uverbs_get_ucontext(attrs), struct bnxt_re_ucontext, ib_uctx); 4740 - if (IS_ERR(uctx)) 4741 - return PTR_ERR(uctx); 4742 - 4743 - err = uverbs_get_const(&alloc_type, attrs, BNXT_RE_ALLOC_PAGE_TYPE); 4744 - if (err) 4745 - return err; 4746 - 4747 - rdev = uctx->rdev; 4748 - cctx = rdev->chip_ctx; 4749 - 4750 - switch (alloc_type) { 4751 - case BNXT_RE_ALLOC_WC_PAGE: 4752 - if (cctx->modes.db_push) { 4753 - if (bnxt_qplib_alloc_dpi(&rdev->qplib_res, &uctx->wcdpi, 4754 - uctx, BNXT_QPLIB_DPI_TYPE_WC)) 4755 - return -ENOMEM; 4756 - length = PAGE_SIZE; 4757 - dpi = uctx->wcdpi.dpi; 4758 - addr = (u64)uctx->wcdpi.umdbr; 4759 - mmap_flag = BNXT_RE_MMAP_WC_DB; 4760 - } else { 4761 - return -EINVAL; 4762 - } 4763 - 4764 - break; 4765 - case BNXT_RE_ALLOC_DBR_BAR_PAGE: 4766 - length = PAGE_SIZE; 4767 - addr = (u64)rdev->pacing.dbr_bar_addr; 4768 - mmap_flag = BNXT_RE_MMAP_DBR_BAR; 4769 - break; 4770 - 4771 - case BNXT_RE_ALLOC_DBR_PAGE: 4772 - length = PAGE_SIZE; 4773 - addr = (u64)rdev->pacing.dbr_page; 4774 - mmap_flag = BNXT_RE_MMAP_DBR_PAGE; 4775 - break; 4776 - 4777 - default: 4778 - return -EOPNOTSUPP; 4779 - } 4780 - 4781 - entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mmap_offset); 4782 - if (!entry) 4783 - return -ENOMEM; 4784 - 4785 - uobj->object = entry; 4786 - uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_PAGE_HANDLE); 4787 - err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_MMAP_OFFSET, 4788 - &mmap_offset, sizeof(mmap_offset)); 4789 - if (err) 4790 - return err; 4791 - 4792 - err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_MMAP_LENGTH, 4793 - &length, sizeof(length)); 4794 - if (err) 4795 - return err; 4796 - 4797 - err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_DPI, 4798 - &dpi, sizeof(dpi)); 4799 - if (err) 4800 - return err; 4801 - 4802 - return 0; 4803 - } 4804 - 4805 - static int alloc_page_obj_cleanup(struct ib_uobject *uobject, 4806 - enum rdma_remove_reason why, 4807 - struct uverbs_attr_bundle *attrs) 4808 - { 4809 - struct bnxt_re_user_mmap_entry *entry = uobject->object; 4810 - struct bnxt_re_ucontext *uctx = entry->uctx; 4811 - 4812 - switch (entry->mmap_flag) { 4813 - case BNXT_RE_MMAP_WC_DB: 4814 - if (uctx && uctx->wcdpi.dbr) { 4815 - struct bnxt_re_dev *rdev = uctx->rdev; 4816 - 4817 - bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->wcdpi); 4818 - uctx->wcdpi.dbr = NULL; 4819 - } 4820 - break; 4821 - case BNXT_RE_MMAP_DBR_BAR: 4822 - case BNXT_RE_MMAP_DBR_PAGE: 4823 - break; 4824 - default: 4825 - goto exit; 4826 - } 4827 - rdma_user_mmap_entry_remove(&entry->rdma_entry); 4828 - exit: 4829 - return 0; 4830 - } 4831 - 4832 - DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_ALLOC_PAGE, 4833 - UVERBS_ATTR_IDR(BNXT_RE_ALLOC_PAGE_HANDLE, 4834 - BNXT_RE_OBJECT_ALLOC_PAGE, 4835 - UVERBS_ACCESS_NEW, 4836 - UA_MANDATORY), 4837 - UVERBS_ATTR_CONST_IN(BNXT_RE_ALLOC_PAGE_TYPE, 4838 - enum bnxt_re_alloc_page_type, 4839 - UA_MANDATORY), 4840 - UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_MMAP_OFFSET, 4841 - UVERBS_ATTR_TYPE(u64), 4842 - UA_MANDATORY), 4843 - UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_MMAP_LENGTH, 4844 - UVERBS_ATTR_TYPE(u32), 4845 - UA_MANDATORY), 4846 - UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_DPI, 4847 - UVERBS_ATTR_TYPE(u32), 4848 - UA_MANDATORY)); 4849 - 4850 - DECLARE_UVERBS_NAMED_METHOD_DESTROY(BNXT_RE_METHOD_DESTROY_PAGE, 4851 - UVERBS_ATTR_IDR(BNXT_RE_DESTROY_PAGE_HANDLE, 4852 - BNXT_RE_OBJECT_ALLOC_PAGE, 4853 - UVERBS_ACCESS_DESTROY, 4854 - UA_MANDATORY)); 4855 - 4856 - DECLARE_UVERBS_NAMED_OBJECT(BNXT_RE_OBJECT_ALLOC_PAGE, 4857 - UVERBS_TYPE_ALLOC_IDR(alloc_page_obj_cleanup), 4858 - &UVERBS_METHOD(BNXT_RE_METHOD_ALLOC_PAGE), 4859 - &UVERBS_METHOD(BNXT_RE_METHOD_DESTROY_PAGE)); 4860 - 4861 - DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_NOTIFY_DRV); 4862 - 4863 - DECLARE_UVERBS_GLOBAL_METHODS(BNXT_RE_OBJECT_NOTIFY_DRV, 4864 - &UVERBS_METHOD(BNXT_RE_METHOD_NOTIFY_DRV)); 4865 - 4866 - /* Toggle MEM */ 4867 - static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bundle *attrs) 4868 - { 4869 - struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, BNXT_RE_TOGGLE_MEM_HANDLE); 4870 - enum bnxt_re_mmap_flag mmap_flag = BNXT_RE_MMAP_TOGGLE_PAGE; 4871 - enum bnxt_re_get_toggle_mem_type res_type; 4872 - struct bnxt_re_user_mmap_entry *entry; 4873 - struct bnxt_re_ucontext *uctx; 4874 - struct ib_ucontext *ib_uctx; 4875 - struct bnxt_re_dev *rdev; 4876 - struct bnxt_re_srq *srq; 4877 - u32 length = PAGE_SIZE; 4878 - struct bnxt_re_cq *cq; 4879 - u64 mem_offset; 4880 - u32 offset = 0; 4881 - u64 addr = 0; 4882 - u32 res_id; 4883 - int err; 4884 - 4885 - ib_uctx = ib_uverbs_get_ucontext(attrs); 4886 - if (IS_ERR(ib_uctx)) 4887 - return PTR_ERR(ib_uctx); 4888 - 4889 - err = uverbs_get_const(&res_type, attrs, BNXT_RE_TOGGLE_MEM_TYPE); 4890 - if (err) 4891 - return err; 4892 - 4893 - uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx); 4894 - rdev = uctx->rdev; 4895 - err = uverbs_copy_from(&res_id, attrs, BNXT_RE_TOGGLE_MEM_RES_ID); 4896 - if (err) 4897 - return err; 4898 - 4899 - switch (res_type) { 4900 - case BNXT_RE_CQ_TOGGLE_MEM: 4901 - cq = bnxt_re_search_for_cq(rdev, res_id); 4902 - if (!cq) 4903 - return -EINVAL; 4904 - 4905 - addr = (u64)cq->uctx_cq_page; 4906 - break; 4907 - case BNXT_RE_SRQ_TOGGLE_MEM: 4908 - srq = bnxt_re_search_for_srq(rdev, res_id); 4909 - if (!srq) 4910 - return -EINVAL; 4911 - 4912 - addr = (u64)srq->uctx_srq_page; 4913 - break; 4914 - 4915 - default: 4916 - return -EOPNOTSUPP; 4917 - } 4918 - 4919 - entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mem_offset); 4920 - if (!entry) 4921 - return -ENOMEM; 4922 - 4923 - uobj->object = entry; 4924 - uverbs_finalize_uobj_create(attrs, BNXT_RE_TOGGLE_MEM_HANDLE); 4925 - err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_PAGE, 4926 - &mem_offset, sizeof(mem_offset)); 4927 - if (err) 4928 - return err; 4929 - 4930 - err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_LENGTH, 4931 - &length, sizeof(length)); 4932 - if (err) 4933 - return err; 4934 - 4935 - err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_OFFSET, 4936 - &offset, sizeof(offset)); 4937 - if (err) 4938 - return err; 4939 - 4940 - return 0; 4941 - } 4942 - 4943 - static int get_toggle_mem_obj_cleanup(struct ib_uobject *uobject, 4944 - enum rdma_remove_reason why, 4945 - struct uverbs_attr_bundle *attrs) 4946 - { 4947 - struct bnxt_re_user_mmap_entry *entry = uobject->object; 4948 - 4949 - rdma_user_mmap_entry_remove(&entry->rdma_entry); 4950 - return 0; 4951 - } 4952 - 4953 - DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM, 4954 - UVERBS_ATTR_IDR(BNXT_RE_TOGGLE_MEM_HANDLE, 4955 - BNXT_RE_OBJECT_GET_TOGGLE_MEM, 4956 - UVERBS_ACCESS_NEW, 4957 - UA_MANDATORY), 4958 - UVERBS_ATTR_CONST_IN(BNXT_RE_TOGGLE_MEM_TYPE, 4959 - enum bnxt_re_get_toggle_mem_type, 4960 - UA_MANDATORY), 4961 - UVERBS_ATTR_PTR_IN(BNXT_RE_TOGGLE_MEM_RES_ID, 4962 - UVERBS_ATTR_TYPE(u32), 4963 - UA_MANDATORY), 4964 - UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_PAGE, 4965 - UVERBS_ATTR_TYPE(u64), 4966 - UA_MANDATORY), 4967 - UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_OFFSET, 4968 - UVERBS_ATTR_TYPE(u32), 4969 - UA_MANDATORY), 4970 - UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_LENGTH, 4971 - UVERBS_ATTR_TYPE(u32), 4972 - UA_MANDATORY)); 4973 - 4974 - DECLARE_UVERBS_NAMED_METHOD_DESTROY(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM, 4975 - UVERBS_ATTR_IDR(BNXT_RE_RELEASE_TOGGLE_MEM_HANDLE, 4976 - BNXT_RE_OBJECT_GET_TOGGLE_MEM, 4977 - UVERBS_ACCESS_DESTROY, 4978 - UA_MANDATORY)); 4979 - 4980 - DECLARE_UVERBS_NAMED_OBJECT(BNXT_RE_OBJECT_GET_TOGGLE_MEM, 4981 - UVERBS_TYPE_ALLOC_IDR(get_toggle_mem_obj_cleanup), 4982 - &UVERBS_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM), 4983 - &UVERBS_METHOD(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM)); 4984 - 4985 - const struct uapi_definition bnxt_re_uapi_defs[] = { 4986 - UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_ALLOC_PAGE), 4987 - UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_NOTIFY_DRV), 4988 - UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_GET_TOGGLE_MEM), 4989 - {} 4990 - };
+3
drivers/infiniband/hw/bnxt_re/ib_verbs.h
··· 293 293 294 294 unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp); 295 295 void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags); 296 + struct bnxt_re_user_mmap_entry* 297 + bnxt_re_mmap_entry_insert(struct bnxt_re_ucontext *uctx, u64 mem_offset, 298 + enum bnxt_re_mmap_flag mmap_flag, u64 *offset); 296 299 #endif /* __BNXT_RE_IB_VERBS_H__ */
+339
drivers/infiniband/hw/bnxt_re/uapi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 + /* 3 + * Copyright (c) 2025, Broadcom. All rights reserved. The term 4 + * Broadcom refers to Broadcom Limited and/or its subsidiaries. 5 + * 6 + * Description: uapi interpreter 7 + */ 8 + 9 + #include <rdma/ib_addr.h> 10 + #include <rdma/uverbs_types.h> 11 + #include <rdma/uverbs_std_types.h> 12 + #include <rdma/ib_user_ioctl_cmds.h> 13 + #define UVERBS_MODULE_NAME bnxt_re 14 + #include <rdma/uverbs_named_ioctl.h> 15 + #include <rdma/bnxt_re-abi.h> 16 + 17 + #include "roce_hsi.h" 18 + #include "qplib_res.h" 19 + #include "qplib_sp.h" 20 + #include "qplib_fp.h" 21 + #include "qplib_rcfw.h" 22 + #include "bnxt_re.h" 23 + #include "ib_verbs.h" 24 + 25 + static struct bnxt_re_cq *bnxt_re_search_for_cq(struct bnxt_re_dev *rdev, u32 cq_id) 26 + { 27 + struct bnxt_re_cq *cq = NULL, *tmp_cq; 28 + 29 + hash_for_each_possible(rdev->cq_hash, tmp_cq, hash_entry, cq_id) { 30 + if (tmp_cq->qplib_cq.id == cq_id) { 31 + cq = tmp_cq; 32 + break; 33 + } 34 + } 35 + return cq; 36 + } 37 + 38 + static struct bnxt_re_srq *bnxt_re_search_for_srq(struct bnxt_re_dev *rdev, u32 srq_id) 39 + { 40 + struct bnxt_re_srq *srq = NULL, *tmp_srq; 41 + 42 + hash_for_each_possible(rdev->srq_hash, tmp_srq, hash_entry, srq_id) { 43 + if (tmp_srq->qplib_srq.id == srq_id) { 44 + srq = tmp_srq; 45 + break; 46 + } 47 + } 48 + return srq; 49 + } 50 + 51 + static int UVERBS_HANDLER(BNXT_RE_METHOD_NOTIFY_DRV)(struct uverbs_attr_bundle *attrs) 52 + { 53 + struct bnxt_re_ucontext *uctx; 54 + struct ib_ucontext *ib_uctx; 55 + 56 + ib_uctx = ib_uverbs_get_ucontext(attrs); 57 + if (IS_ERR(ib_uctx)) 58 + return PTR_ERR(ib_uctx); 59 + 60 + uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx); 61 + if (IS_ERR(uctx)) 62 + return PTR_ERR(uctx); 63 + 64 + bnxt_re_pacing_alert(uctx->rdev); 65 + return 0; 66 + } 67 + 68 + static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *attrs) 69 + { 70 + struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, BNXT_RE_ALLOC_PAGE_HANDLE); 71 + enum bnxt_re_alloc_page_type alloc_type; 72 + struct bnxt_re_user_mmap_entry *entry; 73 + enum bnxt_re_mmap_flag mmap_flag; 74 + struct bnxt_qplib_chip_ctx *cctx; 75 + struct bnxt_re_ucontext *uctx; 76 + struct ib_ucontext *ib_uctx; 77 + struct bnxt_re_dev *rdev; 78 + u64 mmap_offset; 79 + u32 length; 80 + u32 dpi; 81 + u64 addr; 82 + int err; 83 + 84 + ib_uctx = ib_uverbs_get_ucontext(attrs); 85 + if (IS_ERR(ib_uctx)) 86 + return PTR_ERR(ib_uctx); 87 + 88 + uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx); 89 + if (IS_ERR(uctx)) 90 + return PTR_ERR(uctx); 91 + 92 + err = uverbs_get_const(&alloc_type, attrs, BNXT_RE_ALLOC_PAGE_TYPE); 93 + if (err) 94 + return err; 95 + 96 + rdev = uctx->rdev; 97 + cctx = rdev->chip_ctx; 98 + 99 + switch (alloc_type) { 100 + case BNXT_RE_ALLOC_WC_PAGE: 101 + if (cctx->modes.db_push) { 102 + if (bnxt_qplib_alloc_dpi(&rdev->qplib_res, &uctx->wcdpi, 103 + uctx, BNXT_QPLIB_DPI_TYPE_WC)) 104 + return -ENOMEM; 105 + length = PAGE_SIZE; 106 + dpi = uctx->wcdpi.dpi; 107 + addr = (u64)uctx->wcdpi.umdbr; 108 + mmap_flag = BNXT_RE_MMAP_WC_DB; 109 + } else { 110 + return -EINVAL; 111 + } 112 + 113 + break; 114 + case BNXT_RE_ALLOC_DBR_BAR_PAGE: 115 + length = PAGE_SIZE; 116 + addr = (u64)rdev->pacing.dbr_bar_addr; 117 + mmap_flag = BNXT_RE_MMAP_DBR_BAR; 118 + break; 119 + 120 + case BNXT_RE_ALLOC_DBR_PAGE: 121 + length = PAGE_SIZE; 122 + addr = (u64)rdev->pacing.dbr_page; 123 + mmap_flag = BNXT_RE_MMAP_DBR_PAGE; 124 + break; 125 + 126 + default: 127 + return -EOPNOTSUPP; 128 + } 129 + 130 + entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mmap_offset); 131 + if (!entry) 132 + return -ENOMEM; 133 + 134 + uobj->object = entry; 135 + uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_PAGE_HANDLE); 136 + err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_MMAP_OFFSET, 137 + &mmap_offset, sizeof(mmap_offset)); 138 + if (err) 139 + return err; 140 + 141 + err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_MMAP_LENGTH, 142 + &length, sizeof(length)); 143 + if (err) 144 + return err; 145 + 146 + err = uverbs_copy_to(attrs, BNXT_RE_ALLOC_PAGE_DPI, 147 + &dpi, sizeof(dpi)); 148 + if (err) 149 + return err; 150 + 151 + return 0; 152 + } 153 + 154 + static int alloc_page_obj_cleanup(struct ib_uobject *uobject, 155 + enum rdma_remove_reason why, 156 + struct uverbs_attr_bundle *attrs) 157 + { 158 + struct bnxt_re_user_mmap_entry *entry = uobject->object; 159 + struct bnxt_re_ucontext *uctx = entry->uctx; 160 + 161 + switch (entry->mmap_flag) { 162 + case BNXT_RE_MMAP_WC_DB: 163 + if (uctx && uctx->wcdpi.dbr) { 164 + struct bnxt_re_dev *rdev = uctx->rdev; 165 + 166 + bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->wcdpi); 167 + uctx->wcdpi.dbr = NULL; 168 + } 169 + break; 170 + case BNXT_RE_MMAP_DBR_BAR: 171 + case BNXT_RE_MMAP_DBR_PAGE: 172 + break; 173 + default: 174 + goto exit; 175 + } 176 + rdma_user_mmap_entry_remove(&entry->rdma_entry); 177 + exit: 178 + return 0; 179 + } 180 + 181 + DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_ALLOC_PAGE, 182 + UVERBS_ATTR_IDR(BNXT_RE_ALLOC_PAGE_HANDLE, 183 + BNXT_RE_OBJECT_ALLOC_PAGE, 184 + UVERBS_ACCESS_NEW, 185 + UA_MANDATORY), 186 + UVERBS_ATTR_CONST_IN(BNXT_RE_ALLOC_PAGE_TYPE, 187 + enum bnxt_re_alloc_page_type, 188 + UA_MANDATORY), 189 + UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_MMAP_OFFSET, 190 + UVERBS_ATTR_TYPE(u64), 191 + UA_MANDATORY), 192 + UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_MMAP_LENGTH, 193 + UVERBS_ATTR_TYPE(u32), 194 + UA_MANDATORY), 195 + UVERBS_ATTR_PTR_OUT(BNXT_RE_ALLOC_PAGE_DPI, 196 + UVERBS_ATTR_TYPE(u32), 197 + UA_MANDATORY)); 198 + 199 + DECLARE_UVERBS_NAMED_METHOD_DESTROY(BNXT_RE_METHOD_DESTROY_PAGE, 200 + UVERBS_ATTR_IDR(BNXT_RE_DESTROY_PAGE_HANDLE, 201 + BNXT_RE_OBJECT_ALLOC_PAGE, 202 + UVERBS_ACCESS_DESTROY, 203 + UA_MANDATORY)); 204 + 205 + DECLARE_UVERBS_NAMED_OBJECT(BNXT_RE_OBJECT_ALLOC_PAGE, 206 + UVERBS_TYPE_ALLOC_IDR(alloc_page_obj_cleanup), 207 + &UVERBS_METHOD(BNXT_RE_METHOD_ALLOC_PAGE), 208 + &UVERBS_METHOD(BNXT_RE_METHOD_DESTROY_PAGE)); 209 + 210 + DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_NOTIFY_DRV); 211 + 212 + DECLARE_UVERBS_GLOBAL_METHODS(BNXT_RE_OBJECT_NOTIFY_DRV, 213 + &UVERBS_METHOD(BNXT_RE_METHOD_NOTIFY_DRV)); 214 + 215 + /* Toggle MEM */ 216 + static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bundle *attrs) 217 + { 218 + struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs, BNXT_RE_TOGGLE_MEM_HANDLE); 219 + enum bnxt_re_mmap_flag mmap_flag = BNXT_RE_MMAP_TOGGLE_PAGE; 220 + enum bnxt_re_get_toggle_mem_type res_type; 221 + struct bnxt_re_user_mmap_entry *entry; 222 + struct bnxt_re_ucontext *uctx; 223 + struct ib_ucontext *ib_uctx; 224 + struct bnxt_re_dev *rdev; 225 + struct bnxt_re_srq *srq; 226 + u32 length = PAGE_SIZE; 227 + struct bnxt_re_cq *cq; 228 + u64 mem_offset; 229 + u32 offset = 0; 230 + u64 addr = 0; 231 + u32 res_id; 232 + int err; 233 + 234 + ib_uctx = ib_uverbs_get_ucontext(attrs); 235 + if (IS_ERR(ib_uctx)) 236 + return PTR_ERR(ib_uctx); 237 + 238 + err = uverbs_get_const(&res_type, attrs, BNXT_RE_TOGGLE_MEM_TYPE); 239 + if (err) 240 + return err; 241 + 242 + uctx = container_of(ib_uctx, struct bnxt_re_ucontext, ib_uctx); 243 + rdev = uctx->rdev; 244 + err = uverbs_copy_from(&res_id, attrs, BNXT_RE_TOGGLE_MEM_RES_ID); 245 + if (err) 246 + return err; 247 + 248 + switch (res_type) { 249 + case BNXT_RE_CQ_TOGGLE_MEM: 250 + cq = bnxt_re_search_for_cq(rdev, res_id); 251 + if (!cq) 252 + return -EINVAL; 253 + 254 + addr = (u64)cq->uctx_cq_page; 255 + break; 256 + case BNXT_RE_SRQ_TOGGLE_MEM: 257 + srq = bnxt_re_search_for_srq(rdev, res_id); 258 + if (!srq) 259 + return -EINVAL; 260 + 261 + addr = (u64)srq->uctx_srq_page; 262 + break; 263 + 264 + default: 265 + return -EOPNOTSUPP; 266 + } 267 + 268 + entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mem_offset); 269 + if (!entry) 270 + return -ENOMEM; 271 + 272 + uobj->object = entry; 273 + uverbs_finalize_uobj_create(attrs, BNXT_RE_TOGGLE_MEM_HANDLE); 274 + err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_PAGE, 275 + &mem_offset, sizeof(mem_offset)); 276 + if (err) 277 + return err; 278 + 279 + err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_LENGTH, 280 + &length, sizeof(length)); 281 + if (err) 282 + return err; 283 + 284 + err = uverbs_copy_to(attrs, BNXT_RE_TOGGLE_MEM_MMAP_OFFSET, 285 + &offset, sizeof(offset)); 286 + if (err) 287 + return err; 288 + 289 + return 0; 290 + } 291 + 292 + static int get_toggle_mem_obj_cleanup(struct ib_uobject *uobject, 293 + enum rdma_remove_reason why, 294 + struct uverbs_attr_bundle *attrs) 295 + { 296 + struct bnxt_re_user_mmap_entry *entry = uobject->object; 297 + 298 + rdma_user_mmap_entry_remove(&entry->rdma_entry); 299 + return 0; 300 + } 301 + 302 + DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM, 303 + UVERBS_ATTR_IDR(BNXT_RE_TOGGLE_MEM_HANDLE, 304 + BNXT_RE_OBJECT_GET_TOGGLE_MEM, 305 + UVERBS_ACCESS_NEW, 306 + UA_MANDATORY), 307 + UVERBS_ATTR_CONST_IN(BNXT_RE_TOGGLE_MEM_TYPE, 308 + enum bnxt_re_get_toggle_mem_type, 309 + UA_MANDATORY), 310 + UVERBS_ATTR_PTR_IN(BNXT_RE_TOGGLE_MEM_RES_ID, 311 + UVERBS_ATTR_TYPE(u32), 312 + UA_MANDATORY), 313 + UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_PAGE, 314 + UVERBS_ATTR_TYPE(u64), 315 + UA_MANDATORY), 316 + UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_OFFSET, 317 + UVERBS_ATTR_TYPE(u32), 318 + UA_MANDATORY), 319 + UVERBS_ATTR_PTR_OUT(BNXT_RE_TOGGLE_MEM_MMAP_LENGTH, 320 + UVERBS_ATTR_TYPE(u32), 321 + UA_MANDATORY)); 322 + 323 + DECLARE_UVERBS_NAMED_METHOD_DESTROY(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM, 324 + UVERBS_ATTR_IDR(BNXT_RE_RELEASE_TOGGLE_MEM_HANDLE, 325 + BNXT_RE_OBJECT_GET_TOGGLE_MEM, 326 + UVERBS_ACCESS_DESTROY, 327 + UA_MANDATORY)); 328 + 329 + DECLARE_UVERBS_NAMED_OBJECT(BNXT_RE_OBJECT_GET_TOGGLE_MEM, 330 + UVERBS_TYPE_ALLOC_IDR(get_toggle_mem_obj_cleanup), 331 + &UVERBS_METHOD(BNXT_RE_METHOD_GET_TOGGLE_MEM), 332 + &UVERBS_METHOD(BNXT_RE_METHOD_RELEASE_TOGGLE_MEM)); 333 + 334 + const struct uapi_definition bnxt_re_uapi_defs[] = { 335 + UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_ALLOC_PAGE), 336 + UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_NOTIFY_DRV), 337 + UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_GET_TOGGLE_MEM), 338 + {} 339 + };