[MLX4] added support to new device. [mlnx: 4473]
[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         HCA(MELLANOX, 0x6764),  /* MT26468 "Hermon" B0 Ethernet PCIe gen2*/\r
59 \r
60         HCA(MELLANOX, 0x0191),  /* MT25408 "Hermon" livefish mode */ \r
61 };\r
62 \r
63 \r
64 struct ibv_context * mlx4_alloc_context()\r
65 {\r
66         struct mlx4_context *context;\r
67         \r
68         /* allocate context */\r
69         context = cl_zalloc(sizeof *context);\r
70         if (!context)\r
71                 goto end;\r
72 \r
73         context->qp_table_mutex = CreateMutex(NULL, FALSE, NULL);\r
74         if (!context->qp_table_mutex)\r
75                 goto err_qp_mutex;\r
76 \r
77 #ifdef XRC_SUPPORT\r
78         context->xrc_srq_table_mutex = CreateMutex(NULL, FALSE, NULL);\r
79         if (!context->xrc_srq_table_mutex)\r
80                 goto err_xrc_mutex;\r
81 #endif  \r
82 \r
83         context->db_list_mutex = CreateMutex(NULL, FALSE, NULL);\r
84         if (!context->db_list_mutex)\r
85                 goto err_db_mutex;\r
86 \r
87         if (cl_spinlock_init(&context->uar_lock))\r
88                 goto err_uar_spinlock;\r
89 \r
90         if (cl_spinlock_init(&context->bf_lock))\r
91                 goto err_bf_spinlock;\r
92 \r
93         return &context->ibv_ctx;\r
94 \r
95 err_bf_spinlock:\r
96         cl_spinlock_destroy(&context->uar_lock);\r
97 err_uar_spinlock:\r
98         CloseHandle(context->db_list_mutex);\r
99 err_db_mutex:\r
100 #ifdef XRC_SUPPORT\r
101         CloseHandle(context->xrc_srq_table_mutex);\r
102 err_xrc_mutex:\r
103 #endif  \r
104         CloseHandle(context->qp_table_mutex);\r
105 err_qp_mutex:\r
106         cl_free(context);\r
107 end:\r
108         return NULL;\r
109         \r
110 }\r
111 \r
112 struct ibv_context * mlx4_fill_context(struct ibv_context *ctx, struct ibv_get_context_resp *p_resp)\r
113 {\r
114         struct mlx4_context *context = to_mctx(ctx);\r
115         SYSTEM_INFO sys_info;\r
116         int i;\r
117 \r
118         /* check device type */\r
119         for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i) \r
120                 if (p_resp->vend_id == hca_table[i].vendor &&\r
121                         p_resp->dev_id == hca_table[i].device) \r
122                         goto found;\r
123         goto err_dev_type;\r
124 \r
125 found:\r
126         context->num_qps                        = p_resp->qp_tab_size;\r
127         context->qp_table_shift = ffsl(context->num_qps) - 1 - MLX4_QP_TABLE_BITS;\r
128         context->qp_table_mask  = (1 << context->qp_table_shift) - 1;\r
129 \r
130         for (i = 0; i < MLX4_QP_TABLE_SIZE; ++i)\r
131                 context->qp_table[i].refcnt = 0;\r
132 \r
133 #ifdef XRC_SUPPORT\r
134         context->num_xrc_srqs   = p_resp->qp_tab_size;\r
135         context->xrc_srq_table_shift = ffsl(context->num_xrc_srqs) - 1\r
136                                        - MLX4_XRC_SRQ_TABLE_BITS;\r
137         context->xrc_srq_table_mask = (1 << context->xrc_srq_table_shift) - 1;\r
138 \r
139         for (i = 0; i < MLX4_XRC_SRQ_TABLE_SIZE; ++i)\r
140                 context->xrc_srq_table[i].refcnt = 0;\r
141 #endif\r
142 \r
143         for (i = 0; i < MLX4_NUM_DB_TYPE; ++i)\r
144                 context->db_list[i] = NULL;\r
145 \r
146         context->uar                    = (uint8_t *)(uintptr_t)p_resp->uar_addr;\r
147         context->bf_page                = (uint8_t *)(uintptr_t)p_resp->bf_page;\r
148         context->bf_buf_size    = p_resp->bf_buf_size;\r
149         context->bf_offset      = p_resp->bf_offset;\r
150 \r
151         context->max_qp_wr      = p_resp->max_qp_wr;\r
152         context->max_sge                = p_resp->max_sge;\r
153         context->max_cqe                = p_resp->max_cqe;\r
154 \r
155         GetSystemInfo(&sys_info);\r
156         context->ibv_ctx.page_size = sys_info.dwPageSize;\r
157 \r
158         return &context->ibv_ctx;\r
159 \r
160 err_dev_type:\r
161         mlx4_free_context(&context->ibv_ctx);\r
162         return NULL;\r
163 }\r
164 \r
165 void mlx4_free_context(struct ibv_context *ctx)\r
166 {\r
167         struct mlx4_context *context = to_mctx(ctx);\r
168 \r
169         cl_spinlock_destroy(&context->bf_lock);\r
170         cl_spinlock_destroy(&context->uar_lock);\r
171         CloseHandle(context->db_list_mutex);\r
172 #ifdef XRC_SUPPORT\r
173         CloseHandle(context->xrc_srq_table_mutex);\r
174 #endif\r
175         CloseHandle(context->qp_table_mutex);\r
176         cl_free(context);\r
177 }\r
178 \r
179 static void __get_uvp_interface(uvp_interface_t *p_uvp)\r
180 {\r
181         p_uvp->pre_open_ca              = mlx4_pre_open_ca;\r
182         p_uvp->post_open_ca             = mlx4_post_open_ca;\r
183         p_uvp->pre_query_ca             = NULL;\r
184         p_uvp->post_query_ca    = NULL;\r
185         p_uvp->pre_modify_ca    = NULL;\r
186         p_uvp->post_modify_ca   = NULL;\r
187         p_uvp->pre_close_ca             = NULL;\r
188         p_uvp->post_close_ca    = mlx4_post_close_ca;\r
189 \r
190 \r
191         /*\r
192          * Protection Domain\r
193          */\r
194         p_uvp->pre_allocate_pd          = mlx4_pre_alloc_pd;\r
195         p_uvp->post_allocate_pd         = mlx4_post_alloc_pd;\r
196         p_uvp->pre_deallocate_pd        = NULL;\r
197         p_uvp->post_deallocate_pd       = mlx4_post_free_pd;\r
198 \r
199 \r
200         /*\r
201          * SRQ Management Verbs\r
202          */\r
203         p_uvp->pre_create_srq   = mlx4_pre_create_srq;\r
204         p_uvp->post_create_srq  = mlx4_post_create_srq;\r
205         p_uvp->pre_query_srq    = NULL;\r
206         p_uvp->post_query_srq   = NULL;\r
207         p_uvp->pre_modify_srq   = NULL;\r
208         p_uvp->post_modify_srq  = NULL;\r
209         p_uvp->pre_destroy_srq  = NULL;\r
210         p_uvp->post_destroy_srq = mlx4_post_destroy_srq;\r
211 \r
212         p_uvp->pre_create_qp    = mlx4_pre_create_qp;\r
213         p_uvp->wv_pre_create_qp = mlx4_wv_pre_create_qp;\r
214         p_uvp->post_create_qp   = mlx4_post_create_qp;\r
215         p_uvp->pre_modify_qp    = mlx4_pre_modify_qp;\r
216         p_uvp->post_modify_qp   = mlx4_post_modify_qp;\r
217         p_uvp->pre_query_qp             = NULL;\r
218         p_uvp->post_query_qp    = mlx4_post_query_qp;\r
219         p_uvp->pre_destroy_qp   = mlx4_pre_destroy_qp;\r
220         p_uvp->post_destroy_qp  = mlx4_post_destroy_qp;\r
221         p_uvp->nd_modify_qp             = mlx4_nd_modify_qp;\r
222         p_uvp->nd_get_qp_state  = mlx4_nd_get_qp_state;\r
223 \r
224 \r
225         /*\r
226          * Completion Queue Management Verbs\r
227          */\r
228         p_uvp->pre_create_cq    = mlx4_pre_create_cq;\r
229         p_uvp->post_create_cq   = mlx4_post_create_cq;\r
230         p_uvp->pre_query_cq             = mlx4_pre_query_cq;\r
231         p_uvp->post_query_cq    = NULL;\r
232         p_uvp->pre_resize_cq    = NULL;\r
233         p_uvp->post_resize_cq   = NULL;\r
234         p_uvp->pre_destroy_cq   = NULL;\r
235         p_uvp->post_destroy_cq  = mlx4_post_destroy_cq;\r
236 \r
237 \r
238         /*\r
239          * AV Management\r
240          */\r
241         p_uvp->pre_create_av    = mlx4_pre_create_ah;\r
242         p_uvp->post_create_av   = NULL;\r
243         p_uvp->pre_query_av             = mlx4_pre_query_ah;\r
244         p_uvp->post_query_av    = mlx4_post_query_ah;\r
245         p_uvp->pre_modify_av    = mlx4_pre_modify_ah;\r
246         p_uvp->post_modify_av   = NULL;\r
247         p_uvp->pre_destroy_av   = mlx4_pre_destroy_ah;\r
248         p_uvp->post_destroy_av  = NULL;\r
249 \r
250 \r
251         /*\r
252          * Memory Region / Window Management Verbs\r
253          */\r
254         p_uvp->pre_create_mw    = NULL;\r
255         p_uvp->post_create_mw   = NULL;\r
256         p_uvp->pre_query_mw     = NULL;\r
257         p_uvp->post_query_mw    = NULL;\r
258         p_uvp->pre_destroy_mw   = NULL;\r
259         p_uvp->post_destroy_mw  = NULL;\r
260 \r
261 \r
262         /*\r
263          * Multicast Support Verbs\r
264          */\r
265         p_uvp->pre_attach_mcast         = NULL;\r
266         p_uvp->post_attach_mcast        = NULL;\r
267         p_uvp->pre_detach_mcast         = NULL;\r
268         p_uvp->post_detach_mcast        = NULL;\r
269 \r
270 \r
271         /*\r
272          * OS bypass (send, receive, poll/notify cq)\r
273          */\r
274         p_uvp->post_send                = mlx4_post_send;\r
275         p_uvp->post_recv                = mlx4_post_recv;\r
276         p_uvp->post_srq_recv    = mlx4_post_srq_recv;\r
277         p_uvp->poll_cq                  = mlx4_poll_cq_list;\r
278         p_uvp->poll_cq_array    = mlx4_poll_cq_array;\r
279         p_uvp->rearm_cq                 = mlx4_arm_cq;\r
280         p_uvp->rearm_n_cq               = NULL;\r
281         p_uvp->peek_cq                  = NULL;\r
282         p_uvp->bind_mw                  = NULL;\r
283 }\r
284 \r
285 /* TODO: define and expose XRC through new interface GUID */\r
286 #ifdef XRC_SUPPORT\r
287 static void __get_xrc_interface(uvp_xrc_interface_t *p_xrc)\r
288 {\r
289         /*\r
290          * XRC Management Verbs\r
291          */\r
292         p_uvp->pre_create_xrc_srq               = mlx4_pre_create_xrc_srq;\r
293         p_uvp->post_create_xrc_srq              = mlx4_post_create_xrc_srq;\r
294         p_uvp->pre_open_xrc_domain              = mlx4_pre_open_xrc_domain;\r
295         p_uvp->post_open_xrc_domain             = mlx4_post_open_xrc_domain;\r
296         p_uvp->pre_close_xrc_domain             = NULL;\r
297         p_uvp->post_close_xrc_domain    = mlx4_post_close_xrc_domain;\r
298         p_uvp->pre_create_xrc_rcv_qp    = NULL;\r
299         p_uvp->post_create_xrc_rcv_qp   = NULL;\r
300         p_uvp->pre_modify_xrc_rcv_qp    = NULL;\r
301         p_uvp->post_modify_xrc_rcv_qp   = NULL;\r
302         p_uvp->pre_query_xrc_rcv_qp             = NULL;\r
303         p_uvp->post_query_xrc_rcv_qp    = NULL;\r
304         p_uvp->pre_reg_xrc_rcv_qp               = NULL;\r
305         p_uvp->post_reg_xrc_rcv_qp              = NULL;\r
306         p_uvp->pre_unreg_xrc_rcv_qp             = NULL;\r
307         p_uvp->post_unreg_xrc_rcv_qp    = NULL;\r
308 }\r
309 #endif\r
310 \r
311 __declspec(dllexport) ib_api_status_t\r
312 uvp_get_interface (GUID iid, void* pifc)\r
313 {\r
314         ib_api_status_t status = IB_SUCCESS;\r
315 \r
316         if (IsEqualGUID(&iid, &IID_UVP))\r
317         {\r
318                 __get_uvp_interface((uvp_interface_t *) pifc);\r
319         }\r
320         else\r
321         {\r
322                 status = IB_UNSUPPORTED;\r
323         }\r
324 \r
325         return status;\r
326 }\r