[DPL] Dynamic EVD enlargement code removed as it caused
[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$\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     dapl_os_assert ( recv_evd_ptr != DAT_HANDLE_NULL );\r
140     {\r
141         cq_recv = (ib_cq_handle_t) recv_evd_ptr->ib_cq_handle;\r
142         \r
143         if ((cq_recv == IB_INVALID_HANDLE) && \r
144             ( 0 != (recv_evd_ptr->evd_flags & ~DAT_EVD_SOFTWARE_FLAG) ))\r
145         {\r
146             dat_status = dapls_ib_cq_late_alloc (\r
147                                                ib_pd_handle,\r
148                                                recv_evd_ptr);\r
149             if (dat_status != DAT_SUCCESS)\r
150             {\r
151                 dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: failed to create CQ\n","DsQA");\r
152                 return (dat_status);\r
153             }\r
154 \r
155             dat_status = dapls_set_cq_notify (ia_ptr, recv_evd_ptr);\r
156 \r
157             if (dat_status != DAT_SUCCESS)\r
158             {\r
159                 dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: failed to enable notify CQ\n","DsQA");\r
160                 return (dat_status);\r
161             }\r
162         \r
163             cq_recv = (ib_cq_handle_t) recv_evd_ptr->ib_cq_handle;\r
164             dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
165                                "--> DsQA: alloc_recv_CQ = %p\n", cq_recv); \r
166         \r
167         }\r
168     }\r
169 \r
170     dapl_os_assert ( request_evd_ptr != DAT_HANDLE_NULL );\r
171     {\r
172         cq_send = (ib_cq_handle_t) request_evd_ptr->ib_cq_handle;\r
173         \r
174         if ((cq_send == IB_INVALID_HANDLE) && \r
175             ( 0 != (request_evd_ptr->evd_flags & ~DAT_EVD_SOFTWARE_FLAG) ))\r
176         {\r
177             dat_status = dapls_ib_cq_late_alloc (\r
178                                                ib_pd_handle,\r
179                                                request_evd_ptr);\r
180             if (dat_status != DAT_SUCCESS)\r
181             {\r
182                 dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: failed to create CQ\n","DsQA");\r
183                 return (dat_status);\r
184             }\r
185 \r
186             dat_status = dapls_set_cq_notify (ia_ptr, request_evd_ptr);\r
187 \r
188             if (dat_status != DAT_SUCCESS)\r
189             {\r
190                 dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: failed to enable notify CQ\n","DsQA");\r
191                 return (dat_status);\r
192             }\r
193 \r
194             cq_send = (ib_cq_handle_t) request_evd_ptr->ib_cq_handle;\r
195             dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
196                                "--> DsQA: alloc_send_CQ = %p\n", cq_send); \r
197         }\r
198     }\r
199 \r
200     /*\r
201      * Get the CA structure\r
202      */\r
203     p_ca = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
204 \r
205     dapl_os_memzero (&qp_create, sizeof (qp_create));\r
206     qp_create.qp_type     = IB_QPT_RELIABLE_CONN;\r
207     qp_create.sq_depth    = attr->max_request_dtos;\r
208     qp_create.rq_depth    = attr->max_recv_dtos;\r
209     qp_create.sq_sge      = attr->max_recv_iov;\r
210     qp_create.rq_sge      = attr->max_request_iov;                        \r
211     qp_create.h_sq_cq     = cq_send;\r
212     qp_create.h_rq_cq     = cq_recv;\r
213     qp_create.sq_signaled = FALSE;\r
214 \r
215     dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
216                 "--> DsQA: sqd,iov=%d,%d rqd,iov=%d,%d\n", \r
217                 attr->max_request_dtos, attr->max_request_iov,\r
218                 attr->max_recv_dtos, attr->max_recv_iov); \r
219     \r
220     ib_status = ib_create_qp ( \r
221                        ib_pd_handle,\r
222                        &qp_create,\r
223                        (void *) ep_ctx_ptr /* context */,\r
224                        dapli_ib_qp_async_error_cb,\r
225                        &ep_ptr->qp_handle);\r
226 \r
227     if (ib_status != IB_SUCCESS)\r
228     {\r
229         dapl_dbg_log (DAPL_DBG_TYPE_ERR, \r
230                 "--> DsQA: Create QP failed = %s\n", ib_get_err_str(ib_status));\r
231         return (DAT_INSUFFICIENT_RESOURCES);\r
232     }\r
233 \r
234     dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
235                                         "--> DsQA: EP=%p, tEVD=%p, rEVD=%p QP=%p\n", \r
236                                         ep_ptr, ep_ptr->param.request_evd_handle,\r
237                                         ep_ptr->param.recv_evd_handle,\r
238                                         ep_ptr->qp_handle ); \r
239 \r
240     ep_ptr->qp_state = IB_QPS_RESET;\r
241 \r
242     p_active_port = dapli_ibal_get_port ( p_ca, (uint8_t)ia_ptr->hca_ptr->port_num );\r
243 \r
244     if (NULL == p_active_port)\r
245     {\r
246         dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsQA: Port %d is not available = %d\n",\r
247                 ia_ptr->hca_ptr->port_num, __LINE__);\r
248         return (DAT_INVALID_STATE);\r
249     }\r
250 \r
251     ib_status = dapls_modify_qp_state_to_init ( \r
252                           ep_ptr->qp_handle, \r
253                                                   &ep_ptr->param.ep_attr, p_active_port);\r
254 \r
255     if ( ib_status != IB_SUCCESS )\r
256     {\r
257         dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsQA: Change QP state to INIT failed = %s\n",\r
258                 ib_get_err_str(ib_status));\r
259         return (DAT_INVALID_HANDLE);\r
260     }\r
261     ib_status = ib_query_qp ( ep_ptr->qp_handle, &qp_attr );\r
262 \r
263     ep_ptr->qp_state = qp_attr.state;\r
264     ep_ptr->qpn = qp_attr.num;\r
265     \r
266     dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
267         "--> DsQAQA: EP:%p new_QP = %p state = %#x\n", ep_ptr, ep_ptr->qp_handle, ep_ptr->qp_state);\r
268 \r
269     return (DAT_SUCCESS);\r
270 }\r
271 \r
272 \r
273 /*\r
274  * dapl_ib_qp_free\r
275  *\r
276  * Free a QP\r
277  *\r
278  * Input:\r
279  *        *ia_ptr                pointer to IA structure\r
280  *        *ep_ptr                pointer to EP structure\r
281  *\r
282  * Output:\r
283  *         none\r
284  *\r
285  * Returns:\r
286  *         none\r
287  *\r
288  */\r
289 DAT_RETURN\r
290 dapls_ib_qp_free (\r
291         IN  DAPL_IA                *ia_ptr,\r
292         IN  DAPL_EP                *ep_ptr )\r
293 {\r
294 \r
295         ib_qp_handle_t          qp_handle;\r
296         UNREFERENCED_PARAMETER(ia_ptr);\r
297 \r
298         dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
299                        "--> DsQF: free %p, state=%d\n", \r
300                                            ep_ptr->qp_handle,ep_ptr->qp_state ); \r
301 \r
302     if (( ep_ptr->qp_handle != IB_INVALID_HANDLE ) &&\r
303         ( ep_ptr->qp_state != DAPL_QP_STATE_UNATTACHED ))\r
304     {\r
305                 qp_handle = ep_ptr->qp_handle;\r
306                 ep_ptr->qp_handle = IB_INVALID_HANDLE;\r
307                 ep_ptr->qp_state = DAPL_QP_STATE_UNATTACHED;\r
308                 ib_destroy_qp ( qp_handle, NULL /* callback */);\r
309                 dapl_dbg_log (DAPL_DBG_TYPE_EP, \r
310                        "--> DsQF: freed QP %p\n", qp_handle ); \r
311     }\r
312 \r
313     return DAT_SUCCESS;\r
314 }\r
315 \r
316 \r
317 /*\r
318  * dapl_ib_qp_modify\r
319  *\r
320  * Set the QP to the parameters specified in an EP_PARAM\r
321  *\r
322  * We can't be sure what state the QP is in so we first obtain the state\r
323  * from the driver. The EP_PARAM structure that is provided has been\r
324  * sanitized such that only non-zero values are valid.\r
325  *\r
326  * Input:\r
327  *        *ia_ptr                pointer to DAPL IA\r
328  *        *ep_ptr                pointer to DAPL EP\r
329  *        *ep_attr               pointer to DAT EP attribute\r
330  *\r
331  * Output:\r
332  *         none\r
333  *\r
334  * Returns:\r
335  *         DAT_SUCCESS\r
336  *        DAT_INSUFFICIENT_RESOURCES\r
337  *        DAT_INVALID_PARAMETER\r
338  *\r
339  */\r
340 DAT_RETURN\r
341 dapls_ib_qp_modify (\r
342         IN  DAPL_IA                        *ia_ptr,\r
343         IN  DAPL_EP                        *ep_ptr,\r
344         IN  DAT_EP_ATTR                    *ep_attr )\r
345 {\r
346     ib_qp_attr_t                  qp_attr;\r
347     ib_api_status_t               ib_status;\r
348     ib_qp_handle_t                qp_handle;\r
349     ib_qp_state_t                 qp_state;\r
350     ib_qp_mod_t                   qp_mod;\r
351     ib_av_attr_t                  *p_av_attr;\r
352     ib_qp_opts_t                  *p_qp_opts;\r
353     uint32_t                      *p_sq_depth, *p_rq_depth;\r
354     DAT_BOOLEAN                   need_modify;\r
355     DAT_RETURN                    dat_status;\r
356 \r
357     qp_handle     = ep_ptr->qp_handle;\r
358     need_modify   = DAT_FALSE;\r
359     dat_status    = DAT_SUCCESS;\r
360         if ( ia_ptr == NULL || ia_ptr->header.magic != DAPL_MAGIC_IA )\r
361         {\r
362                 dat_status = DAT_INVALID_HANDLE;\r
363                 goto bail;\r
364         }\r
365     /* \r
366      * Query the QP to get the current state */\r
367     ib_status = ib_query_qp ( qp_handle, &qp_attr );\r
368                        \r
369     if ( ib_status != IB_SUCCESS )\r
370     {\r
371         dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsIQM: Query QP failed = %s\n", ib_get_err_str(ib_status));\r
372         dat_status = DAT_INTERNAL_ERROR;\r
373         goto bail;\r
374     }\r
375 \r
376     qp_state = qp_attr.state;\r
377 \r
378         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
379                                         "--> DsIQM: modify qp state=%d\n",qp_state);\r
380     /*\r
381      * Check if we have the right qp_state or not\r
382      */\r
383     if ( (qp_state != IB_QPS_RTR ) && \r
384          (qp_state != IB_QPS_RTS ) )\r
385     {\r
386         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
387                       "--> DsIQM: postpone to modify qp to EP values later\n");\r
388         dat_status = DAT_SUCCESS;\r
389         goto bail;\r
390     }\r
391 \r
392     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
393 \r
394     if (qp_state == IB_QPS_RTR)\r
395     {\r
396         p_av_attr   = &qp_mod.state.rtr.primary_av;\r
397         p_qp_opts   = &qp_mod.state.rtr.opts;\r
398         p_sq_depth  = &qp_mod.state.rtr.sq_depth;\r
399         p_rq_depth  = &qp_mod.state.rtr.rq_depth;\r
400     }\r
401     else\r
402     {\r
403         /*\r
404          * RTS does not have primary_av field\r
405          */\r
406         p_av_attr   = &qp_mod.state.rts.alternate_av;\r
407         p_qp_opts   = &qp_mod.state.rts.opts;\r
408         p_sq_depth  = &qp_mod.state.rts.sq_depth;\r
409         p_rq_depth  = &qp_mod.state.rts.rq_depth;\r
410     }\r
411 \r
412     if ( (ep_attr->max_recv_dtos > 0) &&\r
413                 ((DAT_UINT32)ep_attr->max_recv_dtos != qp_attr.rq_depth) )\r
414     {\r
415                 dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
416                                         "--> DsIQM: rq_depth modified (%d,%d)\n",\r
417                                         qp_attr.rq_depth, ep_attr->max_recv_dtos);\r
418 \r
419         *p_rq_depth = ep_attr->max_recv_dtos;\r
420         *p_qp_opts |= IB_MOD_QP_RQ_DEPTH;\r
421         need_modify = DAT_TRUE;\r
422     }\r
423 \r
424     if ( (ep_attr->max_request_dtos > 0) &&\r
425                 ((DAT_UINT32)ep_attr->max_request_dtos != qp_attr.sq_depth) ) \r
426     {\r
427                 dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
428                                         "--> DsIQM: sq_depth modified (%d,%d)\n",\r
429                                         qp_attr.sq_depth, ep_attr->max_request_dtos);\r
430 \r
431         *p_sq_depth = ep_attr->max_request_dtos;\r
432         *p_qp_opts |= IB_MOD_QP_SQ_DEPTH;\r
433         need_modify = DAT_TRUE;\r
434         }\r
435 \r
436     qp_mod.req_state  = qp_state;\r
437 \r
438     if ( need_modify == DAT_TRUE )\r
439     {\r
440                 ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
441 \r
442         if ( ib_status != IB_SUCCESS)\r
443         {\r
444             dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> %s: ib_status = %d\n", "DsIQM", ib_status);\r
445             dat_status = DAT_INTERNAL_ERROR;\r
446         }\r
447     }\r
448 \r
449 bail:\r
450 \r
451     return dat_status;\r
452 }\r
453 \r
454 \r
455 ib_api_status_t \r
456 dapls_modify_qp_state_to_error (\r
457         ib_qp_handle_t                qp_handle )\r
458 {\r
459     ib_qp_mod_t      qp_mod;\r
460     ib_api_status_t  ib_status;\r
461 \r
462         dapl_dbg_log (DAPL_DBG_TYPE_WARN,\r
463                                         "--> DsIQM_ERR: QP state change\n");\r
464 \r
465     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
466 \r
467     qp_mod.req_state  = IB_QPS_ERROR;\r
468 \r
469     ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
470 \r
471     return (ib_status);\r
472 }\r
473 \r
474 \r
475 ib_api_status_t \r
476 dapls_modify_qp_state_to_reset (\r
477         ib_qp_handle_t                qp_handle )\r
478 {\r
479     ib_qp_mod_t      qp_mod;\r
480     ib_api_status_t  ib_status;\r
481 \r
482         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
483                                         "--> DsIQM_RESET: QP state change\n");\r
484 \r
485     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
486 \r
487     qp_mod.req_state  = IB_QPS_RESET;\r
488 \r
489     ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
490 \r
491     return (ib_status);\r
492 }\r
493 \r
494 \r
495 ib_api_status_t \r
496 dapls_modify_qp_state_to_init (\r
497         IN    ib_qp_handle_t         qp_handle,\r
498                 IN    DAT_EP_ATTR            *p_attr,\r
499         IN    dapl_ibal_port_t       *p_port )\r
500 {\r
501     ib_qp_mod_t                   qp_mod;\r
502     ib_api_status_t               ib_status;\r
503 \r
504         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
505                                         "--> DsIQM_INIT: QP state change\n");\r
506 \r
507     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
508 \r
509     qp_mod.req_state               = IB_QPS_INIT;\r
510     qp_mod.state.init.primary_port = p_port->p_attr->port_num;\r
511     qp_mod.state.init.qkey         = DAPL_IBAL_QKEY;\r
512     qp_mod.state.init.pkey_index   = 0;\r
513         qp_mod.state.init.access_ctrl = \r
514                 IB_AC_LOCAL_WRITE|IB_AC_RDMA_WRITE|IB_AC_MW_BIND;\r
515         if ((p_attr->max_rdma_read_in > 0) ||\r
516                         (p_attr->max_rdma_read_out > 0))\r
517         {\r
518                 qp_mod.state.init.access_ctrl |= IB_AC_RDMA_READ;\r
519         }\r
520     ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
521 \r
522     return (ib_status);\r
523 }\r
524 \r
525 ib_api_status_t \r
526 dapls_modify_qp_state_to_rtr (\r
527         ib_qp_handle_t          qp_handle,\r
528         ib_net32_t              dest_qp,\r
529         ib_lid_t                dest_lid,\r
530         dapl_ibal_port_t        *p_port)\r
531 {\r
532     ib_qp_mod_t                   qp_mod;\r
533     ib_api_status_t               ib_status;\r
534 \r
535         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
536                                         "--> DsIQM_RTR: QP state change\n");\r
537 \r
538     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
539 \r
540     qp_mod.req_state                        = IB_QPS_RTR;\r
541     qp_mod.state.rtr.rq_psn                 = DAPL_IBAL_START_PSN;\r
542     qp_mod.state.rtr.dest_qp                = dest_qp;\r
543     qp_mod.state.rtr.resp_res               = 7;\r
544     qp_mod.state.rtr.rnr_nak_timeout        = 7;\r
545     qp_mod.state.rtr.primary_av.sl          = 0;\r
546     qp_mod.state.rtr.primary_av.dlid        = dest_lid;\r
547     qp_mod.state.rtr.primary_av.port_num    = p_port->p_attr->port_num;\r
548     qp_mod.state.rtr.primary_av.grh_valid   = 0; /* FALSE */\r
549     qp_mod.state.rtr.primary_av.path_bits   = 0;\r
550     qp_mod.state.rtr.primary_av.static_rate = IB_PATH_RECORD_RATE_10_GBS;\r
551     qp_mod.state.rtr.primary_av.conn.path_mtu = p_port->p_attr->mtu;\r
552     qp_mod.state.rtr.primary_av.conn.rnr_retry_cnt     = 7;\r
553     qp_mod.state.rtr.primary_av.conn.local_ack_timeout = 7;\r
554     qp_mod.state.rtr.primary_av.conn.seq_err_retry_cnt = 7;\r
555  \r
556     qp_mod.state.rtr.opts = IB_MOD_QP_PRIMARY_AV | IB_MOD_QP_RESP_RES;\r
557     \r
558     ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
559     \r
560     return (ib_status);\r
561 }\r
562 \r
563 ib_api_status_t \r
564 dapls_modify_qp_state_to_rts (\r
565         ib_qp_handle_t                qp_handle )\r
566 {\r
567     ib_qp_mod_t        qp_mod;\r
568     ib_api_status_t    ib_status;\r
569 \r
570         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
571                                         "--> DsIQM_RTS: QP state change\n");\r
572 \r
573     dapl_os_memzero (&qp_mod, sizeof (ib_qp_mod_t));\r
574 \r
575     qp_mod.req_state                 = IB_QPS_RTS;\r
576     qp_mod.state.rts.sq_psn          = DAPL_IBAL_START_PSN;\r
577     qp_mod.state.rts.retry_cnt = 7;\r
578     qp_mod.state.rts.rnr_retry_cnt = 6;\r
579     qp_mod.state.rts.rnr_nak_timeout = 7;\r
580     qp_mod.state.rts.local_ack_timeout = 7;\r
581     qp_mod.state.rts.init_depth = 4; \r
582 \r
583     ib_status = ib_modify_qp (qp_handle, &qp_mod);\r
584 \r
585     return (ib_status);\r
586 }\r
587 \r
588 \r
589 /*\r
590  * dapls_ib_reinit_ep\r
591  *\r
592  * Move the QP to INIT state again.\r
593  *\r
594  * Input:\r
595  *      ep_ptr          DAPL_EP\r
596  *\r
597  * Output:\r
598  *      none\r
599  *\r
600  * Returns:\r
601  *      void\r
602  *\r
603  */\r
604 DAT_RETURN\r
605 dapls_ib_reinit_ep (\r
606         IN  DAPL_EP                     *ep_ptr)\r
607 {\r
608     DAPL_IA                  *ia_ptr;\r
609     ib_api_status_t          ib_status;\r
610     dapl_ibal_ca_t           *p_ca;\r
611     dapl_ibal_port_t         *p_active_port;\r
612         \r
613         dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
614                                         "--> DsIQM_REINIT: EP(%p) QP(%p) state change\n", \r
615                                         ep_ptr, ep_ptr->qp_handle );\r
616 \r
617         if ( ep_ptr->param.ep_state != DAT_EP_STATE_DISCONNECTED )\r
618         {\r
619                 dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DsIRE: EP invalid state(%d)\n", ep_ptr->param.ep_state);\r
620                 return DAT_INVALID_STATE;\r
621         }\r
622 \r
623         ia_ptr = ep_ptr->header.owner_ia;\r
624 \r
625         /* Re-create QP if cleaned up, alloc will return init state */\r
626         if ( ep_ptr->qp_handle == IB_INVALID_HANDLE )\r
627         {\r
628             dapl_dbg_log (DAPL_DBG_TYPE_EP,\r
629                                         "--> DsIRE: !EP(%p)->qp_handle, re-create QP\n",ep_ptr);\r
630             return ( dapls_ib_qp_alloc ( ia_ptr, ep_ptr, ep_ptr ) );\r
631         }\r
632 \r
633         ib_status = dapls_modify_qp_state_to_reset ( ep_ptr->qp_handle);\r
634 \r
635         if ( ib_status != IB_SUCCESS )\r
636         {\r
637             dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DsIRE: failed to move qp to RESET status = %s\n", \r
638                      ib_get_err_str(ib_status));\r
639             return DAT_INTERNAL_ERROR;\r
640         }\r
641 \r
642         ep_ptr->qp_state = IB_QPS_RESET;\r
643 \r
644     p_ca   = (dapl_ibal_ca_t *) ia_ptr->hca_ptr->ib_hca_handle;\r
645     p_active_port = dapli_ibal_get_port ( p_ca, (uint8_t)ia_ptr->hca_ptr->port_num );\r
646 \r
647     if (NULL == p_active_port)\r
648     {\r
649         dapl_dbg_log (DAPL_DBG_TYPE_ERR,"--> DsIRE: Port %d is not available = %d\n",\r
650                 ia_ptr->hca_ptr->port_num, __LINE__);\r
651         return DAT_INTERNAL_ERROR;\r
652     }\r
653 \r
654         /* May fail if QP still RESET and in timewait, keep in reset state */\r
655     ib_status = dapls_modify_qp_state_to_init ( ep_ptr->qp_handle,\r
656                                                 &ep_ptr->param.ep_attr,\r
657                                                                                                 p_active_port);\r
658     if ( ib_status != IB_SUCCESS )\r
659     {\r
660         ep_ptr->qp_state = IB_QPS_RESET;\r
661 \r
662         dapl_dbg_log (DAPL_DBG_TYPE_ERR, "--> DsIRE: failed to move qp to INIT status = %s\n", \r
663                  ib_get_err_str(ib_status));\r
664         return DAT_INTERNAL_ERROR;\r
665     }\r
666 \r
667     ep_ptr->qp_state = IB_QPS_INIT;\r
668 \r
669     return DAT_SUCCESS;\r
670 \r
671 }\r
672 \r
673 \r
674 /*\r
675  * Local variables:\r
676  *  c-indent-level: 4\r
677  *  c-basic-offset: 4\r
678  *  tab-width: 8\r
679  * End:\r
680  */\r
681 \r