[DAPL2] Sync with OFED DAPL 2.0.21 src release
[mirror/winof/.git] / ulp / dapl2 / dapl / ibal / dapl_ibal_cq.c
1 \r
2 /*\r
3  * Copyright (c) 2007 Intel Corporation.  All rights reserved.\r
4  * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. \r
5  * \r
6  * This Software is licensed under the terms of the "Common Public\r
7  * License" a copy of which is in the file LICENSE.txt in the root\r
8  * directory. The license is also available from the Open Source\r
9  * Initiative, see http://www.opensource.org/licenses/cpl.php.\r
10  *\r
11  */\r
12 \r
13 /**********************************************************************\r
14  * \r
15  * MODULE: dapl_ibal_cq.c\r
16  *\r
17  * PURPOSE: CQ (Completion Qeueu) access routine using IBAL APIs\r
18  *\r
19  * $Id$\r
20  *\r
21  **********************************************************************/\r
22 \r
23 #include "dapl.h"\r
24 #include "dapl_adapter_util.h"\r
25 #include "dapl_evd_util.h"\r
26 #include "dapl_cr_util.h"\r
27 #include "dapl_lmr_util.h"\r
28 #include "dapl_rmr_util.h"\r
29 #include "dapl_cookie.h"\r
30 #include "dapl_ring_buffer_util.h"\r
31 \r
32 #ifndef NO_NAME_SERVICE\r
33 #include "dapl_name_service.h"\r
34 #endif /* NO_NAME_SERVICE */\r
35 \r
36 \r
37 static void\r
38 dapli_ibal_cq_async_error_callback ( IN  ib_async_event_rec_t  *p_err_rec )\r
39 {\r
40     DAPL_EVD            *evd_ptr = (DAPL_EVD*)((void *)p_err_rec->context);\r
41     DAPL_EVD            *async_evd_ptr;\r
42     DAPL_IA             *ia_ptr;\r
43     dapl_ibal_ca_t      *p_ca;\r
44     dapl_ibal_evd_cb_t  *evd_cb;\r
45         \r
46     dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
47             "--> DiCqAEC: CQ error %d for EVD context %lx\n", \r
48             p_err_rec->code, p_err_rec->context);\r
49 \r
50     if (DAPL_BAD_HANDLE (evd_ptr, DAPL_MAGIC_EVD))\r
51     {\r
52         dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
53                       "--> DiCqAEC: invalid EVD %lx\n", evd_ptr);\r
54         return;\r
55     }\r
56                 \r
57     ia_ptr = evd_ptr->header.owner_ia;\r
58     async_evd_ptr = ia_ptr->async_error_evd;\r
59     if (async_evd_ptr == NULL)\r
60     {\r
61         dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiCqAEC: can't find async_error_evd on %s HCA\n", \r
62                 (ia_ptr->header.provider)->device_name );\r
63         return;\r
64     }\r
65 \r
66     p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
67     if (p_ca == NULL)\r
68     {\r
69         dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiCqAEC: can't find %s HCA\n", \r
70                 (ia_ptr->header.provider)->device_name);\r
71         return;\r
72     }\r
73 \r
74     /* find CQ error callback using ia_ptr for context */\r
75     evd_cb = dapli_find_evd_cb_by_context ( async_evd_ptr, p_ca );\r
76     if ((evd_cb == NULL) || (evd_cb->pfn_async_cq_err_cb == NULL))\r
77     {\r
78         dapl_dbg_log (DAPL_DBG_TYPE_ERR,\r
79                       "--> DiCqAEC: no ERROR cb on %lx found \n", p_ca);\r
80         return;\r
81     }\r
82 \r
83     /* maps to dapl_evd_cq_async_error_callback(), context is EVD */\r
84     evd_cb->pfn_async_cq_err_cb( (ib_hca_handle_t)p_ca, \r
85                                  evd_ptr->ib_cq_handle,\r
86                                  (ib_error_record_t*)&p_err_rec->code,\r
87                                  evd_ptr );\r
88 \r
89 }\r
90 \r
91 \r
92 /*\r
93  * dapli_ibal_cq_competion_callback\r
94  *\r
95  * Completion callback for a CQ\r
96  *\r
97  * Input:\r
98  *      cq_context               User context\r
99  *\r
100  * Output:\r
101  *      none\r
102  *\r
103  * Returns:\r
104  */\r
105 static void\r
106 dapli_ib_cq_completion_cb (\r
107         IN   const   ib_cq_handle_t   h_cq,\r
108         IN   void                     *cq_context )\r
109 {\r
110     DAPL_EVD           *evd_ptr;\r
111     dapl_ibal_ca_t     *p_ca;\r
112 \r
113     evd_ptr = (DAPL_EVD *) cq_context;\r
114 \r
115     dapl_dbg_log (DAPL_DBG_TYPE_CALLBACK, \r
116                   "--> DiICCC: cq_completion_cb evd %lx CQ %lx\n", \r
117                   evd_ptr, evd_ptr->ib_cq_handle);\r
118 \r
119     dapl_os_assert (evd_ptr != DAT_HANDLE_NULL);\r
120 \r
121     p_ca = (dapl_ibal_ca_t *) evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle;\r
122 \r
123     dapl_os_assert( h_cq == evd_ptr->ib_cq_handle );\r
124 \r
125     dapl_evd_dto_callback ( (ib_hca_handle_t) p_ca, h_cq, cq_context);\r
126 }\r
127 \r
128 \r
129 /*\r
130  * dapl_ib_cq_late_alloc\r
131  *\r
132  * Alloc a CQ\r
133  *\r
134  * Input:\r
135  *      ia_handle               IA handle\r
136  *      evd_ptr                 pointer to EVD struct\r
137  *      cqlen                   minimum QLen\r
138  *\r
139  * Output:\r
140  *      none\r
141  *\r
142  * Returns:\r
143  *      DAT_SUCCESS\r
144  *      DAT_INSUFFICIENT_RESOURCES\r
145  *\r
146  */\r
147 DAT_RETURN\r
148 dapls_ib_cq_late_alloc (\r
149         IN  ib_pd_handle_t        pd_handle,\r
150         IN  DAPL_EVD              *evd_ptr )\r
151 {\r
152     ib_cq_create_t  cq_create;\r
153     ib_api_status_t ib_status;\r
154     DAT_RETURN      dat_status;\r
155     dapl_ibal_ca_t  *ibal_ca;\r
156     \r
157     dat_status            = DAT_SUCCESS;\r
158     cq_create.size        = evd_ptr->qlen;\r
159     \r
160     ibal_ca = (dapl_ibal_ca_t*)evd_ptr->header.owner_ia->hca_ptr->ib_hca_handle;\r
161         \r
162     cq_create.h_wait_obj  = NULL;\r
163     cq_create.pfn_comp_cb = dapli_ib_cq_completion_cb;\r
164 \r
165     ib_status = ib_create_cq (\r
166                         (ib_ca_handle_t)ibal_ca->h_ca,\r
167                         &cq_create,\r
168                         evd_ptr /* context */,\r
169                         dapli_ibal_cq_async_error_callback,\r
170                         &evd_ptr->ib_cq_handle);\r
171 \r
172     dat_status = dapl_ib_status_convert (ib_status);\r
173 \r
174     if ( dat_status != DAT_SUCCESS )\r
175     {\r
176         dapl_dbg_log ( DAPL_DBG_TYPE_ERR,\r
177                        "--> DsICLA: failed to create CQ for EVD %lx\n",evd_ptr);\r
178         goto bail;\r
179     }\r
180 \r
181     dapl_dbg_log (DAPL_DBG_TYPE_UTIL, \r
182                   "--> DsCQ_alloc: pd=%lx cq=%lx CQsz=%d EVD->Qln=%d\n",\r
183                   pd_handle, evd_ptr->ib_cq_handle,\r
184                   cq_create.size, evd_ptr->qlen);\r
185 \r
186     /*\r
187      * As long as the CQ size is >= the evd size, then things are OK; sez Arlin.\r
188      */\r
189     if ( cq_create.size < (uint32_t)evd_ptr->qlen )\r
190     {\r
191         dapl_dbg_log (DAPL_DBG_TYPE_UTIL, \r
192                       "--> DsCQ_alloc: created CQ size(%d) < evd->qlen(%d)?\n",\r
193                       cq_create.size, evd_ptr->qlen);\r
194         dat_status = dapl_ib_status_convert (IB_INVALID_CQ_SIZE);\r
195     }\r
196     \r
197 bail: \r
198     return dat_status;\r
199 }\r
200 \r
201 /*\r
202  * dapl_ib_cq_alloc\r
203  *\r
204  * Alloc a CQ\r
205  *\r
206  * Input:\r
207  *      ia_handle               IA handle\r
208  *      evd_ptr                 pointer to EVD struct\r
209  *      cqlen                   minimum QLen\r
210  *\r
211  * Output:\r
212  *      none\r
213  *\r
214  * Returns:\r
215  *      DAT_SUCCESS\r
216  *      DAT_INSUFFICIENT_RESOURCES\r
217  *\r
218  */\r
219 \r
220 \r
221 /*\r
222  * dapl_ib_cq_free\r
223  *\r
224  * Dealloc a CQ\r
225  *\r
226  * Input:\r
227  *      ia_handle               IA handle\r
228  *      evd_ptr                 pointer to EVD struct\r
229  *\r
230  * Output:\r
231  *      none\r
232  *\r
233  * Returns:\r
234  *      DAT_SUCCESS\r
235  *      DAT_INVALID_HANDLE\r
236  *      DAT_INSUFFICIENT_RESOURCES\r
237  *\r
238  */\r
239 DAT_RETURN\r
240 dapls_ib_cq_free (\r
241         IN  DAPL_IA                *ia_ptr,\r
242         IN  DAPL_EVD                *evd_ptr)\r
243 {\r
244     ib_api_status_t             ib_status;\r
245         \r
246         if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )\r
247         {\r
248                 return DAT_INVALID_HANDLE;\r
249         }\r
250 \r
251     ib_status = ib_destroy_cq (evd_ptr->ib_cq_handle, \r
252                                /* destroy_callback */ NULL);\r
253                      \r
254     return dapl_ib_status_convert (ib_status);\r
255 }\r
256 \r
257 /*\r
258  * dapls_cq_resize\r
259  *\r
260  * Resize CQ completion notifications\r
261  *\r
262  * Input:\r
263  *      ia_handle               IA handle\r
264  *      evd_ptr                 pointer to EVD struct\r
265  *      cqlen                   minimum QLen \r
266  *\r
267  * Output:\r
268  *      cqlen                   may round up for optimal memory boundaries \r
269  *\r
270  * Returns:\r
271  *      DAT_SUCCESS\r
272  *      DAT_INVALID_HANDLE\r
273  *      DAT_INSUFFICIENT_RESOURCES\r
274  *\r
275  */\r
276 \r
277 DAT_RETURN\r
278 dapls_ib_cq_resize (\r
279          IN  DAPL_IA             *ia_ptr,\r
280          IN  DAPL_EVD            *evd_ptr,\r
281          IN  DAT_COUNT           *cqlen )\r
282 {\r
283     ib_api_status_t             ib_status = IB_SUCCESS;\r
284 \r
285     if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )\r
286     {\r
287         return DAT_INVALID_HANDLE;\r
288     }\r
289     /* \r
290      * Resize CQ only if CQ handle is valid, may be delayed waiting\r
291      * for PZ allocation with IBAL \r
292      */\r
293 #if defined(_VENDOR_IBAL_)\r
294     if ( evd_ptr->ib_cq_handle != IB_INVALID_HANDLE ) \r
295 #endif /* _VENDOR_IBAL_ */\r
296     {\r
297         ib_status = ib_modify_cq ( evd_ptr->ib_cq_handle, \r
298                                        (uint32_t *)cqlen );\r
299         dapl_dbg_log (DAPL_DBG_TYPE_EVD,\r
300                       "ib_modify_cq ( new cqlen = %d, status=%d ) \n",\r
301                       *cqlen, ib_status );\r
302     }          \r
303     return dapl_ib_status_convert (ib_status);\r
304 }\r
305 \r
306 \r
307 /*\r
308  * dapl_set_cq_notify\r
309  *\r
310  * Set up CQ completion notifications\r
311  *\r
312  * Input:\r
313  *      ia_handle               IA handle\r
314  *      evd_ptr                 pointer to EVD struct\r
315  *\r
316  * Output:\r
317  *      none\r
318  *\r
319  * Returns:\r
320  *      DAT_SUCCESS\r
321  *      DAT_INVALID_HANDLE\r
322  *      DAT_INSUFFICIENT_RESOURCES\r
323  *\r
324  */\r
325 DAT_RETURN\r
326 dapls_set_cq_notify (\r
327     IN  DAPL_IA            *ia_ptr,\r
328     IN  DAPL_EVD           *evd_ptr )\r
329 {\r
330     ib_api_status_t             ib_status;\r
331         if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )\r
332         {\r
333                 return DAT_INVALID_HANDLE;\r
334         }\r
335     ib_status = ib_rearm_cq ( \r
336                          evd_ptr->ib_cq_handle,\r
337                          FALSE /* next event but not solicited event */ );\r
338 \r
339     return dapl_ib_status_convert (ib_status);\r
340 }\r
341 \r
342 \r
343 /*\r
344  * dapls_ib_cqd_create\r
345  *\r
346  * Set up CQ notification event thread\r
347  *\r
348  * Input:\r
349  *      ia_handle       HCA handle\r
350  *\r
351  * Output:\r
352  *      none\r
353  *\r
354  * Returns:\r
355  *      DAT_SUCCESS\r
356  *      DAT_INVALID_HANDLE\r
357  *      DAT_INSUFFICIENT_RESOURCES\r
358  *\r
359  */\r
360 DAT_RETURN\r
361 dapls_ib_cqd_create ( IN  DAPL_HCA  *p_hca )\r
362 {\r
363     /*\r
364      * We do not have CQD concept\r
365      */\r
366     p_hca->ib_trans.ib_cqd_handle = IB_INVALID_HANDLE;\r
367 \r
368     return DAT_SUCCESS;\r
369 }\r
370 \r
371 \r
372 /*\r
373  * dapl_cqd_destroy\r
374  *\r
375  * Destroy CQ notification event thread\r
376  *\r
377  * Input:\r
378  *      ia_handle               IA handle\r
379  *\r
380  * Output:\r
381  *      none\r
382  *\r
383  * Returns:\r
384  *      DAT_SUCCESS\r
385  *      DAT_INVALID_HANDLE\r
386  *      DAT_INSUFFICIENT_RESOURCES\r
387  *\r
388  */\r
389 DAT_RETURN\r
390 dapls_ib_cqd_destroy ( IN  DAPL_HCA  *p_hca )\r
391 {\r
392     p_hca->ib_trans.ib_cqd_handle = IB_INVALID_HANDLE;\r
393     return (DAT_SUCCESS);\r
394 }\r
395 \r
396 \r
397 \r
398 DAT_RETURN\r
399 dapls_ib_n_completions_notify (\r
400         IN ib_hca_handle_t    hca_handle,\r
401         IN ib_cq_handle_t     cq_handle,\r
402         IN uint32_t           n_cqes )\r
403 {\r
404     ib_api_status_t        ib_status;\r
405     UNREFERENCED_PARAMETER(hca_handle);\r
406 \r
407     ib_status = ib_rearm_n_cq ( \r
408                          cq_handle,\r
409                          n_cqes );\r
410 \r
411     return dapl_ib_status_convert (ib_status);\r
412 }\r
413 \r
414 \r
415 DAT_RETURN\r
416 dapls_ib_peek_cq (\r
417         IN ib_cq_handle_t cq_handle,\r
418         OUT uint32_t* p_n_cqes)\r
419 {\r
420     ib_api_status_t        ib_status;\r
421 \r
422     ib_status = ib_peek_cq ( cq_handle, p_n_cqes );\r
423 \r
424     return dapl_ib_status_convert (ib_status);\r
425 }\r
426 \r
427 \r
428 /*\r
429  * Local variables:\r
430  *  c-indent-level: 4\r
431  *  c-basic-offset: 4\r
432  *  tab-width: 8\r
433  * End:\r
434  */\r
435 \r