fe3b5cabbec1d308a38342a4eadf420b9e1a1cd9
[mirror/winof/.git] / hw / mthca / kernel / hca_memory.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  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  *\r
30  * $Id: hca_memory.c 46 2005-05-30 17:55:53Z sleybo $\r
31  */\r
32 \r
33 \r
34 #include "hca_utils.h"\r
35 #include "mthca_dev.h"\r
36 \r
37 #if defined(EVENT_TRACING)\r
38 #ifdef offsetof\r
39 #undef offsetof\r
40 #endif\r
41 #include "hca_memory.tmh"\r
42 #endif\r
43 \r
44 /*\r
45  *      Memory Management Verbs.\r
46  */\r
47 \r
48 ib_api_status_t\r
49 mlnx_register_mr (\r
50         IN              const   ib_pd_handle_t                          h_pd,\r
51         IN              const   ib_mr_create_t                          *p_mr_create,\r
52         OUT                     net32_t* const                          p_lkey,\r
53         OUT                     net32_t* const                          p_rkey,\r
54         OUT                     ib_mr_handle_t                          *ph_mr,\r
55         IN                              boolean_t                                       um_call )\r
56 {\r
57         ib_api_status_t         status;\r
58         int err;\r
59         struct ib_mr *mr_p;\r
60         struct ib_pd *ib_pd_p = (struct ib_pd *)h_pd;\r
61         PREP_IBDEV_FOR_PRINT(ib_pd_p->device)\r
62 \r
63         HCA_ENTER(HCA_DBG_MEMORY);\r
64 \r
65         // sanity checks\r
66         if( !cl_is_blockable() ) {\r
67                 status = IB_UNSUPPORTED;\r
68                 goto err_unsupported;\r
69         } \r
70         if (!p_mr_create || 0 == p_mr_create->length) {\r
71                 HCA_PRINT(TRACE_LEVEL_WARNING ,HCA_DBG_MEMORY,\r
72                         ("invalid attributes\n"));\r
73                 status = IB_INVALID_PARAMETER;\r
74                 goto err_invalid_parm; \r
75         }\r
76         /*\r
77          * Local write permission is required if remote write or\r
78          * remote atomic permission is also requested.\r
79          */\r
80         if (p_mr_create->access_ctrl & (IB_AC_RDMA_WRITE | IB_AC_ATOMIC) &&\r
81             !(p_mr_create->access_ctrl & IB_AC_LOCAL_WRITE)) {\r
82                 HCA_PRINT(TRACE_LEVEL_WARNING ,HCA_DBG_MEMORY,\r
83                         ("invalid access rights\n"));\r
84                 status = IB_INVALID_PERMISSION;\r
85                 goto err_invalid_access; \r
86         }               \r
87 \r
88         // register mr \r
89         mr_p = ibv_reg_mr(ib_pd_p, map_qp_ibal_acl(p_mr_create->access_ctrl), \r
90                 p_mr_create->vaddr, p_mr_create->length, \r
91                 (uint64_t)(ULONG_PTR)(void*)p_mr_create->vaddr, um_call );\r
92         if (IS_ERR(mr_p)) {\r
93                 err = PTR_ERR(mr_p);\r
94                 HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_MEMORY,\r
95                         ("ibv_reg_mr failed (%d)\n", err));\r
96                 status = errno_to_iberr(err);\r
97                 goto err_reg_mr;\r
98         }\r
99 \r
100         // results\r
101         *p_lkey = mr_p->lkey;\r
102         *p_rkey = cl_hton32( mr_p->rkey );\r
103         if (ph_mr)      *ph_mr = (ib_mr_handle_t)mr_p;\r
104         status = IB_SUCCESS;\r
105 \r
106 err_reg_mr:\r
107 err_invalid_access:     \r
108 err_invalid_parm:\r
109 err_unsupported:\r
110         HCA_PRINT_EXIT(TRACE_LEVEL_ERROR ,HCA_DBG_MEMORY,\r
111                 ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
112         return status;\r
113 }\r
114 \r
115 ib_api_status_t\r
116 mlnx_register_pmr (\r
117         IN              const   ib_pd_handle_t                          h_pd,\r
118         IN              const   ib_phys_create_t* const         p_pmr_create,\r
119         IN      OUT                     uint64_t* const                         p_vaddr,\r
120                 OUT                     net32_t* const                          p_lkey,\r
121                 OUT                     net32_t* const                          p_rkey,\r
122                 OUT                     ib_mr_handle_t* const           ph_mr,\r
123         IN                              boolean_t                                       um_call )\r
124 {\r
125         ib_api_status_t         status;\r
126         int err;\r
127         struct ib_mr *mr_p;\r
128         struct ib_phys_buf *buffer_list;\r
129         struct ib_pd *ib_pd_p = (struct ib_pd *)h_pd;\r
130         PREP_IBDEV_FOR_PRINT(ib_pd_p->device)\r
131 \r
132         UNUSED_PARAM( um_call );\r
133 \r
134         HCA_ENTER(HCA_DBG_SHIM);\r
135 \r
136         // sanity checks\r
137         if( !cl_is_blockable() ) {\r
138                 status = IB_UNSUPPORTED;\r
139                 goto err_unsupported;\r
140         }       \r
141         if (!p_vaddr || !p_pmr_create ||\r
142                 0 == p_pmr_create->length ) {\r
143                 status = IB_INVALID_PARAMETER;\r
144                 goto err_invalid_parm; \r
145         }\r
146 \r
147         // prepare parameters\r
148         buffer_list = (void*)p_pmr_create->range_array;\r
149         //NB: p_pmr_create->buf_offset is not used, i.e. supposed that region is page-aligned\r
150         //NB: p_pmr_create->hca_page_size is not used, i.e. supposed it is always the same\r
151         \r
152         // register pmr \r
153         if (p_pmr_create->length == (uint64_t)-1i64)\r
154         {\r
155                 mr_p = ibv_get_dma_mr( ib_pd_p,\r
156                         map_qp_ibal_acl(p_pmr_create->access_ctrl) );\r
157         }\r
158         else\r
159                 mr_p = ibv_reg_phys_mr(ib_pd_p, buffer_list, p_pmr_create->num_ranges, \r
160                         map_qp_ibal_acl(p_pmr_create->access_ctrl), p_vaddr );\r
161         if (IS_ERR(mr_p)) {\r
162                 err = PTR_ERR(mr_p);\r
163                 HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_MEMORY,\r
164                         ("mthca_reg_phys_mr failed (%d)\n", err));\r
165                 status = errno_to_iberr(err);\r
166                 goto err_reg_phys_mr;\r
167         }\r
168 \r
169         // results\r
170         if (ph_mr)      *ph_mr = (ib_mr_handle_t)mr_p;\r
171         *p_lkey = mr_p->lkey;\r
172         *p_rkey = cl_hton32( mr_p->rkey );\r
173         //NB:  p_vaddr was not changed\r
174         status = IB_SUCCESS;\r
175 \r
176 err_reg_phys_mr:\r
177 err_invalid_parm:\r
178 err_unsupported:\r
179         HCA_PRINT_EXIT(TRACE_LEVEL_ERROR  , HCA_DBG_MEMORY,\r
180                 ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
181         return status;\r
182         \r
183 }\r
184 \r
185 ib_api_status_t\r
186 mlnx_query_mr (\r
187         IN              const   ib_mr_handle_t                          h_mr,\r
188                 OUT                     ib_mr_attr_t                            *p_mr_query )\r
189 {\r
190         UNREFERENCED_PARAMETER(h_mr);\r
191         UNREFERENCED_PARAMETER(p_mr_query);\r
192         HCA_PRINT(TRACE_LEVEL_ERROR  , HCA_DBG_MEMORY  ,("mlnx_query_mr not implemented\n"));\r
193         return IB_UNSUPPORTED;\r
194 }\r
195 \r
196 \r
197 ib_api_status_t\r
198 mlnx_modify_mr (\r
199         IN              const   ib_mr_handle_t                          h_mr,\r
200         IN              const   ib_mr_mod_t                                     mem_modify_req,\r
201         IN              const   ib_mr_create_t                          *p_mr_create,\r
202                 OUT                     uint32_t                                        *p_lkey,\r
203                 OUT                     uint32_t                                        *p_rkey,\r
204         IN              const   ib_pd_handle_t                          h_pd OPTIONAL,\r
205         IN                              boolean_t                                       um_call )\r
206 {\r
207         UNREFERENCED_PARAMETER(h_mr);\r
208         UNREFERENCED_PARAMETER(mem_modify_req);\r
209         UNREFERENCED_PARAMETER(p_mr_create);\r
210         UNREFERENCED_PARAMETER(p_lkey);\r
211         UNREFERENCED_PARAMETER(p_rkey);\r
212         UNREFERENCED_PARAMETER(h_pd);\r
213         UNREFERENCED_PARAMETER(um_call);\r
214         HCA_PRINT(TRACE_LEVEL_ERROR  , HCA_DBG_MEMORY  ,("mlnx_modify_mr not implemented\n"));\r
215         return IB_UNSUPPORTED;\r
216 }\r
217 \r
218 \r
219 ib_api_status_t\r
220 mlnx_modify_pmr (\r
221         IN              const   ib_mr_handle_t                          h_mr,\r
222         IN              const   ib_mr_mod_t                                     mem_modify_req,\r
223         IN              const   ib_phys_create_t* const         p_pmr_create,\r
224         IN      OUT                     uint64_t* const                         p_vaddr,\r
225                 OUT                     uint32_t* const                         p_lkey,\r
226                 OUT                     uint32_t* const                         p_rkey,\r
227         IN              const   ib_pd_handle_t                          h_pd OPTIONAL,\r
228         IN                              boolean_t                                       um_call )\r
229 {\r
230         UNREFERENCED_PARAMETER(h_mr);\r
231         UNREFERENCED_PARAMETER(mem_modify_req);\r
232         UNREFERENCED_PARAMETER(p_pmr_create);\r
233         UNREFERENCED_PARAMETER(p_vaddr);\r
234         UNREFERENCED_PARAMETER(p_lkey);\r
235         UNREFERENCED_PARAMETER(p_rkey);\r
236         UNREFERENCED_PARAMETER(h_pd);\r
237         UNREFERENCED_PARAMETER(um_call);\r
238         HCA_PRINT(TRACE_LEVEL_ERROR  , HCA_DBG_MEMORY  ,("mlnx_modify_pmr not implemented\n"));\r
239         return IB_UNSUPPORTED;\r
240 }\r
241 \r
242 ib_api_status_t\r
243 mlnx_register_smr (\r
244         IN              const   ib_mr_handle_t                          h_mr,\r
245         IN              const   ib_pd_handle_t                          h_pd,\r
246         IN              const   ib_access_t                                     access_ctrl,\r
247         IN      OUT                     uint64_t* const                         p_vaddr,\r
248                 OUT                     net32_t* const                          p_lkey,\r
249                 OUT                     net32_t* const                          p_rkey,\r
250                 OUT                     ib_mr_handle_t* const           ph_mr,\r
251         IN                              boolean_t                                       um_call )\r
252 {\r
253         UNREFERENCED_PARAMETER(h_mr);\r
254         UNREFERENCED_PARAMETER(h_pd);\r
255         UNREFERENCED_PARAMETER(access_ctrl);\r
256         UNREFERENCED_PARAMETER(p_vaddr);\r
257         UNREFERENCED_PARAMETER(p_lkey);\r
258         UNREFERENCED_PARAMETER(p_rkey);\r
259         UNREFERENCED_PARAMETER(ph_mr);\r
260         UNREFERENCED_PARAMETER(um_call);\r
261         HCA_PRINT(TRACE_LEVEL_ERROR  , HCA_DBG_MEMORY  ,("mlnx_register_smr not implemented\n"));\r
262         return IB_UNSUPPORTED;\r
263 }\r
264 \r
265 ib_api_status_t\r
266 mlnx_deregister_mr (\r
267         IN              const   ib_mr_handle_t                          h_mr)\r
268 {\r
269         ib_api_status_t         status;\r
270         int err;\r
271         PREP_IBDEV_FOR_PRINT(((struct ib_mr *)h_mr)->device)\r
272 \r
273         HCA_ENTER(HCA_DBG_SHIM);\r
274 \r
275         // sanity checks\r
276         if( !cl_is_blockable() ) {\r
277                         status = IB_UNSUPPORTED;\r
278                         goto err_unsupported;\r
279         } \r
280 \r
281         // deregister   \r
282         err = ibv_dereg_mr((struct ib_mr *)h_mr);\r
283         if (err) {\r
284                 status = errno_to_iberr(err);\r
285                 HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_MEMORY, \r
286                         ("mthca_dereg_mr failed (%d)", status));\r
287                 goto err_dereg_mr;\r
288         }\r
289 \r
290         status = IB_SUCCESS;\r
291         \r
292 err_dereg_mr:\r
293 err_unsupported:\r
294         HCA_PRINT_EXIT(TRACE_LEVEL_ERROR  , HCA_DBG_MEMORY,\r
295                 ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
296         return status;\r
297                 \r
298 }\r
299 \r
300 /*\r
301 *       Memory Window Verbs.\r
302 */\r
303 \r
304 ib_api_status_t\r
305 mlnx_create_mw (\r
306         IN              const   ib_pd_handle_t                          h_pd,\r
307                 OUT                     net32_t* const                          p_rkey,\r
308                 OUT                     ib_mw_handle_t                          *ph_mw,\r
309         IN      OUT                     ci_umv_buf_t                            *p_umv_buf )\r
310 {\r
311         UNREFERENCED_PARAMETER(h_pd);\r
312         UNREFERENCED_PARAMETER(p_rkey);\r
313         UNREFERENCED_PARAMETER(ph_mw);\r
314         UNREFERENCED_PARAMETER(p_umv_buf);\r
315         HCA_PRINT(TRACE_LEVEL_ERROR  , HCA_DBG_MEMORY  ,("mlnx_create_mw not implemented\n"));\r
316         return IB_UNSUPPORTED;\r
317 }\r
318 \r
319 ib_api_status_t\r
320 mlnx_query_mw (\r
321         IN              const   ib_mw_handle_t                          h_mw,\r
322                 OUT                     ib_pd_handle_t                          *ph_pd,\r
323                 OUT                     net32_t* const                          p_rkey,\r
324         IN      OUT                     ci_umv_buf_t                            *p_umv_buf )\r
325 {\r
326         UNREFERENCED_PARAMETER(h_mw);\r
327         UNREFERENCED_PARAMETER(ph_pd);\r
328         UNREFERENCED_PARAMETER(p_rkey);\r
329         UNREFERENCED_PARAMETER(p_umv_buf);\r
330         HCA_PRINT(TRACE_LEVEL_ERROR  , HCA_DBG_MEMORY  ,("mlnx_query_mw not implemented\n"));\r
331         return IB_UNSUPPORTED;\r
332 }\r
333 \r
334 ib_api_status_t\r
335 mlnx_destroy_mw (\r
336         IN              const   ib_mw_handle_t                          h_mw)\r
337 {\r
338         UNREFERENCED_PARAMETER(h_mw);\r
339         HCA_PRINT(TRACE_LEVEL_ERROR  , HCA_DBG_MEMORY  ,("mlnx_destroy_mw not implemented\n"));\r
340         return IB_UNSUPPORTED;\r
341 }\r
342 \r
343 \r
344 void\r
345 mlnx_memory_if(\r
346         IN      OUT                     ci_interface_t                          *p_interface )\r
347 {\r
348         p_interface->register_mr = mlnx_register_mr;\r
349         p_interface->register_pmr = mlnx_register_pmr;\r
350         p_interface->query_mr = mlnx_query_mr;\r
351         p_interface->modify_mr = mlnx_modify_mr;\r
352         p_interface->modify_pmr = mlnx_modify_pmr;\r
353         p_interface->register_smr = mlnx_register_smr;\r
354         p_interface->deregister_mr = mlnx_deregister_mr;\r
355 \r
356         p_interface->create_mw = mlnx_create_mw;\r
357         p_interface->query_mw = mlnx_query_mw;\r
358         p_interface->destroy_mw = mlnx_destroy_mw;\r
359 }\r
360 \r
361 void\r
362 mlnx_memory_if_livefish(\r
363         IN      OUT                     ci_interface_t                          *p_interface )\r
364 {\r
365         p_interface->register_pmr = mlnx_register_pmr;\r
366         p_interface->deregister_mr = mlnx_deregister_mr;\r
367 }\r
368 \r