initial implementation
[mirror/winof/.git] / ulp / dapl / dapl / ibal / dapl_ibal_qp.c
1 \r
2 /*\r
3  * Copyright (c) 2002, Network Appliance, Inc. All rights reserved. \r
4  * \r
5  * This Software is licensed under the terms of the "Common Public\r
6  * License" a copy of which is in the file LICENSE.txt in the root\r
7  * directory. The license is also available from the Open Source\r
8  * Initiative, see http://www.opensource.org/licenses/cpl.php.\r
9  *\r
10  */\r
11 \r
12 /**********************************************************************\r
13  * \r
14  * MODULE: dapl_ibal_qp.c\r
15  *\r
16  * PURPOSE: IB QP routines  for access to IBAL APIs\r
17  *\r
18  * $Id: dapl_ibal_qp.c 1.25 04/08/06 18:43:01-04:00 aestrin@aestrin.infiniconsys.com $\r
19  *\r
20  **********************************************************************/\r
21 \r
22 #include "dapl.h"\r
23 #include "dapl_adapter_util.h"\r
24 #include "dapl_evd_util.h"\r
25 #include "dapl_ibal_util.h"\r
26 \r
27 #define DAPL_IBAL_QKEY              0\r
28 #define DAPL_IBAL_START_PSN         0\r
29 \r
30 static void\r
31 dapli_ib_qp_async_error_cb(\r
32     IN    ib_async_event_rec_t* p_err_rec )\r
33 {\r
34         DAPL_EP                         *ep_ptr = (DAPL_EP *)p_err_rec->context;\r
35         DAPL_EVD                        *evd_ptr;\r
36         DAPL_IA                         *ia_ptr;\r
37         dapl_ibal_ca_t          *p_ca;\r
38     dapl_ibal_evd_cb_t  *evd_cb;\r
39 \r
40     dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiQpAEC QP error %d for qp context %p\n", \r
41             p_err_rec->code, p_err_rec->context);\r
42     dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiQpAEC qp_handle %p qpn %u\n", \r
43             ((DAPL_EP *)p_err_rec->context)->qp_handle, \r
44                         ((DAPL_EP *)p_err_rec->context)->qpn);\r
45 \r
46         /*\r
47      * Verify handles EP, EVD, and hca_handle\r
48      */\r
49         if ( DAPL_BAD_HANDLE (ep_ptr, DAPL_MAGIC_EP ) ||\r
50          DAPL_BAD_HANDLE (ep_ptr->param.connect_evd_handle, DAPL_MAGIC_EVD) )\r
51         {\r
52                 dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiQpAEC: invalid EP %p \n", ep_ptr);\r
53                 return;\r
54         }\r
55         ia_ptr = ep_ptr->header.owner_ia;\r
56     evd_ptr = ia_ptr->async_error_evd;\r
57 \r
58         if (DAPL_BAD_HANDLE (evd_ptr, DAPL_MAGIC_EVD) ||\r
59             ! (evd_ptr->evd_flags & DAT_EVD_ASYNC_FLAG))\r
60         {\r
61                 dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiQpAEC: invalid EVD %p \n", evd_ptr);\r
62                 return;\r
63         }\r
64         p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
65         if (p_ca == NULL)\r
66     {\r
67         dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiQpAEC: can't find %s HCA\n", \r
68                 (ia_ptr->header.provider)->device_name);\r
69         return;\r
70     }\r
71 \r
72         /* find QP error callback using ia_ptr for context */\r
73         evd_cb = dapli_find_evd_cb_by_context (ia_ptr, p_ca);\r
74         if ((evd_cb == NULL) || (evd_cb->pfn_async_qp_err_cb == NULL))\r
75         {\r
76                 dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DiQpAEC: no ERROR cb on %p found \n", p_ca);\r
77                 return;\r
78         }\r
79 \r
80         dapl_os_lock (&ep_ptr->header.lock);\r
81         ep_ptr->param.ep_state = DAT_EP_STATE_DISCONNECT_PENDING;\r
82         dapl_os_unlock (&ep_ptr->header.lock);\r
83 \r
84         /* force disconnect, QP error state, to insure DTO's get flushed */\r
85         dapls_ib_disconnect ( ep_ptr, DAT_CLOSE_ABRUPT_FLAG );\r
86         \r
87         /* maps to dapl_evd_qp_async_error_callback(), context is EP */\r
88         evd_cb->pfn_async_qp_err_cb( (ib_hca_handle_t)p_ca, \r
89                                                                 (ib_error_record_t*)&p_err_rec->code, ep_ptr);\r
90 }\r
91 \r
92 /*\r
93  * dapl_ib_qp_alloc\r
94  *\r
95  * Alloc a QP\r
96  *\r
97  * Input:\r
98  *        *ia_ptr                pointer to DAPL IA\r
99  *        *ep_ptr                pointer to DAPL EP\r
100  *        *ep_ctx_ptr            pointer to DAPL EP context\r
101  *\r
102  * Output:\r
103  *         none\r
104  *\r
105  * Returns:\r
106  *        DAT_SUCCESS\r
107  *        DAT_INSUFFICIENT_RESOURCES\r
108  *\r
109  */\r
110 DAT_RETURN\r
111 dapls_ib_qp_alloc (\r
112         IN  DAPL_IA                *ia_ptr,\r
113         IN  DAPL_EP                *ep_ptr,\r
114         IN  DAPL_EP                *ep_ctx_ptr)\r
115 {\r
116     DAT_EP_ATTR           *attr;\r
117     DAPL_EVD              *recv_evd_ptr, *request_evd_ptr;\r
118     DAT_RETURN            dat_status;\r
119     ib_api_status_t       ib_status;\r
120     ib_qp_create_t        qp_create;\r
121     ib_pd_handle_t        ib_pd_handle;\r
122     ib_cq_handle_t        cq_recv;\r
123     ib_cq_handle_t        cq_send;\r
124     dapl_ibal_ca_t        *p_ca;\r
125     dapl_ibal_port_t      *p_active_port;\r
126     ib_qp_attr_t           qp_attr;\r
127 \r
128     attr = &ep_ptr->param.ep_attr;\r
129 \r
130     dapl_os_assert ( ep_ptr->param.pz_handle != NULL );\r
131 \r
132     ib_pd_handle    = ((DAPL_PZ *)ep_ptr->param.pz_handle)->pd_handle;\r
133     recv_evd_ptr    = (DAPL_EVD *) ep_ptr->param.recv_evd_handle;\r
134     request_evd_ptr = (DAPL_EVD *) ep_ptr->param.request_evd_handle;\r
135     \r
136     cq_recv = IB_INVALID_HANDLE;\r
137     cq_send = IB_INVALID_HANDLE;\r
138 \r
139         /* Dynamic EVD enlargement */\r
140         if ( recv_evd_ptr == request_evd_ptr ) \r
141         {\r
142                 DAT_COUNT       min_qlen = attr->max_recv_dtos + attr->max_request_dtos;\r
143                 if ( min_qlen > recv_evd_ptr->qlen )\r
144                 {\r
145                         dat_status = dapl_evd_resize ((DAT_EVD_HANDLE)recv_evd_ptr, \r
146                                                                                         min_qlen);\r
147                         if ( dat_status != DAT_SUCCESS ) {\r
148                                 dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DsQA: failed to resize EVD(%p)\n",recv_evd_ptr);\r
149                                 return dat_status;\r
150                         }\r
151                 }\r
152         } else {\r
153                 if (attr->max_recv_dtos > recv_evd_ptr->qlen)\r
154                 {\r
155                         dat_status = dapl_evd_resize ((DAT_EVD_HANDLE)recv_evd_ptr, \r
156                                                                                         attr->max_recv_dtos);\r
157                         if ( dat_status != DAT_SUCCESS ) {\r
158                                 dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DsQA: failed to resize EVD(%p)\n",recv_evd_ptr);\r
159                                 return dat_status;\r
160                         }\r
161                 }\r
162                 if (attr->max_request_dtos > request_evd_ptr->qlen)\r
163                 {\r
164                         dat_status = dapl_evd_resize ((DAT_EVD_HANDLE)request_evd_ptr, \r
165                                                                                         attr->max_request_dtos);\r
166                         if ( dat_status != DAT_SUCCESS ) {\r
167                                 dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DsQA: failed to resize EVD(%p)\n",request_evd_ptr);\r
168                                 return dat_status;\r
169                         }\r
170                 }\r
171         }\r
172 \r
173     dapl_os_assert ( recv_evd_ptr != DAT_HANDLE_NULL );\r
174     {\r
175         cq_recv = (ib_cq_handle_t) recv_evd_ptr->ib_cq_handle;\r
176         \r
177         if ((cq_recv == IB_INVALID_HANDLE) && \r
178             ( 0 != (recv_evd_ptr->evd_flags & ~DAT_EVD_SOFTWARE_FLAG) ))\r
179         {\r
180             dat_status = dapls_ib_cq_late_alloc (\r
181                                                ib_pd_handle,\r
182                                                recv_evd_ptr);\r
183             if (dat_status != DAT_SUCCESS)\r
184             {\r
185                 dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: failed to create CQ\n","DsQA");\r
186                 return (dat_status);\r
187             }\r
188 \r
189             dat_status = dapls_set_cq_notify (ia_ptr, recv_evd_ptr);\r
190 \r
191             if (dat_status != DAT_SUCCESS)\r
192             {\r
193                 dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: failed to enable notify CQ\n","DsQA");\r
194                 return (dat_status);\r
195             }\r
196         \r
197             cq_recv = (ib_cq_handle_t) recv_evd_ptr->ib_cq_handle;\r
198             dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
199                                "--> DsQA: alloc_recv_CQ = %p\n", cq_recv); \r
200         \r
201         }\r
202     }\r
203 \r
204     dapl_os_assert ( request_evd_ptr != DAT_HANDLE_NULL );\r
205     {\r
206         cq_send = (ib_cq_handle_t) request_evd_ptr->ib_cq_handle;\r
207         \r
208         if ((cq_send == IB_INVALID_HANDLE) && \r
209             ( 0 != (request_evd_ptr->evd_flags & ~DAT_EVD_SOFTWARE_FLAG) ))\r
210         {\r
211             dat_status = dapls_ib_cq_late_alloc (\r
212                                                ib_pd_handle,\r
213                                                request_evd_ptr);\r
214             if (dat_status != DAT_SUCCESS)\r
215             {\r
216                 dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: failed to create CQ\n","DsQA");\r
217                 return (dat_status);\r
218             }\r
219 \r
220             dat_status = dapls_set_cq_notify (ia_ptr, request_evd_ptr);\r
221 \r
222             if (dat_status != DAT_SUCCESS)\r
223             {\r
224                 dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: failed to enable notify CQ\n","DsQA");\r
225                 return (dat_status);\r
226             }\r
227 \r
228             cq_send = (ib_cq_handle_t) request_evd_ptr->ib_cq_handle;\r
229             dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
230                                "--> DsQA: alloc_send_CQ = %p\n", cq_send); \r
231         }\r
232     }\r
233 \r
234     /*\r
235      * Get the CA structure\r
236      */\r
237     p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
238 \r
239 \r
240     dapl_os_memzero (&qp_create, sizeof (qp_create));\r
241     qp_create.qp_type     = IB_QPT_RELIABLE_CONN;\r
242     qp_create.sq_depth    = attr->max_request_dtos;\r
243     qp_create.rq_depth    = attr->max_recv_dtos;\r
244     qp_create.sq_sge      = p_ca->p_ca_attr->max_sges;\r
245     qp_create.rq_sge      = p_ca->p_ca_attr->max_sges;\r
246     qp_create.h_sq_cq     = cq_send;\r
247     qp_create.h_rq_cq     = cq_recv;\r
248     qp_create.sq_signaled = FALSE;\r
249 \r
250     ib_status = ib_create_qp ( \r
251                        ib_pd_handle,\r
252                        &qp_create,\r
253                        (void *) ep_ctx_ptr /* context */,\r
254                        dapli_ib_qp_async_error_cb,\r
255                        &ep_ptr->qp_handle);\r
256 \r
257     if (ib_status != IB_SUCCESS)\r
258     {\r
259         dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsQA: Create QP failed = %s\n", ib_get_err_str(ib_status));\r
260         return (DAT_INSUFFICIENT_RESOURCES);\r
261     }\r
262 \r
263     dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
264                                         "--> DsQA: EP=%p, tEVD=%p, rEVD=%p QP=%p\n", \r
265                                         ep_ptr, ep_ptr->param.request_evd_handle,\r
266                                         ep_ptr->param.recv_evd_handle,\r
267                                         ep_ptr->qp_handle ); \r
268 \r
269     ep_ptr->qp_state = IB_QPS_RESET;\r
270 \r
271     p_active_port = dapli_ibal_get_port ( p_ca, (uint8_t)ia_ptr->hca_ptr->port_num );\r
272 \r
273     if (NULL == p_active_port)\r
274     {\r
275         dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsQA: Port %d is not available = %d\n",\r
276                 ia_ptr->hca_ptr->port_num, __LINE__);\r
277         return (DAT_INVALID_STATE);\r
278     }\r
279 \r
280     ib_status = dapls_modify_qp_state_to_init ( \r
281                           ep_ptr->qp_handle, \r
282                                                   &ep_ptr->param.ep_attr, p_active_port);\r
283 \r
284     if ( ib_status != IB_SUCCESS )\r
285     {\r
286         dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsQA: Change QP state to INIT failed = %s\n",\r
287                 ib_get_err_str(ib_status));\r
288         return (DAT_INVALID_HANDLE);\r
289     }\r
290     ib_status = ib_query_qp ( ep_ptr->qp_handle, &qp_attr );\r
291 \r
292     ep_ptr->qp_state = qp_attr.state;\r
293     ep_ptr->qpn = qp_attr.num;\r
294     \r
295     dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
296         "--> DsQAQA: EP:%p new_QP = %p state = %#x\n", ep_ptr, ep_ptr->qp_handle, ep_ptr->qp_state);\r
297 \r
298     return (DAT_SUCCESS);\r
299 }\r
300 \r
301 \r
302 /*\r
303  * dapl_ib_qp_free\r
304  *\r
305  * Free a QP\r
306  *\r
307  * Input:\r
308  *        *ia_ptr                pointer to IA structure\r
309  *        *ep_ptr                pointer to EP structure\r
310  *\r
311  * Output:\r
312  *         none\r
313  *\r
314  * Returns:\r
315  *         none\r
316  *\r
317  */\r
318 DAT_RETURN\r
319 dapls_ib_qp_free (\r
320         IN  DAPL_IA                *ia_ptr,\r
321         IN  DAPL_EP                *ep_ptr )\r
322 {\r
323 \r
324         ib_qp_handle_t          qp_handle;\r
325         UNREFERENCED_PARAMETER(ia_ptr);\r
326 \r
327         dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
328                        "--> DsQF: free %p, state=%d\n", \r
329                                            ep_ptr->qp_handle,ep_ptr->qp_state ); \r
330 \r
331     if (( ep_ptr->qp_handle != IB_INVALID_HANDLE ) &&\r
332         ( ep_ptr->qp_state != DAPL_QP_STATE_UNATTACHED ))\r
333     {\r
334                 qp_handle = ep_ptr->qp_handle;\r
335                 ep_ptr->qp_handle = IB_INVALID_HANDLE;\r
336                 ep_ptr->qp_state = DAPL_QP_STATE_UNATTACHED;\r
337                 ib_destroy_qp ( qp_handle, NULL /* callback */);\r
338                 dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
339                        "--> DsQF: freed QP %p\n", qp_handle ); \r
340     }\r
341 \r
342     return DAT_SUCCESS;\r
343 }\r
344 \r
345 \r
346 /*\r
347  * dapl_ib_qp_modify\r
348  *\r
349  * Set the QP to the parameters specified in an EP_PARAM\r
350  *\r
351  * We can't be sure what state the QP is in so we first obtain the state\r
352  * from the driver. The EP_PARAM structure that is provided has been\r
353  * sanitized such that only non-zero values are valid.\r
354  *\r
355  * Input:\r
356  *        *ia_ptr                pointer to DAPL IA\r
357  *        *ep_ptr                pointer to DAPL EP\r
358  *        *ep_attr               pointer to DAT EP attribute\r
359  *\r
360  * Output:\r
361  *         none\r
362  *\r
363  * Returns:\r
364  *         DAT_SUCCESS\r
365  *        DAT_INSUFFICIENT_RESOURCES\r
366  *        DAT_INVALID_PARAMETER\r
367  *\r
368  */\r
369 DAT_RETURN\r
370 dapls_ib_qp_modify (\r
371         IN  DAPL_IA                        *ia_ptr,\r
372         IN  DAPL_EP                        *ep_ptr,\r
373         IN  DAT_EP_ATTR                    *ep_attr )\r
374 {\r
375     ib_qp_attr_t                  qp_attr;\r
376     ib_api_status_t               ib_status;\r
377     ib_qp_handle_t                qp_handle;\r
378     ib_qp_state_t                 qp_state;\r
379     ib_qp_mod_t                   qp_mod;\r
380     ib_av_attr_t                  *p_av_attr;\r
381     ib_qp_opts_t                  *p_qp_opts;\r
382     uint32_t                      *p_sq_depth, *p_rq_depth;\r
383     DAT_BOOLEAN                   need_modify;\r
384     DAT_RETURN                    dat_status;\r
385 \r
386     qp_handle     = ep_ptr->qp_handle;\r
387     need_modify   = DAT_FALSE;\r
388     dat_status    = DAT_SUCCESS;\r
389         if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )\r
390         {\r
391                 dat_status = DAT_INVALID_HANDLE;\r
392                 goto bail;\r
393         }\r
394     /* \r
395      * Query the QP to get the current state */\r
396     ib_status = ib_query_qp ( qp_handle, &qp_attr );\r
397                        \r
398     if ( ib_status != IB_SUCCESS )\r
399     {\r
400         dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsIQM: Query QP failed = %s\n", ib_get_err_str(ib_status));\r
401         dat_status = DAT_INTERNAL_ERROR;\r
402         goto bail;\r
403     }\r
404 \r
405     qp_state = qp_attr.state;\r
406 \r
407         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
408                                         "--> DsIQM: modify qp state=%d\n",qp_state);\r
409     /*\r
410      * Check if we have the right qp_state or not\r
411      */\r
412     if ( (qp_state != IB_QPS_RTR ) && \r
413          (qp_state != IB_QPS_RTS ) )\r
414     {\r
415         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
416                       "--> DsIQM: postpone to modify qp to EP values later\n");\r
417         dat_status = DAT_SUCCESS;\r
418         goto bail;\r
419     }\r
420 \r
421     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
422 \r
423     if (qp_state == IB_QPS_RTR)\r
424     {\r
425         p_av_attr   = &qp_mod.state.rtr.primary_av;\r
426         p_qp_opts   = &qp_mod.state.rtr.opts;\r
427         p_sq_depth  = &qp_mod.state.rtr.sq_depth;\r
428         p_rq_depth  = &qp_mod.state.rtr.rq_depth;\r
429     }\r
430     else\r
431     {\r
432         /*\r
433          * RTS does not have primary_av field\r
434          */\r
435         p_av_attr   = &qp_mod.state.rts.alternate_av;\r
436         p_qp_opts   = &qp_mod.state.rts.opts;\r
437         p_sq_depth  = &qp_mod.state.rts.sq_depth;\r
438         p_rq_depth  = &qp_mod.state.rts.rq_depth;\r
439     }\r
440 \r
441     if ( (ep_attr->max_recv_dtos > 0) &&\r
442                 ((DAT_UINT32)ep_attr->max_recv_dtos != qp_attr.rq_depth) )\r
443     {\r
444                 dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
445                                         "--> DsIQM: rq_depth modified (%d,%d)\n",\r
446                                         qp_attr.rq_depth, ep_attr->max_recv_dtos);\r
447 \r
448         *p_rq_depth = ep_attr->max_recv_dtos;\r
449         *p_qp_opts |= IB_MOD_QP_RQ_DEPTH;\r
450         need_modify = DAT_TRUE;\r
451     }\r
452 \r
453     if ( (ep_attr->max_request_dtos > 0) &&\r
454                 ((DAT_UINT32)ep_attr->max_request_dtos != qp_attr.sq_depth) ) \r
455     {\r
456                 dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
457                                         "--> DsIQM: sq_depth modified (%d,%d)\n",\r
458                                         qp_attr.sq_depth, ep_attr->max_request_dtos);\r
459 \r
460         *p_sq_depth = ep_attr->max_request_dtos;\r
461         *p_qp_opts |= IB_MOD_QP_SQ_DEPTH;\r
462         need_modify = DAT_TRUE;\r
463         }\r
464 \r
465     qp_mod.req_state  = qp_state;\r
466 \r
467     if ( need_modify == DAT_TRUE )\r
468     {\r
469                 ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
470 \r
471         if ( ib_status != IB_SUCCESS)\r
472         {\r
473             dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: ib_status = %d\n", "DsIQM", ib_status);\r
474             dat_status = DAT_INTERNAL_ERROR;\r
475         }\r
476     }\r
477 \r
478 bail:\r
479 \r
480     return dat_status;\r
481 }\r
482 \r
483 \r
484 ib_api_status_t \r
485 dapls_modify_qp_state_to_error (\r
486         ib_qp_handle_t                qp_handle )\r
487 {\r
488     ib_qp_mod_t      qp_mod;\r
489     ib_api_status_t  ib_status;\r
490 \r
491         dapl_dbg_log (DAPL_DBG_TYPE_WARN,\r
492                                         "--> DsIQM_ERR: QP state change\n");\r
493 \r
494     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
495 \r
496     qp_mod.req_state  = IB_QPS_ERROR;\r
497 \r
498     ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
499 \r
500     return (ib_status);\r
501 }\r
502 \r
503 \r
504 ib_api_status_t \r
505 dapls_modify_qp_state_to_reset (\r
506         ib_qp_handle_t                qp_handle )\r
507 {\r
508     ib_qp_mod_t      qp_mod;\r
509     ib_api_status_t  ib_status;\r
510 \r
511         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
512                                         "--> DsIQM_RESET: QP state change\n");\r
513 \r
514     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
515 \r
516     qp_mod.req_state  = IB_QPS_RESET;\r
517 \r
518     ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
519 \r
520     return (ib_status);\r
521 }\r
522 \r
523 \r
524 ib_api_status_t \r
525 dapls_modify_qp_state_to_init (\r
526         IN    ib_qp_handle_t         qp_handle,\r
527                 IN    DAT_EP_ATTR            *p_attr,\r
528         IN    dapl_ibal_port_t       *p_port )\r
529 {\r
530     ib_qp_mod_t                   qp_mod;\r
531     ib_api_status_t               ib_status;\r
532 \r
533         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
534                                         "--> DsIQM_INIT: QP state change\n");\r
535 \r
536     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
537 \r
538     qp_mod.req_state               = IB_QPS_INIT;\r
539     qp_mod.state.init.primary_port = p_port->p_attr->port_num;\r
540     qp_mod.state.init.qkey         = DAPL_IBAL_QKEY;\r
541     qp_mod.state.init.pkey_index   = 0;\r
542         qp_mod.state.init.access_ctrl = \r
543                 IB_AC_LOCAL_WRITE|IB_AC_RDMA_WRITE|IB_AC_MW_BIND;\r
544         if ((p_attr->max_rdma_read_in > 0) ||\r
545                         (p_attr->max_rdma_read_out > 0))\r
546         {\r
547                 qp_mod.state.init.access_ctrl |= IB_AC_RDMA_READ;\r
548         }\r
549     ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
550 \r
551     return (ib_status);\r
552 }\r
553 \r
554 ib_api_status_t \r
555 dapls_modify_qp_state_to_rtr (\r
556         ib_qp_handle_t          qp_handle,\r
557         ib_net32_t              dest_qp,\r
558         ib_lid_t                dest_lid,\r
559         dapl_ibal_port_t        *p_port)\r
560 {\r
561     ib_qp_mod_t                   qp_mod;\r
562     ib_api_status_t               ib_status;\r
563 \r
564         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
565                                         "--> DsIQM_RTR: QP state change\n");\r
566 \r
567     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
568 \r
569     qp_mod.req_state                        = IB_QPS_RTR;\r
570     qp_mod.state.rtr.rq_psn                 = DAPL_IBAL_START_PSN;\r
571     qp_mod.state.rtr.dest_qp                = dest_qp;\r
572     qp_mod.state.rtr.resp_res               = 7;\r
573     qp_mod.state.rtr.rnr_nak_timeout        = 7;\r
574     qp_mod.state.rtr.primary_av.sl          = 0;\r
575     qp_mod.state.rtr.primary_av.dlid        = dest_lid;\r
576     qp_mod.state.rtr.primary_av.port_num    = p_port->p_attr->port_num;\r
577     qp_mod.state.rtr.primary_av.grh_valid   = 0; /* FALSE */\r
578     qp_mod.state.rtr.primary_av.path_bits   = 0;\r
579     qp_mod.state.rtr.primary_av.static_rate = IB_PATH_RECORD_RATE_10_GBS;\r
580     qp_mod.state.rtr.primary_av.conn.path_mtu = p_port->p_attr->mtu;\r
581     qp_mod.state.rtr.primary_av.conn.rnr_retry_cnt     = 7;\r
582     qp_mod.state.rtr.primary_av.conn.local_ack_timeout = 7;\r
583     qp_mod.state.rtr.primary_av.conn.seq_err_retry_cnt = 7;\r
584  \r
585     qp_mod.state.rtr.opts = IB_MOD_QP_PRIMARY_AV | IB_MOD_QP_RESP_RES;\r
586     \r
587     ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
588     \r
589     return (ib_status);\r
590 }\r
591 \r
592 ib_api_status_t \r
593 dapls_modify_qp_state_to_rts (\r
594         ib_qp_handle_t                qp_handle )\r
595 {\r
596     ib_qp_mod_t        qp_mod;\r
597     ib_api_status_t    ib_status;\r
598 \r
599         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
600                                         "--> DsIQM_RTS: QP state change\n");\r
601 \r
602     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
603 \r
604     qp_mod.req_state                 = IB_QPS_RTS;\r
605     qp_mod.state.rts.sq_psn          = DAPL_IBAL_START_PSN;\r
606     qp_mod.state.rts.retry_cnt = 7;\r
607     qp_mod.state.rts.rnr_retry_cnt = 6;\r
608     qp_mod.state.rts.rnr_nak_timeout = 7;\r
609     qp_mod.state.rts.local_ack_timeout = 7;\r
610     qp_mod.state.rts.init_depth = 4; \r
611 \r
612     ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
613 \r
614     return (ib_status);\r
615 }\r
616 \r
617 \r
618 /*\r
619  * dapls_ib_reinit_ep\r
620  *\r
621  * Move the QP to INIT state again.\r
622  *\r
623  * Input:\r
624  *      ep_ptr          DAPL_EP\r
625  *\r
626  * Output:\r
627  *      none\r
628  *\r
629  * Returns:\r
630  *      void\r
631  *\r
632  */\r
633 DAT_RETURN\r
634 dapls_ib_reinit_ep (\r
635         IN  DAPL_EP                     *ep_ptr)\r
636 {\r
637     DAPL_IA                  *ia_ptr;\r
638     ib_api_status_t          ib_status;\r
639     dapl_ibal_ca_t           *p_ca;\r
640     dapl_ibal_port_t         *p_active_port;\r
641         \r
642         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
643                                         "--> DsIQM_REINIT: EP(%p) QP(%p) state change\n", \r
644                                         ep_ptr, ep_ptr->qp_handle );\r
645 \r
646         if ( ep_ptr->param.ep_state != DAT_EP_STATE_DISCONNECTED )\r
647         {\r
648                 dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DsIRE: EP invalid state(%d)\n", ep_ptr->param.ep_state);\r
649                 return DAT_INVALID_STATE;\r
650         }\r
651 \r
652         ia_ptr = ep_ptr->header.owner_ia;\r
653 \r
654         /* Re-create QP if cleaned up, alloc will return init state */\r
655         if ( ep_ptr->qp_handle == IB_INVALID_HANDLE )\r
656         {\r
657             dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
658                                         "--> DsIRE: !EP(%p)->qp_handle, re-create QP\n",ep_ptr);\r
659             return ( dapls_ib_qp_alloc ( ia_ptr, ep_ptr, ep_ptr ) );\r
660         }\r
661 \r
662         ib_status = dapls_modify_qp_state_to_reset ( ep_ptr->qp_handle);\r
663 \r
664         if ( ib_status != IB_SUCCESS )\r
665         {\r
666             dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DsIRE: failed to move qp to RESET status = %s\n", \r
667                      ib_get_err_str(ib_status));\r
668             return DAT_INTERNAL_ERROR;\r
669         }\r
670 \r
671         ep_ptr->qp_state = IB_QPS_RESET;\r
672 \r
673     p_ca   = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
674     p_active_port = dapli_ibal_get_port ( p_ca, (uint8_t)ia_ptr->hca_ptr->port_num );\r
675 \r
676     if (NULL == p_active_port)\r
677     {\r
678         dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DsIRE: Port %d is not available = %d\n",\r
679                 ia_ptr->hca_ptr->port_num, __LINE__);\r
680         return DAT_INTERNAL_ERROR;\r
681     }\r
682 \r
683         /* May fail if QP still RESET and in timewait, keep in reset state */\r
684     ib_status = dapls_modify_qp_state_to_init ( ep_ptr->qp_handle,\r
685                                                 &ep_ptr->param.ep_attr,\r
686                                                                                                 p_active_port);\r
687     if ( ib_status != IB_SUCCESS )\r
688     {\r
689         ep_ptr->qp_state = IB_QPS_RESET;\r
690 \r
691         dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsIRE: failed to move qp to INIT status = %s\n", \r
692                  ib_get_err_str(ib_status));\r
693         return DAT_INTERNAL_ERROR;\r
694     }\r
695 \r
696     ep_ptr->qp_state = IB_QPS_INIT;\r
697 \r
698     return DAT_SUCCESS;\r
699 \r
700 }\r
701 \r
702 \r
703 /*\r
704  * Local variables:\r
705  *  c-indent-level: 4\r
706  *  c-basic-offset: 4\r
707  *  tab-width: 8\r
708  * End:\r
709  */\r
710 \r