[DAPL2] DAPL Counters & 2.0.3 extensions to support counter retrieval.
[mirror/winof/.git] / ulp / dapl2 / dapl / ibal / dapl_ibal_extensions.c
1 /*\r
2  * Copyright (c) 2007 Intel Corporation.  All rights reserved.\r
3  *\r
4  * This Software is licensed under one of the following licenses:\r
5  *\r
6  * 1) under the terms of the "Common Public License 1.0" a copy of which is\r
7  *    available from the Open Source Initiative, see\r
8  *    http://www.opensource.org/licenses/cpl.php.\r
9  *\r
10  * 2) under the terms of the "The BSD License" a copy of which is\r
11  *    available from the Open Source Initiative, see\r
12  *    http://www.opensource.org/licenses/bsd-license.php.\r
13  *\r
14  * 3) under the terms of the "GNU General Public License (GPL) Version 2" a\r
15  *    copy of which is available from the Open Source Initiative, see\r
16  *    http://www.opensource.org/licenses/gpl-license.php.\r
17  *\r
18  * Licensee has the right to choose one of the above licenses.\r
19  *\r
20  * Redistributions of source code must retain the above copyright\r
21  * notice and one of the license notices.\r
22  *\r
23  * Redistributions in binary form must reproduce both the above copyright\r
24  * notice, one of the license notices in the documentation\r
25  * and/or other materials provided with the distribution.\r
26  */\r
27 \r
28 /**********************************************************************\r
29  * \r
30  * MODULE: dapl_ibal_extensions.c\r
31  *\r
32  * PURPOSE:  Extensions routines for OpenIB-windows IBAL provider\r
33  *\r
34  * $Id: $\r
35  *\r
36  **********************************************************************/\r
37 \r
38 #include "dapl.h"\r
39 #include "dapl_adapter_util.h"\r
40 #include "dapl_evd_util.h"\r
41 #include "dapl_ibal_util.h"\r
42 #include "dapl_ep_util.h"\r
43 #include "dapl_cookie.h"\r
44 #include <stdarg.h>\r
45 \r
46 DAT_RETURN\r
47 dapli_post_ext( IN       DAT_EP_HANDLE          ep_handle,\r
48                 IN       DAT_UINT64             cmp_add,        \r
49                 IN       DAT_UINT64             swap,\r
50                 IN       DAT_UINT32             immed_data,\r
51                 IN       DAT_COUNT              segments,\r
52                 IN       DAT_LMR_TRIPLET        *local_iov,\r
53                 IN       DAT_DTO_COOKIE         user_cookie,\r
54                 IN const DAT_RMR_TRIPLET        *remote_iov,\r
55                 IN       int                    op_type, \r
56                 IN       DAT_COMPLETION_FLAGS   flags );\r
57 \r
58 \r
59 /*\r
60  * dapl_extensions\r
61  *\r
62  * Process extension requests\r
63  *\r
64  * Input:\r
65  *      ext_type,\r
66  *      ...\r
67  *\r
68  * Output:\r
69  *      Depends....\r
70  *\r
71  * Returns:\r
72  *      DAT_SUCCESS\r
73  *      DAT_NOT_IMPLEMENTED\r
74  *      .....\r
75  *\r
76  */\r
77 DAT_RETURN\r
78 dapl_extensions(IN DAT_HANDLE           dat_handle, \r
79                 IN DAT_EXTENDED_OP      ext_op, \r
80                 IN va_list              args)\r
81 {\r
82         DAT_EP_HANDLE           ep;\r
83         DAT_LMR_TRIPLET         *lmr_p;\r
84         DAT_DTO_COOKIE          cookie;\r
85         const DAT_RMR_TRIPLET   *rmr_p;\r
86         DAT_UINT64              dat_uint64a, dat_uint64b;\r
87         DAT_UINT32              dat_uint32;\r
88         DAT_COUNT               segments = 1;\r
89         DAT_COMPLETION_FLAGS    comp_flags;\r
90         DAT_RETURN              status = DAT_NOT_IMPLEMENTED;\r
91 \r
92         dapl_dbg_log(DAPL_DBG_TYPE_API,\r
93                      "dapl_extensions(hdl %p operation %d, ...)\n",\r
94                      dat_handle, ext_op);\r
95 \r
96         switch ((int)ext_op)\r
97         {\r
98         \r
99         case DAT_IB_RDMA_WRITE_IMMED_OP:\r
100                 dapl_dbg_log(DAPL_DBG_TYPE_RTN, \r
101                              " WRITE_IMMED_DATA extension call\n");\r
102                 \r
103                 ep          = dat_handle;                /* ep_handle */\r
104                 segments    = va_arg( args, DAT_COUNT);  /* num segments */\r
105                 lmr_p       = va_arg( args, DAT_LMR_TRIPLET*);  \r
106                 cookie      = va_arg( args, DAT_DTO_COOKIE);\r
107                 rmr_p       = va_arg( args, const DAT_RMR_TRIPLET*); \r
108                 dat_uint32  = va_arg( args, DAT_UINT32); /* immed data */\r
109                 comp_flags  = va_arg( args, DAT_COMPLETION_FLAGS);   \r
110                 \r
111                 status = dapli_post_ext(ep, 0, 0, dat_uint32, segments, lmr_p,\r
112                                         cookie, rmr_p, OP_RDMA_WRITE_IMM,\r
113                                         comp_flags );\r
114                 break;\r
115 \r
116         case DAT_IB_CMP_AND_SWAP_OP:\r
117                 dapl_dbg_log(DAPL_DBG_TYPE_RTN, \r
118                              " CMP_AND_SWAP extension call\n");\r
119 \r
120                 ep          = dat_handle;               /* ep_handle */\r
121                 dat_uint64a = va_arg( args, DAT_UINT64); /* cmp_value */\r
122                 dat_uint64b = va_arg( args, DAT_UINT64); /* swap_value */\r
123                 lmr_p       = va_arg( args, DAT_LMR_TRIPLET*); \r
124                 cookie      = va_arg( args, DAT_DTO_COOKIE);  \r
125                 rmr_p       = va_arg( args, const DAT_RMR_TRIPLET*);\r
126                 comp_flags  = va_arg( args, DAT_COMPLETION_FLAGS);\r
127 \r
128                 status = dapli_post_ext(ep, dat_uint64a, dat_uint64b,\r
129                                         0, segments, lmr_p, cookie, rmr_p, \r
130                                         OP_COMP_AND_SWAP, comp_flags );\r
131                 break;\r
132 \r
133         case DAT_IB_FETCH_AND_ADD_OP:\r
134                 dapl_dbg_log(DAPL_DBG_TYPE_RTN, \r
135                              " FETCH_AND_ADD extension call\n");\r
136                 \r
137                 ep          = dat_handle;               /* ep_handle */\r
138                 dat_uint64a = va_arg( args, DAT_UINT64); /* add value */\r
139                 lmr_p       = va_arg( args, DAT_LMR_TRIPLET*);  \r
140                 cookie      = va_arg( args, DAT_DTO_COOKIE);\r
141                 rmr_p       = va_arg( args, const DAT_RMR_TRIPLET*); \r
142                 comp_flags  = va_arg( args, DAT_COMPLETION_FLAGS);   \r
143                 \r
144                 status = dapli_post_ext(ep, dat_uint64a, 0, 0, segments, \r
145                                         lmr_p, cookie, rmr_p, \r
146                                         OP_FETCH_AND_ADD, comp_flags );\r
147 \r
148                 break;\r
149 \r
150         default:\r
151                 dapl_dbg_log(DAPL_DBG_TYPE_ERR, \r
152                              "unsupported extension(%d)\n", (int)ext_op);\r
153         }\r
154         \r
155         return(status);\r
156 }\r
157 \r
158 \r
159 DAT_RETURN\r
160 dapli_post_ext( IN       DAT_EP_HANDLE          ep_handle,\r
161                 IN       DAT_UINT64             cmp_add,        \r
162                 IN       DAT_UINT64             swap,\r
163                 IN       DAT_UINT32             immed_data,\r
164                 IN       DAT_COUNT              segments,\r
165                 IN       DAT_LMR_TRIPLET        *local_iov,\r
166                 IN       DAT_DTO_COOKIE         user_cookie,\r
167                 IN const DAT_RMR_TRIPLET        *remote_iov,\r
168                 IN       int                    op_type, \r
169                 IN       DAT_COMPLETION_FLAGS   flags )\r
170 {\r
171         DAPL_EP         *ep_ptr;\r
172         ib_qp_handle_t  qp_ptr;\r
173         DAPL_COOKIE     *cookie;\r
174         DAT_RETURN      dat_status = DAT_SUCCESS;\r
175 \r
176         dapl_dbg_log(DAPL_DBG_TYPE_API,\r
177                      "--> post_ext_op: ep %p cmp_val %x swap_val %x cookie "\r
178                      "0x%x\n    r_iov %p, flags 0x%x op %d segs %d\n",\r
179                      ep_handle, (unsigned)cmp_add, (unsigned)swap, \r
180                      (unsigned)user_cookie.as_64, remote_iov, flags, op_type,\r
181                      segments);\r
182 \r
183         if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP))\r
184                 return(DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP));\r
185 \r
186         if ((NULL == remote_iov) || (NULL == local_iov))\r
187                 return DAT_INVALID_PARAMETER;\r
188 \r
189         ep_ptr = (DAPL_EP *) ep_handle;\r
190         qp_ptr = ep_ptr->qp_handle;\r
191 \r
192         /*\r
193          * Synchronization ok since this buffer is only used for send\r
194          * requests, which aren't allowed to race with each other.\r
195          */\r
196         dat_status = dapls_dto_cookie_alloc(\r
197                                         &ep_ptr->req_buffer,\r
198                                         DAPL_DTO_TYPE_EXTENSION,\r
199                                         user_cookie,\r
200                                         &cookie );\r
201 \r
202         if ( dat_status != DAT_SUCCESS )\r
203         {\r
204 #ifdef DAPL_DBG\r
205                 dapl_dbg_log(DAPL_DBG_TYPE_ERR,"%s() cookie alloc faulure %x\n",\r
206                                 __FUNCTION__,dat_status);\r
207 #endif\r
208                 goto bail;\r
209         }\r
210                 \r
211         /*\r
212          * Invoke provider specific routine to post DTO\r
213          */\r
214         dat_status = dapls_ib_post_ext_send(ep_ptr,     \r
215                                             op_type,\r
216                                             cookie,     \r
217                                             segments,   /* data segments */\r
218                                             local_iov, \r
219                                             remote_iov,\r
220                                             immed_data, /* immed data */\r
221                                             cmp_add,    /* compare or add */\r
222                                             swap,       /* swap */\r
223                                             flags);\r
224 \r
225         if (dat_status != DAT_SUCCESS)\r
226         {\r
227                 dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);\r
228 #ifdef DAPL_DBG\r
229                 dapl_dbg_log(DAPL_DBG_TYPE_ERR,\r
230                                 "%s() post_ex_send err %d @ line %d\n",\r
231                                 __FUNCTION__,dat_status,__LINE__);\r
232 #endif\r
233         }\r
234 \r
235 bail:\r
236         return dat_status;\r
237 \r
238 }\r
239 \r
240 \r
241 /* \r
242  * New provider routine to process extended DTO events \r
243  */\r
244 void\r
245 dapls_cqe_to_event_extension(IN DAPL_EP                 *ep_ptr,\r
246                              IN DAPL_COOKIE             *cookie,\r
247                              IN ib_work_completion_t    *cqe_ptr,\r
248                              IN DAT_EVENT               *event_ptr)\r
249 {\r
250     uint32_t ibtype;\r
251     DAT_DTO_COMPLETION_EVENT_DATA *dto = \r
252                         &event_ptr->event_data.dto_completion_event_data;\r
253     DAT_IB_EXTENSION_EVENT_DATA *ext_data = \r
254                         (DAT_IB_EXTENSION_EVENT_DATA *)\r
255                         &event_ptr->event_extension_data[0];\r
256     DAT_DTO_COMPLETION_STATUS dto_status;\r
257 \r
258     /* Get status from cqe */\r
259     dto_status = dapls_ib_get_dto_status(cqe_ptr);\r
260         \r
261     dapl_dbg_log(DAPL_DBG_TYPE_EVD,\r
262              " cqe_to_event_ext: dto_ptr %p ext_ptr %p status %d\n",\r
263              dto, ext_data, dto_status);\r
264 \r
265     event_ptr->event_number = DAT_IB_DTO_EVENT;\r
266     dto->ep_handle = cookie->ep;\r
267     dto->user_cookie = cookie->val.dto.cookie;\r
268     dto->operation = DAPL_GET_CQE_DTOS_OPTYPE(cqe_ptr); /* new for 2.0 */\r
269     dto->status = ext_data->status = dto_status;\r
270 \r
271     if (dto_status != DAT_DTO_SUCCESS)\r
272         return;\r
273         \r
274     /* \r
275      * Get operation type from CQ work completion entry and\r
276      * if extented operation then set extended event data\r
277      */\r
278     ibtype = DAPL_GET_CQE_OPTYPE(cqe_ptr);\r
279         \r
280     switch (ibtype)     {\r
281 \r
282     case OP_RDMA_WRITE_IMM:\r
283         dapl_dbg_log (DAPL_DBG_TYPE_EVD,\r
284                       " cqe_to_event_ext: OP_RDMA_WRITE_IMMED\n");\r
285                 \r
286         /* type and outbound rdma write transfer size */\r
287         dto->transfered_length = cookie->val.dto.size;\r
288         ext_data->type = DAT_IB_RDMA_WRITE_IMMED;\r
289         break;\r
290 \r
291     case OP_RECEIVE_IMM:\r
292         dapl_dbg_log (DAPL_DBG_TYPE_EVD,\r
293                                 " cqe_to_event_ext: OP_RECEIVE_RDMA_IMMED\n");\r
294 \r
295         /* immed recvd, type and inbound rdma write transfer size */\r
296         dto->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);\r
297         ext_data->type = DAT_IB_RDMA_WRITE_IMMED_DATA;\r
298         ext_data->val.immed.data = DAPL_GET_CQE_IMMED_DATA(cqe_ptr);\r
299         break;\r
300 \r
301     case OP_COMP_AND_SWAP:\r
302         dapl_dbg_log (DAPL_DBG_TYPE_EVD,\r
303                       " cqe_to_event_ext: COMP_AND_SWAP_RESP\n");\r
304 \r
305         /* original data is returned in LMR provided with post */\r
306         ext_data->type = DAT_IB_CMP_AND_SWAP;\r
307         dto->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);\r
308         break;\r
309 \r
310     case OP_FETCH_AND_ADD:\r
311         dapl_dbg_log (DAPL_DBG_TYPE_EVD,\r
312                       " cqe_to_event_ext: FETCH_AND_ADD_RESP\n");\r
313 \r
314         /* original data is returned in LMR provided with post */\r
315         ext_data->type = DAT_IB_FETCH_AND_ADD;\r
316         dto->transfered_length = DAPL_GET_CQE_BYTESNUM(cqe_ptr);\r
317         break;\r
318 \r
319     default:\r
320         /* not extended operation */\r
321         ext_data->status = DAT_IB_OP_ERR;\r
322         dto->status = DAT_DTO_ERR_TRANSPORT;\r
323         break;\r
324     }\r
325 }\r
326 \r