The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/mthca/mthca_provider.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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, 2006 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 
   37 #include <rdma/ib_smi.h>
   38 #include <rdma/ib_umem.h>
   39 #include <rdma/ib_user_verbs.h>
   40 #include <rdma/uverbs_ioctl.h>
   41 
   42 #include <linux/sched.h>
   43 #include <linux/slab.h>
   44 #include <linux/mm.h>
   45 #include <linux/fs.h>
   46 
   47 #include "mthca_dev.h"
   48 #include "mthca_cmd.h"
   49 #include <rdma/mthca-abi.h>
   50 #include "mthca_memfree.h"
   51 
   52 static void init_query_mad(struct ib_smp *mad)
   53 {
   54         mad->base_version  = 1;
   55         mad->mgmt_class    = IB_MGMT_CLASS_SUBN_LID_ROUTED;
   56         mad->class_version = 1;
   57         mad->method        = IB_MGMT_METHOD_GET;
   58 }
   59 
   60 static int mthca_query_device(struct ib_device *ibdev, struct ib_device_attr *props,
   61                               struct ib_udata *uhw)
   62 {
   63         struct ib_smp *in_mad  = NULL;
   64         struct ib_smp *out_mad = NULL;
   65         int err = -ENOMEM;
   66         struct mthca_dev *mdev = to_mdev(ibdev);
   67 
   68         if (uhw->inlen || uhw->outlen)
   69                 return -EINVAL;
   70 
   71         in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
   72         out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
   73         if (!in_mad || !out_mad)
   74                 goto out;
   75 
   76         memset(props, 0, sizeof *props);
   77 
   78         props->fw_ver              = mdev->fw_ver;
   79 
   80         init_query_mad(in_mad);
   81         in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
   82 
   83         err = mthca_MAD_IFC(mdev, 1, 1,
   84                             1, NULL, NULL, in_mad, out_mad);
   85         if (err)
   86                 goto out;
   87 
   88         props->device_cap_flags    = mdev->device_cap_flags;
   89         props->vendor_id           = be32_to_cpup((__be32 *) (out_mad->data + 36)) &
   90                 0xffffff;
   91         props->vendor_part_id      = be16_to_cpup((__be16 *) (out_mad->data + 30));
   92         props->hw_ver              = be32_to_cpup((__be32 *) (out_mad->data + 32));
   93         memcpy(&props->sys_image_guid, out_mad->data +  4, 8);
   94 
   95         props->max_mr_size         = ~0ull;
   96         props->page_size_cap       = mdev->limits.page_size_cap;
   97         props->max_qp              = mdev->limits.num_qps - mdev->limits.reserved_qps;
   98         props->max_qp_wr           = mdev->limits.max_wqes;
   99         props->max_sge             = mdev->limits.max_sg;
  100         props->max_sge_rd          = props->max_sge;
  101         props->max_cq              = mdev->limits.num_cqs - mdev->limits.reserved_cqs;
  102         props->max_cqe             = mdev->limits.max_cqes;
  103         props->max_mr              = mdev->limits.num_mpts - mdev->limits.reserved_mrws;
  104         props->max_pd              = mdev->limits.num_pds - mdev->limits.reserved_pds;
  105         props->max_qp_rd_atom      = 1 << mdev->qp_table.rdb_shift;
  106         props->max_qp_init_rd_atom = mdev->limits.max_qp_init_rdma;
  107         props->max_res_rd_atom     = props->max_qp_rd_atom * props->max_qp;
  108         props->max_srq             = mdev->limits.num_srqs - mdev->limits.reserved_srqs;
  109         props->max_srq_wr          = mdev->limits.max_srq_wqes;
  110         props->max_srq_sge         = mdev->limits.max_srq_sge;
  111         props->local_ca_ack_delay  = mdev->limits.local_ca_ack_delay;
  112         props->atomic_cap          = mdev->limits.flags & DEV_LIM_FLAG_ATOMIC ?
  113                                         IB_ATOMIC_HCA : IB_ATOMIC_NONE;
  114         props->max_pkeys           = mdev->limits.pkey_table_len;
  115         props->max_mcast_grp       = mdev->limits.num_mgms + mdev->limits.num_amgms;
  116         props->max_mcast_qp_attach = MTHCA_QP_PER_MGM;
  117         props->max_total_mcast_qp_attach = props->max_mcast_qp_attach *
  118                                            props->max_mcast_grp;
  119         /*
  120          * If Sinai memory key optimization is being used, then only
  121          * the 8-bit key portion will change.  For other HCAs, the
  122          * unused index bits will also be used for FMR remapping.
  123          */
  124         if (mdev->mthca_flags & MTHCA_FLAG_SINAI_OPT)
  125                 props->max_map_per_fmr = 255;
  126         else
  127                 props->max_map_per_fmr =
  128                         (1 << (32 - ilog2(mdev->limits.num_mpts))) - 1;
  129 
  130         err = 0;
  131  out:
  132         kfree(in_mad);
  133         kfree(out_mad);
  134         return err;
  135 }
  136 
  137 static int mthca_query_port(struct ib_device *ibdev,
  138                             u8 port, struct ib_port_attr *props)
  139 {
  140         struct ib_smp *in_mad  = NULL;
  141         struct ib_smp *out_mad = NULL;
  142         int err = -ENOMEM;
  143 
  144         in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
  145         out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
  146         if (!in_mad || !out_mad)
  147                 goto out;
  148 
  149         memset(props, 0, sizeof *props);
  150 
  151         init_query_mad(in_mad);
  152         in_mad->attr_id  = IB_SMP_ATTR_PORT_INFO;
  153         in_mad->attr_mod = cpu_to_be32(port);
  154 
  155         err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
  156                             port, NULL, NULL, in_mad, out_mad);
  157         if (err)
  158                 goto out;
  159 
  160         props->lid               = be16_to_cpup((__be16 *) (out_mad->data + 16));
  161         props->lmc               = out_mad->data[34] & 0x7;
  162         props->sm_lid            = be16_to_cpup((__be16 *) (out_mad->data + 18));
  163         props->sm_sl             = out_mad->data[36] & 0xf;
  164         props->state             = out_mad->data[32] & 0xf;
  165         props->phys_state        = out_mad->data[33] >> 4;
  166         props->port_cap_flags    = be32_to_cpup((__be32 *) (out_mad->data + 20));
  167         props->gid_tbl_len       = to_mdev(ibdev)->limits.gid_table_len;
  168         props->max_msg_sz        = 0x80000000;
  169         props->pkey_tbl_len      = to_mdev(ibdev)->limits.pkey_table_len;
  170         props->bad_pkey_cntr     = be16_to_cpup((__be16 *) (out_mad->data + 46));
  171         props->qkey_viol_cntr    = be16_to_cpup((__be16 *) (out_mad->data + 48));
  172         props->active_width      = out_mad->data[31] & 0xf;
  173         props->active_speed      = out_mad->data[35] >> 4;
  174         props->max_mtu           = out_mad->data[41] & 0xf;
  175         props->active_mtu        = out_mad->data[36] >> 4;
  176         props->subnet_timeout    = out_mad->data[51] & 0x1f;
  177         props->max_vl_num        = out_mad->data[37] >> 4;
  178         props->init_type_reply   = out_mad->data[41] >> 4;
  179 
  180  out:
  181         kfree(in_mad);
  182         kfree(out_mad);
  183         return err;
  184 }
  185 
  186 static int mthca_modify_device(struct ib_device *ibdev,
  187                                int mask,
  188                                struct ib_device_modify *props)
  189 {
  190         if (mask & ~IB_DEVICE_MODIFY_NODE_DESC)
  191                 return -EOPNOTSUPP;
  192 
  193         if (mask & IB_DEVICE_MODIFY_NODE_DESC) {
  194                 if (mutex_lock_interruptible(&to_mdev(ibdev)->cap_mask_mutex))
  195                         return -ERESTARTSYS;
  196                 memcpy(ibdev->node_desc, props->node_desc,
  197                        IB_DEVICE_NODE_DESC_MAX);
  198                 mutex_unlock(&to_mdev(ibdev)->cap_mask_mutex);
  199         }
  200 
  201         return 0;
  202 }
  203 
  204 static int mthca_modify_port(struct ib_device *ibdev,
  205                              u8 port, int port_modify_mask,
  206                              struct ib_port_modify *props)
  207 {
  208         struct mthca_set_ib_param set_ib;
  209         struct ib_port_attr attr;
  210         int err;
  211 
  212         if (mutex_lock_interruptible(&to_mdev(ibdev)->cap_mask_mutex))
  213                 return -ERESTARTSYS;
  214 
  215         err = mthca_query_port(ibdev, port, &attr);
  216         if (err)
  217                 goto out;
  218 
  219         set_ib.set_si_guid     = 0;
  220         set_ib.reset_qkey_viol = !!(port_modify_mask & IB_PORT_RESET_QKEY_CNTR);
  221 
  222         set_ib.cap_mask = (attr.port_cap_flags | props->set_port_cap_mask) &
  223                 ~props->clr_port_cap_mask;
  224 
  225         err = mthca_SET_IB(to_mdev(ibdev), &set_ib, port);
  226         if (err)
  227                 goto out;
  228 out:
  229         mutex_unlock(&to_mdev(ibdev)->cap_mask_mutex);
  230         return err;
  231 }
  232 
  233 static int mthca_query_pkey(struct ib_device *ibdev,
  234                             u8 port, u16 index, u16 *pkey)
  235 {
  236         struct ib_smp *in_mad  = NULL;
  237         struct ib_smp *out_mad = NULL;
  238         int err = -ENOMEM;
  239 
  240         in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
  241         out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
  242         if (!in_mad || !out_mad)
  243                 goto out;
  244 
  245         init_query_mad(in_mad);
  246         in_mad->attr_id  = IB_SMP_ATTR_PKEY_TABLE;
  247         in_mad->attr_mod = cpu_to_be32(index / 32);
  248 
  249         err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
  250                             port, NULL, NULL, in_mad, out_mad);
  251         if (err)
  252                 goto out;
  253 
  254         *pkey = be16_to_cpu(((__be16 *) out_mad->data)[index % 32]);
  255 
  256  out:
  257         kfree(in_mad);
  258         kfree(out_mad);
  259         return err;
  260 }
  261 
  262 static int mthca_query_gid(struct ib_device *ibdev, u8 port,
  263                            int index, union ib_gid *gid)
  264 {
  265         struct ib_smp *in_mad  = NULL;
  266         struct ib_smp *out_mad = NULL;
  267         int err = -ENOMEM;
  268 
  269         in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
  270         out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
  271         if (!in_mad || !out_mad)
  272                 goto out;
  273 
  274         init_query_mad(in_mad);
  275         in_mad->attr_id  = IB_SMP_ATTR_PORT_INFO;
  276         in_mad->attr_mod = cpu_to_be32(port);
  277 
  278         err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
  279                             port, NULL, NULL, in_mad, out_mad);
  280         if (err)
  281                 goto out;
  282 
  283         memcpy(gid->raw, out_mad->data + 8, 8);
  284 
  285         init_query_mad(in_mad);
  286         in_mad->attr_id  = IB_SMP_ATTR_GUID_INFO;
  287         in_mad->attr_mod = cpu_to_be32(index / 8);
  288 
  289         err = mthca_MAD_IFC(to_mdev(ibdev), 1, 1,
  290                             port, NULL, NULL, in_mad, out_mad);
  291         if (err)
  292                 goto out;
  293 
  294         memcpy(gid->raw + 8, out_mad->data + (index % 8) * 8, 8);
  295 
  296  out:
  297         kfree(in_mad);
  298         kfree(out_mad);
  299         return err;
  300 }
  301 
  302 static int mthca_alloc_ucontext(struct ib_ucontext *uctx,
  303                                 struct ib_udata *udata)
  304 {
  305         struct ib_device *ibdev = uctx->device;
  306         struct mthca_alloc_ucontext_resp uresp = {};
  307         struct mthca_ucontext *context = to_mucontext(uctx);
  308         int                              err;
  309 
  310         if (!(to_mdev(ibdev)->active))
  311                 return -EAGAIN;
  312 
  313         uresp.qp_tab_size = to_mdev(ibdev)->limits.num_qps;
  314         if (mthca_is_memfree(to_mdev(ibdev)))
  315                 uresp.uarc_size = to_mdev(ibdev)->uar_table.uarc_size;
  316         else
  317                 uresp.uarc_size = 0;
  318 
  319         err = mthca_uar_alloc(to_mdev(ibdev), &context->uar);
  320         if (err)
  321                 return err;
  322 
  323         context->db_tab = mthca_init_user_db_tab(to_mdev(ibdev));
  324         if (IS_ERR(context->db_tab)) {
  325                 err = PTR_ERR(context->db_tab);
  326                 mthca_uar_free(to_mdev(ibdev), &context->uar);
  327                 return err;
  328         }
  329 
  330         if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) {
  331                 mthca_cleanup_user_db_tab(to_mdev(ibdev), &context->uar, context->db_tab);
  332                 mthca_uar_free(to_mdev(ibdev), &context->uar);
  333                 return -EFAULT;
  334         }
  335 
  336         context->reg_mr_warned = 0;
  337 
  338         return 0;
  339 }
  340 
  341 static void mthca_dealloc_ucontext(struct ib_ucontext *context)
  342 {
  343         mthca_cleanup_user_db_tab(to_mdev(context->device), &to_mucontext(context)->uar,
  344                                   to_mucontext(context)->db_tab);
  345         mthca_uar_free(to_mdev(context->device), &to_mucontext(context)->uar);
  346 }
  347 
  348 static int mthca_mmap_uar(struct ib_ucontext *context,
  349                           struct vm_area_struct *vma)
  350 {
  351         if (vma->vm_end - vma->vm_start != PAGE_SIZE)
  352                 return -EINVAL;
  353 
  354         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  355 
  356         if (io_remap_pfn_range(vma, vma->vm_start,
  357                                to_mucontext(context)->uar.pfn,
  358                                PAGE_SIZE, vma->vm_page_prot))
  359                 return -EAGAIN;
  360 
  361         return 0;
  362 }
  363 
  364 static int mthca_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
  365 {
  366         struct ib_device *ibdev = ibpd->device;
  367         struct mthca_pd *pd = to_mpd(ibpd);
  368         int err;
  369 
  370         err = mthca_pd_alloc(to_mdev(ibdev), !udata, pd);
  371         if (err)
  372                 return err;
  373 
  374         if (udata) {
  375                 if (ib_copy_to_udata(udata, &pd->pd_num, sizeof (__u32))) {
  376                         mthca_pd_free(to_mdev(ibdev), pd);
  377                         return -EFAULT;
  378                 }
  379         }
  380 
  381         return 0;
  382 }
  383 
  384 static void mthca_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
  385 {
  386         mthca_pd_free(to_mdev(pd->device), to_mpd(pd));
  387 }
  388 
  389 static int mthca_ah_create(struct ib_ah *ibah,
  390                            struct ib_ah_attr *init_attr, u32 flags,
  391                            struct ib_udata *udata)
  392 
  393 {
  394         struct mthca_ah *ah = to_mah(ibah);
  395 
  396         return mthca_create_ah(to_mdev(ibah->device), to_mpd(ibah->pd),
  397                                init_attr, ah);
  398 }
  399 
  400 static void mthca_ah_destroy(struct ib_ah *ah, u32 flags)
  401 {
  402         mthca_destroy_ah(to_mdev(ah->device), to_mah(ah));
  403 }
  404 
  405 static int mthca_create_srq(struct ib_srq *ibsrq,
  406                             struct ib_srq_init_attr *init_attr,
  407                             struct ib_udata *udata)
  408 {
  409         struct mthca_create_srq ucmd;
  410         struct mthca_ucontext *context = rdma_udata_to_drv_context(
  411                 udata, struct mthca_ucontext, ibucontext);
  412         struct mthca_srq *srq = to_msrq(ibsrq);
  413         int err;
  414 
  415         if (init_attr->srq_type != IB_SRQT_BASIC)
  416                 return -EOPNOTSUPP;
  417 
  418         if (udata) {
  419                 if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)))
  420                         return -EFAULT;
  421 
  422                 err = mthca_map_user_db(to_mdev(ibsrq->device), &context->uar,
  423                                         context->db_tab, ucmd.db_index,
  424                                         ucmd.db_page);
  425 
  426                 if (err)
  427                         return err;
  428 
  429                 srq->mr.ibmr.lkey = ucmd.lkey;
  430                 srq->db_index     = ucmd.db_index;
  431         }
  432 
  433         err = mthca_alloc_srq(to_mdev(ibsrq->device), to_mpd(ibsrq->pd),
  434                               &init_attr->attr, srq, udata);
  435 
  436         if (err && udata)
  437                 mthca_unmap_user_db(to_mdev(ibsrq->device), &context->uar,
  438                                     context->db_tab, ucmd.db_index);
  439 
  440         if (err)
  441                 return err;
  442 
  443         if (context && ib_copy_to_udata(udata, &srq->srqn, sizeof(__u32))) {
  444                 mthca_free_srq(to_mdev(ibsrq->device), srq);
  445                 return -EFAULT;
  446         }
  447 
  448         return 0;
  449 }
  450 
  451 static void mthca_destroy_srq(struct ib_srq *srq, struct ib_udata *udata)
  452 {
  453         if (udata) {
  454                 struct mthca_ucontext *context =
  455                         rdma_udata_to_drv_context(
  456                                 udata,
  457                                 struct mthca_ucontext,
  458                                 ibucontext);
  459 
  460                 mthca_unmap_user_db(to_mdev(srq->device), &context->uar,
  461                                     context->db_tab, to_msrq(srq)->db_index);
  462         }
  463 
  464         mthca_free_srq(to_mdev(srq->device), to_msrq(srq));
  465 }
  466 
  467 static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
  468                                      struct ib_qp_init_attr *init_attr,
  469                                      struct ib_udata *udata)
  470 {
  471         struct mthca_ucontext *context = rdma_udata_to_drv_context(
  472                 udata, struct mthca_ucontext, ibucontext);
  473         struct mthca_create_qp ucmd;
  474         struct mthca_qp *qp;
  475         int err;
  476 
  477         if (init_attr->create_flags)
  478                 return ERR_PTR(-EINVAL);
  479 
  480         switch (init_attr->qp_type) {
  481         case IB_QPT_RC:
  482         case IB_QPT_UC:
  483         case IB_QPT_UD:
  484         {
  485                 qp = kzalloc(sizeof(*qp), GFP_KERNEL);
  486                 if (!qp)
  487                         return ERR_PTR(-ENOMEM);
  488 
  489                 if (udata) {
  490                         if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) {
  491                                 kfree(qp);
  492                                 return ERR_PTR(-EFAULT);
  493                         }
  494 
  495                         err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
  496                                                 context->db_tab,
  497                                                 ucmd.sq_db_index, ucmd.sq_db_page);
  498                         if (err) {
  499                                 kfree(qp);
  500                                 return ERR_PTR(err);
  501                         }
  502 
  503                         err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
  504                                                 context->db_tab,
  505                                                 ucmd.rq_db_index, ucmd.rq_db_page);
  506                         if (err) {
  507                                 mthca_unmap_user_db(to_mdev(pd->device),
  508                                                     &context->uar,
  509                                                     context->db_tab,
  510                                                     ucmd.sq_db_index);
  511                                 kfree(qp);
  512                                 return ERR_PTR(err);
  513                         }
  514 
  515                         qp->mr.ibmr.lkey = ucmd.lkey;
  516                         qp->sq.db_index  = ucmd.sq_db_index;
  517                         qp->rq.db_index  = ucmd.rq_db_index;
  518                 }
  519 
  520                 err = mthca_alloc_qp(to_mdev(pd->device), to_mpd(pd),
  521                                      to_mcq(init_attr->send_cq),
  522                                      to_mcq(init_attr->recv_cq),
  523                                      init_attr->qp_type, init_attr->sq_sig_type,
  524                                      &init_attr->cap, qp, udata);
  525 
  526                 if (err && udata) {
  527                         mthca_unmap_user_db(to_mdev(pd->device),
  528                                             &context->uar,
  529                                             context->db_tab,
  530                                             ucmd.sq_db_index);
  531                         mthca_unmap_user_db(to_mdev(pd->device),
  532                                             &context->uar,
  533                                             context->db_tab,
  534                                             ucmd.rq_db_index);
  535                 }
  536 
  537                 qp->ibqp.qp_num = qp->qpn;
  538                 break;
  539         }
  540         case IB_QPT_SMI:
  541         case IB_QPT_GSI:
  542         {
  543                 qp = kzalloc(sizeof(*qp), GFP_KERNEL);
  544                 if (!qp)
  545                         return ERR_PTR(-ENOMEM);
  546 
  547                 qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1;
  548 
  549                 err = mthca_alloc_sqp(to_mdev(pd->device), to_mpd(pd),
  550                                       to_mcq(init_attr->send_cq),
  551                                       to_mcq(init_attr->recv_cq),
  552                                       init_attr->sq_sig_type, &init_attr->cap,
  553                                       qp->ibqp.qp_num, init_attr->port_num,
  554                                       to_msqp(qp), udata);
  555                 break;
  556         }
  557         default:
  558                 /* Don't support raw QPs */
  559                 return ERR_PTR(-ENOSYS);
  560         }
  561 
  562         if (err) {
  563                 kfree(qp);
  564                 return ERR_PTR(err);
  565         }
  566 
  567         init_attr->cap.max_send_wr     = qp->sq.max;
  568         init_attr->cap.max_recv_wr     = qp->rq.max;
  569         init_attr->cap.max_send_sge    = qp->sq.max_gs;
  570         init_attr->cap.max_recv_sge    = qp->rq.max_gs;
  571         init_attr->cap.max_inline_data = qp->max_inline_data;
  572 
  573         return &qp->ibqp;
  574 }
  575 
  576 static int mthca_destroy_qp(struct ib_qp *qp, struct ib_udata *udata)
  577 {
  578         if (udata) {
  579                 struct mthca_ucontext *context =
  580                         rdma_udata_to_drv_context(
  581                                 udata,
  582                                 struct mthca_ucontext,
  583                                 ibucontext);
  584 
  585                 mthca_unmap_user_db(to_mdev(qp->device),
  586                                     &context->uar,
  587                                     context->db_tab,
  588                                     to_mqp(qp)->sq.db_index);
  589                 mthca_unmap_user_db(to_mdev(qp->device),
  590                                     &context->uar,
  591                                     context->db_tab,
  592                                     to_mqp(qp)->rq.db_index);
  593         }
  594         mthca_free_qp(to_mdev(qp->device), to_mqp(qp));
  595         kfree(to_mqp(qp));
  596         return 0;
  597 }
  598 
  599 static int mthca_create_cq(struct ib_cq *ibcq,
  600                            const struct ib_cq_init_attr *attr,
  601                            struct ib_udata *udata)
  602 {
  603         struct ib_device *ibdev = ibcq->device;
  604         int entries = attr->cqe;
  605         struct mthca_create_cq ucmd;
  606         struct mthca_cq *cq;
  607         int nent;
  608         int err;
  609         struct mthca_ucontext *context = rdma_udata_to_drv_context(
  610                 udata, struct mthca_ucontext, ibucontext);
  611 
  612         if (attr->flags)
  613                 return -EOPNOTSUPP;
  614 
  615         if (entries < 1 || entries > to_mdev(ibdev)->limits.max_cqes)
  616                 return -EINVAL;
  617 
  618         if (udata) {
  619                 if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)))
  620                         return -EFAULT;
  621 
  622                 err = mthca_map_user_db(to_mdev(ibdev), &context->uar,
  623                                         context->db_tab, ucmd.set_db_index,
  624                                         ucmd.set_db_page);
  625                 if (err)
  626                         return err;
  627 
  628                 err = mthca_map_user_db(to_mdev(ibdev), &context->uar,
  629                                         context->db_tab, ucmd.arm_db_index,
  630                                         ucmd.arm_db_page);
  631                 if (err)
  632                         goto err_unmap_set;
  633         }
  634 
  635         cq = to_mcq(ibcq);
  636 
  637         if (udata) {
  638                 cq->buf.mr.ibmr.lkey = ucmd.lkey;
  639                 cq->set_ci_db_index  = ucmd.set_db_index;
  640                 cq->arm_db_index     = ucmd.arm_db_index;
  641         }
  642 
  643         for (nent = 1; nent <= entries; nent <<= 1)
  644                 ; /* nothing */
  645 
  646         err = mthca_init_cq(to_mdev(ibdev), nent, context,
  647                             udata ? ucmd.pdn : to_mdev(ibdev)->driver_pd.pd_num,
  648                             cq);
  649         if (err)
  650                 goto err_unmap_arm;
  651 
  652         if (udata && ib_copy_to_udata(udata, &cq->cqn, sizeof(__u32))) {
  653                 mthca_free_cq(to_mdev(ibdev), cq);
  654                 err = -EFAULT;
  655                 goto err_unmap_arm;
  656         }
  657 
  658         cq->resize_buf = NULL;
  659 
  660         return 0;
  661 
  662 err_unmap_arm:
  663         if (udata)
  664                 mthca_unmap_user_db(to_mdev(ibdev), &context->uar,
  665                                     context->db_tab, ucmd.arm_db_index);
  666 
  667 err_unmap_set:
  668         if (udata)
  669                 mthca_unmap_user_db(to_mdev(ibdev), &context->uar,
  670                                     context->db_tab, ucmd.set_db_index);
  671 
  672         return err;
  673 }
  674 
  675 static int mthca_alloc_resize_buf(struct mthca_dev *dev, struct mthca_cq *cq,
  676                                   int entries)
  677 {
  678         int ret;
  679 
  680         spin_lock_irq(&cq->lock);
  681         if (cq->resize_buf) {
  682                 ret = -EBUSY;
  683                 goto unlock;
  684         }
  685 
  686         cq->resize_buf = kmalloc(sizeof *cq->resize_buf, GFP_ATOMIC);
  687         if (!cq->resize_buf) {
  688                 ret = -ENOMEM;
  689                 goto unlock;
  690         }
  691 
  692         cq->resize_buf->state = CQ_RESIZE_ALLOC;
  693 
  694         ret = 0;
  695 
  696 unlock:
  697         spin_unlock_irq(&cq->lock);
  698 
  699         if (ret)
  700                 return ret;
  701 
  702         ret = mthca_alloc_cq_buf(dev, &cq->resize_buf->buf, entries);
  703         if (ret) {
  704                 spin_lock_irq(&cq->lock);
  705                 kfree(cq->resize_buf);
  706                 cq->resize_buf = NULL;
  707                 spin_unlock_irq(&cq->lock);
  708                 return ret;
  709         }
  710 
  711         cq->resize_buf->cqe = entries - 1;
  712 
  713         spin_lock_irq(&cq->lock);
  714         cq->resize_buf->state = CQ_RESIZE_READY;
  715         spin_unlock_irq(&cq->lock);
  716 
  717         return 0;
  718 }
  719 
  720 static int mthca_resize_cq(struct ib_cq *ibcq, int entries, struct ib_udata *udata)
  721 {
  722         struct mthca_dev *dev = to_mdev(ibcq->device);
  723         struct mthca_cq *cq = to_mcq(ibcq);
  724         struct mthca_resize_cq ucmd;
  725         u32 lkey;
  726         int ret;
  727 
  728         if (entries < 1 || entries > dev->limits.max_cqes)
  729                 return -EINVAL;
  730 
  731         mutex_lock(&cq->mutex);
  732 
  733         entries = roundup_pow_of_two(entries + 1);
  734         if (entries == ibcq->cqe + 1) {
  735                 ret = 0;
  736                 goto out;
  737         }
  738 
  739         if (cq->is_kernel) {
  740                 ret = mthca_alloc_resize_buf(dev, cq, entries);
  741                 if (ret)
  742                         goto out;
  743                 lkey = cq->resize_buf->buf.mr.ibmr.lkey;
  744         } else {
  745                 if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) {
  746                         ret = -EFAULT;
  747                         goto out;
  748                 }
  749                 lkey = ucmd.lkey;
  750         }
  751 
  752         ret = mthca_RESIZE_CQ(dev, cq->cqn, lkey, ilog2(entries));
  753 
  754         if (ret) {
  755                 if (cq->resize_buf) {
  756                         mthca_free_cq_buf(dev, &cq->resize_buf->buf,
  757                                           cq->resize_buf->cqe);
  758                         kfree(cq->resize_buf);
  759                         spin_lock_irq(&cq->lock);
  760                         cq->resize_buf = NULL;
  761                         spin_unlock_irq(&cq->lock);
  762                 }
  763                 goto out;
  764         }
  765 
  766         if (cq->is_kernel) {
  767                 struct mthca_cq_buf tbuf;
  768                 int tcqe;
  769 
  770                 spin_lock_irq(&cq->lock);
  771                 if (cq->resize_buf->state == CQ_RESIZE_READY) {
  772                         mthca_cq_resize_copy_cqes(cq);
  773                         tbuf         = cq->buf;
  774                         tcqe         = cq->ibcq.cqe;
  775                         cq->buf      = cq->resize_buf->buf;
  776                         cq->ibcq.cqe = cq->resize_buf->cqe;
  777                 } else {
  778                         tbuf = cq->resize_buf->buf;
  779                         tcqe = cq->resize_buf->cqe;
  780                 }
  781 
  782                 kfree(cq->resize_buf);
  783                 cq->resize_buf = NULL;
  784                 spin_unlock_irq(&cq->lock);
  785 
  786                 mthca_free_cq_buf(dev, &tbuf, tcqe);
  787         } else
  788                 ibcq->cqe = entries - 1;
  789 
  790 out:
  791         mutex_unlock(&cq->mutex);
  792 
  793         return ret;
  794 }
  795 
  796 static void mthca_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
  797 {
  798         if (udata) {
  799                 struct mthca_ucontext *context =
  800                         rdma_udata_to_drv_context(
  801                                 udata,
  802                                 struct mthca_ucontext,
  803                                 ibucontext);
  804 
  805                 mthca_unmap_user_db(to_mdev(cq->device),
  806                                     &context->uar,
  807                                     context->db_tab,
  808                                     to_mcq(cq)->arm_db_index);
  809                 mthca_unmap_user_db(to_mdev(cq->device),
  810                                     &context->uar,
  811                                     context->db_tab,
  812                                     to_mcq(cq)->set_ci_db_index);
  813         }
  814         mthca_free_cq(to_mdev(cq->device), to_mcq(cq));
  815 }
  816 
  817 static inline u32 convert_access(int acc)
  818 {
  819         return (acc & IB_ACCESS_REMOTE_ATOMIC ? MTHCA_MPT_FLAG_ATOMIC       : 0) |
  820                (acc & IB_ACCESS_REMOTE_WRITE  ? MTHCA_MPT_FLAG_REMOTE_WRITE : 0) |
  821                (acc & IB_ACCESS_REMOTE_READ   ? MTHCA_MPT_FLAG_REMOTE_READ  : 0) |
  822                (acc & IB_ACCESS_LOCAL_WRITE   ? MTHCA_MPT_FLAG_LOCAL_WRITE  : 0) |
  823                MTHCA_MPT_FLAG_LOCAL_READ;
  824 }
  825 
  826 static struct ib_mr *mthca_get_dma_mr(struct ib_pd *pd, int acc)
  827 {
  828         struct mthca_mr *mr;
  829         int err;
  830 
  831         mr = kmalloc(sizeof *mr, GFP_KERNEL);
  832         if (!mr)
  833                 return ERR_PTR(-ENOMEM);
  834 
  835         err = mthca_mr_alloc_notrans(to_mdev(pd->device),
  836                                      to_mpd(pd)->pd_num,
  837                                      convert_access(acc), mr);
  838 
  839         if (err) {
  840                 kfree(mr);
  841                 return ERR_PTR(err);
  842         }
  843 
  844         mr->umem = NULL;
  845 
  846         return &mr->ibmr;
  847 }
  848 
  849 static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
  850                                        u64 virt, int acc, struct ib_udata *udata)
  851 {
  852         struct mthca_dev *dev = to_mdev(pd->device);
  853         struct scatterlist *sg;
  854         struct mthca_mr *mr;
  855         struct mthca_reg_mr ucmd;
  856         u64 *pages;
  857         int shift, n, len;
  858         int i, k, entry;
  859         int err = 0;
  860         int write_mtt_size;
  861 
  862         if (udata->inlen - sizeof (struct ib_uverbs_cmd_hdr) < sizeof ucmd) {
  863                 if (!to_mucontext(pd->uobject->context)->reg_mr_warned) {
  864                         mthca_warn(dev, "Process '%s' did not pass in MR attrs.\n",
  865                                    current->comm);
  866                         mthca_warn(dev, "  Update libmthca to fix this.\n");
  867                 }
  868                 ++to_mucontext(pd->uobject->context)->reg_mr_warned;
  869                 ucmd.mr_attrs = 0;
  870         } else if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
  871                 return ERR_PTR(-EFAULT);
  872 
  873         mr = kmalloc(sizeof *mr, GFP_KERNEL);
  874         if (!mr)
  875                 return ERR_PTR(-ENOMEM);
  876 
  877         mr->umem = ib_umem_get(pd->uobject->context, start, length, acc,
  878                                ucmd.mr_attrs & MTHCA_MR_DMASYNC);
  879 
  880         if (IS_ERR(mr->umem)) {
  881                 err = PTR_ERR(mr->umem);
  882                 goto err;
  883         }
  884 
  885         shift = ffs(mr->umem->page_size) - 1;
  886         n = mr->umem->nmap;
  887 
  888         mr->mtt = mthca_alloc_mtt(dev, n);
  889         if (IS_ERR(mr->mtt)) {
  890                 err = PTR_ERR(mr->mtt);
  891                 goto err_umem;
  892         }
  893 
  894         pages = (u64 *) __get_free_page(GFP_KERNEL);
  895         if (!pages) {
  896                 err = -ENOMEM;
  897                 goto err_mtt;
  898         }
  899 
  900         i = n = 0;
  901 
  902         write_mtt_size = min(mthca_write_mtt_size(dev), (int) (PAGE_SIZE / sizeof *pages));
  903 
  904         for_each_sg(mr->umem->sg_head.sgl, sg, mr->umem->nmap, entry) {
  905                 len = sg_dma_len(sg) >> shift;
  906                 for (k = 0; k < len; ++k) {
  907                         pages[i++] = sg_dma_address(sg) +
  908                                 mr->umem->page_size * k;
  909                         /*
  910                          * Be friendly to write_mtt and pass it chunks
  911                          * of appropriate size.
  912                          */
  913                         if (i == write_mtt_size) {
  914                                 err = mthca_write_mtt(dev, mr->mtt, n, pages, i);
  915                                 if (err)
  916                                         goto mtt_done;
  917                                 n += i;
  918                                 i = 0;
  919                         }
  920                 }
  921         }
  922 
  923         if (i)
  924                 err = mthca_write_mtt(dev, mr->mtt, n, pages, i);
  925 mtt_done:
  926         free_page((unsigned long) pages);
  927         if (err)
  928                 goto err_mtt;
  929 
  930         err = mthca_mr_alloc(dev, to_mpd(pd)->pd_num, shift, virt, length,
  931                              convert_access(acc), mr);
  932 
  933         if (err)
  934                 goto err_mtt;
  935 
  936         return &mr->ibmr;
  937 
  938 err_mtt:
  939         mthca_free_mtt(dev, mr->mtt);
  940 
  941 err_umem:
  942         ib_umem_release(mr->umem);
  943 
  944 err:
  945         kfree(mr);
  946         return ERR_PTR(err);
  947 }
  948 
  949 static int mthca_dereg_mr(struct ib_mr *mr, struct ib_udata *udata)
  950 {
  951         struct mthca_mr *mmr = to_mmr(mr);
  952 
  953         mthca_free_mr(to_mdev(mr->device), mmr);
  954         ib_umem_release(mmr->umem);
  955         kfree(mmr);
  956 
  957         return 0;
  958 }
  959 
  960 static struct ib_fmr *mthca_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
  961                                       struct ib_fmr_attr *fmr_attr)
  962 {
  963         struct mthca_fmr *fmr;
  964         int err;
  965 
  966         fmr = kmalloc(sizeof *fmr, GFP_KERNEL);
  967         if (!fmr)
  968                 return ERR_PTR(-ENOMEM);
  969 
  970         memcpy(&fmr->attr, fmr_attr, sizeof *fmr_attr);
  971         err = mthca_fmr_alloc(to_mdev(pd->device), to_mpd(pd)->pd_num,
  972                              convert_access(mr_access_flags), fmr);
  973 
  974         if (err) {
  975                 kfree(fmr);
  976                 return ERR_PTR(err);
  977         }
  978 
  979         return &fmr->ibmr;
  980 }
  981 
  982 static int mthca_dealloc_fmr(struct ib_fmr *fmr)
  983 {
  984         struct mthca_fmr *mfmr = to_mfmr(fmr);
  985         int err;
  986 
  987         err = mthca_free_fmr(to_mdev(fmr->device), mfmr);
  988         if (err)
  989                 return err;
  990 
  991         kfree(mfmr);
  992         return 0;
  993 }
  994 
  995 static int mthca_unmap_fmr(struct list_head *fmr_list)
  996 {
  997         struct ib_fmr *fmr;
  998         int err;
  999         struct mthca_dev *mdev = NULL;
 1000 
 1001         list_for_each_entry(fmr, fmr_list, list) {
 1002                 if (mdev && to_mdev(fmr->device) != mdev)
 1003                         return -EINVAL;
 1004                 mdev = to_mdev(fmr->device);
 1005         }
 1006 
 1007         if (!mdev)
 1008                 return 0;
 1009 
 1010         if (mthca_is_memfree(mdev)) {
 1011                 list_for_each_entry(fmr, fmr_list, list)
 1012                         mthca_arbel_fmr_unmap(mdev, to_mfmr(fmr));
 1013 
 1014                 wmb();
 1015         } else
 1016                 list_for_each_entry(fmr, fmr_list, list)
 1017                         mthca_tavor_fmr_unmap(mdev, to_mfmr(fmr));
 1018 
 1019         err = mthca_SYNC_TPT(mdev);
 1020         return err;
 1021 }
 1022 
 1023 static ssize_t show_rev(struct device *device, struct device_attribute *attr,
 1024                         char *buf)
 1025 {
 1026         struct mthca_dev *dev =
 1027                 container_of(device, struct mthca_dev, ib_dev.dev);
 1028         return sprintf(buf, "%x\n", dev->rev_id);
 1029 }
 1030 
 1031 static ssize_t show_hca(struct device *device, struct device_attribute *attr,
 1032                         char *buf)
 1033 {
 1034         struct mthca_dev *dev =
 1035                 container_of(device, struct mthca_dev, ib_dev.dev);
 1036         switch (dev->pdev->device) {
 1037         case PCI_DEVICE_ID_MELLANOX_TAVOR:
 1038                 return sprintf(buf, "MT23108\n");
 1039         case PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT:
 1040                 return sprintf(buf, "MT25208 (MT23108 compat mode)\n");
 1041         case PCI_DEVICE_ID_MELLANOX_ARBEL:
 1042                 return sprintf(buf, "MT25208\n");
 1043         case PCI_DEVICE_ID_MELLANOX_SINAI:
 1044         case PCI_DEVICE_ID_MELLANOX_SINAI_OLD:
 1045                 return sprintf(buf, "MT25204\n");
 1046         default:
 1047                 return sprintf(buf, "unknown\n");
 1048         }
 1049 }
 1050 
 1051 static ssize_t show_board(struct device *device, struct device_attribute *attr,
 1052                           char *buf)
 1053 {
 1054         struct mthca_dev *dev =
 1055                 container_of(device, struct mthca_dev, ib_dev.dev);
 1056         return sprintf(buf, "%.*s\n", MTHCA_BOARD_ID_LEN, dev->board_id);
 1057 }
 1058 
 1059 static DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
 1060 static DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
 1061 static DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
 1062 
 1063 static struct device_attribute *mthca_dev_attributes[] = {
 1064         &dev_attr_hw_rev,
 1065         &dev_attr_hca_type,
 1066         &dev_attr_board_id
 1067 };
 1068 
 1069 static int mthca_init_node_data(struct mthca_dev *dev)
 1070 {
 1071         struct ib_smp *in_mad  = NULL;
 1072         struct ib_smp *out_mad = NULL;
 1073         int err = -ENOMEM;
 1074 
 1075         in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
 1076         out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
 1077         if (!in_mad || !out_mad)
 1078                 goto out;
 1079 
 1080         init_query_mad(in_mad);
 1081         in_mad->attr_id = IB_SMP_ATTR_NODE_DESC;
 1082 
 1083         err = mthca_MAD_IFC(dev, 1, 1,
 1084                             1, NULL, NULL, in_mad, out_mad);
 1085         if (err)
 1086                 goto out;
 1087 
 1088         memcpy(dev->ib_dev.node_desc, out_mad->data, IB_DEVICE_NODE_DESC_MAX);
 1089 
 1090         in_mad->attr_id = IB_SMP_ATTR_NODE_INFO;
 1091 
 1092         err = mthca_MAD_IFC(dev, 1, 1,
 1093                             1, NULL, NULL, in_mad, out_mad);
 1094         if (err)
 1095                 goto out;
 1096 
 1097         if (mthca_is_memfree(dev))
 1098                 dev->rev_id = be32_to_cpup((__be32 *) (out_mad->data + 32));
 1099         memcpy(&dev->ib_dev.node_guid, out_mad->data + 12, 8);
 1100 
 1101 out:
 1102         kfree(in_mad);
 1103         kfree(out_mad);
 1104         return err;
 1105 }
 1106 
 1107 static int mthca_port_immutable(struct ib_device *ibdev, u8 port_num,
 1108                                 struct ib_port_immutable *immutable)
 1109 {
 1110         struct ib_port_attr attr;
 1111         int err;
 1112 
 1113         err = mthca_query_port(ibdev, port_num, &attr);
 1114         if (err)
 1115                 return err;
 1116 
 1117         immutable->pkey_tbl_len = attr.pkey_tbl_len;
 1118         immutable->gid_tbl_len = attr.gid_tbl_len;
 1119         immutable->core_cap_flags = RDMA_CORE_PORT_IBA_IB;
 1120         immutable->max_mad_size = IB_MGMT_MAD_SIZE;
 1121 
 1122         return 0;
 1123 }
 1124 
 1125 static void get_dev_fw_str(struct ib_device *device, char *str,
 1126                            size_t str_len)
 1127 {
 1128         struct mthca_dev *dev =
 1129                 container_of(device, struct mthca_dev, ib_dev);
 1130         snprintf(str, str_len, "%d.%d.%d",
 1131                  (int) (dev->fw_ver >> 32),
 1132                  (int) (dev->fw_ver >> 16) & 0xffff,
 1133                  (int) dev->fw_ver & 0xffff);
 1134 }
 1135 
 1136 int mthca_register_device(struct mthca_dev *dev)
 1137 {
 1138         int ret;
 1139         int i;
 1140 
 1141         ret = mthca_init_node_data(dev);
 1142         if (ret)
 1143                 return ret;
 1144 
 1145 #define mthca_ib_ah mthca_ah
 1146 #define mthca_ib_cq mthca_cq
 1147 #define mthca_ib_pd mthca_pd
 1148 #define mthca_ib_qp mthca_qp
 1149 #define mthca_ib_srq mthca_srq
 1150 #define mthca_ib_ucontext mthca_ucontext
 1151         INIT_IB_DEVICE_OPS(&dev->ib_dev.ops, mthca, MTHCA);
 1152         strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX);
 1153         dev->ib_dev.owner                = THIS_MODULE;
 1154 
 1155         dev->ib_dev.uverbs_abi_ver       = MTHCA_UVERBS_ABI_VERSION;
 1156         dev->ib_dev.uverbs_cmd_mask      =
 1157                 (1ull << IB_USER_VERBS_CMD_GET_CONTEXT)         |
 1158                 (1ull << IB_USER_VERBS_CMD_QUERY_DEVICE)        |
 1159                 (1ull << IB_USER_VERBS_CMD_QUERY_PORT)          |
 1160                 (1ull << IB_USER_VERBS_CMD_ALLOC_PD)            |
 1161                 (1ull << IB_USER_VERBS_CMD_DEALLOC_PD)          |
 1162                 (1ull << IB_USER_VERBS_CMD_REG_MR)              |
 1163                 (1ull << IB_USER_VERBS_CMD_DEREG_MR)            |
 1164                 (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
 1165                 (1ull << IB_USER_VERBS_CMD_CREATE_CQ)           |
 1166                 (1ull << IB_USER_VERBS_CMD_RESIZE_CQ)           |
 1167                 (1ull << IB_USER_VERBS_CMD_DESTROY_CQ)          |
 1168                 (1ull << IB_USER_VERBS_CMD_CREATE_QP)           |
 1169                 (1ull << IB_USER_VERBS_CMD_QUERY_QP)            |
 1170                 (1ull << IB_USER_VERBS_CMD_MODIFY_QP)           |
 1171                 (1ull << IB_USER_VERBS_CMD_DESTROY_QP)          |
 1172                 (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST)        |
 1173                 (1ull << IB_USER_VERBS_CMD_DETACH_MCAST);
 1174         dev->ib_dev.node_type            = RDMA_NODE_IB_CA;
 1175         dev->ib_dev.phys_port_cnt        = dev->limits.num_ports;
 1176         dev->ib_dev.num_comp_vectors     = 1;
 1177         dev->ib_dev.dma_device           = &dev->pdev->dev;
 1178         dev->ib_dev.query_device         = mthca_query_device;
 1179         dev->ib_dev.query_port           = mthca_query_port;
 1180         dev->ib_dev.modify_device        = mthca_modify_device;
 1181         dev->ib_dev.modify_port          = mthca_modify_port;
 1182         dev->ib_dev.query_pkey           = mthca_query_pkey;
 1183         dev->ib_dev.query_gid            = mthca_query_gid;
 1184         dev->ib_dev.alloc_ucontext       = mthca_alloc_ucontext;
 1185         dev->ib_dev.dealloc_ucontext     = mthca_dealloc_ucontext;
 1186         dev->ib_dev.mmap                 = mthca_mmap_uar;
 1187         dev->ib_dev.alloc_pd             = mthca_alloc_pd;
 1188         dev->ib_dev.dealloc_pd           = mthca_dealloc_pd;
 1189         dev->ib_dev.create_ah            = mthca_ah_create;
 1190         dev->ib_dev.query_ah             = mthca_ah_query;
 1191         dev->ib_dev.destroy_ah           = mthca_ah_destroy;
 1192 
 1193         if (dev->mthca_flags & MTHCA_FLAG_SRQ) {
 1194                 dev->ib_dev.create_srq           = mthca_create_srq;
 1195                 dev->ib_dev.modify_srq           = mthca_modify_srq;
 1196                 dev->ib_dev.query_srq            = mthca_query_srq;
 1197                 dev->ib_dev.destroy_srq          = mthca_destroy_srq;
 1198                 dev->ib_dev.uverbs_cmd_mask     |=
 1199                         (1ull << IB_USER_VERBS_CMD_CREATE_SRQ)          |
 1200                         (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ)          |
 1201                         (1ull << IB_USER_VERBS_CMD_QUERY_SRQ)           |
 1202                         (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
 1203 
 1204                 if (mthca_is_memfree(dev))
 1205                         dev->ib_dev.post_srq_recv = mthca_arbel_post_srq_recv;
 1206                 else
 1207                         dev->ib_dev.post_srq_recv = mthca_tavor_post_srq_recv;
 1208         }
 1209 
 1210         dev->ib_dev.create_qp            = mthca_create_qp;
 1211         dev->ib_dev.modify_qp            = mthca_modify_qp;
 1212         dev->ib_dev.query_qp             = mthca_query_qp;
 1213         dev->ib_dev.destroy_qp           = mthca_destroy_qp;
 1214         dev->ib_dev.create_cq            = mthca_create_cq;
 1215         dev->ib_dev.resize_cq            = mthca_resize_cq;
 1216         dev->ib_dev.destroy_cq           = mthca_destroy_cq;
 1217         dev->ib_dev.poll_cq              = mthca_poll_cq;
 1218         dev->ib_dev.get_dma_mr           = mthca_get_dma_mr;
 1219         dev->ib_dev.reg_user_mr          = mthca_reg_user_mr;
 1220         dev->ib_dev.dereg_mr             = mthca_dereg_mr;
 1221         dev->ib_dev.get_port_immutable   = mthca_port_immutable;
 1222         dev->ib_dev.get_dev_fw_str       = get_dev_fw_str;
 1223 
 1224         if (dev->mthca_flags & MTHCA_FLAG_FMR) {
 1225                 dev->ib_dev.alloc_fmr            = mthca_alloc_fmr;
 1226                 dev->ib_dev.unmap_fmr            = mthca_unmap_fmr;
 1227                 dev->ib_dev.dealloc_fmr          = mthca_dealloc_fmr;
 1228                 if (mthca_is_memfree(dev))
 1229                         dev->ib_dev.map_phys_fmr = mthca_arbel_map_phys_fmr;
 1230                 else
 1231                         dev->ib_dev.map_phys_fmr = mthca_tavor_map_phys_fmr;
 1232         }
 1233 
 1234         dev->ib_dev.attach_mcast         = mthca_multicast_attach;
 1235         dev->ib_dev.detach_mcast         = mthca_multicast_detach;
 1236         dev->ib_dev.process_mad          = mthca_process_mad;
 1237 
 1238         if (mthca_is_memfree(dev)) {
 1239                 dev->ib_dev.req_notify_cq = mthca_arbel_arm_cq;
 1240                 dev->ib_dev.post_send     = mthca_arbel_post_send;
 1241                 dev->ib_dev.post_recv     = mthca_arbel_post_receive;
 1242         } else {
 1243                 dev->ib_dev.req_notify_cq = mthca_tavor_arm_cq;
 1244                 dev->ib_dev.post_send     = mthca_tavor_post_send;
 1245                 dev->ib_dev.post_recv     = mthca_tavor_post_receive;
 1246         }
 1247 
 1248         mutex_init(&dev->cap_mask_mutex);
 1249 
 1250         ret = ib_register_device(&dev->ib_dev, NULL);
 1251         if (ret)
 1252                 return ret;
 1253 
 1254         for (i = 0; i < ARRAY_SIZE(mthca_dev_attributes); ++i) {
 1255                 ret = device_create_file(&dev->ib_dev.dev,
 1256                                          mthca_dev_attributes[i]);
 1257                 if (ret) {
 1258                         ib_unregister_device(&dev->ib_dev);
 1259                         return ret;
 1260                 }
 1261         }
 1262 
 1263         mthca_start_catas_poll(dev);
 1264 
 1265         return 0;
 1266 }
 1267 
 1268 void mthca_unregister_device(struct mthca_dev *dev)
 1269 {
 1270         mthca_stop_catas_poll(dev);
 1271         ib_unregister_device(&dev->ib_dev);
 1272 }

Cache object: d3dd848021223e81773ff9777a26cfb9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.