[MTHCA]bug fixes:
[mirror/winof/.git] / hw / mthca / user / mlnx_uvp.c
1 /*
2  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  *
32  * $Id$
33  */
34
35 #include "mt_l2w.h"
36 #include "mlnx_uvp.h"
37
38 #if defined(EVENT_TRACING)
39 #include "mlnx_uvp.tmh"
40 #endif
41
42 #include "mx_abi.h"
43
44 size_t g_page_size = 0;
45
46 #ifndef PCI_VENDOR_ID_MELLANOX
47 #define PCI_VENDOR_ID_MELLANOX                  0x15b3
48 #endif
49
50 #ifndef PCI_DEVICE_ID_MELLANOX_TAVOR
51 #define PCI_DEVICE_ID_MELLANOX_TAVOR            0x5a44
52 #endif
53
54 #ifndef PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT
55 #define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT     0x6278
56 #endif
57
58 #ifndef PCI_DEVICE_ID_MELLANOX_ARBEL
59 #define PCI_DEVICE_ID_MELLANOX_ARBEL            0x6282
60 #endif
61
62 #ifndef PCI_DEVICE_ID_MELLANOX_SINAI_OLD
63 #define PCI_DEVICE_ID_MELLANOX_SINAI_OLD        0x5e8c
64 #endif
65
66 #ifndef PCI_DEVICE_ID_MELLANOX_SINAI
67 #define PCI_DEVICE_ID_MELLANOX_SINAI            0x6274
68 #endif
69
70 #ifndef PCI_VENDOR_ID_TOPSPIN
71 #define PCI_VENDOR_ID_TOPSPIN                   0x1867
72 #endif
73
74 /* live fishes */
75 #ifndef PCI_DEVICE_ID_MELLANOX_TAVOR_BD
76 #define PCI_DEVICE_ID_MELLANOX_TAVOR_BD         0x5a45
77 #endif
78
79 #ifndef PCI_DEVICE_ID_MELLANOX_ARBEL_BD
80 #define PCI_DEVICE_ID_MELLANOX_ARBEL_BD         0x6279
81 #endif
82
83 #ifndef PCI_DEVICE_ID_MELLANOX_SINAI_OLD_BD
84 #define PCI_DEVICE_ID_MELLANOX_SINAI_OLD_BD     0x5e8d
85 #endif
86
87 #ifndef PCI_DEVICE_ID_MELLANOX_SINAI_BD
88 #define PCI_DEVICE_ID_MELLANOX_SINAI_BD         0x6275
89 #endif
90
91
92 #define HCA(v, d, t) \
93         { PCI_VENDOR_ID_##v,    PCI_DEVICE_ID_MELLANOX_##d, MTHCA_##t }
94
95 static struct pci_device_id {
96         unsigned                vendor;
97         unsigned                device;
98         enum mthca_hca_type     type;
99 } mthca_pci_table[] = {
100         HCA( MELLANOX,  TAVOR,                          TAVOR),
101         HCA( MELLANOX,  ARBEL_COMPAT,   TAVOR),
102         HCA( MELLANOX,  ARBEL,                                  ARBEL),
103         HCA( MELLANOX,  SINAI_OLD,              ARBEL),
104         HCA( MELLANOX,  SINAI,                                  ARBEL),
105         HCA( TOPSPIN,           TAVOR,                          TAVOR),
106         HCA( TOPSPIN,           ARBEL_COMPAT,   TAVOR),
107         HCA( TOPSPIN,           ARBEL,                                  ARBEL),
108         HCA( TOPSPIN,           SINAI_OLD,                      ARBEL),
109         HCA( TOPSPIN,           SINAI,                                  ARBEL),
110         // live fishes
111         HCA(MELLANOX, TAVOR_BD, LIVEFISH),
112         HCA(MELLANOX, ARBEL_BD,         LIVEFISH),
113         HCA(MELLANOX, SINAI_OLD_BD, LIVEFISH),
114         HCA(MELLANOX, SINAI_BD,         LIVEFISH),
115         HCA(TOPSPIN, TAVOR_BD,          LIVEFISH),
116         HCA(TOPSPIN, ARBEL_BD,          LIVEFISH),
117         HCA(TOPSPIN, SINAI_OLD_BD,      LIVEFISH),
118         HCA(TOPSPIN, SINAI_BD,          LIVEFISH),
119 };
120
121 static struct ibv_context_ops mthca_ctx_ops = {
122         NULL,   // mthca_query_device,
123         NULL,   // mthca_query_port,
124         mthca_alloc_pd,
125         mthca_free_pd,
126         NULL,   // mthca_reg_mr,
127         NULL,   // mthca_dereg_mr,
128         mthca_create_cq_pre,
129         mthca_create_cq_post,
130         mthca_poll_cq,
131         mthca_poll_cq_list,
132         NULL,   /* req_notify_cq */
133         mthca_destroy_cq,
134         NULL,   // mthca_create_srq,
135         NULL,   // mthca_modify_srq,
136         NULL,   // mthca_destroy_srq,
137         NULL,   /* post_srq_recv */
138         mthca_create_qp_pre,
139         mthca_create_qp_post,
140         mthca_modify_qp,
141         NULL,
142         NULL,   /* post_send */
143         NULL,   /* post_recv */
144         mthca_attach_mcast,
145         mthca_detach_mcast
146 };
147
148 struct ibv_context *mthca_alloc_context(struct ibv_get_context_resp *resp_p)
149 {
150         struct mthca_context    *       context;
151         struct ibv_alloc_pd_resp        pd_resp;
152         int                                             i;
153
154         /* allocate context */
155         context = cl_zalloc(sizeof *context);
156         if (!context)
157                 return NULL;
158
159         /* find page size  */
160         if (!g_page_size) {
161                 SYSTEM_INFO sys_info;
162                 GetSystemInfo(&sys_info);
163                 g_page_size     = sys_info.dwPageSize;
164         }
165
166         /* calculate device type */
167         for (i = 0; i < sizeof mthca_pci_table / sizeof mthca_pci_table[0]; ++i) 
168                 if (resp_p->vend_id == mthca_pci_table[i].vendor &&
169                         resp_p->dev_id == mthca_pci_table[i].device) 
170                         goto found;
171         goto err_dev_type;
172
173 found:
174         context->hca_type = mthca_pci_table[i].type;
175         context->uar = (void*)(UINT_PTR)resp_p->uar_addr;
176         context->num_qps        = resp_p->qp_tab_size;
177         context->qp_table_shift = ffs(context->num_qps) - 1 - MTHCA_QP_TABLE_BITS;
178         context->qp_table_mask  = (1 << context->qp_table_shift) - 1;
179
180         if (mthca_is_memfree(&context->ibv_ctx)) {
181                 context->db_tab = mthca_alloc_db_tab(resp_p->uarc_size);
182                 if (!context->db_tab)
183                         goto err_alloc_db_tab;
184         } else
185                 context->db_tab = NULL;
186
187         context->qp_table_mutex = CreateMutex( NULL, FALSE, NULL );
188         if (!context->qp_table_mutex)
189                 goto err_mutex;
190         for (i = 0; i < MTHCA_QP_TABLE_SIZE; ++i)
191                 context->qp_table[i].refcnt = 0;
192
193         cl_spinlock_construct(&context->uar_lock);
194         if (cl_spinlock_init(&context->uar_lock))
195                 goto err_spinlock;
196
197         pd_resp.pd_handle = resp_p->pd_handle;
198         pd_resp.pdn = resp_p->pdn;
199         context->pd = mthca_alloc_pd(&context->ibv_ctx, &pd_resp);
200         if (!context->pd)
201                 goto err_unmap;
202
203         context->ibv_ctx.ops = mthca_ctx_ops;
204
205         if (mthca_is_memfree(&context->ibv_ctx)) {
206                 context->ibv_ctx.ops.req_notify_cq = mthca_arbel_arm_cq;
207                 context->ibv_ctx.ops.post_send     = mthca_arbel_post_send;
208                 context->ibv_ctx.ops.post_recv     = mthca_arbel_post_recv;
209                 context->ibv_ctx.ops.post_srq_recv = mthca_arbel_post_srq_recv;
210         } else {
211                 context->ibv_ctx.ops.req_notify_cq = mthca_tavor_arm_cq;
212                 context->ibv_ctx.ops.post_send     = mthca_tavor_post_send;
213                 context->ibv_ctx.ops.post_recv     = mthca_tavor_post_recv;
214                 context->ibv_ctx.ops.post_srq_recv = mthca_tavor_post_srq_recv;
215         }
216
217         return &context->ibv_ctx;
218
219 err_unmap:
220 err_spinlock:
221 err_mutex:
222         mthca_free_db_tab(context->db_tab);
223
224 err_alloc_db_tab:
225 err_dev_type:
226         cl_free(context);
227         return NULL;
228 }
229
230 void mthca_free_context(struct ibv_context *ibctx)
231 {
232         struct mthca_context *context = to_mctx(ibctx);
233
234         cl_spinlock_destroy(&context->uar_lock);
235         mthca_free_pd(context->pd);
236         mthca_free_db_tab(context->db_tab);
237         cl_free(context);
238 }