0145247bb10e57cbe051f2130d7c8f40382a6979
[mirror/winof/.git] / hw / mthca / user / mlnx_ual_ca.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 "mlnx_ual_main.h"\r
35 #include "mt_l2w.h"\r
36 #include "mlnx_uvp.h"\r
37 #include "mlnx_uvp_verbs.h"\r
38 #include "mx_abi.h"\r
39 \r
40 #if defined(EVENT_TRACING)\r
41 #include "mlnx_ual_ca.tmh"\r
42 #endif\r
43 \r
44 extern uint32_t mlnx_dbg_lvl;\r
45 \r
46 static ib_api_status_t\r
47 __pre_open_ca (\r
48         IN              const   ib_net64_t                                      ca_guid,\r
49         IN      OUT                     ci_umv_buf_t                            *p_umv_buf,\r
50                 OUT                     ib_ca_handle_t                          *ph_uvp_ca)\r
51 {\r
52         ib_api_status_t  status = IB_SUCCESS;\r
53 \r
54         UNREFERENCED_PARAMETER(ph_uvp_ca);\r
55                 \r
56         UVP_ENTER(UVP_DBG_SHIM);\r
57         if( p_umv_buf )\r
58         {\r
59                 if( !p_umv_buf->p_inout_buf )\r
60                 {\r
61                         p_umv_buf->p_inout_buf = cl_zalloc( sizeof(struct ibv_get_context_resp) );\r
62                         if( !p_umv_buf->p_inout_buf )\r
63                         {\r
64                                 status = IB_INSUFFICIENT_MEMORY;\r
65                                 goto err_memory;\r
66                         }\r
67                 }\r
68                 p_umv_buf->input_size = p_umv_buf->output_size = sizeof(struct ibv_get_context_resp);\r
69                 p_umv_buf->command = TRUE;\r
70         }\r
71 err_memory:     \r
72         UVP_EXIT(UVP_DBG_SHIM);\r
73         return IB_SUCCESS;\r
74 }\r
75 \r
76 \r
77 static ib_api_status_t\r
78 __post_open_ca (\r
79         IN                              const ib_net64_t                        ca_guid,\r
80         IN                              ib_api_status_t                         ioctl_status,\r
81         IN      OUT                     ib_ca_handle_t                          *ph_uvp_ca,\r
82         IN                              ci_umv_buf_t                            *p_umv_buf )\r
83 {\r
84         ib_api_status_t  status = ioctl_status;\r
85         mlnx_ual_hobul_t *new_ca;\r
86         struct ibv_get_context_resp *p_resp;\r
87         struct ibv_context * ibvcontext;\r
88         int err;\r
89 \r
90         UVP_ENTER(UVP_DBG_SHIM);\r
91 \r
92         p_resp = (struct ibv_get_context_resp *)p_umv_buf->p_inout_buf;\r
93 \r
94         if (IB_SUCCESS == status) {\r
95                 /* allocate ibv context */\r
96                 ibvcontext = mthca_alloc_context(p_resp);\r
97                 if (IS_ERR(ibvcontext)) {\r
98                         err = PTR_ERR(ibvcontext);\r
99                         UVP_PRINT(TRACE_LEVEL_ERROR ,UVP_DBG_SHIM ,("mthca_alloc_context failed (%d)\n", err));\r
100                         status = errno_to_iberr(err);\r
101                         goto err_alloc_context;\r
102                 }\r
103 \r
104                 /* allocate mthca context */\r
105                 new_ca = (mlnx_ual_hobul_t *)cl_zalloc( sizeof(mlnx_ual_hobul_t) );\r
106                 if( !new_ca ) {\r
107                         status = IB_INSUFFICIENT_MEMORY;\r
108                         goto err_memory;\r
109                 }\r
110 \r
111                 /* return results */\r
112                 new_ca->ibv_ctx = ibvcontext;\r
113                 new_ca->p_hca_attr = NULL;\r
114                 *ph_uvp_ca = (ib_ca_handle_t)new_ca;\r
115         }\r
116 \r
117 err_memory:     \r
118 err_alloc_context:\r
119         if (p_resp)\r
120                 cl_free( p_resp );\r
121         UVP_EXIT(UVP_DBG_SHIM);\r
122         return status;\r
123 }\r
124 \r
125 static ib_api_status_t\r
126 __pre_query_ca (\r
127         IN                              ib_ca_handle_t                          h_uvp_ca,\r
128         IN                              ib_ca_attr_t                            *p_ca_attr,\r
129         IN                              size_t                                          byte_count,\r
130         IN                              ci_umv_buf_t                            *p_umv_buf )\r
131 {\r
132         ib_api_status_t status = IB_SUCCESS;\r
133 \r
134         UVP_ENTER(UVP_DBG_SHIM);\r
135 \r
136         CL_ASSERT(h_uvp_ca);\r
137 \r
138         /*\r
139          * First time call query_ca - populate our internal cached attributes\r
140          * so we can access the GID table.  Note that query_ca calls *always*\r
141          * get their attributes from the kernel.\r
142          */\r
143         if ( !h_uvp_ca->p_hca_attr )\r
144         {\r
145                 /*\r
146                  * Assume if user buffer is valid then byte_cnt is valid too \r
147                  * so we can preallocate ca attr buffer for post ioctl data saving\r
148                  *\r
149                  * Note that we squirel the buffer away into the umv_buf and only\r
150                  * set it into the HCA if the query is successful.\r
151                  */\r
152                 if ( p_ca_attr != NULL )\r
153                 {\r
154                         p_umv_buf->p_inout_buf = cl_zalloc(byte_count);\r
155                         if ( !p_umv_buf->p_inout_buf )\r
156                         {\r
157                                 UVP_PRINT(TRACE_LEVEL_ERROR ,UVP_DBG_SHIM ,\r
158                                         ("Failed to alloc new_ca\n"));\r
159                                 status = IB_INSUFFICIENT_RESOURCES;\r
160                                 return status;\r
161                         }\r
162                 }\r
163                 p_umv_buf->input_size = p_umv_buf->output_size = 0;\r
164         }\r
165 \r
166         UVP_EXIT(UVP_DBG_SHIM);\r
167         return status;\r
168 }\r
169 \r
170 \r
171 static void\r
172 __post_query_ca (\r
173         IN                              ib_ca_handle_t                          h_uvp_ca,\r
174         IN                              ib_api_status_t                         ioctl_status,\r
175         IN                              ib_ca_attr_t                            *p_ca_attr,\r
176         IN                              size_t                                          byte_count,\r
177         IN                              ci_umv_buf_t                            *p_umv_buf )\r
178 {\r
179         UVP_ENTER(UVP_DBG_SHIM);\r
180 \r
181         CL_ASSERT(h_uvp_ca);\r
182         CL_ASSERT(p_umv_buf);\r
183 \r
184         if ( ioctl_status == IB_SUCCESS && p_ca_attr &&\r
185                 byte_count && !h_uvp_ca->p_hca_attr )\r
186         {\r
187                 CL_ASSERT( byte_count >= p_ca_attr->size );\r
188                 h_uvp_ca->p_hca_attr = p_umv_buf->p_inout_buf;\r
189                 ib_copy_ca_attr( h_uvp_ca->p_hca_attr, p_ca_attr );\r
190         }\r
191         else if (p_umv_buf->p_inout_buf) \r
192         {\r
193                 cl_free (p_umv_buf->p_inout_buf);\r
194         }\r
195 \r
196         UVP_EXIT(UVP_DBG_SHIM);\r
197         return;\r
198 }\r
199 \r
200 \r
201 static ib_api_status_t\r
202 __pre_modify_ca (\r
203     IN          ib_ca_handle_t                          h_uvp_ca,\r
204     IN          uint8_t                                         port_num,\r
205     IN          ib_ca_mod_t                                     ca_mod,\r
206     IN          const ib_port_attr_mod_t*       p_port_attr_mod)\r
207 {\r
208     UVP_ENTER(UVP_DBG_SHIM);\r
209     UVP_EXIT(UVP_DBG_SHIM);\r
210     return IB_SUCCESS;\r
211 }\r
212 \r
213 \r
214 static void\r
215 __post_modify_ca (\r
216         IN              ib_ca_handle_t                  h_uvp_ca,\r
217         IN              ib_api_status_t                 ioctl_status)\r
218 {\r
219         UVP_ENTER(UVP_DBG_SHIM);\r
220         UVP_EXIT(UVP_DBG_SHIM);\r
221 }\r
222 \r
223 \r
224 static ib_api_status_t\r
225 __pre_close_ca (\r
226         IN              ib_ca_handle_t          h_uvp_ca)\r
227 {\r
228         UVP_ENTER(UVP_DBG_SHIM);\r
229         UVP_EXIT(UVP_DBG_SHIM);\r
230         return IB_SUCCESS;\r
231 }\r
232 \r
233 \r
234 static ib_api_status_t\r
235 __post_close_ca (\r
236         IN              ib_ca_handle_t          h_uvp_ca,\r
237         IN              ib_api_status_t         ioctl_status )\r
238 {\r
239         mlnx_ual_hobul_t *p_hobul = (mlnx_ual_hobul_t *)((void*)h_uvp_ca);\r
240 \r
241         UVP_ENTER(UVP_DBG_SHIM);\r
242 \r
243         CL_ASSERT(p_hobul);\r
244 \r
245         if (IB_SUCCESS == ioctl_status) {\r
246                 if (p_hobul->ibv_ctx) {\r
247                         mthca_free_context(p_hobul->ibv_ctx);\r
248                         p_hobul->ibv_ctx = NULL;\r
249                 }\r
250 \r
251                 if (p_hobul->p_hca_attr) {\r
252                         cl_free( p_hobul->p_hca_attr);\r
253                         p_hobul->p_hca_attr = NULL;\r
254                 }\r
255 \r
256                 cl_free(p_hobul);\r
257         }\r
258         \r
259         UVP_EXIT(UVP_DBG_SHIM);\r
260         return IB_SUCCESS;\r
261 }\r
262 \r
263 void\r
264 mlnx_get_ca_interface (\r
265         IN OUT  uvp_interface_t         *p_uvp )\r
266 {\r
267         CL_ASSERT(p_uvp);\r
268 \r
269         /*\r
270          * HCA Access Verbs\r
271          */\r
272         p_uvp->pre_open_ca  = __pre_open_ca;\r
273         p_uvp->post_open_ca = __post_open_ca;\r
274 \r
275 \r
276         p_uvp->pre_query_ca  = __pre_query_ca;\r
277         p_uvp->post_query_ca = __post_query_ca;\r
278 \r
279         p_uvp->pre_modify_ca  = NULL;\r
280         p_uvp->post_modify_ca = NULL;\r
281 \r
282         p_uvp->pre_close_ca  = __pre_close_ca;\r
283         p_uvp->post_close_ca = __post_close_ca;\r
284 \r
285 }\r
286 \r
287 \r