]> err.no Git - linux-2.6/blob - drivers/infiniband/hw/mthca/mthca_provider.c
[IB] mthca: Fill in more fields in query_port method
[linux-2.6] / drivers / infiniband / hw / mthca / mthca_provider.c
1 /*
2  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
3  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4  * Copyright (c) 2005 Cisco Systems. All rights reserved.
5  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
6  * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
7  *
8  * This software is available to you under a choice of one of two
9  * licenses.  You may choose to be licensed under the terms of the GNU
10  * General Public License (GPL) Version 2, available from the file
11  * COPYING in the main directory of this source tree, or the
12  * OpenIB.org BSD license below:
13  *
14  *     Redistribution and use in source and binary forms, with or
15  *     without modification, are permitted provided that the following
16  *     conditions are met:
17  *
18  *      - Redistributions of source code must retain the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer.
21  *
22  *      - Redistributions in binary form must reproduce the above
23  *        copyright notice, this list of conditions and the following
24  *        disclaimer in the documentation and/or other materials
25  *        provided with the distribution.
26  *
27  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34  * SOFTWARE.
35  *
36  * $Id: mthca_provider.c 1397 2004-12-28 05:09:00Z roland $
37  */
38
39 #include <rdma/ib_smi.h>
40 #include <linux/mm.h>
41
42 #include "mthca_dev.h"
43 #include "mthca_cmd.h"
44 #include "mthca_user.h"
45 #include "mthca_memfree.h"
46
47 static int mthca_query_device(struct ib_device *ibdev,
48                               struct ib_device_attr *props)
49 {
50         struct ib_smp *in_mad  = NULL;
51         struct ib_smp *out_mad = NULL;
52         int err = -ENOMEM;
53         struct mthca_dev* mdev = to_mdev(ibdev);
54
55         u8 status;
56
57         in_mad  = kmalloc(sizeof *in_mad, GFP_KERNEL);
58         out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
59         if (!in_mad || !out_mad)
60                 goto out;
61
62         memset(props, 0, sizeof *props);
63
64         props->fw_ver              = mdev->fw_ver;
65
66         memset(in_mad, 0, sizeof *in_mad);
67         in_mad->base_version       = 1;
68         in_mad->mgmt_class         = IB_MGMT_CLASS_SUBN_LID_ROUTED;
69         in_mad->class_version      = 1;
70         in_mad->method             = IB_MGMT_METHOD_GET;
71         in_mad->attr_id            = IB_SMP_ATTR_NODE_INFO;
72
73         err = mthca_MAD_IFC(mdev, 1, 1,
74                             1, NULL, NULL, in_mad, out_mad,
75                             &status);
76         if (err)
77                 goto out;
78         if (status) {
79                 err = -EINVAL;
80                 goto out;
81         }
82
83         props->device_cap_flags    = mdev->device_cap_flags;
84         props->vendor_id           = be32_to_cpup((__be32 *) (out_mad->data + 36)) &
85                 0xffffff;
86         props->vendor_part_id      = be16_to_cpup((__be16 *) (out_mad->data + 30));
87         props->hw_ver              = be32_to_cpup((__be32 *) (out_mad->data + 32));
88         memcpy(&props->sys_image_guid, out_mad->data +  4, 8);
89         memcpy(&props->node_guid,      out_mad->data + 12, 8);
90
91         props->max_mr_size         = ~0ull;
92         props->max_qp              = mdev->limits.num_qps - mdev->limits.reserved_qps;
93         props->max_qp_wr           = 0xffff;
94         props->max_sge             = mdev->limits.max_sg;
95         props->max_cq              = mdev->limits.num_cqs - mdev->limits.reserved_cqs;
96         props->max_cqe             = 0xffff;
97         props->max_mr              = mdev->limits.num_mpts - mdev->limits.reserved_mrws;
98         props->max_pd              = mdev->limits.num_pds - mdev->limits.reserved_pds;
99         props->max_qp_rd_atom      = 1 << mdev->qp_table.rdb_shift;
100         props->max_qp_init_rd_atom = 1 << mdev->qp_table.rdb_shift;
101         props->local_ca_ack_delay  = mdev->limits.local_ca_ack_delay;
102         props->atomic_cap          = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ? 
103                                         IB_ATOMIC_HCA : IB_ATOMIC_NONE;
104
105         err = 0;
106  out:
107         kfree(in_mad);
108         kfree(out_mad);
109         return err;
110 }
111
112 static int mthca_query_port(struct ib_device *ibdev,
113                             u8 port, struct ib_port_attr *props)
114 {
115         struct ib_smp *in_mad  = NULL;
116         struct ib_smp *out_mad = NULL;
117         int err = -ENOMEM;
118         u8 status;
119
120         in_mad  = kmalloc(sizeof *in_mad, GFP_KERNEL);
121         out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
122         if (!in_mad || !out_mad)
123                 goto out;
124
125         memset(props, 0, sizeof *props);
126
127         memset(in_mad, 0, sizeof *in_mad);
128         in_mad->base_version       = 1;
129         in_mad->mgmt_class         = IB_MGMT_CLASS_SUBN_LID_ROUTED;
130         in_mad->class_version      = 1;
131         in_mad->method             = IB_MGMT_METHOD_GET;
132         in_mad->attr_id            = IB_SMP_ATTR_PORT_INFO;
133         in_mad->attr_mod           = cpu_to_be32(port);
134
135         err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
136                             port, NULL, NULL, in_mad, out_mad,
137                             &status);
138         if (err)
139                 goto out;
140         if (status) {
141                 err = -EINVAL;
142                 goto out;
143         }
144
145         props->lid               = be16_to_cpup((__be16 *) (out_mad->data + 16));
146         props->lmc               = out_mad->data[34] & 0x7;
147         props->sm_lid            = be16_to_cpup((__be16 *) (out_mad->data + 18));
148         props->sm_sl             = out_mad->data[36] & 0xf;
149         props->state             = out_mad->data[32] & 0xf;
150         props->phys_state        = out_mad->data[33] >> 4;
151         props->port_cap_flags    = be32_to_cpup((__be32 *) (out_mad->data + 20));
152         props->gid_tbl_len       = to_mdev(ibdev)->limits.gid_table_len;
153         props->max_msg_sz        = 0x80000000;
154         props->pkey_tbl_len      = to_mdev(ibdev)->limits.pkey_table_len;
155         props->bad_pkey_cntr     = be16_to_cpup((__be16 *) (out_mad->data + 46));
156         props->qkey_viol_cntr    = be16_to_cpup((__be16 *) (out_mad->data + 48));
157         props->active_width      = out_mad->data[31] & 0xf;
158         props->active_speed      = out_mad->data[35] >> 4;
159         props->max_mtu           = out_mad->data[41] & 0xf;
160         props->active_mtu        = out_mad->data[36] >> 4;
161         props->subnet_timeout    = out_mad->data[51] & 0x1f;
162
163  out:
164         kfree(in_mad);
165         kfree(out_mad);
166         return err;
167 }
168
169 static int mthca_modify_port(struct ib_device *ibdev,
170                              u8 port, int port_modify_mask,
171                              struct ib_port_modify *props)
172 {
173         struct mthca_set_ib_param set_ib;
174         struct ib_port_attr attr;
175         int err;
176         u8 status;
177
178         if (down_interruptible(&to_mdev(ibdev)->cap_mask_mutex))
179                 return -ERESTARTSYS;
180
181         err = mthca_query_port(ibdev, port, &attr);
182         if (err)
183                 goto out;
184
185         set_ib.set_si_guid     = 0;
186         set_ib.reset_qkey_viol = !!(port_modify_mask & IB_PORT_RESET_QKEY_CNTR);
187
188         set_ib.cap_mask = (attr.port_cap_flags | props->set_port_cap_mask) &
189                 ~props->clr_port_cap_mask;
190
191         err = mthca_SET_IB(to_mdev(ibdev), &set_ib, port, &status);
192         if (err)
193                 goto out;
194         if (status) {
195                 err = -EINVAL;
196                 goto out;
197         }
198
199 out:
200         up(&to_mdev(ibdev)->cap_mask_mutex);
201         return err;
202 }
203
204 static int mthca_query_pkey(struct ib_device *ibdev,
205                             u8 port, u16 index, u16 *pkey)
206 {
207         struct ib_smp *in_mad  = NULL;
208         struct ib_smp *out_mad = NULL;
209         int err = -ENOMEM;
210         u8 status;
211
212         in_mad  = kmalloc(sizeof *in_mad, GFP_KERNEL);
213         out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
214         if (!in_mad || !out_mad)
215                 goto out;
216
217         memset(in_mad, 0, sizeof *in_mad);
218         in_mad->base_version       = 1;
219         in_mad->mgmt_class         = IB_MGMT_CLASS_SUBN_LID_ROUTED;
220         in_mad->class_version      = 1;
221         in_mad->method             = IB_MGMT_METHOD_GET;
222         in_mad->attr_id            = IB_SMP_ATTR_PKEY_TABLE;
223         in_mad->attr_mod           = cpu_to_be32(index / 32);
224
225         err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
226                             port, NULL, NULL, in_mad, out_mad,
227                             &status);
228         if (err)
229                 goto out;
230         if (status) {
231                 err = -EINVAL;
232                 goto out;
233         }
234
235         *pkey = be16_to_cpu(((__be16 *) out_mad->data)[index % 32]);
236
237  out:
238         kfree(in_mad);
239         kfree(out_mad);
240         return err;
241 }
242
243 static int mthca_query_gid(struct ib_device *ibdev, u8 port,
244                            int index, union ib_gid *gid)
245 {
246         struct ib_smp *in_mad  = NULL;
247         struct ib_smp *out_mad = NULL;
248         int err = -ENOMEM;
249         u8 status;
250
251         in_mad  = kmalloc(sizeof *in_mad, GFP_KERNEL);
252         out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
253         if (!in_mad || !out_mad)
254                 goto out;
255
256         memset(in_mad, 0, sizeof *in_mad);
257         in_mad->base_version       = 1;
258         in_mad->mgmt_class         = IB_MGMT_CLASS_SUBN_LID_ROUTED;
259         in_mad->class_version      = 1;
260         in_mad->method             = IB_MGMT_METHOD_GET;
261         in_mad->attr_id            = IB_SMP_ATTR_PORT_INFO;
262         in_mad->attr_mod           = cpu_to_be32(port);
263
264         err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
265                             port, NULL, NULL, in_mad, out_mad,
266                             &status);
267         if (err)
268                 goto out;
269         if (status) {
270                 err = -EINVAL;
271                 goto out;
272         }
273
274         memcpy(gid->raw, out_mad->data + 8, 8);
275
276         memset(in_mad, 0, sizeof *in_mad);
277         in_mad->base_version       = 1;
278         in_mad->mgmt_class         = IB_MGMT_CLASS_SUBN_LID_ROUTED;
279         in_mad->class_version      = 1;
280         in_mad->method             = IB_MGMT_METHOD_GET;
281         in_mad->attr_id            = IB_SMP_ATTR_GUID_INFO;
282         in_mad->attr_mod           = cpu_to_be32(index / 8);
283
284         err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
285                             port, NULL, NULL, in_mad, out_mad,
286                             &status);
287         if (err)
288                 goto out;
289         if (status) {
290                 err = -EINVAL;
291                 goto out;
292         }
293
294         memcpy(gid->raw + 8, out_mad->data + (index % 8) * 16, 8);
295
296  out:
297         kfree(in_mad);
298         kfree(out_mad);
299         return err;
300 }
301
302 static struct ib_ucontext *mthca_alloc_ucontext(struct ib_device *ibdev,
303                                                 struct ib_udata *udata)
304 {
305         struct mthca_alloc_ucontext_resp uresp;
306         struct mthca_ucontext           *context;
307         int                              err;
308
309         memset(&uresp, 0, sizeof uresp);
310
311         uresp.qp_tab_size = to_mdev(ibdev)->limits.num_qps;
312         if (mthca_is_memfree(to_mdev(ibdev)))
313                 uresp.uarc_size = to_mdev(ibdev)->uar_table.uarc_size;
314         else
315                 uresp.uarc_size = 0;
316
317         context = kmalloc(sizeof *context, GFP_KERNEL);
318         if (!context)
319                 return ERR_PTR(-ENOMEM);
320
321         err = mthca_uar_alloc(to_mdev(ibdev), &context->uar);
322         if (err) {
323                 kfree(context);
324                 return ERR_PTR(err);
325         }
326
327         context->db_tab = mthca_init_user_db_tab(to_mdev(ibdev));
328         if (IS_ERR(context->db_tab)) {
329                 err = PTR_ERR(context->db_tab);
330                 mthca_uar_free(to_mdev(ibdev), &context->uar);
331                 kfree(context);
332                 return ERR_PTR(err);
333         }
334
335         if (ib_copy_to_udata(udata, &uresp, sizeof uresp)) {
336                 mthca_cleanup_user_db_tab(to_mdev(ibdev), &context->uar, context->db_tab);
337                 mthca_uar_free(to_mdev(ibdev), &context->uar);
338                 kfree(context);
339                 return ERR_PTR(-EFAULT);
340         }
341
342         return &context->ibucontext;
343 }
344
345 static int mthca_dealloc_ucontext(struct ib_ucontext *context)
346 {
347         mthca_cleanup_user_db_tab(to_mdev(context->device), &to_mucontext(context)->uar,
348                                   to_mucontext(context)->db_tab);
349         mthca_uar_free(to_mdev(context->device), &to_mucontext(context)->uar);
350         kfree(to_mucontext(context));
351
352         return 0;
353 }
354
355 static int mthca_mmap_uar(struct ib_ucontext *context,
356                           struct vm_area_struct *vma)
357 {
358         if (vma->vm_end - vma->vm_start != PAGE_SIZE)
359                 return -EINVAL;
360
361         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
362
363         if (io_remap_pfn_range(vma, vma->vm_start,
364                                to_mucontext(context)->uar.pfn,
365                                PAGE_SIZE, vma->vm_page_prot))
366                 return -EAGAIN;
367
368         return 0;
369 }
370
371 static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev,
372                                     struct ib_ucontext *context,
373                                     struct ib_udata *udata)
374 {
375         struct mthca_pd *pd;
376         int err;
377
378         pd = kmalloc(sizeof *pd, GFP_KERNEL);
379         if (!pd)
380                 return ERR_PTR(-ENOMEM);
381
382         err = mthca_pd_alloc(to_mdev(ibdev), !context, pd);
383         if (err) {
384                 kfree(pd);
385                 return ERR_PTR(err);
386         }
387
388         if (context) {
389                 if (ib_copy_to_udata(udata, &pd->pd_num, sizeof (__u32))) {
390                         mthca_pd_free(to_mdev(ibdev), pd);
391                         kfree(pd);
392                         return ERR_PTR(-EFAULT);
393                 }
394         }
395
396         return &pd->ibpd;
397 }
398
399 static int mthca_dealloc_pd(struct ib_pd *pd)
400 {
401         mthca_pd_free(to_mdev(pd->device), to_mpd(pd));
402         kfree(pd);
403
404         return 0;
405 }
406
407 static struct ib_ah *mthca_ah_create(struct ib_pd *pd,
408                                      struct ib_ah_attr *ah_attr)
409 {
410         int err;
411         struct mthca_ah *ah;
412
413         ah = kmalloc(sizeof *ah, GFP_ATOMIC);
414         if (!ah)
415                 return ERR_PTR(-ENOMEM);
416
417         err = mthca_create_ah(to_mdev(pd->device), to_mpd(pd), ah_attr, ah);
418         if (err) {
419                 kfree(ah);
420                 return ERR_PTR(err);
421         }
422
423         return &ah->ibah;
424 }
425
426 static int mthca_ah_destroy(struct ib_ah *ah)
427 {
428         mthca_destroy_ah(to_mdev(ah->device), to_mah(ah));
429         kfree(ah);
430
431         return 0;
432 }
433
434 static struct ib_srq *mthca_create_srq(struct ib_pd *pd,
435                                        struct ib_srq_init_attr *init_attr,
436                                        struct ib_udata *udata)
437 {
438         struct mthca_create_srq ucmd;
439         struct mthca_ucontext *context = NULL;
440         struct mthca_srq *srq;
441         int err;
442
443         srq = kmalloc(sizeof *srq, GFP_KERNEL);
444         if (!srq)
445                 return ERR_PTR(-ENOMEM);
446
447         if (pd->uobject) {
448                 context = to_mucontext(pd->uobject->context);
449
450                 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
451                         return ERR_PTR(-EFAULT);
452
453                 err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
454                                         context->db_tab, ucmd.db_index,
455                                         ucmd.db_page);
456
457                 if (err)
458                         goto err_free;
459
460                 srq->mr.ibmr.lkey = ucmd.lkey;
461                 srq->db_index     = ucmd.db_index;
462         }
463
464         err = mthca_alloc_srq(to_mdev(pd->device), to_mpd(pd),
465                               &init_attr->attr, srq);
466
467         if (err && pd->uobject)
468                 mthca_unmap_user_db(to_mdev(pd->device), &context->uar,
469                                     context->db_tab, ucmd.db_index);
470
471         if (err)
472                 goto err_free;
473
474         if (context && ib_copy_to_udata(udata, &srq->srqn, sizeof (__u32))) {
475                 mthca_free_srq(to_mdev(pd->device), srq);
476                 err = -EFAULT;
477                 goto err_free;
478         }
479
480         return &srq->ibsrq;
481
482 err_free:
483         kfree(srq);
484
485         return ERR_PTR(err);
486 }
487
488 static int mthca_destroy_srq(struct ib_srq *srq)
489 {
490         struct mthca_ucontext *context;
491
492         if (srq->uobject) {
493                 context = to_mucontext(srq->uobject->context);
494
495                 mthca_unmap_user_db(to_mdev(srq->device), &context->uar,
496                                     context->db_tab, to_msrq(srq)->db_index);
497         }
498
499         mthca_free_srq(to_mdev(srq->device), to_msrq(srq));
500         kfree(srq);
501
502         return 0;
503 }
504
505 static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
506                                      struct ib_qp_init_attr *init_attr,
507                                      struct ib_udata *udata)
508 {
509         struct mthca_create_qp ucmd;
510         struct mthca_qp *qp;
511         int err;
512
513         switch (init_attr->qp_type) {
514         case IB_QPT_RC:
515         case IB_QPT_UC:
516         case IB_QPT_UD:
517         {
518                 struct mthca_ucontext *context;
519
520                 qp = kmalloc(sizeof *qp, GFP_KERNEL);
521                 if (!qp)
522                         return ERR_PTR(-ENOMEM);
523
524                 if (pd->uobject) {
525                         context = to_mucontext(pd->uobject->context);
526
527                         if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
528                                 return ERR_PTR(-EFAULT);
529
530                         err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
531                                                 context->db_tab,
532                                                 ucmd.sq_db_index, ucmd.sq_db_page);
533                         if (err) {
534                                 kfree(qp);
535                                 return ERR_PTR(err);
536                         }
537
538                         err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
539                                                 context->db_tab,
540                                                 ucmd.rq_db_index, ucmd.rq_db_page);
541                         if (err) {
542                                 mthca_unmap_user_db(to_mdev(pd->device),
543                                                     &context->uar,
544                                                     context->db_tab,
545                                                     ucmd.sq_db_index);
546                                 kfree(qp);
547                                 return ERR_PTR(err);
548                         }
549
550                         qp->mr.ibmr.lkey = ucmd.lkey;
551                         qp->sq.db_index  = ucmd.sq_db_index;
552                         qp->rq.db_index  = ucmd.rq_db_index;
553                 }
554
555                 err = mthca_alloc_qp(to_mdev(pd->device), to_mpd(pd),
556                                      to_mcq(init_attr->send_cq),
557                                      to_mcq(init_attr->recv_cq),
558                                      init_attr->qp_type, init_attr->sq_sig_type,
559                                      &init_attr->cap, qp);
560
561                 if (err && pd->uobject) {
562                         context = to_mucontext(pd->uobject->context);
563
564                         mthca_unmap_user_db(to_mdev(pd->device),
565                                             &context->uar,
566                                             context->db_tab,
567                                             ucmd.sq_db_index);
568                         mthca_unmap_user_db(to_mdev(pd->device),
569                                             &context->uar,
570                                             context->db_tab,
571                                             ucmd.rq_db_index);
572                 }
573
574                 qp->ibqp.qp_num = qp->qpn;
575                 break;
576         }
577         case IB_QPT_SMI:
578         case IB_QPT_GSI:
579         {
580                 /* Don't allow userspace to create special QPs */
581                 if (pd->uobject)
582                         return ERR_PTR(-EINVAL);
583
584                 qp = kmalloc(sizeof (struct mthca_sqp), GFP_KERNEL);
585                 if (!qp)
586                         return ERR_PTR(-ENOMEM);
587
588                 qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1;
589
590                 err = mthca_alloc_sqp(to_mdev(pd->device), to_mpd(pd),
591                                       to_mcq(init_attr->send_cq),
592                                       to_mcq(init_attr->recv_cq),
593                                       init_attr->sq_sig_type, &init_attr->cap,
594                                       qp->ibqp.qp_num, init_attr->port_num,
595                                       to_msqp(qp));
596                 break;
597         }
598         default:
599                 /* Don't support raw QPs */
600                 return ERR_PTR(-ENOSYS);
601         }
602
603         if (err) {
604                 kfree(qp);
605                 return ERR_PTR(err);
606         }
607
608         init_attr->cap.max_inline_data = 0;
609         init_attr->cap.max_send_wr     = qp->sq.max;
610         init_attr->cap.max_recv_wr     = qp->rq.max;
611         init_attr->cap.max_send_sge    = qp->sq.max_gs;
612         init_attr->cap.max_recv_sge    = qp->rq.max_gs;
613
614         return &qp->ibqp;
615 }
616
617 static int mthca_destroy_qp(struct ib_qp *qp)
618 {
619         if (qp->uobject) {
620                 mthca_unmap_user_db(to_mdev(qp->device),
621                                     &to_mucontext(qp->uobject->context)->uar,
622                                     to_mucontext(qp->uobject->context)->db_tab,
623                                     to_mqp(qp)->sq.db_index);
624                 mthca_unmap_user_db(to_mdev(qp->device),
625                                     &to_mucontext(qp->uobject->context)->uar,
626                                     to_mucontext(qp->uobject->context)->db_tab,
627                                     to_mqp(qp)->rq.db_index);
628         }
629         mthca_free_qp(to_mdev(qp->device), to_mqp(qp));
630         kfree(qp);
631         return 0;
632 }
633
634 static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
635                                      struct ib_ucontext *context,
636                                      struct ib_udata *udata)
637 {
638         struct mthca_create_cq ucmd;
639         struct mthca_cq *cq;
640         int nent;
641         int err;
642
643         if (context) {
644                 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
645                         return ERR_PTR(-EFAULT);
646
647                 err = mthca_map_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
648                                         to_mucontext(context)->db_tab,
649                                         ucmd.set_db_index, ucmd.set_db_page);
650                 if (err)
651                         return ERR_PTR(err);
652
653                 err = mthca_map_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
654                                         to_mucontext(context)->db_tab,
655                                         ucmd.arm_db_index, ucmd.arm_db_page);
656                 if (err)
657                         goto err_unmap_set;
658         }
659
660         cq = kmalloc(sizeof *cq, GFP_KERNEL);
661         if (!cq) {
662                 err = -ENOMEM;
663                 goto err_unmap_arm;
664         }
665
666         if (context) {
667                 cq->mr.ibmr.lkey    = ucmd.lkey;
668                 cq->set_ci_db_index = ucmd.set_db_index;
669                 cq->arm_db_index    = ucmd.arm_db_index;
670         }
671
672         for (nent = 1; nent <= entries; nent <<= 1)
673                 ; /* nothing */
674
675         err = mthca_init_cq(to_mdev(ibdev), nent,
676                             context ? to_mucontext(context) : NULL,
677                             context ? ucmd.pdn : to_mdev(ibdev)->driver_pd.pd_num,
678                             cq);
679         if (err)
680                 goto err_free;
681
682         if (context && ib_copy_to_udata(udata, &cq->cqn, sizeof (__u32))) {
683                 mthca_free_cq(to_mdev(ibdev), cq);
684                 goto err_free;
685         }
686
687         return &cq->ibcq;
688
689 err_free:
690         kfree(cq);
691
692 err_unmap_arm:
693         if (context)
694                 mthca_unmap_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
695                                     to_mucontext(context)->db_tab, ucmd.arm_db_index);
696
697 err_unmap_set:
698         if (context)
699                 mthca_unmap_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
700                                     to_mucontext(context)->db_tab, ucmd.set_db_index);
701
702         return ERR_PTR(err);
703 }
704
705 static int mthca_destroy_cq(struct ib_cq *cq)
706 {
707         if (cq->uobject) {
708                 mthca_unmap_user_db(to_mdev(cq->device),
709                                     &to_mucontext(cq->uobject->context)->uar,
710                                     to_mucontext(cq->uobject->context)->db_tab,
711                                     to_mcq(cq)->arm_db_index);
712                 mthca_unmap_user_db(to_mdev(cq->device),
713                                     &to_mucontext(cq->uobject->context)->uar,
714                                     to_mucontext(cq->uobject->context)->db_tab,
715                                     to_mcq(cq)->set_ci_db_index);
716         }
717         mthca_free_cq(to_mdev(cq->device), to_mcq(cq));
718         kfree(cq);
719
720         return 0;
721 }
722
723 static inline u32 convert_access(int acc)
724 {
725         return (acc & IB_ACCESS_REMOTE_ATOMIC ? MTHCA_MPT_FLAG_ATOMIC       : 0) |
726                (acc & IB_ACCESS_REMOTE_WRITE  ? MTHCA_MPT_FLAG_REMOTE_WRITE : 0) |
727                (acc & IB_ACCESS_REMOTE_READ   ? MTHCA_MPT_FLAG_REMOTE_READ  : 0) |
728                (acc & IB_ACCESS_LOCAL_WRITE   ? MTHCA_MPT_FLAG_LOCAL_WRITE  : 0) |
729                MTHCA_MPT_FLAG_LOCAL_READ;
730 }
731
732 static struct ib_mr *mthca_get_dma_mr(struct ib_pd *pd, int acc)
733 {
734         struct mthca_mr *mr;
735         int err;
736
737         mr = kmalloc(sizeof *mr, GFP_KERNEL);
738         if (!mr)
739                 return ERR_PTR(-ENOMEM);
740
741         err = mthca_mr_alloc_notrans(to_mdev(pd->device),
742                                      to_mpd(pd)->pd_num,
743                                      convert_access(acc), mr);
744
745         if (err) {
746                 kfree(mr);
747                 return ERR_PTR(err);
748         }
749
750         return &mr->ibmr;
751 }
752
753 static struct ib_mr *mthca_reg_phys_mr(struct ib_pd       *pd,
754                                        struct ib_phys_buf *buffer_list,
755                                        int                 num_phys_buf,
756                                        int                 acc,
757                                        u64                *iova_start)
758 {
759         struct mthca_mr *mr;
760         u64 *page_list;
761         u64 total_size;
762         u64 mask;
763         int shift;
764         int npages;
765         int err;
766         int i, j, n;
767
768         /* First check that we have enough alignment */
769         if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK))
770                 return ERR_PTR(-EINVAL);
771
772         if (num_phys_buf > 1 &&
773             ((buffer_list[0].addr + buffer_list[0].size) & ~PAGE_MASK))
774                 return ERR_PTR(-EINVAL);
775
776         mask = 0;
777         total_size = 0;
778         for (i = 0; i < num_phys_buf; ++i) {
779                 if (i != 0 && buffer_list[i].addr & ~PAGE_MASK)
780                         return ERR_PTR(-EINVAL);
781                 if (i != 0 && i != num_phys_buf - 1 &&
782                     (buffer_list[i].size & ~PAGE_MASK))
783                         return ERR_PTR(-EINVAL);
784
785                 total_size += buffer_list[i].size;
786                 if (i > 0)
787                         mask |= buffer_list[i].addr;
788         }
789
790         /* Find largest page shift we can use to cover buffers */
791         for (shift = PAGE_SHIFT; shift < 31; ++shift)
792                 if (num_phys_buf > 1) {
793                         if ((1ULL << shift) & mask)
794                                 break;
795                 } else {
796                         if (1ULL << shift >=
797                             buffer_list[0].size +
798                             (buffer_list[0].addr & ((1ULL << shift) - 1)))
799                                 break;
800                 }
801
802         buffer_list[0].size += buffer_list[0].addr & ((1ULL << shift) - 1);
803         buffer_list[0].addr &= ~0ull << shift;
804
805         mr = kmalloc(sizeof *mr, GFP_KERNEL);
806         if (!mr)
807                 return ERR_PTR(-ENOMEM);
808
809         npages = 0;
810         for (i = 0; i < num_phys_buf; ++i)
811                 npages += (buffer_list[i].size + (1ULL << shift) - 1) >> shift;
812
813         if (!npages)
814                 return &mr->ibmr;
815
816         page_list = kmalloc(npages * sizeof *page_list, GFP_KERNEL);
817         if (!page_list) {
818                 kfree(mr);
819                 return ERR_PTR(-ENOMEM);
820         }
821
822         n = 0;
823         for (i = 0; i < num_phys_buf; ++i)
824                 for (j = 0;
825                      j < (buffer_list[i].size + (1ULL << shift) - 1) >> shift;
826                      ++j)
827                         page_list[n++] = buffer_list[i].addr + ((u64) j << shift);
828
829         mthca_dbg(to_mdev(pd->device), "Registering memory at %llx (iova %llx) "
830                   "in PD %x; shift %d, npages %d.\n",
831                   (unsigned long long) buffer_list[0].addr,
832                   (unsigned long long) *iova_start,
833                   to_mpd(pd)->pd_num,
834                   shift, npages);
835
836         err = mthca_mr_alloc_phys(to_mdev(pd->device),
837                                   to_mpd(pd)->pd_num,
838                                   page_list, shift, npages,
839                                   *iova_start, total_size,
840                                   convert_access(acc), mr);
841
842         if (err) {
843                 kfree(page_list);
844                 kfree(mr);
845                 return ERR_PTR(err);
846         }
847
848         kfree(page_list);
849         return &mr->ibmr;
850 }
851
852 static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
853                                        int acc, struct ib_udata *udata)
854 {
855         struct mthca_dev *dev = to_mdev(pd->device);
856         struct ib_umem_chunk *chunk;
857         struct mthca_mr *mr;
858         u64 *pages;
859         int shift, n, len;
860         int i, j, k;
861         int err = 0;
862
863         shift = ffs(region->page_size) - 1;
864
865         mr = kmalloc(sizeof *mr, GFP_KERNEL);
866         if (!mr)
867                 return ERR_PTR(-ENOMEM);
868
869         n = 0;
870         list_for_each_entry(chunk, &region->chunk_list, list)
871                 n += chunk->nents;
872
873         mr->mtt = mthca_alloc_mtt(dev, n);
874         if (IS_ERR(mr->mtt)) {
875                 err = PTR_ERR(mr->mtt);
876                 goto err;
877         }
878
879         pages = (u64 *) __get_free_page(GFP_KERNEL);
880         if (!pages) {
881                 err = -ENOMEM;
882                 goto err_mtt;
883         }
884
885         i = n = 0;
886
887         list_for_each_entry(chunk, &region->chunk_list, list)
888                 for (j = 0; j < chunk->nmap; ++j) {
889                         len = sg_dma_len(&chunk->page_list[j]) >> shift;
890                         for (k = 0; k < len; ++k) {
891                                 pages[i++] = sg_dma_address(&chunk->page_list[j]) +
892                                         region->page_size * k;
893                                 /*
894                                  * Be friendly to WRITE_MTT command
895                                  * and leave two empty slots for the
896                                  * index and reserved fields of the
897                                  * mailbox.
898                                  */
899                                 if (i == PAGE_SIZE / sizeof (u64) - 2) {
900                                         err = mthca_write_mtt(dev, mr->mtt,
901                                                               n, pages, i);
902                                         if (err)
903                                                 goto mtt_done;
904                                         n += i;
905                                         i = 0;
906                                 }
907                         }
908                 }
909
910         if (i)
911                 err = mthca_write_mtt(dev, mr->mtt, n, pages, i);
912 mtt_done:
913         free_page((unsigned long) pages);
914         if (err)
915                 goto err_mtt;
916
917         err = mthca_mr_alloc(dev, to_mpd(pd)->pd_num, shift, region->virt_base,
918                              region->length, convert_access(acc), mr);
919
920         if (err)
921                 goto err_mtt;
922
923         return &mr->ibmr;
924
925 err_mtt:
926         mthca_free_mtt(dev, mr->mtt);
927
928 err:
929         kfree(mr);
930         return ERR_PTR(err);
931 }
932
933 static int mthca_dereg_mr(struct ib_mr *mr)
934 {
935         struct mthca_mr *mmr = to_mmr(mr);
936         mthca_free_mr(to_mdev(mr->device), mmr);
937         kfree(mmr);
938         return 0;
939 }
940
941 static struct ib_fmr *mthca_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
942                                       struct ib_fmr_attr *fmr_attr)
943 {
944         struct mthca_fmr *fmr;
945         int err;
946
947         fmr = kmalloc(sizeof *fmr, GFP_KERNEL);
948         if (!fmr)
949                 return ERR_PTR(-ENOMEM);
950
951         memcpy(&fmr->attr, fmr_attr, sizeof *fmr_attr);
952         err = mthca_fmr_alloc(to_mdev(pd->device), to_mpd(pd)->pd_num,
953                              convert_access(mr_access_flags), fmr);
954
955         if (err) {
956                 kfree(fmr);
957                 return ERR_PTR(err);
958         }
959
960         return &fmr->ibmr;
961 }
962
963 static int mthca_dealloc_fmr(struct ib_fmr *fmr)
964 {
965         struct mthca_fmr *mfmr = to_mfmr(fmr);
966         int err;
967
968         err = mthca_free_fmr(to_mdev(fmr->device), mfmr);
969         if (err)
970                 return err;
971
972         kfree(mfmr);
973         return 0;
974 }
975
976 static int mthca_unmap_fmr(struct list_head *fmr_list)
977 {
978         struct ib_fmr *fmr;
979         int err;
980         u8 status;
981         struct mthca_dev *mdev = NULL;
982
983         list_for_each_entry(fmr, fmr_list, list) {
984                 if (mdev && to_mdev(fmr->device) != mdev)
985                         return -EINVAL;
986                 mdev = to_mdev(fmr->device);
987         }
988
989         if (!mdev)
990                 return 0;
991
992         if (mthca_is_memfree(mdev)) {
993                 list_for_each_entry(fmr, fmr_list, list)
994                         mthca_arbel_fmr_unmap(mdev, to_mfmr(fmr));
995
996                 wmb();
997         } else
998                 list_for_each_entry(fmr, fmr_list, list)
999                         mthca_tavor_fmr_unmap(mdev, to_mfmr(fmr));
1000
1001         err = mthca_SYNC_TPT(mdev, &status);
1002         if (err)
1003                 return err;
1004         if (status)
1005                 return -EINVAL;
1006         return 0;
1007 }
1008
1009 static ssize_t show_rev(struct class_device *cdev, char *buf)
1010 {
1011         struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
1012         return sprintf(buf, "%x\n", dev->rev_id);
1013 }
1014
1015 static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
1016 {
1017         struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
1018         return sprintf(buf, "%x.%x.%x\n", (int) (dev->fw_ver >> 32),
1019                        (int) (dev->fw_ver >> 16) & 0xffff,
1020                        (int) dev->fw_ver & 0xffff);
1021 }
1022
1023 static ssize_t show_hca(struct class_device *cdev, char *buf)
1024 {
1025         struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
1026         switch (dev->pdev->device) {
1027         case PCI_DEVICE_ID_MELLANOX_TAVOR:
1028                 return sprintf(buf, "MT23108\n");
1029         case PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT:
1030                 return sprintf(buf, "MT25208 (MT23108 compat mode)\n");
1031         case PCI_DEVICE_ID_MELLANOX_ARBEL:
1032                 return sprintf(buf, "MT25208\n");
1033         case PCI_DEVICE_ID_MELLANOX_SINAI:
1034         case PCI_DEVICE_ID_MELLANOX_SINAI_OLD:
1035                 return sprintf(buf, "MT25204\n");
1036         default:
1037                 return sprintf(buf, "unknown\n");
1038         }
1039 }
1040
1041 static ssize_t show_board(struct class_device *cdev, char *buf)
1042 {
1043         struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
1044         return sprintf(buf, "%.*s\n", MTHCA_BOARD_ID_LEN, dev->board_id);
1045 }
1046
1047 static CLASS_DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
1048 static CLASS_DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
1049 static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
1050 static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
1051
1052 static struct class_device_attribute *mthca_class_attributes[] = {
1053         &class_device_attr_hw_rev,
1054         &class_device_attr_fw_ver,
1055         &class_device_attr_hca_type,
1056         &class_device_attr_board_id
1057 };
1058
1059 int mthca_register_device(struct mthca_dev *dev)
1060 {
1061         int ret;
1062         int i;
1063
1064         strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX);
1065         dev->ib_dev.owner                = THIS_MODULE;
1066
1067         dev->ib_dev.uverbs_abi_ver       = MTHCA_UVERBS_ABI_VERSION;
1068         dev->ib_dev.node_type            = IB_NODE_CA;
1069         dev->ib_dev.phys_port_cnt        = dev->limits.num_ports;
1070         dev->ib_dev.dma_device           = &dev->pdev->dev;
1071         dev->ib_dev.class_dev.dev        = &dev->pdev->dev;
1072         dev->ib_dev.query_device         = mthca_query_device;
1073         dev->ib_dev.query_port           = mthca_query_port;
1074         dev->ib_dev.modify_port          = mthca_modify_port;
1075         dev->ib_dev.query_pkey           = mthca_query_pkey;
1076         dev->ib_dev.query_gid            = mthca_query_gid;
1077         dev->ib_dev.alloc_ucontext       = mthca_alloc_ucontext;
1078         dev->ib_dev.dealloc_ucontext     = mthca_dealloc_ucontext;
1079         dev->ib_dev.mmap                 = mthca_mmap_uar;
1080         dev->ib_dev.alloc_pd             = mthca_alloc_pd;
1081         dev->ib_dev.dealloc_pd           = mthca_dealloc_pd;
1082         dev->ib_dev.create_ah            = mthca_ah_create;
1083         dev->ib_dev.destroy_ah           = mthca_ah_destroy;
1084
1085         if (dev->mthca_flags & MTHCA_FLAG_SRQ) {
1086                 dev->ib_dev.create_srq           = mthca_create_srq;
1087                 dev->ib_dev.destroy_srq          = mthca_destroy_srq;
1088
1089                 if (mthca_is_memfree(dev))
1090                         dev->ib_dev.post_srq_recv = mthca_arbel_post_srq_recv;
1091                 else
1092                         dev->ib_dev.post_srq_recv = mthca_tavor_post_srq_recv;
1093         }
1094
1095         dev->ib_dev.create_qp            = mthca_create_qp;
1096         dev->ib_dev.modify_qp            = mthca_modify_qp;
1097         dev->ib_dev.destroy_qp           = mthca_destroy_qp;
1098         dev->ib_dev.create_cq            = mthca_create_cq;
1099         dev->ib_dev.destroy_cq           = mthca_destroy_cq;
1100         dev->ib_dev.poll_cq              = mthca_poll_cq;
1101         dev->ib_dev.get_dma_mr           = mthca_get_dma_mr;
1102         dev->ib_dev.reg_phys_mr          = mthca_reg_phys_mr;
1103         dev->ib_dev.reg_user_mr          = mthca_reg_user_mr;
1104         dev->ib_dev.dereg_mr             = mthca_dereg_mr;
1105
1106         if (dev->mthca_flags & MTHCA_FLAG_FMR) {
1107                 dev->ib_dev.alloc_fmr            = mthca_alloc_fmr;
1108                 dev->ib_dev.unmap_fmr            = mthca_unmap_fmr;
1109                 dev->ib_dev.dealloc_fmr          = mthca_dealloc_fmr;
1110                 if (mthca_is_memfree(dev))
1111                         dev->ib_dev.map_phys_fmr = mthca_arbel_map_phys_fmr;
1112                 else
1113                         dev->ib_dev.map_phys_fmr = mthca_tavor_map_phys_fmr;
1114         }
1115
1116         dev->ib_dev.attach_mcast         = mthca_multicast_attach;
1117         dev->ib_dev.detach_mcast         = mthca_multicast_detach;
1118         dev->ib_dev.process_mad          = mthca_process_mad;
1119
1120         if (mthca_is_memfree(dev)) {
1121                 dev->ib_dev.req_notify_cq = mthca_arbel_arm_cq;
1122                 dev->ib_dev.post_send     = mthca_arbel_post_send;
1123                 dev->ib_dev.post_recv     = mthca_arbel_post_receive;
1124         } else {
1125                 dev->ib_dev.req_notify_cq = mthca_tavor_arm_cq;
1126                 dev->ib_dev.post_send     = mthca_tavor_post_send;
1127                 dev->ib_dev.post_recv     = mthca_tavor_post_receive;
1128         }
1129
1130         init_MUTEX(&dev->cap_mask_mutex);
1131
1132         ret = ib_register_device(&dev->ib_dev);
1133         if (ret)
1134                 return ret;
1135
1136         for (i = 0; i < ARRAY_SIZE(mthca_class_attributes); ++i) {
1137                 ret = class_device_create_file(&dev->ib_dev.class_dev,
1138                                                mthca_class_attributes[i]);
1139                 if (ret) {
1140                         ib_unregister_device(&dev->ib_dev);
1141                         return ret;
1142                 }
1143         }
1144
1145         return 0;
1146 }
1147
1148 void mthca_unregister_device(struct mthca_dev *dev)
1149 {
1150         ib_unregister_device(&dev->ib_dev);
1151 }