[IBAL, HW] Remove pointers from ci_umv_buf_t.
[mirror/winof/.git] / hw / mthca / user / mlnx_ual_qp.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$\r
32  */\r
33 \r
34 #include "mt_l2w.h"\r
35 #include "mlnx_uvp.h"\r
36 #include "mx_abi.h"\r
37 \r
38 #include "mlnx_ual_main.h"\r
39 #if defined(EVENT_TRACING)\r
40 #include "mlnx_ual_qp.tmh"\r
41 #endif\r
42 \r
43 static void\r
44 __nd_modify_qp(\r
45         IN              const   ib_qp_handle_t                          h_uvp_qp,\r
46         OUT                             void**                                          pp_outbuf,\r
47         OUT                             DWORD*                                  p_size\r
48         )\r
49 {\r
50         struct ibv_qp *ibv_qp = (struct ibv_qp *)h_uvp_qp;\r
51         UVP_ENTER(UVP_DBG_QP);\r
52         *(uint32_t**)pp_outbuf = (uint32_t*)&ibv_qp->state;\r
53         *p_size = sizeof(ibv_qp->state);\r
54         UVP_EXIT(UVP_DBG_QP);\r
55 }\r
56 \r
57 static ib_qp_state_t __qp_state_to_ibal(enum ibv_qp_state state)\r
58 {\r
59         switch ( state ) {\r
60                 case IBV_QPS_RESET: return IB_QPS_RESET;\r
61                 case IBV_QPS_INIT: return IB_QPS_INIT;\r
62                 case IBV_QPS_RTR: return IB_QPS_RTR;\r
63                 case IBV_QPS_RTS: return IB_QPS_RTS;\r
64                 case IBV_QPS_SQD: return IB_QPS_SQD;\r
65                 case IBV_QPS_SQE: return IB_QPS_SQERR;\r
66                 case IBV_QPS_ERR: return IB_QPS_ERROR;\r
67                 default: return IB_QPS_TIME_WAIT;\r
68         };\r
69 }\r
70 \r
71 static uint32_t\r
72 __nd_get_qp_state(\r
73         IN              const   ib_qp_handle_t                          h_uvp_qp\r
74         )\r
75 {\r
76         struct ibv_qp *ibv_qp = (struct ibv_qp *)h_uvp_qp;\r
77         UVP_ENTER(UVP_DBG_QP);\r
78         return __qp_state_to_ibal( ibv_qp->state );\r
79         UVP_EXIT(UVP_DBG_QP);\r
80 }\r
81 \r
82 static ib_api_status_t\r
83 __pre_create_qp (\r
84         IN              const ib_pd_handle_t            h_uvp_pd,\r
85         IN              const ib_qp_create_t            *p_create_attr,\r
86         IN OUT  ci_umv_buf_t                    *p_umv_buf,\r
87            OUT  ib_qp_handle_t                          *ph_uvp_qp)\r
88 {\r
89         int err;\r
90         struct ibv_qp *ibv_qp;\r
91         struct ibv_qp_init_attr attr;\r
92         struct ibv_create_qp *p_create_qp;\r
93         ib_api_status_t status = IB_SUCCESS;\r
94         size_t size = max( sizeof(struct ibv_create_qp), sizeof(struct ibv_create_qp_resp) );\r
95         struct ibv_pd *ibv_pd = h_uvp_pd->ibv_pd;\r
96 \r
97         UNREFERENCED_PARAMETER(ph_uvp_qp);\r
98                 \r
99         UVP_ENTER(UVP_DBG_QP);\r
100 \r
101         CL_ASSERT(p_umv_buf);\r
102 \r
103         if( !p_umv_buf->p_inout_buf )\r
104         {\r
105                 p_umv_buf->p_inout_buf = (ULONG_PTR)cl_zalloc( size );\r
106                 if( !p_umv_buf->p_inout_buf )\r
107                 {\r
108                         status = IB_INSUFFICIENT_MEMORY;\r
109                         goto err_memory;\r
110                 }\r
111         }\r
112         p_umv_buf->input_size = sizeof(struct ibv_create_qp);\r
113         p_umv_buf->output_size = sizeof(struct ibv_create_qp_resp);\r
114         p_umv_buf->command = TRUE;\r
115 \r
116         /* convert attributes */\r
117         attr.send_cq                            = (struct ibv_cq *)p_create_attr->h_sq_cq;\r
118         attr.recv_cq                            = (struct ibv_cq *)p_create_attr->h_rq_cq;\r
119         attr.srq                                        = (struct ibv_srq*)p_create_attr->h_srq;\r
120         attr.cap.max_send_wr            = p_create_attr->sq_depth;\r
121         attr.cap.max_recv_wr            = p_create_attr->rq_depth;\r
122         attr.cap.max_send_sge           = p_create_attr->sq_sge;\r
123         attr.cap.max_recv_sge           = p_create_attr->rq_sge;\r
124         attr.cap.max_inline_data        = p_create_attr->sq_max_inline;\r
125         attr.qp_type                                                    = p_create_attr->qp_type;\r
126         attr.sq_sig_all                                         = p_create_attr->sq_signaled;\r
127         \r
128         /* allocate ibv_qp */\r
129         p_create_qp = (struct ibv_create_qp *)p_umv_buf->p_inout_buf;\r
130         ibv_qp = ibv_pd->context->ops.create_qp_pre(ibv_pd, &attr, p_create_qp);\r
131         if (IS_ERR(ibv_qp)) {\r
132                 err = PTR_ERR(ibv_qp);\r
133                 UVP_PRINT(TRACE_LEVEL_ERROR ,UVP_DBG_QP ,("mthca_create_qp_pre failed (%d)\n", err));\r
134                 if(err == -ENOMEM && (attr.cap.max_send_sge == 0 ||attr.cap.max_recv_sge == 0|| \r
135                         attr.cap.max_send_wr == 0 || attr.cap.max_recv_wr == 0))\r
136                         status = IB_INVALID_SETTING;\r
137                 else\r
138                         status = errno_to_iberr(err);\r
139                 goto err_alloc_qp;\r
140         }\r
141 \r
142         goto end;\r
143                 \r
144 err_alloc_qp:\r
145         cl_free((void*)(ULONG_PTR)p_umv_buf->p_inout_buf);\r
146 err_memory:\r
147 end:\r
148                 UVP_EXIT(UVP_DBG_QP);\r
149                 return status;\r
150 }\r
151 \r
152 static ib_api_status_t\r
153 __post_create_qp (\r
154         IN              const ib_pd_handle_t                            h_uvp_pd,\r
155         IN                              ib_api_status_t                         ioctl_status,\r
156         IN      OUT                     ib_qp_handle_t                          *ph_uvp_qp,\r
157         IN                              ci_umv_buf_t                            *p_umv_buf )\r
158 {\r
159         int err;\r
160         struct ibv_qp *ibv_qp;\r
161         struct ibv_create_qp_resp *p_resp;\r
162         struct ibv_create_qp *p_create_qp;\r
163         ib_api_status_t status = IB_SUCCESS;\r
164         struct ibv_pd *ibv_pd = h_uvp_pd->ibv_pd;\r
165 \r
166         UVP_ENTER(UVP_DBG_QP);\r
167 \r
168 \r
169         CL_ASSERT(p_umv_buf);\r
170         p_resp = (struct ibv_create_qp_resp *)p_umv_buf->p_inout_buf;\r
171 \r
172         if (IB_SUCCESS == ioctl_status) {\r
173 \r
174                 /* allocate ibv_qp */\r
175                 ibv_qp = ibv_pd->context->ops.create_qp_post(ibv_pd, p_resp);\r
176                 if (IS_ERR(ibv_qp)) {\r
177                         err = PTR_ERR(ibv_qp);\r
178                         UVP_PRINT(TRACE_LEVEL_ERROR ,UVP_DBG_QP , ("mthca_create_qp_post failed (%d)\n", err));\r
179                         status = errno_to_iberr(err);\r
180                         goto err_create_cq;\r
181                 }\r
182 \r
183                 *ph_uvp_qp = (ib_qp_handle_t)ibv_qp;\r
184         }\r
185         goto end;\r
186         \r
187         ibv_pd->context->ops.destroy_qp(ibv_qp);\r
188 err_create_cq:\r
189 end:    \r
190         if (p_resp)\r
191                 cl_free( p_resp );\r
192         UVP_EXIT(UVP_DBG_QP);\r
193         return status;\r
194 }\r
195 \r
196 static ib_api_status_t\r
197 __pre_modify_qp (\r
198         IN              const ib_qp_handle_t    h_uvp_qp,\r
199         IN              const ib_qp_mod_t               *p_modify_attr,\r
200         IN OUT  ci_umv_buf_t                    *p_umv_buf)\r
201 {\r
202         ib_api_status_t status = IB_SUCCESS;\r
203         UNREFERENCED_PARAMETER(h_uvp_qp);\r
204         UNREFERENCED_PARAMETER(p_modify_attr);\r
205 \r
206         UVP_ENTER(UVP_DBG_SHIM);\r
207 \r
208         CL_ASSERT(p_umv_buf);\r
209 \r
210         if( !p_umv_buf->p_inout_buf )\r
211         {\r
212                 p_umv_buf->p_inout_buf =\r
213                         (ULONG_PTR)cl_zalloc( sizeof(struct ibv_modify_qp_resp) );\r
214                 if( !p_umv_buf->p_inout_buf )\r
215                 {\r
216                         status = IB_INSUFFICIENT_MEMORY;\r
217                         goto err_memory;\r
218                 }\r
219         }\r
220         p_umv_buf->input_size = 0;\r
221         p_umv_buf->output_size = sizeof(struct ibv_modify_qp_resp);\r
222         p_umv_buf->command = TRUE;\r
223         \r
224 err_memory:\r
225         UVP_EXIT(UVP_DBG_SHIM);\r
226         return status;\r
227 }\r
228 \r
229 \r
230 static void\r
231 __post_modify_qp (\r
232         IN              const ib_qp_handle_t    h_uvp_qp,\r
233         IN              ib_api_status_t                 ioctl_status,\r
234         IN OUT  ci_umv_buf_t                    *p_umv_buf)\r
235 {\r
236         int err;\r
237         ib_api_status_t status;\r
238         struct ibv_modify_qp_resp *p_resp; \r
239         struct ibv_qp_attr attr;\r
240         struct ibv_qp *ibv_qp = (struct ibv_qp *)h_uvp_qp;\r
241 \r
242         UVP_ENTER(UVP_DBG_SHIM);\r
243         CL_ASSERT(p_umv_buf);\r
244 \r
245         p_resp = (struct ibv_modify_qp_resp *)p_umv_buf->p_inout_buf;\r
246 \r
247         if (IB_SUCCESS == ioctl_status) \r
248         {\r
249                 memset( &attr, 0, sizeof(attr));\r
250                 attr.qp_state = p_resp->qp_state;\r
251                 if (ibv_qp) {\r
252                         err = ibv_qp->context->ops.modify_qp(   ibv_qp,\r
253                                                                                                         &attr, p_resp->attr_mask);\r
254                         if (err) {\r
255                                 UVP_PRINT(TRACE_LEVEL_ERROR ,UVP_DBG_SHIM , ("mthca_modify_qp failed (%d)\n", err));\r
256                                 status = errno_to_iberr(err);\r
257                                 goto err_modify_qp;\r
258                         }\r
259                 }\r
260                 UVP_PRINT(TRACE_LEVEL_INFORMATION ,UVP_DBG_SHIM ,\r
261                         ("Committed to modify QP to state %d\n", p_resp->qp_state));\r
262         }\r
263 \r
264 \r
265 err_modify_qp:\r
266         if (p_resp)\r
267                 cl_free (p_resp);\r
268         UVP_EXIT(UVP_DBG_SHIM);\r
269         return;\r
270         }\r
271 \r
272 \r
273 static ib_api_status_t\r
274 __pre_query_qp (\r
275         IN              ib_qp_handle_t                          h_uvp_qp,\r
276         IN OUT  ci_umv_buf_t                            *p_umv_buf)\r
277 {\r
278         UNREFERENCED_PARAMETER(h_uvp_qp);\r
279         UVP_ENTER(UVP_DBG_SHIM);\r
280         p_umv_buf->input_size = p_umv_buf->output_size = 0;\r
281         p_umv_buf->command = FALSE;\r
282         p_umv_buf->status = IB_SUCCESS;\r
283         UVP_EXIT(UVP_DBG_SHIM);\r
284         return IB_SUCCESS;\r
285 }\r
286 \r
287 \r
288 static void\r
289 __post_query_qp (\r
290         IN                              ib_qp_handle_t                          h_uvp_qp,\r
291         IN                              ib_api_status_t                         ioctl_status,\r
292         IN      OUT                     ib_qp_attr_t                            *p_query_attr,\r
293         IN      OUT                     ci_umv_buf_t                            *p_umv_buf)\r
294 {\r
295         struct mthca_qp *p_mthca_qp = (struct mthca_qp *)h_uvp_qp;\r
296         UVP_ENTER(UVP_DBG_SHIM);\r
297 \r
298         UNREFERENCED_PARAMETER(p_umv_buf);\r
299         if(IB_SUCCESS == ioctl_status)\r
300         {\r
301                 p_query_attr->sq_max_inline = p_mthca_qp->max_inline_data;\r
302                 p_query_attr->sq_sge = p_mthca_qp->sq.max_gs;\r
303                 p_query_attr->sq_depth = p_mthca_qp->sq.max;\r
304                 p_query_attr->rq_sge = p_mthca_qp->rq.max_gs;\r
305                 p_query_attr->rq_depth = p_mthca_qp->rq.max;\r
306         }\r
307         UVP_EXIT(UVP_DBG_SHIM);\r
308 }\r
309 \r
310 \r
311 static ib_api_status_t\r
312 __pre_destroy_qp (\r
313     IN          const ib_qp_handle_t            h_uvp_qp)\r
314 {\r
315         int err;\r
316 \r
317 \r
318         UVP_ENTER(UVP_DBG_SHIM);\r
319 \r
320         mthca_destroy_qp_pre((struct ibv_qp*)h_uvp_qp);\r
321 \r
322         UVP_EXIT(UVP_DBG_SHIM);\r
323         return IB_SUCCESS;\r
324 }\r
325 \r
326 static void\r
327 __post_destroy_qp (\r
328         IN              const ib_qp_handle_t    h_uvp_qp,\r
329     IN          ib_api_status_t                 ioctl_status)\r
330 {\r
331         int err;\r
332 \r
333         UVP_ENTER(UVP_DBG_SHIM);\r
334 \r
335         CL_ASSERT(h_uvp_qp);\r
336 \r
337         mthca_destroy_qp_post((struct ibv_qp*)h_uvp_qp, (int)ioctl_status);\r
338         if (ioctl_status != IB_SUCCESS) \r
339                 UVP_PRINT(TRACE_LEVEL_ERROR ,UVP_DBG_SHIM , ("mthca_destroy_qp_post failed (%d)\n", ioctl_status));\r
340 \r
341         UVP_EXIT(UVP_DBG_SHIM);\r
342         return;\r
343 }\r
344 \r
345 \r
346 void\r
347 mlnx_get_qp_interface (\r
348     IN OUT      uvp_interface_t         *p_uvp )\r
349 {\r
350     UVP_ENTER(UVP_DBG_SHIM);\r
351 \r
352     CL_ASSERT(p_uvp);\r
353 \r
354     /*\r
355      * QP Management Verbs\r
356      */\r
357     p_uvp->pre_create_qp   = __pre_create_qp;\r
358     p_uvp->post_create_qp  = __post_create_qp;\r
359 \r
360     // !!! none for create_spl_qp, UAL will return error !!!\r
361 \r
362     p_uvp->pre_modify_qp   = __pre_modify_qp;\r
363     p_uvp->post_modify_qp  = __post_modify_qp;\r
364     p_uvp->pre_query_qp    = NULL;\r
365     p_uvp->post_query_qp   = __post_query_qp;\r
366     p_uvp->pre_destroy_qp  = __pre_destroy_qp;\r
367     p_uvp->post_destroy_qp = __post_destroy_qp;\r
368     p_uvp->nd_modify_qp   = __nd_modify_qp;\r
369     p_uvp->nd_get_qp_state = __nd_get_qp_state;\r
370 \r
371     UVP_EXIT(UVP_DBG_SHIM);\r
372 }\r
373 \r
374 \r
375 \r