1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <sys/ib/ibtl/impl/ibtl.h>
26
27 /*
28 * ibtl_srq.c
29 * These routines implement (most of) the verbs related to
30 * Shared Receive Queues.
31 */
32
33 /*
34 * Globals
35 */
36
37 static char ibtf_srq[] = "ibtl_srq";
38
39 /*
40 * This file contains code for the TI SRQ calls
41 */
42
43 /*
44 *
45 * ibt_alloc_srq() - Allocate a completion queue
46 */
47 ibt_status_t
48 ibt_alloc_srq(ibt_hca_hdl_t hca_hdl, ibt_srq_flags_t flags, ibt_pd_hdl_t pd,
49 ibt_srq_sizes_t *srq_sizes, ibt_srq_hdl_t *ibt_srq_p,
50 ibt_srq_sizes_t *real_sizes_p)
51 {
52 ibt_status_t status;
53 ibt_srq_hdl_t ibt_srq;
54
55 IBTF_DPRINTF_L3(ibtf_srq, "ibt_alloc_srq(%p, %p)",
56 hca_hdl, srq_sizes);
57
58 ibt_srq = kmem_zalloc(sizeof (struct ibtl_srq_s), KM_SLEEP);
59 *ibt_srq_p = ibt_srq;
60
61 /*
62 * Set the following values before creating CI SRQ, to avoid race
63 * conditions on async callback.
64 */
65 ibt_srq->srq_hca = hca_hdl;
66
67 status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_srq(
68 IBTL_HCA2CIHCA(hca_hdl), flags, ibt_srq, pd, srq_sizes,
69 &ibt_srq->srq_ibc_srq_hdl, real_sizes_p);
70
71 if (status != IBT_SUCCESS) {
72 IBTF_DPRINTF_L2(ibtf_srq, "ibt_alloc_srq: "
73 "CI SRQ handle allocation failed: status = %d", status);
74 kmem_free(ibt_srq, sizeof (struct ibtl_srq_s));
75 *ibt_srq_p = NULL;
76 return (status);
77 }
78
79 /* Update the srq resource count */
80 atomic_inc_32(&hca_hdl->ha_srq_cnt);
81
82 return (IBT_SUCCESS);
83 }
84
85
86 /*
87 * ibt_free_srq() - Free a shared receive queue
88 *
89 */
90 ibt_status_t
91 ibt_free_srq(ibt_srq_hdl_t ibt_srq)
92 {
93 ibt_status_t status;
94 ibtl_hca_t *ibt_hca = ibt_srq->srq_hca;
95
96 IBTF_DPRINTF_L3(ibtf_srq, "ibt_free_srq(%p)", ibt_srq);
97
98 status = ((IBTL_SRQ2CIHCAOPS_P(ibt_srq))->ibc_free_srq)
99 (IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl);
100
101 if (status != IBT_SUCCESS) {
102 IBTF_DPRINTF_L2(ibtf_srq, "ibt_free_srq: "
103 "CI SRQ handle de-allocation failed: status = %d", status);
104 return (status);
105 }
106
107 ibtl_free_srq_async_check(ibt_srq);
108
109 /* Update the srq resource count */
110 atomic_dec_32(&ibt_hca->ha_srq_cnt);
111
112 return (status);
113 }
114
115
116 /*
117 * ibt_query_srq() - Returns the size of the srq
118 */
119 ibt_status_t
120 ibt_query_srq(ibt_srq_hdl_t ibt_srq, ibt_pd_hdl_t *pd_p,
121 ibt_srq_sizes_t *sizes_p, uint_t *limit)
122 {
123 IBTF_DPRINTF_L3(ibtf_srq, "ibt_query_srq(%p)", ibt_srq);
124
125 return (IBTL_SRQ2CIHCAOPS_P(ibt_srq)->ibc_query_srq(
126 IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl, pd_p,
127 sizes_p, limit));
128 }
129
130
131 /*
132 * ibt_resize_srq() - Change the size of a srq.
133 */
134 ibt_status_t
135 ibt_modify_srq(ibt_srq_hdl_t ibt_srq, ibt_srq_modify_flags_t flags,
136 uint_t size, uint_t limit, uint_t *real_size_p)
137 {
138 IBTF_DPRINTF_L3(ibtf_srq, "ibt_modify_srq(%p, %d, %d, %d)",
139 ibt_srq, flags, size, limit);
140
141 return (IBTL_SRQ2CIHCAOPS_P(ibt_srq)->ibc_modify_srq(
142 IBTL_SRQ2CIHCA(ibt_srq), ibt_srq->srq_ibc_srq_hdl,
143 flags, size, limit, real_size_p));
144 }
145
146
147 /*
148 * ibt_set_srq_private - Sets the private data on a given SRQ
149 *
150 * ibt_srq The ibt_srq_hdl_t of the allocated SRQ.
151 * clnt_private The client private data.
152 */
153 void
154 ibt_set_srq_private(ibt_srq_hdl_t ibt_srq, void *clnt_private)
155 {
156 ibt_srq->srq_clnt_private = clnt_private;
157 }
158
159
160 /*
161 * ibt_get_srq_private - Retrieves the private data for a given SRQ
162 *
163 * ibt_srq The ibt_srq_hdl_t of the allocated SRQ.
164 */
165 void *
166 ibt_get_srq_private(ibt_srq_hdl_t ibt_srq)
167 {
168 return (ibt_srq->srq_clnt_private);
169 }
170
171 /*
172 * Function:
173 * ibt_post_srq
174 * Input:
175 * srq - SRQ.
176 * wr_list - Address of array[size] of work requests.
177 * size - Number of work requests.
178 * Output:
179 * posted - Address to return the number of work requests
180 * successfully posted. May be NULL.
181 * Description:
182 * Post one or more receive work requests to the SRQ.
183 */
184
185 ibt_status_t
186 ibt_post_srq(ibt_srq_hdl_t srq, ibt_recv_wr_t *wr_list, uint_t size,
187 uint_t *posted)
188 {
189 IBTF_DPRINTF_L4(ibtf_srq, "ibt_post_srq(%p, %p, %d)",
190 srq, wr_list, size);
191
192 return (IBTL_SRQ2CIHCAOPS_P(srq)->ibc_post_srq(IBTL_SRQ2CIHCA(srq),
193 srq->srq_ibc_srq_hdl, wr_list, size, posted));
194 }