2 * Copyright (c) 2016 Hisilicon Limited.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 #include <rdma/ib_umem.h>
34 #include <rdma/uverbs_ioctl.h>
35 #include "hns_roce_device.h"
36 #include "hns_roce_cmd.h"
37 #include "hns_roce_hem.h"
38 #include "hns_roce_common.h"
40 static u8
get_least_load_bankid_for_cq(struct hns_roce_bank
*bank
)
42 u32 least_load
= bank
[0].inuse
;
47 for (i
= 1; i
< HNS_ROCE_CQ_BANK_NUM
; i
++) {
48 bankcnt
= bank
[i
].inuse
;
49 if (bankcnt
< least_load
) {
58 static int alloc_cqn(struct hns_roce_dev
*hr_dev
, struct hns_roce_cq
*hr_cq
)
60 struct hns_roce_cq_table
*cq_table
= &hr_dev
->cq_table
;
61 struct hns_roce_bank
*bank
;
65 mutex_lock(&cq_table
->bank_mutex
);
66 bankid
= get_least_load_bankid_for_cq(cq_table
->bank
);
67 bank
= &cq_table
->bank
[bankid
];
69 id
= ida_alloc_range(&bank
->ida
, bank
->min
, bank
->max
, GFP_KERNEL
);
71 mutex_unlock(&cq_table
->bank_mutex
);
75 /* the lower 2 bits is bankid */
76 hr_cq
->cqn
= (id
<< CQ_BANKID_SHIFT
) | bankid
;
78 mutex_unlock(&cq_table
->bank_mutex
);
83 static inline u8
get_cq_bankid(unsigned long cqn
)
85 /* The lower 2 bits of CQN are used to hash to different banks */
86 return (u8
)(cqn
& GENMASK(1, 0));
89 static void free_cqn(struct hns_roce_dev
*hr_dev
, unsigned long cqn
)
91 struct hns_roce_cq_table
*cq_table
= &hr_dev
->cq_table
;
92 struct hns_roce_bank
*bank
;
94 bank
= &cq_table
->bank
[get_cq_bankid(cqn
)];
96 ida_free(&bank
->ida
, cqn
>> CQ_BANKID_SHIFT
);
98 mutex_lock(&cq_table
->bank_mutex
);
100 mutex_unlock(&cq_table
->bank_mutex
);
103 static int hns_roce_create_cqc(struct hns_roce_dev
*hr_dev
,
104 struct hns_roce_cq
*hr_cq
,
105 u64
*mtts
, dma_addr_t dma_handle
)
107 struct ib_device
*ibdev
= &hr_dev
->ib_dev
;
108 struct hns_roce_cmd_mailbox
*mailbox
;
111 mailbox
= hns_roce_alloc_cmd_mailbox(hr_dev
);
112 if (IS_ERR(mailbox
)) {
113 ibdev_err(ibdev
, "failed to alloc mailbox for CQC.\n");
114 return PTR_ERR(mailbox
);
117 hr_dev
->hw
->write_cqc(hr_dev
, hr_cq
, mailbox
->buf
, mtts
, dma_handle
);
119 ret
= hns_roce_create_hw_ctx(hr_dev
, mailbox
, HNS_ROCE_CMD_CREATE_CQC
,
123 "failed to send create cmd for CQ(0x%lx), ret = %d.\n",
126 hns_roce_free_cmd_mailbox(hr_dev
, mailbox
);
131 static int alloc_cqc(struct hns_roce_dev
*hr_dev
, struct hns_roce_cq
*hr_cq
)
133 struct hns_roce_cq_table
*cq_table
= &hr_dev
->cq_table
;
134 struct ib_device
*ibdev
= &hr_dev
->ib_dev
;
135 u64 mtts
[MTT_MIN_COUNT
] = {};
138 ret
= hns_roce_mtr_find(hr_dev
, &hr_cq
->mtr
, 0, mtts
, ARRAY_SIZE(mtts
));
140 ibdev_err(ibdev
, "failed to find CQ mtr, ret = %d.\n", ret
);
144 /* Get CQC memory HEM(Hardware Entry Memory) table */
145 ret
= hns_roce_table_get(hr_dev
, &cq_table
->table
, hr_cq
->cqn
);
147 ibdev_err(ibdev
, "failed to get CQ(0x%lx) context, ret = %d.\n",
152 ret
= xa_err(xa_store_irq(&cq_table
->array
, hr_cq
->cqn
, hr_cq
, GFP_KERNEL
));
154 ibdev_err(ibdev
, "failed to xa_store CQ, ret = %d.\n", ret
);
158 ret
= hns_roce_create_cqc(hr_dev
, hr_cq
, mtts
,
159 hns_roce_get_mtr_ba(&hr_cq
->mtr
));
166 xa_erase_irq(&cq_table
->array
, hr_cq
->cqn
);
168 hns_roce_table_put(hr_dev
, &cq_table
->table
, hr_cq
->cqn
);
173 static void free_cqc(struct hns_roce_dev
*hr_dev
, struct hns_roce_cq
*hr_cq
)
175 struct hns_roce_cq_table
*cq_table
= &hr_dev
->cq_table
;
176 struct device
*dev
= hr_dev
->dev
;
179 ret
= hns_roce_destroy_hw_ctx(hr_dev
, HNS_ROCE_CMD_DESTROY_CQC
,
182 dev_err_ratelimited(dev
, "DESTROY_CQ failed (%d) for CQN %06lx\n",
185 xa_erase_irq(&cq_table
->array
, hr_cq
->cqn
);
187 /* Waiting interrupt process procedure carried out */
188 synchronize_irq(hr_dev
->eq_table
.eq
[hr_cq
->vector
].irq
);
190 /* wait for all interrupt processed */
191 if (refcount_dec_and_test(&hr_cq
->refcount
))
192 complete(&hr_cq
->free
);
193 wait_for_completion(&hr_cq
->free
);
195 hns_roce_table_put(hr_dev
, &cq_table
->table
, hr_cq
->cqn
);
198 static int alloc_cq_buf(struct hns_roce_dev
*hr_dev
, struct hns_roce_cq
*hr_cq
,
199 struct ib_udata
*udata
, unsigned long addr
)
201 struct ib_device
*ibdev
= &hr_dev
->ib_dev
;
202 struct hns_roce_buf_attr buf_attr
= {};
205 buf_attr
.page_shift
= hr_dev
->caps
.cqe_buf_pg_sz
+ PAGE_SHIFT
;
206 buf_attr
.region
[0].size
= hr_cq
->cq_depth
* hr_cq
->cqe_size
;
207 buf_attr
.region
[0].hopnum
= hr_dev
->caps
.cqe_hop_num
;
208 buf_attr
.region_count
= 1;
210 ret
= hns_roce_mtr_create(hr_dev
, &hr_cq
->mtr
, &buf_attr
,
211 hr_dev
->caps
.cqe_ba_pg_sz
+ PAGE_SHIFT
,
214 ibdev_err(ibdev
, "failed to alloc CQ mtr, ret = %d.\n", ret
);
219 static void free_cq_buf(struct hns_roce_dev
*hr_dev
, struct hns_roce_cq
*hr_cq
)
221 hns_roce_mtr_destroy(hr_dev
, &hr_cq
->mtr
);
224 static int alloc_cq_db(struct hns_roce_dev
*hr_dev
, struct hns_roce_cq
*hr_cq
,
225 struct ib_udata
*udata
, unsigned long addr
,
226 struct hns_roce_ib_create_cq_resp
*resp
)
228 bool has_db
= hr_dev
->caps
.flags
& HNS_ROCE_CAP_FLAG_CQ_RECORD_DB
;
229 struct hns_roce_ucontext
*uctx
;
234 udata
->outlen
>= offsetofend(typeof(*resp
), cap_flags
)) {
235 uctx
= rdma_udata_to_drv_context(udata
,
236 struct hns_roce_ucontext
, ibucontext
);
237 err
= hns_roce_db_map_user(uctx
, addr
, &hr_cq
->db
);
240 hr_cq
->flags
|= HNS_ROCE_CQ_FLAG_RECORD_DB
;
241 resp
->cap_flags
|= HNS_ROCE_CQ_FLAG_RECORD_DB
;
245 err
= hns_roce_alloc_db(hr_dev
, &hr_cq
->db
, 1);
248 hr_cq
->set_ci_db
= hr_cq
->db
.db_record
;
249 *hr_cq
->set_ci_db
= 0;
250 hr_cq
->flags
|= HNS_ROCE_CQ_FLAG_RECORD_DB
;
252 hr_cq
->db_reg
= hr_dev
->reg_base
+ hr_dev
->odb_offset
+
253 DB_REG_OFFSET
* hr_dev
->priv_uar
.index
;
259 static void free_cq_db(struct hns_roce_dev
*hr_dev
, struct hns_roce_cq
*hr_cq
,
260 struct ib_udata
*udata
)
262 struct hns_roce_ucontext
*uctx
;
264 if (!(hr_cq
->flags
& HNS_ROCE_CQ_FLAG_RECORD_DB
))
267 hr_cq
->flags
&= ~HNS_ROCE_CQ_FLAG_RECORD_DB
;
269 uctx
= rdma_udata_to_drv_context(udata
,
270 struct hns_roce_ucontext
,
272 hns_roce_db_unmap_user(uctx
, &hr_cq
->db
);
274 hns_roce_free_db(hr_dev
, &hr_cq
->db
);
278 static int verify_cq_create_attr(struct hns_roce_dev
*hr_dev
,
279 const struct ib_cq_init_attr
*attr
)
281 struct ib_device
*ibdev
= &hr_dev
->ib_dev
;
283 if (!attr
->cqe
|| attr
->cqe
> hr_dev
->caps
.max_cqes
) {
284 ibdev_err(ibdev
, "failed to check CQ count %u, max = %u.\n",
285 attr
->cqe
, hr_dev
->caps
.max_cqes
);
289 if (attr
->comp_vector
>= hr_dev
->caps
.num_comp_vectors
) {
290 ibdev_err(ibdev
, "failed to check CQ vector = %u, max = %d.\n",
291 attr
->comp_vector
, hr_dev
->caps
.num_comp_vectors
);
298 static int get_cq_ucmd(struct hns_roce_cq
*hr_cq
, struct ib_udata
*udata
,
299 struct hns_roce_ib_create_cq
*ucmd
)
301 struct ib_device
*ibdev
= hr_cq
->ib_cq
.device
;
304 ret
= ib_copy_from_udata(ucmd
, udata
, min(udata
->inlen
, sizeof(*ucmd
)));
306 ibdev_err(ibdev
, "failed to copy CQ udata, ret = %d.\n", ret
);
313 static void set_cq_param(struct hns_roce_cq
*hr_cq
, u32 cq_entries
, int vector
,
314 struct hns_roce_ib_create_cq
*ucmd
)
316 struct hns_roce_dev
*hr_dev
= to_hr_dev(hr_cq
->ib_cq
.device
);
318 cq_entries
= max(cq_entries
, hr_dev
->caps
.min_cqes
);
319 cq_entries
= roundup_pow_of_two(cq_entries
);
320 hr_cq
->ib_cq
.cqe
= cq_entries
- 1; /* used as cqe index */
321 hr_cq
->cq_depth
= cq_entries
;
322 hr_cq
->vector
= vector
;
324 spin_lock_init(&hr_cq
->lock
);
325 INIT_LIST_HEAD(&hr_cq
->sq_list
);
326 INIT_LIST_HEAD(&hr_cq
->rq_list
);
329 static int set_cqe_size(struct hns_roce_cq
*hr_cq
, struct ib_udata
*udata
,
330 struct hns_roce_ib_create_cq
*ucmd
)
332 struct hns_roce_dev
*hr_dev
= to_hr_dev(hr_cq
->ib_cq
.device
);
335 hr_cq
->cqe_size
= hr_dev
->caps
.cqe_sz
;
339 if (udata
->inlen
>= offsetofend(typeof(*ucmd
), cqe_size
)) {
340 if (ucmd
->cqe_size
!= HNS_ROCE_V2_CQE_SIZE
&&
341 ucmd
->cqe_size
!= HNS_ROCE_V3_CQE_SIZE
) {
342 ibdev_err(&hr_dev
->ib_dev
,
343 "invalid cqe size %u.\n", ucmd
->cqe_size
);
347 hr_cq
->cqe_size
= ucmd
->cqe_size
;
349 hr_cq
->cqe_size
= HNS_ROCE_V2_CQE_SIZE
;
355 int hns_roce_create_cq(struct ib_cq
*ib_cq
, const struct ib_cq_init_attr
*attr
,
356 struct uverbs_attr_bundle
*attrs
)
358 struct hns_roce_dev
*hr_dev
= to_hr_dev(ib_cq
->device
);
359 struct ib_udata
*udata
= &attrs
->driver_udata
;
360 struct hns_roce_ib_create_cq_resp resp
= {};
361 struct hns_roce_cq
*hr_cq
= to_hr_cq(ib_cq
);
362 struct ib_device
*ibdev
= &hr_dev
->ib_dev
;
363 struct hns_roce_ib_create_cq ucmd
= {};
371 ret
= verify_cq_create_attr(hr_dev
, attr
);
376 ret
= get_cq_ucmd(hr_cq
, udata
, &ucmd
);
381 set_cq_param(hr_cq
, attr
->cqe
, attr
->comp_vector
, &ucmd
);
383 ret
= set_cqe_size(hr_cq
, udata
, &ucmd
);
387 ret
= alloc_cq_buf(hr_dev
, hr_cq
, udata
, ucmd
.buf_addr
);
389 ibdev_err(ibdev
, "failed to alloc CQ buf, ret = %d.\n", ret
);
393 ret
= alloc_cq_db(hr_dev
, hr_cq
, udata
, ucmd
.db_addr
, &resp
);
395 ibdev_err(ibdev
, "failed to alloc CQ db, ret = %d.\n", ret
);
399 ret
= alloc_cqn(hr_dev
, hr_cq
);
401 ibdev_err(ibdev
, "failed to alloc CQN, ret = %d.\n", ret
);
405 ret
= alloc_cqc(hr_dev
, hr_cq
);
408 "failed to alloc CQ context, ret = %d.\n", ret
);
413 resp
.cqn
= hr_cq
->cqn
;
414 ret
= ib_copy_to_udata(udata
, &resp
,
415 min(udata
->outlen
, sizeof(resp
)));
420 hr_cq
->cons_index
= 0;
422 refcount_set(&hr_cq
->refcount
, 1);
423 init_completion(&hr_cq
->free
);
428 free_cqc(hr_dev
, hr_cq
);
430 free_cqn(hr_dev
, hr_cq
->cqn
);
432 free_cq_db(hr_dev
, hr_cq
, udata
);
434 free_cq_buf(hr_dev
, hr_cq
);
436 atomic64_inc(&hr_dev
->dfx_cnt
[HNS_ROCE_DFX_CQ_CREATE_ERR_CNT
]);
441 int hns_roce_destroy_cq(struct ib_cq
*ib_cq
, struct ib_udata
*udata
)
443 struct hns_roce_dev
*hr_dev
= to_hr_dev(ib_cq
->device
);
444 struct hns_roce_cq
*hr_cq
= to_hr_cq(ib_cq
);
446 free_cqc(hr_dev
, hr_cq
);
447 free_cqn(hr_dev
, hr_cq
->cqn
);
448 free_cq_db(hr_dev
, hr_cq
, udata
);
449 free_cq_buf(hr_dev
, hr_cq
);
454 void hns_roce_cq_completion(struct hns_roce_dev
*hr_dev
, u32 cqn
)
456 struct hns_roce_cq
*hr_cq
;
459 hr_cq
= xa_load(&hr_dev
->cq_table
.array
,
460 cqn
& (hr_dev
->caps
.num_cqs
- 1));
462 dev_warn(hr_dev
->dev
, "completion event for bogus CQ 0x%06x\n",
468 ibcq
= &hr_cq
->ib_cq
;
469 if (ibcq
->comp_handler
)
470 ibcq
->comp_handler(ibcq
, ibcq
->cq_context
);
473 void hns_roce_cq_event(struct hns_roce_dev
*hr_dev
, u32 cqn
, int event_type
)
475 struct device
*dev
= hr_dev
->dev
;
476 struct hns_roce_cq
*hr_cq
;
477 struct ib_event event
;
480 if (event_type
!= HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID
&&
481 event_type
!= HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR
&&
482 event_type
!= HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW
) {
483 dev_err(dev
, "unexpected event type 0x%x on CQ 0x%06x\n",
488 xa_lock(&hr_dev
->cq_table
.array
);
489 hr_cq
= xa_load(&hr_dev
->cq_table
.array
,
490 cqn
& (hr_dev
->caps
.num_cqs
- 1));
492 refcount_inc(&hr_cq
->refcount
);
493 xa_unlock(&hr_dev
->cq_table
.array
);
495 dev_warn(dev
, "async event for bogus CQ 0x%06x\n", cqn
);
499 ibcq
= &hr_cq
->ib_cq
;
500 if (ibcq
->event_handler
) {
501 event
.device
= ibcq
->device
;
502 event
.element
.cq
= ibcq
;
503 event
.event
= IB_EVENT_CQ_ERR
;
504 ibcq
->event_handler(&event
, ibcq
->cq_context
);
507 if (refcount_dec_and_test(&hr_cq
->refcount
))
508 complete(&hr_cq
->free
);
511 void hns_roce_init_cq_table(struct hns_roce_dev
*hr_dev
)
513 struct hns_roce_cq_table
*cq_table
= &hr_dev
->cq_table
;
514 unsigned int reserved_from_bot
;
517 mutex_init(&cq_table
->bank_mutex
);
518 xa_init(&cq_table
->array
);
520 reserved_from_bot
= hr_dev
->caps
.reserved_cqs
;
522 for (i
= 0; i
< reserved_from_bot
; i
++) {
523 cq_table
->bank
[get_cq_bankid(i
)].inuse
++;
524 cq_table
->bank
[get_cq_bankid(i
)].min
++;
527 for (i
= 0; i
< HNS_ROCE_CQ_BANK_NUM
; i
++) {
528 ida_init(&cq_table
->bank
[i
].ida
);
529 cq_table
->bank
[i
].max
= hr_dev
->caps
.num_cqs
/
530 HNS_ROCE_CQ_BANK_NUM
- 1;
534 void hns_roce_cleanup_cq_table(struct hns_roce_dev
*hr_dev
)
538 for (i
= 0; i
< HNS_ROCE_CQ_BANK_NUM
; i
++)
539 ida_destroy(&hr_dev
->cq_table
.bank
[i
].ida
);
540 mutex_destroy(&hr_dev
->cq_table
.bank_mutex
);