5f22b95fbb49ad739316c48f5919e71e195172d6
[mirror/winof/.git] / hw / mthca / user / mlnx_ual_srq.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 2004-2005 Mellanox Technologies, Inc. All rights reserved. \r
4  * Portions Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
5  *\r
6  * This software is available to you under the OpenIB.org BSD license\r
7  * below:\r
8  *\r
9  *     Redistribution and use in source and binary forms, with or\r
10  *     without modification, are permitted provided that the following\r
11  *     conditions are met:\r
12  *\r
13  *      - Redistributions of source code must retain the above\r
14  *        copyright notice, this list of conditions and the following\r
15  *        disclaimer.\r
16  *\r
17  *      - Redistributions in binary form must reproduce the above\r
18  *        copyright notice, this list of conditions and the following\r
19  *        disclaimer in the documentation and/or other materials\r
20  *        provided with the distribution.\r
21  *\r
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
25  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
26  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
27  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
28  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
29  * SOFTWARE.\r
30  *\r
31  * $Id: mlnx_ual_srq.c 1611 2006-08-20 14:48:55Z leonid $\r
32  */\r
33 \r
34 #include "mt_l2w.h"\r
35 #include "mlnx_ual_main.h"\r
36 #include "mlnx_uvp.h"\r
37 #include "mx_abi.h"\r
38 \r
39 #if defined(EVENT_TRACING)\r
40 #include "mlnx_ual_srq.tmh"\r
41 #endif\r
42 \r
43 \r
44 extern uint32_t mlnx_dbg_lvl;\r
45 \r
46 static void __free_srq(struct mthca_srq *srq)\r
47 {\r
48         /* srq may be NULL, when ioctl returned with some kind of error, e.g. IB_INVALID_PARAM */\r
49         if (!srq)\r
50                 return;\r
51         \r
52         if (mthca_is_memfree(srq->ibv_srq.context)) {\r
53                 mthca_free_db(to_mctx(srq->ibv_srq.context)->db_tab, MTHCA_DB_TYPE_SRQ,\r
54                 srq->db_index);\r
55         }\r
56 \r
57         if (srq->buf) {\r
58                 posix_memfree(srq->buf);\r
59         }\r
60 \r
61         if (srq->wrid) \r
62                 cl_free(srq->wrid);\r
63 \r
64         cl_spinlock_destroy(&srq->lock);\r
65         cl_free (srq);\r
66 }\r
67 \r
68 static ib_api_status_t  \r
69 __pre_create_srq (\r
70         IN              const   ib_pd_handle_t          h_uvp_pd,// Fix me: if needed\r
71         IN              const   ib_srq_attr_t           *p_srq_attr,\r
72         IN OUT  ci_umv_buf_t                            *p_umv_buf,\r
73             OUT ib_srq_handle_t                         *ph_uvp_srq)\r
74 {\r
75         struct mthca_srq *srq;\r
76         ib_api_status_t status = IB_SUCCESS;\r
77         size_t size = max( sizeof(struct ibv_create_srq), sizeof(struct ibv_create_srq_resp) );\r
78         mlnx_ual_pd_info_t *p_pd = (mlnx_ual_pd_info_t *)h_uvp_pd;\r
79         struct ibv_pd *ibv_pd = p_pd->ibv_pd;\r
80         struct ibv_create_srq *p_create_srq;\r
81         int err;\r
82 \r
83         UNREFERENCED_PARAMETER(ph_uvp_srq);\r
84         \r
85         UVP_ENTER(UVP_DBG_SRQ);\r
86 \r
87         CL_ASSERT(p_umv_buf);\r
88 \r
89         /* Sanity check SRQ size before proceeding */\r
90         if (p_srq_attr->max_wr > 1 << 16 || p_srq_attr->max_sge > 64)\r
91         {\r
92                 status = IB_INVALID_PARAMETER;\r
93                 goto err_params;\r
94         }\r
95 \r
96         if( !p_umv_buf->p_inout_buf )\r
97         {\r
98                 p_umv_buf->p_inout_buf = cl_zalloc( size );\r
99                 if( !p_umv_buf->p_inout_buf )\r
100                 {\r
101                         status = IB_INSUFFICIENT_MEMORY;\r
102                         goto err_memory;\r
103                 }\r
104         }\r
105         p_umv_buf->input_size = sizeof(struct ibv_create_srq);\r
106         p_umv_buf->output_size = sizeof(struct ibv_create_srq_resp);\r
107         p_umv_buf->command = TRUE;\r
108 \r
109         /* allocate srq */\r
110         srq = cl_zalloc(sizeof *srq);\r
111         if (!srq)\r
112         {\r
113                 status = IB_INSUFFICIENT_MEMORY;\r
114                 goto err_alloc_srq;\r
115         }\r
116 \r
117         /* init fields */\r
118         cl_spinlock_construct(&srq->lock);\r
119         if (cl_spinlock_init(&srq->lock))\r
120                 goto err_lock;\r
121 \r
122         srq->ibv_srq.pd = ibv_pd;\r
123         srq->ibv_srq.context                    = ibv_pd->context;\r
124         srq->max     = align_queue_size(ibv_pd->context, p_srq_attr->max_wr, 1);\r
125         srq->max_gs  = p_srq_attr->max_sge;\r
126         srq->counter = 0;\r
127 \r
128         if (mthca_alloc_srq_buf(ibv_pd, (void*)p_srq_attr, srq))\r
129         {\r
130                 status = IB_INSUFFICIENT_MEMORY;\r
131                 goto err_alloc_buf;\r
132         }\r
133 \r
134         // fill the parameters for ioctl\r
135         p_create_srq = (struct ibv_create_srq *)p_umv_buf->p_inout_buf;\r
136         p_create_srq->user_handle = (uint64_t)(ULONG_PTR)srq;\r
137         p_create_srq->mr.start = (uint64_t)(ULONG_PTR)srq->buf;\r
138         p_create_srq->mr.length = srq->buf_size;\r
139         p_create_srq->mr.hca_va = 0;\r
140         p_create_srq->mr.pd_handle       = p_pd->ibv_pd->handle;\r
141         p_create_srq->mr.pdn = to_mpd(p_pd->ibv_pd)->pdn;\r
142         p_create_srq->mr.access_flags = 0;      //local read\r
143 \r
144         if (mthca_is_memfree(ibv_pd->context)) {\r
145                 srq->db_index = mthca_alloc_db(to_mctx(ibv_pd->context)->db_tab,\r
146                         MTHCA_DB_TYPE_SRQ, &srq->db);\r
147                 if (srq->db_index < 0)\r
148                         goto err_alloc_db;\r
149 \r
150                 p_create_srq->db_page  = db_align(srq->db);\r
151                 p_create_srq->db_index = srq->db_index;\r
152         }\r
153 \r
154         status = IB_SUCCESS;\r
155         goto end;\r
156 \r
157 err_alloc_db:\r
158         posix_memfree(srq->buf);\r
159         cl_free(srq->wrid);\r
160 err_alloc_buf:\r
161         cl_spinlock_destroy(&srq->lock);\r
162 err_lock:\r
163         cl_free(srq);\r
164 err_alloc_srq:\r
165         cl_free(p_umv_buf->p_inout_buf);\r
166 err_memory:\r
167 err_params:\r
168 end:\r
169         UVP_EXIT(UVP_DBG_SRQ);\r
170         return status;\r
171 }\r
172 \r
173 \r
174 static void\r
175 __post_create_srq (\r
176         IN              const   ib_pd_handle_t                          h_uvp_pd,\r
177         IN                              ib_api_status_t                         ioctl_status,\r
178         IN      OUT                     ib_srq_handle_t                         *ph_uvp_srq,\r
179         IN                              ci_umv_buf_t                            *p_umv_buf )\r
180 {\r
181         int err;\r
182         struct mthca_srq *srq;\r
183         struct ibv_create_srq_resp *p_resp;\r
184         mlnx_ual_pd_info_t *p_pd = (mlnx_ual_pd_info_t *)h_uvp_pd;\r
185         struct ibv_pd *ibv_pd = p_pd->ibv_pd;\r
186         ib_api_status_t status = IB_SUCCESS;\r
187 \r
188         UVP_ENTER(UVP_DBG_SRQ);\r
189 \r
190         CL_ASSERT(p_umv_buf);\r
191         p_resp = (struct ibv_create_srq_resp *)p_umv_buf->p_inout_buf;\r
192         srq = (struct mthca_srq *)(ULONG_PTR)p_resp->user_handle;\r
193 \r
194         if (IB_SUCCESS == ioctl_status) {\r
195 \r
196                 /* complete filling SRQ object */\r
197                 srq->ibv_srq.handle                     = p_resp->srq_handle;\r
198                 srq->srqn                                       = p_resp->srqn;\r
199                 srq->max                                        = p_resp->max_wr;\r
200                 srq->max_gs                                     = p_resp->max_sge;\r
201                 srq->mr.handle = p_resp->mr.mr_handle;\r
202                 srq->mr.lkey = p_resp->mr.lkey;\r
203                 srq->mr.rkey = p_resp->mr.rkey;\r
204                 srq->mr.pd = ibv_pd;\r
205                 srq->mr.context = ibv_pd->context;\r
206 \r
207                 if (mthca_is_memfree(ibv_pd->context))\r
208                         mthca_set_db_qn(srq->db, MTHCA_DB_TYPE_SRQ, srq->srqn);\r
209                 \r
210                 *ph_uvp_srq = (ib_srq_handle_t)srq;\r
211         }\r
212         else\r
213                 __free_srq(srq);\r
214 \r
215         if (p_resp)\r
216                 cl_free( p_resp );\r
217         UVP_EXIT(UVP_DBG_SRQ);\r
218         return;\r
219 }\r
220 \r
221 static void\r
222 __post_destroy_srq (\r
223         IN              const ib_srq_handle_t   h_uvp_srq,\r
224         IN              ib_api_status_t                 ioctl_status)\r
225 {\r
226         int err;\r
227         struct mthca_srq *srq = (struct mthca_srq *) ((void*)h_uvp_srq);\r
228 \r
229         UVP_ENTER(UVP_DBG_CQ);\r
230 \r
231         CL_ASSERT(srq);\r
232 \r
233         if (IB_SUCCESS == ioctl_status) \r
234                 __free_srq(srq);\r
235 \r
236         UVP_EXIT(UVP_DBG_CQ);\r
237 }\r
238 \r
239 void\r
240 mlnx_get_srq_interface (\r
241         IN OUT  uvp_interface_t         *p_uvp )\r
242 {\r
243         UVP_ENTER(UVP_DBG_DEV);\r
244 \r
245         CL_ASSERT(p_uvp);\r
246 \r
247         /*\r
248          * Completion Queue Management Verbs\r
249          */\r
250         p_uvp->pre_create_srq  = __pre_create_srq;\r
251         p_uvp->post_create_srq = __post_create_srq;\r
252 \r
253         p_uvp->pre_query_srq  = NULL; /* __pre_query_srq; */\r
254         p_uvp->post_query_srq = NULL; /*__post_query_srq;*/\r
255 \r
256         p_uvp->pre_modify_srq  = NULL; /* __modify_srq;*/\r
257         p_uvp->post_modify_srq = NULL; /*__post_modify_srq;*/\r
258 \r
259         p_uvp->pre_destroy_srq  = NULL; /* __pre_destroy_srq; */\r
260         p_uvp->post_destroy_srq = __post_destroy_srq;\r
261 \r
262         UVP_EXIT(UVP_DBG_DEV);\r
263 }\r
264 \r
265 \r