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.
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:
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
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.
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
36 * $Id: mthca_provider.c 1397 2004-12-28 05:09:00Z roland $
39 #include <rdma/ib_smi.h>
40 #include <rdma/ib_user_verbs.h>
43 #include "mthca_dev.h"
44 #include "mthca_cmd.h"
45 #include "mthca_user.h"
46 #include "mthca_memfree.h"
48 static int mthca_query_device(struct ib_device
*ibdev
,
49 struct ib_device_attr
*props
)
51 struct ib_smp
*in_mad
= NULL
;
52 struct ib_smp
*out_mad
= NULL
;
54 struct mthca_dev
* mdev
= to_mdev(ibdev
);
58 in_mad
= kmalloc(sizeof *in_mad
, GFP_KERNEL
);
59 out_mad
= kmalloc(sizeof *out_mad
, GFP_KERNEL
);
60 if (!in_mad
|| !out_mad
)
63 memset(props
, 0, sizeof *props
);
65 props
->fw_ver
= mdev
->fw_ver
;
67 memset(in_mad
, 0, sizeof *in_mad
);
68 in_mad
->base_version
= 1;
69 in_mad
->mgmt_class
= IB_MGMT_CLASS_SUBN_LID_ROUTED
;
70 in_mad
->class_version
= 1;
71 in_mad
->method
= IB_MGMT_METHOD_GET
;
72 in_mad
->attr_id
= IB_SMP_ATTR_NODE_INFO
;
74 err
= mthca_MAD_IFC(mdev
, 1, 1,
75 1, NULL
, NULL
, in_mad
, out_mad
,
84 props
->device_cap_flags
= mdev
->device_cap_flags
;
85 props
->vendor_id
= be32_to_cpup((__be32
*) (out_mad
->data
+ 36)) &
87 props
->vendor_part_id
= be16_to_cpup((__be16
*) (out_mad
->data
+ 30));
88 props
->hw_ver
= be32_to_cpup((__be32
*) (out_mad
->data
+ 32));
89 memcpy(&props
->sys_image_guid
, out_mad
->data
+ 4, 8);
90 memcpy(&props
->node_guid
, out_mad
->data
+ 12, 8);
92 props
->max_mr_size
= ~0ull;
93 props
->page_size_cap
= mdev
->limits
.page_size_cap
;
94 props
->max_qp
= mdev
->limits
.num_qps
- mdev
->limits
.reserved_qps
;
95 props
->max_qp_wr
= mdev
->limits
.max_wqes
;
96 props
->max_sge
= mdev
->limits
.max_sg
;
97 props
->max_cq
= mdev
->limits
.num_cqs
- mdev
->limits
.reserved_cqs
;
98 props
->max_cqe
= mdev
->limits
.max_cqes
;
99 props
->max_mr
= mdev
->limits
.num_mpts
- mdev
->limits
.reserved_mrws
;
100 props
->max_pd
= mdev
->limits
.num_pds
- mdev
->limits
.reserved_pds
;
101 props
->max_qp_rd_atom
= 1 << mdev
->qp_table
.rdb_shift
;
102 props
->max_qp_init_rd_atom
= mdev
->limits
.max_qp_init_rdma
;
103 props
->max_res_rd_atom
= props
->max_qp_rd_atom
* props
->max_qp
;
104 props
->max_srq
= mdev
->limits
.num_srqs
- mdev
->limits
.reserved_srqs
;
105 props
->max_srq_wr
= mdev
->limits
.max_srq_wqes
;
106 props
->max_srq_sge
= mdev
->limits
.max_sg
;
107 props
->local_ca_ack_delay
= mdev
->limits
.local_ca_ack_delay
;
108 props
->atomic_cap
= mdev
->limits
.flags
& DEV_LIM_FLAG_ATOMIC
?
109 IB_ATOMIC_HCA
: IB_ATOMIC_NONE
;
110 props
->max_pkeys
= mdev
->limits
.pkey_table_len
;
111 props
->max_mcast_grp
= mdev
->limits
.num_mgms
+ mdev
->limits
.num_amgms
;
112 props
->max_mcast_qp_attach
= MTHCA_QP_PER_MGM
;
113 props
->max_total_mcast_qp_attach
= props
->max_mcast_qp_attach
*
114 props
->max_mcast_grp
;
123 static int mthca_query_port(struct ib_device
*ibdev
,
124 u8 port
, struct ib_port_attr
*props
)
126 struct ib_smp
*in_mad
= NULL
;
127 struct ib_smp
*out_mad
= NULL
;
131 in_mad
= kmalloc(sizeof *in_mad
, GFP_KERNEL
);
132 out_mad
= kmalloc(sizeof *out_mad
, GFP_KERNEL
);
133 if (!in_mad
|| !out_mad
)
136 memset(props
, 0, sizeof *props
);
138 memset(in_mad
, 0, sizeof *in_mad
);
139 in_mad
->base_version
= 1;
140 in_mad
->mgmt_class
= IB_MGMT_CLASS_SUBN_LID_ROUTED
;
141 in_mad
->class_version
= 1;
142 in_mad
->method
= IB_MGMT_METHOD_GET
;
143 in_mad
->attr_id
= IB_SMP_ATTR_PORT_INFO
;
144 in_mad
->attr_mod
= cpu_to_be32(port
);
146 err
= mthca_MAD_IFC(to_mdev(ibdev
), 1, 1,
147 port
, NULL
, NULL
, in_mad
, out_mad
,
156 props
->lid
= be16_to_cpup((__be16
*) (out_mad
->data
+ 16));
157 props
->lmc
= out_mad
->data
[34] & 0x7;
158 props
->sm_lid
= be16_to_cpup((__be16
*) (out_mad
->data
+ 18));
159 props
->sm_sl
= out_mad
->data
[36] & 0xf;
160 props
->state
= out_mad
->data
[32] & 0xf;
161 props
->phys_state
= out_mad
->data
[33] >> 4;
162 props
->port_cap_flags
= be32_to_cpup((__be32
*) (out_mad
->data
+ 20));
163 props
->gid_tbl_len
= to_mdev(ibdev
)->limits
.gid_table_len
;
164 props
->max_msg_sz
= 0x80000000;
165 props
->pkey_tbl_len
= to_mdev(ibdev
)->limits
.pkey_table_len
;
166 props
->bad_pkey_cntr
= be16_to_cpup((__be16
*) (out_mad
->data
+ 46));
167 props
->qkey_viol_cntr
= be16_to_cpup((__be16
*) (out_mad
->data
+ 48));
168 props
->active_width
= out_mad
->data
[31] & 0xf;
169 props
->active_speed
= out_mad
->data
[35] >> 4;
170 props
->max_mtu
= out_mad
->data
[41] & 0xf;
171 props
->active_mtu
= out_mad
->data
[36] >> 4;
172 props
->subnet_timeout
= out_mad
->data
[51] & 0x1f;
180 static int mthca_modify_port(struct ib_device
*ibdev
,
181 u8 port
, int port_modify_mask
,
182 struct ib_port_modify
*props
)
184 struct mthca_set_ib_param set_ib
;
185 struct ib_port_attr attr
;
189 if (down_interruptible(&to_mdev(ibdev
)->cap_mask_mutex
))
192 err
= mthca_query_port(ibdev
, port
, &attr
);
196 set_ib
.set_si_guid
= 0;
197 set_ib
.reset_qkey_viol
= !!(port_modify_mask
& IB_PORT_RESET_QKEY_CNTR
);
199 set_ib
.cap_mask
= (attr
.port_cap_flags
| props
->set_port_cap_mask
) &
200 ~props
->clr_port_cap_mask
;
202 err
= mthca_SET_IB(to_mdev(ibdev
), &set_ib
, port
, &status
);
211 up(&to_mdev(ibdev
)->cap_mask_mutex
);
215 static int mthca_query_pkey(struct ib_device
*ibdev
,
216 u8 port
, u16 index
, u16
*pkey
)
218 struct ib_smp
*in_mad
= NULL
;
219 struct ib_smp
*out_mad
= NULL
;
223 in_mad
= kmalloc(sizeof *in_mad
, GFP_KERNEL
);
224 out_mad
= kmalloc(sizeof *out_mad
, GFP_KERNEL
);
225 if (!in_mad
|| !out_mad
)
228 memset(in_mad
, 0, sizeof *in_mad
);
229 in_mad
->base_version
= 1;
230 in_mad
->mgmt_class
= IB_MGMT_CLASS_SUBN_LID_ROUTED
;
231 in_mad
->class_version
= 1;
232 in_mad
->method
= IB_MGMT_METHOD_GET
;
233 in_mad
->attr_id
= IB_SMP_ATTR_PKEY_TABLE
;
234 in_mad
->attr_mod
= cpu_to_be32(index
/ 32);
236 err
= mthca_MAD_IFC(to_mdev(ibdev
), 1, 1,
237 port
, NULL
, NULL
, in_mad
, out_mad
,
246 *pkey
= be16_to_cpu(((__be16
*) out_mad
->data
)[index
% 32]);
254 static int mthca_query_gid(struct ib_device
*ibdev
, u8 port
,
255 int index
, union ib_gid
*gid
)
257 struct ib_smp
*in_mad
= NULL
;
258 struct ib_smp
*out_mad
= NULL
;
262 in_mad
= kmalloc(sizeof *in_mad
, GFP_KERNEL
);
263 out_mad
= kmalloc(sizeof *out_mad
, GFP_KERNEL
);
264 if (!in_mad
|| !out_mad
)
267 memset(in_mad
, 0, sizeof *in_mad
);
268 in_mad
->base_version
= 1;
269 in_mad
->mgmt_class
= IB_MGMT_CLASS_SUBN_LID_ROUTED
;
270 in_mad
->class_version
= 1;
271 in_mad
->method
= IB_MGMT_METHOD_GET
;
272 in_mad
->attr_id
= IB_SMP_ATTR_PORT_INFO
;
273 in_mad
->attr_mod
= cpu_to_be32(port
);
275 err
= mthca_MAD_IFC(to_mdev(ibdev
), 1, 1,
276 port
, NULL
, NULL
, in_mad
, out_mad
,
285 memcpy(gid
->raw
, out_mad
->data
+ 8, 8);
287 memset(in_mad
, 0, sizeof *in_mad
);
288 in_mad
->base_version
= 1;
289 in_mad
->mgmt_class
= IB_MGMT_CLASS_SUBN_LID_ROUTED
;
290 in_mad
->class_version
= 1;
291 in_mad
->method
= IB_MGMT_METHOD_GET
;
292 in_mad
->attr_id
= IB_SMP_ATTR_GUID_INFO
;
293 in_mad
->attr_mod
= cpu_to_be32(index
/ 8);
295 err
= mthca_MAD_IFC(to_mdev(ibdev
), 1, 1,
296 port
, NULL
, NULL
, in_mad
, out_mad
,
305 memcpy(gid
->raw
+ 8, out_mad
->data
+ (index
% 8) * 16, 8);
313 static struct ib_ucontext
*mthca_alloc_ucontext(struct ib_device
*ibdev
,
314 struct ib_udata
*udata
)
316 struct mthca_alloc_ucontext_resp uresp
;
317 struct mthca_ucontext
*context
;
320 memset(&uresp
, 0, sizeof uresp
);
322 uresp
.qp_tab_size
= to_mdev(ibdev
)->limits
.num_qps
;
323 if (mthca_is_memfree(to_mdev(ibdev
)))
324 uresp
.uarc_size
= to_mdev(ibdev
)->uar_table
.uarc_size
;
328 context
= kmalloc(sizeof *context
, GFP_KERNEL
);
330 return ERR_PTR(-ENOMEM
);
332 err
= mthca_uar_alloc(to_mdev(ibdev
), &context
->uar
);
338 context
->db_tab
= mthca_init_user_db_tab(to_mdev(ibdev
));
339 if (IS_ERR(context
->db_tab
)) {
340 err
= PTR_ERR(context
->db_tab
);
341 mthca_uar_free(to_mdev(ibdev
), &context
->uar
);
346 if (ib_copy_to_udata(udata
, &uresp
, sizeof uresp
)) {
347 mthca_cleanup_user_db_tab(to_mdev(ibdev
), &context
->uar
, context
->db_tab
);
348 mthca_uar_free(to_mdev(ibdev
), &context
->uar
);
350 return ERR_PTR(-EFAULT
);
353 return &context
->ibucontext
;
356 static int mthca_dealloc_ucontext(struct ib_ucontext
*context
)
358 mthca_cleanup_user_db_tab(to_mdev(context
->device
), &to_mucontext(context
)->uar
,
359 to_mucontext(context
)->db_tab
);
360 mthca_uar_free(to_mdev(context
->device
), &to_mucontext(context
)->uar
);
361 kfree(to_mucontext(context
));
366 static int mthca_mmap_uar(struct ib_ucontext
*context
,
367 struct vm_area_struct
*vma
)
369 if (vma
->vm_end
- vma
->vm_start
!= PAGE_SIZE
)
372 vma
->vm_page_prot
= pgprot_noncached(vma
->vm_page_prot
);
374 if (io_remap_pfn_range(vma
, vma
->vm_start
,
375 to_mucontext(context
)->uar
.pfn
,
376 PAGE_SIZE
, vma
->vm_page_prot
))
382 static struct ib_pd
*mthca_alloc_pd(struct ib_device
*ibdev
,
383 struct ib_ucontext
*context
,
384 struct ib_udata
*udata
)
389 pd
= kmalloc(sizeof *pd
, GFP_KERNEL
);
391 return ERR_PTR(-ENOMEM
);
393 err
= mthca_pd_alloc(to_mdev(ibdev
), !context
, pd
);
400 if (ib_copy_to_udata(udata
, &pd
->pd_num
, sizeof (__u32
))) {
401 mthca_pd_free(to_mdev(ibdev
), pd
);
403 return ERR_PTR(-EFAULT
);
410 static int mthca_dealloc_pd(struct ib_pd
*pd
)
412 mthca_pd_free(to_mdev(pd
->device
), to_mpd(pd
));
418 static struct ib_ah
*mthca_ah_create(struct ib_pd
*pd
,
419 struct ib_ah_attr
*ah_attr
)
424 ah
= kmalloc(sizeof *ah
, GFP_ATOMIC
);
426 return ERR_PTR(-ENOMEM
);
428 err
= mthca_create_ah(to_mdev(pd
->device
), to_mpd(pd
), ah_attr
, ah
);
437 static int mthca_ah_destroy(struct ib_ah
*ah
)
439 mthca_destroy_ah(to_mdev(ah
->device
), to_mah(ah
));
445 static struct ib_srq
*mthca_create_srq(struct ib_pd
*pd
,
446 struct ib_srq_init_attr
*init_attr
,
447 struct ib_udata
*udata
)
449 struct mthca_create_srq ucmd
;
450 struct mthca_ucontext
*context
= NULL
;
451 struct mthca_srq
*srq
;
454 srq
= kmalloc(sizeof *srq
, GFP_KERNEL
);
456 return ERR_PTR(-ENOMEM
);
459 context
= to_mucontext(pd
->uobject
->context
);
461 if (ib_copy_from_udata(&ucmd
, udata
, sizeof ucmd
))
462 return ERR_PTR(-EFAULT
);
464 err
= mthca_map_user_db(to_mdev(pd
->device
), &context
->uar
,
465 context
->db_tab
, ucmd
.db_index
,
471 srq
->mr
.ibmr
.lkey
= ucmd
.lkey
;
472 srq
->db_index
= ucmd
.db_index
;
475 err
= mthca_alloc_srq(to_mdev(pd
->device
), to_mpd(pd
),
476 &init_attr
->attr
, srq
);
478 if (err
&& pd
->uobject
)
479 mthca_unmap_user_db(to_mdev(pd
->device
), &context
->uar
,
480 context
->db_tab
, ucmd
.db_index
);
485 if (context
&& ib_copy_to_udata(udata
, &srq
->srqn
, sizeof (__u32
))) {
486 mthca_free_srq(to_mdev(pd
->device
), srq
);
499 static int mthca_destroy_srq(struct ib_srq
*srq
)
501 struct mthca_ucontext
*context
;
504 context
= to_mucontext(srq
->uobject
->context
);
506 mthca_unmap_user_db(to_mdev(srq
->device
), &context
->uar
,
507 context
->db_tab
, to_msrq(srq
)->db_index
);
510 mthca_free_srq(to_mdev(srq
->device
), to_msrq(srq
));
516 static struct ib_qp
*mthca_create_qp(struct ib_pd
*pd
,
517 struct ib_qp_init_attr
*init_attr
,
518 struct ib_udata
*udata
)
520 struct mthca_create_qp ucmd
;
524 switch (init_attr
->qp_type
) {
529 struct mthca_ucontext
*context
;
531 qp
= kmalloc(sizeof *qp
, GFP_KERNEL
);
533 return ERR_PTR(-ENOMEM
);
536 context
= to_mucontext(pd
->uobject
->context
);
538 if (ib_copy_from_udata(&ucmd
, udata
, sizeof ucmd
))
539 return ERR_PTR(-EFAULT
);
541 err
= mthca_map_user_db(to_mdev(pd
->device
), &context
->uar
,
543 ucmd
.sq_db_index
, ucmd
.sq_db_page
);
549 err
= mthca_map_user_db(to_mdev(pd
->device
), &context
->uar
,
551 ucmd
.rq_db_index
, ucmd
.rq_db_page
);
553 mthca_unmap_user_db(to_mdev(pd
->device
),
561 qp
->mr
.ibmr
.lkey
= ucmd
.lkey
;
562 qp
->sq
.db_index
= ucmd
.sq_db_index
;
563 qp
->rq
.db_index
= ucmd
.rq_db_index
;
566 err
= mthca_alloc_qp(to_mdev(pd
->device
), to_mpd(pd
),
567 to_mcq(init_attr
->send_cq
),
568 to_mcq(init_attr
->recv_cq
),
569 init_attr
->qp_type
, init_attr
->sq_sig_type
,
570 &init_attr
->cap
, qp
);
572 if (err
&& pd
->uobject
) {
573 context
= to_mucontext(pd
->uobject
->context
);
575 mthca_unmap_user_db(to_mdev(pd
->device
),
579 mthca_unmap_user_db(to_mdev(pd
->device
),
585 qp
->ibqp
.qp_num
= qp
->qpn
;
591 /* Don't allow userspace to create special QPs */
593 return ERR_PTR(-EINVAL
);
595 qp
= kmalloc(sizeof (struct mthca_sqp
), GFP_KERNEL
);
597 return ERR_PTR(-ENOMEM
);
599 qp
->ibqp
.qp_num
= init_attr
->qp_type
== IB_QPT_SMI
? 0 : 1;
601 err
= mthca_alloc_sqp(to_mdev(pd
->device
), to_mpd(pd
),
602 to_mcq(init_attr
->send_cq
),
603 to_mcq(init_attr
->recv_cq
),
604 init_attr
->sq_sig_type
, &init_attr
->cap
,
605 qp
->ibqp
.qp_num
, init_attr
->port_num
,
610 /* Don't support raw QPs */
611 return ERR_PTR(-ENOSYS
);
619 init_attr
->cap
.max_send_wr
= qp
->sq
.max
;
620 init_attr
->cap
.max_recv_wr
= qp
->rq
.max
;
621 init_attr
->cap
.max_send_sge
= qp
->sq
.max_gs
;
622 init_attr
->cap
.max_recv_sge
= qp
->rq
.max_gs
;
623 init_attr
->cap
.max_inline_data
= qp
->max_inline_data
;
628 static int mthca_destroy_qp(struct ib_qp
*qp
)
631 mthca_unmap_user_db(to_mdev(qp
->device
),
632 &to_mucontext(qp
->uobject
->context
)->uar
,
633 to_mucontext(qp
->uobject
->context
)->db_tab
,
634 to_mqp(qp
)->sq
.db_index
);
635 mthca_unmap_user_db(to_mdev(qp
->device
),
636 &to_mucontext(qp
->uobject
->context
)->uar
,
637 to_mucontext(qp
->uobject
->context
)->db_tab
,
638 to_mqp(qp
)->rq
.db_index
);
640 mthca_free_qp(to_mdev(qp
->device
), to_mqp(qp
));
645 static struct ib_cq
*mthca_create_cq(struct ib_device
*ibdev
, int entries
,
646 struct ib_ucontext
*context
,
647 struct ib_udata
*udata
)
649 struct mthca_create_cq ucmd
;
654 if (entries
< 1 || entries
> to_mdev(ibdev
)->limits
.max_cqes
)
655 return ERR_PTR(-EINVAL
);
658 if (ib_copy_from_udata(&ucmd
, udata
, sizeof ucmd
))
659 return ERR_PTR(-EFAULT
);
661 err
= mthca_map_user_db(to_mdev(ibdev
), &to_mucontext(context
)->uar
,
662 to_mucontext(context
)->db_tab
,
663 ucmd
.set_db_index
, ucmd
.set_db_page
);
667 err
= mthca_map_user_db(to_mdev(ibdev
), &to_mucontext(context
)->uar
,
668 to_mucontext(context
)->db_tab
,
669 ucmd
.arm_db_index
, ucmd
.arm_db_page
);
674 cq
= kmalloc(sizeof *cq
, GFP_KERNEL
);
681 cq
->mr
.ibmr
.lkey
= ucmd
.lkey
;
682 cq
->set_ci_db_index
= ucmd
.set_db_index
;
683 cq
->arm_db_index
= ucmd
.arm_db_index
;
686 for (nent
= 1; nent
<= entries
; nent
<<= 1)
689 err
= mthca_init_cq(to_mdev(ibdev
), nent
,
690 context
? to_mucontext(context
) : NULL
,
691 context
? ucmd
.pdn
: to_mdev(ibdev
)->driver_pd
.pd_num
,
696 if (context
&& ib_copy_to_udata(udata
, &cq
->cqn
, sizeof (__u32
))) {
697 mthca_free_cq(to_mdev(ibdev
), cq
);
708 mthca_unmap_user_db(to_mdev(ibdev
), &to_mucontext(context
)->uar
,
709 to_mucontext(context
)->db_tab
, ucmd
.arm_db_index
);
713 mthca_unmap_user_db(to_mdev(ibdev
), &to_mucontext(context
)->uar
,
714 to_mucontext(context
)->db_tab
, ucmd
.set_db_index
);
719 static int mthca_destroy_cq(struct ib_cq
*cq
)
722 mthca_unmap_user_db(to_mdev(cq
->device
),
723 &to_mucontext(cq
->uobject
->context
)->uar
,
724 to_mucontext(cq
->uobject
->context
)->db_tab
,
725 to_mcq(cq
)->arm_db_index
);
726 mthca_unmap_user_db(to_mdev(cq
->device
),
727 &to_mucontext(cq
->uobject
->context
)->uar
,
728 to_mucontext(cq
->uobject
->context
)->db_tab
,
729 to_mcq(cq
)->set_ci_db_index
);
731 mthca_free_cq(to_mdev(cq
->device
), to_mcq(cq
));
737 static inline u32
convert_access(int acc
)
739 return (acc
& IB_ACCESS_REMOTE_ATOMIC
? MTHCA_MPT_FLAG_ATOMIC
: 0) |
740 (acc
& IB_ACCESS_REMOTE_WRITE
? MTHCA_MPT_FLAG_REMOTE_WRITE
: 0) |
741 (acc
& IB_ACCESS_REMOTE_READ
? MTHCA_MPT_FLAG_REMOTE_READ
: 0) |
742 (acc
& IB_ACCESS_LOCAL_WRITE
? MTHCA_MPT_FLAG_LOCAL_WRITE
: 0) |
743 MTHCA_MPT_FLAG_LOCAL_READ
;
746 static struct ib_mr
*mthca_get_dma_mr(struct ib_pd
*pd
, int acc
)
751 mr
= kmalloc(sizeof *mr
, GFP_KERNEL
);
753 return ERR_PTR(-ENOMEM
);
755 err
= mthca_mr_alloc_notrans(to_mdev(pd
->device
),
757 convert_access(acc
), mr
);
767 static struct ib_mr
*mthca_reg_phys_mr(struct ib_pd
*pd
,
768 struct ib_phys_buf
*buffer_list
,
782 /* First check that we have enough alignment */
783 if ((*iova_start
& ~PAGE_MASK
) != (buffer_list
[0].addr
& ~PAGE_MASK
))
784 return ERR_PTR(-EINVAL
);
786 if (num_phys_buf
> 1 &&
787 ((buffer_list
[0].addr
+ buffer_list
[0].size
) & ~PAGE_MASK
))
788 return ERR_PTR(-EINVAL
);
792 for (i
= 0; i
< num_phys_buf
; ++i
) {
793 if (i
!= 0 && buffer_list
[i
].addr
& ~PAGE_MASK
)
794 return ERR_PTR(-EINVAL
);
795 if (i
!= 0 && i
!= num_phys_buf
- 1 &&
796 (buffer_list
[i
].size
& ~PAGE_MASK
))
797 return ERR_PTR(-EINVAL
);
799 total_size
+= buffer_list
[i
].size
;
801 mask
|= buffer_list
[i
].addr
;
804 /* Find largest page shift we can use to cover buffers */
805 for (shift
= PAGE_SHIFT
; shift
< 31; ++shift
)
806 if (num_phys_buf
> 1) {
807 if ((1ULL << shift
) & mask
)
811 buffer_list
[0].size
+
812 (buffer_list
[0].addr
& ((1ULL << shift
) - 1)))
816 buffer_list
[0].size
+= buffer_list
[0].addr
& ((1ULL << shift
) - 1);
817 buffer_list
[0].addr
&= ~0ull << shift
;
819 mr
= kmalloc(sizeof *mr
, GFP_KERNEL
);
821 return ERR_PTR(-ENOMEM
);
824 for (i
= 0; i
< num_phys_buf
; ++i
)
825 npages
+= (buffer_list
[i
].size
+ (1ULL << shift
) - 1) >> shift
;
830 page_list
= kmalloc(npages
* sizeof *page_list
, GFP_KERNEL
);
833 return ERR_PTR(-ENOMEM
);
837 for (i
= 0; i
< num_phys_buf
; ++i
)
839 j
< (buffer_list
[i
].size
+ (1ULL << shift
) - 1) >> shift
;
841 page_list
[n
++] = buffer_list
[i
].addr
+ ((u64
) j
<< shift
);
843 mthca_dbg(to_mdev(pd
->device
), "Registering memory at %llx (iova %llx) "
844 "in PD %x; shift %d, npages %d.\n",
845 (unsigned long long) buffer_list
[0].addr
,
846 (unsigned long long) *iova_start
,
850 err
= mthca_mr_alloc_phys(to_mdev(pd
->device
),
852 page_list
, shift
, npages
,
853 *iova_start
, total_size
,
854 convert_access(acc
), mr
);
866 static struct ib_mr
*mthca_reg_user_mr(struct ib_pd
*pd
, struct ib_umem
*region
,
867 int acc
, struct ib_udata
*udata
)
869 struct mthca_dev
*dev
= to_mdev(pd
->device
);
870 struct ib_umem_chunk
*chunk
;
877 shift
= ffs(region
->page_size
) - 1;
879 mr
= kmalloc(sizeof *mr
, GFP_KERNEL
);
881 return ERR_PTR(-ENOMEM
);
884 list_for_each_entry(chunk
, ®ion
->chunk_list
, list
)
887 mr
->mtt
= mthca_alloc_mtt(dev
, n
);
888 if (IS_ERR(mr
->mtt
)) {
889 err
= PTR_ERR(mr
->mtt
);
893 pages
= (u64
*) __get_free_page(GFP_KERNEL
);
901 list_for_each_entry(chunk
, ®ion
->chunk_list
, list
)
902 for (j
= 0; j
< chunk
->nmap
; ++j
) {
903 len
= sg_dma_len(&chunk
->page_list
[j
]) >> shift
;
904 for (k
= 0; k
< len
; ++k
) {
905 pages
[i
++] = sg_dma_address(&chunk
->page_list
[j
]) +
906 region
->page_size
* k
;
908 * Be friendly to WRITE_MTT command
909 * and leave two empty slots for the
910 * index and reserved fields of the
913 if (i
== PAGE_SIZE
/ sizeof (u64
) - 2) {
914 err
= mthca_write_mtt(dev
, mr
->mtt
,
925 err
= mthca_write_mtt(dev
, mr
->mtt
, n
, pages
, i
);
927 free_page((unsigned long) pages
);
931 err
= mthca_mr_alloc(dev
, to_mpd(pd
)->pd_num
, shift
, region
->virt_base
,
932 region
->length
, convert_access(acc
), mr
);
940 mthca_free_mtt(dev
, mr
->mtt
);
947 static int mthca_dereg_mr(struct ib_mr
*mr
)
949 struct mthca_mr
*mmr
= to_mmr(mr
);
950 mthca_free_mr(to_mdev(mr
->device
), mmr
);
955 static struct ib_fmr
*mthca_alloc_fmr(struct ib_pd
*pd
, int mr_access_flags
,
956 struct ib_fmr_attr
*fmr_attr
)
958 struct mthca_fmr
*fmr
;
961 fmr
= kmalloc(sizeof *fmr
, GFP_KERNEL
);
963 return ERR_PTR(-ENOMEM
);
965 memcpy(&fmr
->attr
, fmr_attr
, sizeof *fmr_attr
);
966 err
= mthca_fmr_alloc(to_mdev(pd
->device
), to_mpd(pd
)->pd_num
,
967 convert_access(mr_access_flags
), fmr
);
977 static int mthca_dealloc_fmr(struct ib_fmr
*fmr
)
979 struct mthca_fmr
*mfmr
= to_mfmr(fmr
);
982 err
= mthca_free_fmr(to_mdev(fmr
->device
), mfmr
);
990 static int mthca_unmap_fmr(struct list_head
*fmr_list
)
995 struct mthca_dev
*mdev
= NULL
;
997 list_for_each_entry(fmr
, fmr_list
, list
) {
998 if (mdev
&& to_mdev(fmr
->device
) != mdev
)
1000 mdev
= to_mdev(fmr
->device
);
1006 if (mthca_is_memfree(mdev
)) {
1007 list_for_each_entry(fmr
, fmr_list
, list
)
1008 mthca_arbel_fmr_unmap(mdev
, to_mfmr(fmr
));
1012 list_for_each_entry(fmr
, fmr_list
, list
)
1013 mthca_tavor_fmr_unmap(mdev
, to_mfmr(fmr
));
1015 err
= mthca_SYNC_TPT(mdev
, &status
);
1023 static ssize_t
show_rev(struct class_device
*cdev
, char *buf
)
1025 struct mthca_dev
*dev
= container_of(cdev
, struct mthca_dev
, ib_dev
.class_dev
);
1026 return sprintf(buf
, "%x\n", dev
->rev_id
);
1029 static ssize_t
show_fw_ver(struct class_device
*cdev
, char *buf
)
1031 struct mthca_dev
*dev
= container_of(cdev
, struct mthca_dev
, ib_dev
.class_dev
);
1032 return sprintf(buf
, "%d.%d.%d\n", (int) (dev
->fw_ver
>> 32),
1033 (int) (dev
->fw_ver
>> 16) & 0xffff,
1034 (int) dev
->fw_ver
& 0xffff);
1037 static ssize_t
show_hca(struct class_device
*cdev
, char *buf
)
1039 struct mthca_dev
*dev
= container_of(cdev
, struct mthca_dev
, ib_dev
.class_dev
);
1040 switch (dev
->pdev
->device
) {
1041 case PCI_DEVICE_ID_MELLANOX_TAVOR
:
1042 return sprintf(buf
, "MT23108\n");
1043 case PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT
:
1044 return sprintf(buf
, "MT25208 (MT23108 compat mode)\n");
1045 case PCI_DEVICE_ID_MELLANOX_ARBEL
:
1046 return sprintf(buf
, "MT25208\n");
1047 case PCI_DEVICE_ID_MELLANOX_SINAI
:
1048 case PCI_DEVICE_ID_MELLANOX_SINAI_OLD
:
1049 return sprintf(buf
, "MT25204\n");
1051 return sprintf(buf
, "unknown\n");
1055 static ssize_t
show_board(struct class_device
*cdev
, char *buf
)
1057 struct mthca_dev
*dev
= container_of(cdev
, struct mthca_dev
, ib_dev
.class_dev
);
1058 return sprintf(buf
, "%.*s\n", MTHCA_BOARD_ID_LEN
, dev
->board_id
);
1061 static CLASS_DEVICE_ATTR(hw_rev
, S_IRUGO
, show_rev
, NULL
);
1062 static CLASS_DEVICE_ATTR(fw_ver
, S_IRUGO
, show_fw_ver
, NULL
);
1063 static CLASS_DEVICE_ATTR(hca_type
, S_IRUGO
, show_hca
, NULL
);
1064 static CLASS_DEVICE_ATTR(board_id
, S_IRUGO
, show_board
, NULL
);
1066 static struct class_device_attribute
*mthca_class_attributes
[] = {
1067 &class_device_attr_hw_rev
,
1068 &class_device_attr_fw_ver
,
1069 &class_device_attr_hca_type
,
1070 &class_device_attr_board_id
1073 int mthca_register_device(struct mthca_dev
*dev
)
1078 strlcpy(dev
->ib_dev
.name
, "mthca%d", IB_DEVICE_NAME_MAX
);
1079 dev
->ib_dev
.owner
= THIS_MODULE
;
1081 dev
->ib_dev
.uverbs_abi_ver
= MTHCA_UVERBS_ABI_VERSION
;
1082 dev
->ib_dev
.uverbs_cmd_mask
=
1083 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT
) |
1084 (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE
) |
1085 (1ull << IB_USER_VERBS_CMD_QUERY_PORT
) |
1086 (1ull << IB_USER_VERBS_CMD_ALLOC_PD
) |
1087 (1ull << IB_USER_VERBS_CMD_DEALLOC_PD
) |
1088 (1ull << IB_USER_VERBS_CMD_REG_MR
) |
1089 (1ull << IB_USER_VERBS_CMD_DEREG_MR
) |
1090 (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL
) |
1091 (1ull << IB_USER_VERBS_CMD_CREATE_CQ
) |
1092 (1ull << IB_USER_VERBS_CMD_DESTROY_CQ
) |
1093 (1ull << IB_USER_VERBS_CMD_CREATE_QP
) |
1094 (1ull << IB_USER_VERBS_CMD_MODIFY_QP
) |
1095 (1ull << IB_USER_VERBS_CMD_DESTROY_QP
) |
1096 (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST
) |
1097 (1ull << IB_USER_VERBS_CMD_DETACH_MCAST
) |
1098 (1ull << IB_USER_VERBS_CMD_CREATE_SRQ
) |
1099 (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ
) |
1100 (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ
);
1101 dev
->ib_dev
.node_type
= IB_NODE_CA
;
1102 dev
->ib_dev
.phys_port_cnt
= dev
->limits
.num_ports
;
1103 dev
->ib_dev
.dma_device
= &dev
->pdev
->dev
;
1104 dev
->ib_dev
.class_dev
.dev
= &dev
->pdev
->dev
;
1105 dev
->ib_dev
.query_device
= mthca_query_device
;
1106 dev
->ib_dev
.query_port
= mthca_query_port
;
1107 dev
->ib_dev
.modify_port
= mthca_modify_port
;
1108 dev
->ib_dev
.query_pkey
= mthca_query_pkey
;
1109 dev
->ib_dev
.query_gid
= mthca_query_gid
;
1110 dev
->ib_dev
.alloc_ucontext
= mthca_alloc_ucontext
;
1111 dev
->ib_dev
.dealloc_ucontext
= mthca_dealloc_ucontext
;
1112 dev
->ib_dev
.mmap
= mthca_mmap_uar
;
1113 dev
->ib_dev
.alloc_pd
= mthca_alloc_pd
;
1114 dev
->ib_dev
.dealloc_pd
= mthca_dealloc_pd
;
1115 dev
->ib_dev
.create_ah
= mthca_ah_create
;
1116 dev
->ib_dev
.destroy_ah
= mthca_ah_destroy
;
1118 if (dev
->mthca_flags
& MTHCA_FLAG_SRQ
) {
1119 dev
->ib_dev
.create_srq
= mthca_create_srq
;
1120 dev
->ib_dev
.modify_srq
= mthca_modify_srq
;
1121 dev
->ib_dev
.destroy_srq
= mthca_destroy_srq
;
1123 if (mthca_is_memfree(dev
))
1124 dev
->ib_dev
.post_srq_recv
= mthca_arbel_post_srq_recv
;
1126 dev
->ib_dev
.post_srq_recv
= mthca_tavor_post_srq_recv
;
1129 dev
->ib_dev
.create_qp
= mthca_create_qp
;
1130 dev
->ib_dev
.modify_qp
= mthca_modify_qp
;
1131 dev
->ib_dev
.destroy_qp
= mthca_destroy_qp
;
1132 dev
->ib_dev
.create_cq
= mthca_create_cq
;
1133 dev
->ib_dev
.destroy_cq
= mthca_destroy_cq
;
1134 dev
->ib_dev
.poll_cq
= mthca_poll_cq
;
1135 dev
->ib_dev
.get_dma_mr
= mthca_get_dma_mr
;
1136 dev
->ib_dev
.reg_phys_mr
= mthca_reg_phys_mr
;
1137 dev
->ib_dev
.reg_user_mr
= mthca_reg_user_mr
;
1138 dev
->ib_dev
.dereg_mr
= mthca_dereg_mr
;
1140 if (dev
->mthca_flags
& MTHCA_FLAG_FMR
) {
1141 dev
->ib_dev
.alloc_fmr
= mthca_alloc_fmr
;
1142 dev
->ib_dev
.unmap_fmr
= mthca_unmap_fmr
;
1143 dev
->ib_dev
.dealloc_fmr
= mthca_dealloc_fmr
;
1144 if (mthca_is_memfree(dev
))
1145 dev
->ib_dev
.map_phys_fmr
= mthca_arbel_map_phys_fmr
;
1147 dev
->ib_dev
.map_phys_fmr
= mthca_tavor_map_phys_fmr
;
1150 dev
->ib_dev
.attach_mcast
= mthca_multicast_attach
;
1151 dev
->ib_dev
.detach_mcast
= mthca_multicast_detach
;
1152 dev
->ib_dev
.process_mad
= mthca_process_mad
;
1154 if (mthca_is_memfree(dev
)) {
1155 dev
->ib_dev
.req_notify_cq
= mthca_arbel_arm_cq
;
1156 dev
->ib_dev
.post_send
= mthca_arbel_post_send
;
1157 dev
->ib_dev
.post_recv
= mthca_arbel_post_receive
;
1159 dev
->ib_dev
.req_notify_cq
= mthca_tavor_arm_cq
;
1160 dev
->ib_dev
.post_send
= mthca_tavor_post_send
;
1161 dev
->ib_dev
.post_recv
= mthca_tavor_post_receive
;
1164 init_MUTEX(&dev
->cap_mask_mutex
);
1166 ret
= ib_register_device(&dev
->ib_dev
);
1170 for (i
= 0; i
< ARRAY_SIZE(mthca_class_attributes
); ++i
) {
1171 ret
= class_device_create_file(&dev
->ib_dev
.class_dev
,
1172 mthca_class_attributes
[i
]);
1174 ib_unregister_device(&dev
->ib_dev
);
1179 mthca_start_catas_poll(dev
);
1184 void mthca_unregister_device(struct mthca_dev
*dev
)
1186 mthca_stop_catas_poll(dev
);
1187 ib_unregister_device(&dev
->ib_dev
);