.. | .. |
---|
30 | 30 | * SOFTWARE. |
---|
31 | 31 | */ |
---|
32 | 32 | |
---|
| 33 | +#include <rdma/uverbs_ioctl.h> |
---|
| 34 | + |
---|
33 | 35 | #include "iw_cxgb4.h" |
---|
34 | 36 | |
---|
35 | | -static int destroy_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, |
---|
36 | | - struct c4iw_dev_ucontext *uctx, struct sk_buff *skb, |
---|
37 | | - struct c4iw_wr_wait *wr_waitp) |
---|
| 37 | +static void destroy_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, |
---|
| 38 | + struct c4iw_dev_ucontext *uctx, struct sk_buff *skb, |
---|
| 39 | + struct c4iw_wr_wait *wr_waitp) |
---|
38 | 40 | { |
---|
39 | 41 | struct fw_ri_res_wr *res_wr; |
---|
40 | 42 | struct fw_ri_res *res; |
---|
41 | 43 | int wr_len; |
---|
42 | | - int ret; |
---|
43 | 44 | |
---|
44 | | - wr_len = sizeof *res_wr + sizeof *res; |
---|
| 45 | + wr_len = sizeof(*res_wr) + sizeof(*res); |
---|
45 | 46 | set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0); |
---|
46 | 47 | |
---|
47 | 48 | res_wr = __skb_put_zero(skb, wr_len); |
---|
.. | .. |
---|
57 | 58 | res->u.cq.iqid = cpu_to_be32(cq->cqid); |
---|
58 | 59 | |
---|
59 | 60 | c4iw_init_wr_wait(wr_waitp); |
---|
60 | | - ret = c4iw_ref_send_wait(rdev, skb, wr_waitp, 0, 0, __func__); |
---|
| 61 | + c4iw_ref_send_wait(rdev, skb, wr_waitp, 0, 0, __func__); |
---|
61 | 62 | |
---|
62 | 63 | kfree(cq->sw_queue); |
---|
63 | 64 | dma_free_coherent(&(rdev->lldi.pdev->dev), |
---|
64 | 65 | cq->memsize, cq->queue, |
---|
65 | 66 | dma_unmap_addr(cq, mapping)); |
---|
66 | 67 | c4iw_put_cqid(rdev, cq->cqid, uctx); |
---|
67 | | - return ret; |
---|
68 | 68 | } |
---|
69 | 69 | |
---|
70 | 70 | static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq, |
---|
.. | .. |
---|
102 | 102 | goto err3; |
---|
103 | 103 | } |
---|
104 | 104 | dma_unmap_addr_set(cq, mapping, cq->dma_addr); |
---|
105 | | - memset(cq->queue, 0, cq->memsize); |
---|
106 | 105 | |
---|
107 | 106 | if (user && ucontext->is_32b_cqe) { |
---|
108 | 107 | cq->qp_errp = &((struct t4_status_page *) |
---|
.. | .. |
---|
115 | 114 | } |
---|
116 | 115 | |
---|
117 | 116 | /* build fw_ri_res_wr */ |
---|
118 | | - wr_len = sizeof *res_wr + sizeof *res; |
---|
| 117 | + wr_len = sizeof(*res_wr) + sizeof(*res); |
---|
119 | 118 | |
---|
120 | 119 | skb = alloc_skb(wr_len, GFP_KERNEL); |
---|
121 | 120 | if (!skb) { |
---|
.. | .. |
---|
755 | 754 | static int __c4iw_poll_cq_one(struct c4iw_cq *chp, struct c4iw_qp *qhp, |
---|
756 | 755 | struct ib_wc *wc, struct c4iw_srq *srq) |
---|
757 | 756 | { |
---|
758 | | - struct t4_cqe uninitialized_var(cqe); |
---|
| 757 | + struct t4_cqe cqe; |
---|
759 | 758 | struct t4_wq *wq = qhp ? &qhp->wq : NULL; |
---|
760 | 759 | u32 credit = 0; |
---|
761 | 760 | u8 cqe_flushed; |
---|
.. | .. |
---|
968 | 967 | return !err || err == -ENODATA ? npolled : err; |
---|
969 | 968 | } |
---|
970 | 969 | |
---|
971 | | -int c4iw_destroy_cq(struct ib_cq *ib_cq) |
---|
| 970 | +int c4iw_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata) |
---|
972 | 971 | { |
---|
973 | 972 | struct c4iw_cq *chp; |
---|
974 | 973 | struct c4iw_ucontext *ucontext; |
---|
.. | .. |
---|
976 | 975 | pr_debug("ib_cq %p\n", ib_cq); |
---|
977 | 976 | chp = to_c4iw_cq(ib_cq); |
---|
978 | 977 | |
---|
979 | | - remove_handle(chp->rhp, &chp->rhp->cqidr, chp->cq.cqid); |
---|
| 978 | + xa_erase_irq(&chp->rhp->cqs, chp->cq.cqid); |
---|
980 | 979 | atomic_dec(&chp->refcnt); |
---|
981 | 980 | wait_event(chp->wait, !atomic_read(&chp->refcnt)); |
---|
982 | 981 | |
---|
983 | | - ucontext = ib_cq->uobject ? to_c4iw_ucontext(ib_cq->uobject->context) |
---|
984 | | - : NULL; |
---|
| 982 | + ucontext = rdma_udata_to_drv_context(udata, struct c4iw_ucontext, |
---|
| 983 | + ibucontext); |
---|
985 | 984 | destroy_cq(&chp->rhp->rdev, &chp->cq, |
---|
986 | 985 | ucontext ? &ucontext->uctx : &chp->cq.rdev->uctx, |
---|
987 | 986 | chp->destroy_skb, chp->wr_waitp); |
---|
988 | 987 | c4iw_put_wr_wait(chp->wr_waitp); |
---|
989 | | - kfree(chp); |
---|
990 | 988 | return 0; |
---|
991 | 989 | } |
---|
992 | 990 | |
---|
993 | | -struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, |
---|
994 | | - const struct ib_cq_init_attr *attr, |
---|
995 | | - struct ib_ucontext *ib_context, |
---|
996 | | - struct ib_udata *udata) |
---|
| 991 | +int c4iw_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, |
---|
| 992 | + struct ib_udata *udata) |
---|
997 | 993 | { |
---|
| 994 | + struct ib_device *ibdev = ibcq->device; |
---|
998 | 995 | int entries = attr->cqe; |
---|
999 | 996 | int vector = attr->comp_vector; |
---|
1000 | | - struct c4iw_dev *rhp; |
---|
1001 | | - struct c4iw_cq *chp; |
---|
| 997 | + struct c4iw_dev *rhp = to_c4iw_dev(ibcq->device); |
---|
| 998 | + struct c4iw_cq *chp = to_c4iw_cq(ibcq); |
---|
1002 | 999 | struct c4iw_create_cq ucmd; |
---|
1003 | 1000 | struct c4iw_create_cq_resp uresp; |
---|
1004 | | - struct c4iw_ucontext *ucontext = NULL; |
---|
1005 | 1001 | int ret, wr_len; |
---|
1006 | 1002 | size_t memsize, hwentries; |
---|
1007 | 1003 | struct c4iw_mm_entry *mm, *mm2; |
---|
| 1004 | + struct c4iw_ucontext *ucontext = rdma_udata_to_drv_context( |
---|
| 1005 | + udata, struct c4iw_ucontext, ibucontext); |
---|
1008 | 1006 | |
---|
1009 | 1007 | pr_debug("ib_dev %p entries %d\n", ibdev, entries); |
---|
1010 | 1008 | if (attr->flags) |
---|
1011 | | - return ERR_PTR(-EINVAL); |
---|
1012 | | - |
---|
1013 | | - rhp = to_c4iw_dev(ibdev); |
---|
| 1009 | + return -EINVAL; |
---|
1014 | 1010 | |
---|
1015 | 1011 | if (entries < 1 || entries > ibdev->attrs.max_cqe) |
---|
1016 | | - return ERR_PTR(-EINVAL); |
---|
| 1012 | + return -EINVAL; |
---|
1017 | 1013 | |
---|
1018 | 1014 | if (vector >= rhp->rdev.lldi.nciq) |
---|
1019 | | - return ERR_PTR(-EINVAL); |
---|
| 1015 | + return -EINVAL; |
---|
1020 | 1016 | |
---|
1021 | | - if (ib_context) { |
---|
1022 | | - ucontext = to_c4iw_ucontext(ib_context); |
---|
| 1017 | + if (udata) { |
---|
1023 | 1018 | if (udata->inlen < sizeof(ucmd)) |
---|
1024 | 1019 | ucontext->is_32b_cqe = 1; |
---|
1025 | 1020 | } |
---|
1026 | | - |
---|
1027 | | - chp = kzalloc(sizeof(*chp), GFP_KERNEL); |
---|
1028 | | - if (!chp) |
---|
1029 | | - return ERR_PTR(-ENOMEM); |
---|
1030 | 1021 | |
---|
1031 | 1022 | chp->wr_waitp = c4iw_alloc_wr_wait(GFP_KERNEL); |
---|
1032 | 1023 | if (!chp->wr_waitp) { |
---|
.. | .. |
---|
1071 | 1062 | /* |
---|
1072 | 1063 | * memsize must be a multiple of the page size if its a user cq. |
---|
1073 | 1064 | */ |
---|
1074 | | - if (ucontext) |
---|
| 1065 | + if (udata) |
---|
1075 | 1066 | memsize = roundup(memsize, PAGE_SIZE); |
---|
1076 | 1067 | |
---|
1077 | 1068 | chp->cq.size = hwentries; |
---|
.. | .. |
---|
1091 | 1082 | spin_lock_init(&chp->comp_handler_lock); |
---|
1092 | 1083 | atomic_set(&chp->refcnt, 1); |
---|
1093 | 1084 | init_waitqueue_head(&chp->wait); |
---|
1094 | | - ret = insert_handle(rhp, &rhp->cqidr, chp, chp->cq.cqid); |
---|
| 1085 | + ret = xa_insert_irq(&rhp->cqs, chp->cq.cqid, chp, GFP_KERNEL); |
---|
1095 | 1086 | if (ret) |
---|
1096 | 1087 | goto err_destroy_cq; |
---|
1097 | 1088 | |
---|
1098 | 1089 | if (ucontext) { |
---|
1099 | 1090 | ret = -ENOMEM; |
---|
1100 | | - mm = kmalloc(sizeof *mm, GFP_KERNEL); |
---|
| 1091 | + mm = kmalloc(sizeof(*mm), GFP_KERNEL); |
---|
1101 | 1092 | if (!mm) |
---|
1102 | 1093 | goto err_remove_handle; |
---|
1103 | | - mm2 = kmalloc(sizeof *mm2, GFP_KERNEL); |
---|
| 1094 | + mm2 = kmalloc(sizeof(*mm2), GFP_KERNEL); |
---|
1104 | 1095 | if (!mm2) |
---|
1105 | 1096 | goto err_free_mm; |
---|
1106 | 1097 | |
---|
.. | .. |
---|
1137 | 1128 | mm2->len = PAGE_SIZE; |
---|
1138 | 1129 | insert_mmap(ucontext, mm2); |
---|
1139 | 1130 | } |
---|
1140 | | - pr_debug("cqid 0x%0x chp %p size %u memsize %zu, dma_addr 0x%0llx\n", |
---|
1141 | | - chp->cq.cqid, chp, chp->cq.size, |
---|
1142 | | - chp->cq.memsize, (unsigned long long)chp->cq.dma_addr); |
---|
1143 | | - return &chp->ibcq; |
---|
| 1131 | + |
---|
| 1132 | + pr_debug("cqid 0x%0x chp %p size %u memsize %zu, dma_addr %pad\n", |
---|
| 1133 | + chp->cq.cqid, chp, chp->cq.size, chp->cq.memsize, |
---|
| 1134 | + &chp->cq.dma_addr); |
---|
| 1135 | + return 0; |
---|
1144 | 1136 | err_free_mm2: |
---|
1145 | 1137 | kfree(mm2); |
---|
1146 | 1138 | err_free_mm: |
---|
1147 | 1139 | kfree(mm); |
---|
1148 | 1140 | err_remove_handle: |
---|
1149 | | - remove_handle(rhp, &rhp->cqidr, chp->cq.cqid); |
---|
| 1141 | + xa_erase_irq(&rhp->cqs, chp->cq.cqid); |
---|
1150 | 1142 | err_destroy_cq: |
---|
1151 | 1143 | destroy_cq(&chp->rhp->rdev, &chp->cq, |
---|
1152 | 1144 | ucontext ? &ucontext->uctx : &rhp->rdev.uctx, |
---|
.. | .. |
---|
1156 | 1148 | err_free_wr_wait: |
---|
1157 | 1149 | c4iw_put_wr_wait(chp->wr_waitp); |
---|
1158 | 1150 | err_free_chp: |
---|
1159 | | - kfree(chp); |
---|
1160 | | - return ERR_PTR(ret); |
---|
| 1151 | + return ret; |
---|
1161 | 1152 | } |
---|
1162 | 1153 | |
---|
1163 | 1154 | int c4iw_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) |
---|