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