7166316d798cb542a94899a75cd61855f09fb1da
[mirror/winof/.git] / hw / mlx4 / user / hca / mlx4.c
1 /*\r
2  * Copyright (c) 2007 Cisco, Inc.  All rights reserved.\r
3  *\r
4  * This software is available to you under a choice of one of two\r
5  * licenses.  You may choose to be licensed under the terms of the GNU\r
6  * General Public License (GPL) Version 2, available from the file\r
7  * COPYING in the main directory of this source tree, or the\r
8  * OpenIB.org BSD license below:\r
9  *\r
10  *     Redistribution and use in source and binary forms, with or\r
11  *     without modification, are permitted provided that the following\r
12  *     conditions are met:\r
13  *\r
14  *      - Redistributions of source code must retain the above\r
15  *        copyright notice, this list of conditions and the following\r
16  *        disclaimer.\r
17  *\r
18  *      - Redistributions in binary form must reproduce the above\r
19  *        copyright notice, this list of conditions and the following\r
20  *        disclaimer in the documentation and/or other materials\r
21  *        provided with the distribution.\r
22  *\r
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
30  * SOFTWARE.\r
31  */\r
32 \r
33 \r
34 #include "mlx4.h"\r
35 #include "mx_abi.h"\r
36 \r
37 #ifndef PCI_VENDOR_ID_MELLANOX\r
38 #define PCI_VENDOR_ID_MELLANOX                  0x15b3\r
39 #endif\r
40 \r
41 #define HCA(v, d) \\r
42         {PCI_VENDOR_ID_##v,                     \\r
43           d }\r
44 \r
45 struct {\r
46         unsigned                vendor;\r
47         unsigned                device;\r
48 } hca_table[] = {\r
49         HCA(MELLANOX, 0x6340),  /* MT25408 "Hermon" SDR */\r
50         HCA(MELLANOX, 0x634a),  /* MT25418 "Hermon" DDR */\r
51         HCA(MELLANOX, 0x6732),  /* MT26418 "Hermon" DDR PCIe gen2 */\r
52         HCA(MELLANOX, 0x673c),  /* MT26428 "Hermon" QDR PCIe gen2 */\r
53 \r
54         HCA(MELLANOX, 0x6368),  /* MT25448 "Hermon" Ethernet */\r
55         HCA(MELLANOX, 0x6372),  /* MT25458 "Hermon" Ethernet Yatir*/\r
56         HCA(MELLANOX, 0x6750),  /* MT26448 "Hermon" Ethernet PCIe gen2 */\r
57         HCA(MELLANOX, 0x675A),  /* MT26458 "Hermon" Ethernet Yatir PCIe gen2*/\r
58 \r
59         HCA(MELLANOX, 0x0191),  /* MT25408 "Hermon" livefish mode */ \r
60 };\r
61 \r
62 \r
63 struct ibv_context * mlx4_alloc_context()\r
64 {\r
65         struct mlx4_context *context;\r
66         \r
67         /* allocate context */\r
68         context = cl_zalloc(sizeof *context);\r
69         if (!context)\r
70                 goto end;\r
71 \r
72         context->qp_table_mutex = CreateMutex(NULL, FALSE, NULL);\r
73         if (!context->qp_table_mutex)\r
74                 goto err_qp_mutex;\r
75 \r
76 #ifdef XRC_SUPPORT\r
77         context->xrc_srq_table_mutex = CreateMutex(NULL, FALSE, NULL);\r
78         if (!context->xrc_srq_table_mutex)\r
79                 goto err_xrc_mutex;\r
80 #endif  \r
81 \r
82         context->db_list_mutex = CreateMutex(NULL, FALSE, NULL);\r
83         if (!context->db_list_mutex)\r
84                 goto err_db_mutex;\r
85 \r
86         if (cl_spinlock_init(&context->uar_lock))\r
87                 goto err_uar_spinlock;\r
88 \r
89         if (cl_spinlock_init(&context->bf_lock))\r
90                 goto err_bf_spinlock;\r
91 \r
92         return &context->ibv_ctx;\r
93 \r
94 err_bf_spinlock:\r
95         cl_spinlock_destroy(&context->uar_lock);\r
96 err_uar_spinlock:\r
97         CloseHandle(context->db_list_mutex);\r
98 err_db_mutex:\r
99 #ifdef XRC_SUPPORT\r
100         CloseHandle(context->xrc_srq_table_mutex);\r
101 err_xrc_mutex:\r
102 #endif  \r
103         CloseHandle(context->qp_table_mutex);\r
104 err_qp_mutex:\r
105         cl_free(context);\r
106 end:\r
107         return NULL;\r
108         \r
109 }\r
110 \r
111 struct ibv_context * mlx4_fill_context(struct ibv_context *ctx, struct ibv_get_context_resp *p_resp)\r
112 {\r
113         struct mlx4_context *context = to_mctx(ctx);\r
114         SYSTEM_INFO sys_info;\r
115         int i;\r
116 \r
117         /* check device type */\r
118         for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i) \r
119                 if (p_resp->vend_id == hca_table[i].vendor &&\r
120                         p_resp->dev_id == hca_table[i].device) \r
121                         goto found;\r
122         goto err_dev_type;\r
123 \r
124 found:\r
125         context->num_qps                        = p_resp->qp_tab_size;\r
126         context->qp_table_shift = ffsl(context->num_qps) - 1 - MLX4_QP_TABLE_BITS;\r
127         context->qp_table_mask  = (1 << context->qp_table_shift) - 1;\r
128 \r
129         for (i = 0; i < MLX4_QP_TABLE_SIZE; ++i)\r
130                 context->qp_table[i].refcnt = 0;\r
131 \r
132 #ifdef XRC_SUPPORT\r
133         context->num_xrc_srqs   = p_resp->qp_tab_size;\r
134         context->xrc_srq_table_shift = ffsl(context->num_xrc_srqs) - 1\r
135                                        - MLX4_XRC_SRQ_TABLE_BITS;\r
136         context->xrc_srq_table_mask = (1 << context->xrc_srq_table_shift) - 1;\r
137 \r
138         for (i = 0; i < MLX4_XRC_SRQ_TABLE_SIZE; ++i)\r
139                 context->xrc_srq_table[i].refcnt = 0;\r
140 #endif\r
141 \r
142         for (i = 0; i < MLX4_NUM_DB_TYPE; ++i)\r
143                 context->db_list[i] = NULL;\r
144 \r
145         context->uar                    = (uint8_t *)(uintptr_t)p_resp->uar_addr;\r
146         context->bf_page                = (uint8_t *)(uintptr_t)p_resp->bf_page;\r
147         context->bf_buf_size    = p_resp->bf_buf_size;\r
148         context->bf_offset      = p_resp->bf_offset;\r
149 \r
150         context->max_qp_wr      = p_resp->max_qp_wr;\r
151         context->max_sge                = p_resp->max_sge;\r
152         context->max_cqe                = p_resp->max_cqe;\r
153 \r
154         GetSystemInfo(&sys_info);\r
155         context->ibv_ctx.page_size = sys_info.dwPageSize;\r
156 \r
157         return &context->ibv_ctx;\r
158 \r
159 err_dev_type:\r
160         mlx4_free_context(&context->ibv_ctx);\r
161         return NULL;\r
162 }\r
163 \r
164 void mlx4_free_context(struct ibv_context *ctx)\r
165 {\r
166         struct mlx4_context *context = to_mctx(ctx);\r
167 \r
168         cl_spinlock_destroy(&context->bf_lock);\r
169         cl_spinlock_destroy(&context->uar_lock);\r
170         CloseHandle(context->db_list_mutex);\r
171 #ifdef XRC_SUPPORT\r
172         CloseHandle(context->xrc_srq_table_mutex);\r
173 #endif\r
174         CloseHandle(context->qp_table_mutex);\r
175         cl_free(context);\r
176 }\r
177 \r
178 static void __get_uvp_interface(uvp_interface_t *p_uvp)\r
179 {\r
180         p_uvp->pre_open_ca              = mlx4_pre_open_ca;\r
181         p_uvp->post_open_ca             = mlx4_post_open_ca;\r
182         p_uvp->pre_query_ca             = NULL;\r
183         p_uvp->post_query_ca    = NULL;\r
184         p_uvp->pre_modify_ca    = NULL;\r
185         p_uvp->post_modify_ca   = NULL;\r
186         p_uvp->pre_close_ca             = NULL;\r
187         p_uvp->post_close_ca    = mlx4_post_close_ca;\r
188 \r
189 \r
190         /*\r
191          * Protection Domain\r
192          */\r
193         p_uvp->pre_allocate_pd          = mlx4_pre_alloc_pd;\r
194         p_uvp->post_allocate_pd         = mlx4_post_alloc_pd;\r
195         p_uvp->pre_deallocate_pd        = NULL;\r
196         p_uvp->post_deallocate_pd       = mlx4_post_free_pd;\r
197 \r
198 \r
199         /*\r
200          * SRQ Management Verbs\r
201          */\r
202         p_uvp->pre_create_srq   = mlx4_pre_create_srq;\r
203         p_uvp->post_create_srq  = mlx4_post_create_srq;\r
204         p_uvp->pre_query_srq    = NULL;\r
205         p_uvp->post_query_srq   = NULL;\r
206         p_uvp->pre_modify_srq   = NULL;\r
207         p_uvp->post_modify_srq  = NULL;\r
208         p_uvp->pre_destroy_srq  = NULL;\r
209         p_uvp->post_destroy_srq = mlx4_post_destroy_srq;\r
210 \r
211         p_uvp->pre_create_qp    = mlx4_pre_create_qp;\r
212         p_uvp->wv_pre_create_qp = mlx4_wv_pre_create_qp;\r
213         p_uvp->post_create_qp   = mlx4_post_create_qp;\r
214         p_uvp->pre_modify_qp    = mlx4_pre_modify_qp;\r
215         p_uvp->post_modify_qp   = mlx4_post_modify_qp;\r
216         p_uvp->pre_query_qp             = NULL;\r
217         p_uvp->post_query_qp    = mlx4_post_query_qp;\r
218         p_uvp->pre_destroy_qp   = mlx4_pre_destroy_qp;\r
219         p_uvp->post_destroy_qp  = mlx4_post_destroy_qp;\r
220         p_uvp->nd_modify_qp             = mlx4_nd_modify_qp;\r
221         p_uvp->nd_get_qp_state  = mlx4_nd_get_qp_state;\r
222 \r
223 \r
224         /*\r
225          * Completion Queue Management Verbs\r
226          */\r
227         p_uvp->pre_create_cq    = mlx4_pre_create_cq;\r
228         p_uvp->post_create_cq   = mlx4_post_create_cq;\r
229         p_uvp->pre_query_cq             = mlx4_pre_query_cq;\r
230         p_uvp->post_query_cq    = NULL;\r
231         p_uvp->pre_resize_cq    = NULL;\r
232         p_uvp->post_resize_cq   = NULL;\r
233         p_uvp->pre_destroy_cq   = NULL;\r
234         p_uvp->post_destroy_cq  = mlx4_post_destroy_cq;\r
235 \r
236 \r
237         /*\r
238          * AV Management\r
239          */\r
240         p_uvp->pre_create_av    = mlx4_pre_create_ah;\r
241         p_uvp->post_create_av   = NULL;\r
242         p_uvp->pre_query_av             = mlx4_pre_query_ah;\r
243         p_uvp->post_query_av    = mlx4_post_query_ah;\r
244         p_uvp->pre_modify_av    = mlx4_pre_modify_ah;\r
245         p_uvp->post_modify_av   = NULL;\r
246         p_uvp->pre_destroy_av   = mlx4_pre_destroy_ah;\r
247         p_uvp->post_destroy_av  = NULL;\r
248 \r
249 \r
250         /*\r
251          * Memory Region / Window Management Verbs\r
252          */\r
253         p_uvp->pre_create_mw    = NULL;\r
254         p_uvp->post_create_mw   = NULL;\r
255         p_uvp->pre_query_mw     = NULL;\r
256         p_uvp->post_query_mw    = NULL;\r
257         p_uvp->pre_destroy_mw   = NULL;\r
258         p_uvp->post_destroy_mw  = NULL;\r
259 \r
260 \r
261         /*\r
262          * Multicast Support Verbs\r
263          */\r
264         p_uvp->pre_attach_mcast         = NULL;\r
265         p_uvp->post_attach_mcast        = NULL;\r
266         p_uvp->pre_detach_mcast         = NULL;\r
267         p_uvp->post_detach_mcast        = NULL;\r
268 \r
269 \r
270         /*\r
271          * OS bypass (send, receive, poll/notify cq)\r
272          */\r
273         p_uvp->post_send                = mlx4_post_send;\r
274         p_uvp->post_recv                = mlx4_post_recv;\r
275         p_uvp->post_srq_recv    = mlx4_post_srq_recv;\r
276         p_uvp->poll_cq                  = mlx4_poll_cq_list;\r
277         p_uvp->poll_cq_array    = mlx4_poll_cq_array;\r
278         p_uvp->rearm_cq                 = mlx4_arm_cq;\r
279         p_uvp->rearm_n_cq               = NULL;\r
280         p_uvp->peek_cq                  = NULL;\r
281         p_uvp->bind_mw                  = NULL;\r
282 }\r
283 \r
284 /* TODO: define and expose XRC through new interface GUID */\r
285 #ifdef XRC_SUPPORT\r
286 static void __get_xrc_interface(uvp_xrc_interface_t *p_xrc)\r
287 {\r
288         /*\r
289          * XRC Management Verbs\r
290          */\r
291         p_uvp->pre_create_xrc_srq               = mlx4_pre_create_xrc_srq;\r
292         p_uvp->post_create_xrc_srq              = mlx4_post_create_xrc_srq;\r
293         p_uvp->pre_open_xrc_domain              = mlx4_pre_open_xrc_domain;\r
294         p_uvp->post_open_xrc_domain             = mlx4_post_open_xrc_domain;\r
295         p_uvp->pre_close_xrc_domain             = NULL;\r
296         p_uvp->post_close_xrc_domain    = mlx4_post_close_xrc_domain;\r
297         p_uvp->pre_create_xrc_rcv_qp    = NULL;\r
298         p_uvp->post_create_xrc_rcv_qp   = NULL;\r
299         p_uvp->pre_modify_xrc_rcv_qp    = NULL;\r
300         p_uvp->post_modify_xrc_rcv_qp   = NULL;\r
301         p_uvp->pre_query_xrc_rcv_qp             = NULL;\r
302         p_uvp->post_query_xrc_rcv_qp    = NULL;\r
303         p_uvp->pre_reg_xrc_rcv_qp               = NULL;\r
304         p_uvp->post_reg_xrc_rcv_qp              = NULL;\r
305         p_uvp->pre_unreg_xrc_rcv_qp             = NULL;\r
306         p_uvp->post_unreg_xrc_rcv_qp    = NULL;\r
307 }\r
308 #endif\r
309 \r
310 __declspec(dllexport) ib_api_status_t\r
311 uvp_get_interface (GUID iid, void* pifc)\r
312 {\r
313         ib_api_status_t status = IB_SUCCESS;\r
314 \r
315         if (IsEqualGUID(&iid, &IID_UVP))\r
316         {\r
317                 __get_uvp_interface((uvp_interface_t *) pifc);\r
318         }\r
319         else\r
320         {\r
321                 status = IB_UNSUPPORTED;\r
322         }\r
323 \r
324         return status;\r
325 }\r