2 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 #include "rxe_queue.h"
38 int rxe_cq_chk_attr(struct rxe_dev
*rxe
, struct rxe_cq
*cq
,
39 int cqe
, int comp_vector
, struct ib_udata
*udata
)
44 pr_warn("cqe(%d) <= 0\n", cqe
);
48 if (cqe
> rxe
->attr
.max_cqe
) {
49 pr_warn("cqe(%d) > max_cqe(%d)\n",
50 cqe
, rxe
->attr
.max_cqe
);
55 count
= queue_count(cq
->queue
);
57 pr_warn("cqe(%d) < current # elements in queue (%d)",
69 static void rxe_send_complete(unsigned long data
)
71 struct rxe_cq
*cq
= (struct rxe_cq
*)data
;
73 cq
->ibcq
.comp_handler(&cq
->ibcq
, cq
->ibcq
.cq_context
);
76 int rxe_cq_from_init(struct rxe_dev
*rxe
, struct rxe_cq
*cq
, int cqe
,
77 int comp_vector
, struct ib_ucontext
*context
,
78 struct ib_udata
*udata
)
82 cq
->queue
= rxe_queue_init(rxe
, &cqe
,
83 sizeof(struct rxe_cqe
));
85 pr_warn("unable to create cq\n");
89 err
= do_mmap_info(rxe
, udata
, false, context
, cq
->queue
->buf
,
90 cq
->queue
->buf_size
, &cq
->queue
->ip
);
92 kvfree(cq
->queue
->buf
);
100 tasklet_init(&cq
->comp_task
, rxe_send_complete
, (unsigned long)cq
);
102 spin_lock_init(&cq
->cq_lock
);
107 int rxe_cq_resize_queue(struct rxe_cq
*cq
, int cqe
, struct ib_udata
*udata
)
111 err
= rxe_queue_resize(cq
->queue
, (unsigned int *)&cqe
,
112 sizeof(struct rxe_cqe
),
113 cq
->queue
->ip
? cq
->queue
->ip
->context
: NULL
,
114 udata
, NULL
, &cq
->cq_lock
);
121 int rxe_cq_post(struct rxe_cq
*cq
, struct rxe_cqe
*cqe
, int solicited
)
126 spin_lock_irqsave(&cq
->cq_lock
, flags
);
128 if (unlikely(queue_full(cq
->queue
))) {
129 spin_unlock_irqrestore(&cq
->cq_lock
, flags
);
130 if (cq
->ibcq
.event_handler
) {
131 ev
.device
= cq
->ibcq
.device
;
132 ev
.element
.cq
= &cq
->ibcq
;
133 ev
.event
= IB_EVENT_CQ_ERR
;
134 cq
->ibcq
.event_handler(&ev
, cq
->ibcq
.cq_context
);
140 memcpy(producer_addr(cq
->queue
), cqe
, sizeof(*cqe
));
142 /* make sure all changes to the CQ are written before we update the
147 advance_producer(cq
->queue
);
148 spin_unlock_irqrestore(&cq
->cq_lock
, flags
);
150 if ((cq
->notify
== IB_CQ_NEXT_COMP
) ||
151 (cq
->notify
== IB_CQ_SOLICITED
&& solicited
)) {
153 tasklet_schedule(&cq
->comp_task
);
159 void rxe_cq_cleanup(struct rxe_pool_entry
*arg
)
161 struct rxe_cq
*cq
= container_of(arg
, typeof(*cq
), pelem
);
164 rxe_queue_cleanup(cq
->queue
);