linux/drivers/infiniband/core/verbs.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
   3 * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
   4 * Copyright (c) 2004 Intel Corporation.  All rights reserved.
   5 * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
   6 * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
   7 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
   8 * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
   9 *
  10 * This software is available to you under a choice of one of two
  11 * licenses.  You may choose to be licensed under the terms of the GNU
  12 * General Public License (GPL) Version 2, available from the file
  13 * COPYING in the main directory of this source tree, or the
  14 * OpenIB.org BSD license below:
  15 *
  16 *     Redistribution and use in source and binary forms, with or
  17 *     without modification, are permitted provided that the following
  18 *     conditions are met:
  19 *
  20 *      - Redistributions of source code must retain the above
  21 *        copyright notice, this list of conditions and the following
  22 *        disclaimer.
  23 *
  24 *      - Redistributions in binary form must reproduce the above
  25 *        copyright notice, this list of conditions and the following
  26 *        disclaimer in the documentation and/or other materials
  27 *        provided with the distribution.
  28 *
  29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  30 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  32 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  33 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  34 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  35 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  36 * SOFTWARE.
  37 */
  38
  39#include <linux/errno.h>
  40#include <linux/err.h>
  41#include <linux/export.h>
  42#include <linux/string.h>
  43#include <linux/slab.h>
  44
  45#include <rdma/ib_verbs.h>
  46#include <rdma/ib_cache.h>
  47#include <rdma/ib_addr.h>
  48
  49#include "core_priv.h"
  50
  51int ib_rate_to_mult(enum ib_rate rate)
  52{
  53        switch (rate) {
  54        case IB_RATE_2_5_GBPS: return  1;
  55        case IB_RATE_5_GBPS:   return  2;
  56        case IB_RATE_10_GBPS:  return  4;
  57        case IB_RATE_20_GBPS:  return  8;
  58        case IB_RATE_30_GBPS:  return 12;
  59        case IB_RATE_40_GBPS:  return 16;
  60        case IB_RATE_60_GBPS:  return 24;
  61        case IB_RATE_80_GBPS:  return 32;
  62        case IB_RATE_120_GBPS: return 48;
  63        default:               return -1;
  64        }
  65}
  66EXPORT_SYMBOL(ib_rate_to_mult);
  67
  68enum ib_rate mult_to_ib_rate(int mult)
  69{
  70        switch (mult) {
  71        case 1:  return IB_RATE_2_5_GBPS;
  72        case 2:  return IB_RATE_5_GBPS;
  73        case 4:  return IB_RATE_10_GBPS;
  74        case 8:  return IB_RATE_20_GBPS;
  75        case 12: return IB_RATE_30_GBPS;
  76        case 16: return IB_RATE_40_GBPS;
  77        case 24: return IB_RATE_60_GBPS;
  78        case 32: return IB_RATE_80_GBPS;
  79        case 48: return IB_RATE_120_GBPS;
  80        default: return IB_RATE_PORT_CURRENT;
  81        }
  82}
  83EXPORT_SYMBOL(mult_to_ib_rate);
  84
  85int ib_rate_to_mbps(enum ib_rate rate)
  86{
  87        switch (rate) {
  88        case IB_RATE_2_5_GBPS: return 2500;
  89        case IB_RATE_5_GBPS:   return 5000;
  90        case IB_RATE_10_GBPS:  return 10000;
  91        case IB_RATE_20_GBPS:  return 20000;
  92        case IB_RATE_30_GBPS:  return 30000;
  93        case IB_RATE_40_GBPS:  return 40000;
  94        case IB_RATE_60_GBPS:  return 60000;
  95        case IB_RATE_80_GBPS:  return 80000;
  96        case IB_RATE_120_GBPS: return 120000;
  97        case IB_RATE_14_GBPS:  return 14062;
  98        case IB_RATE_56_GBPS:  return 56250;
  99        case IB_RATE_112_GBPS: return 112500;
 100        case IB_RATE_168_GBPS: return 168750;
 101        case IB_RATE_25_GBPS:  return 25781;
 102        case IB_RATE_100_GBPS: return 103125;
 103        case IB_RATE_200_GBPS: return 206250;
 104        case IB_RATE_300_GBPS: return 309375;
 105        default:               return -1;
 106        }
 107}
 108EXPORT_SYMBOL(ib_rate_to_mbps);
 109
 110enum rdma_transport_type
 111rdma_node_get_transport(enum rdma_node_type node_type)
 112{
 113        switch (node_type) {
 114        case RDMA_NODE_IB_CA:
 115        case RDMA_NODE_IB_SWITCH:
 116        case RDMA_NODE_IB_ROUTER:
 117                return RDMA_TRANSPORT_IB;
 118        case RDMA_NODE_RNIC:
 119                return RDMA_TRANSPORT_IWARP;
 120        case RDMA_NODE_USNIC:
 121                return RDMA_TRANSPORT_USNIC;
 122        case RDMA_NODE_USNIC_UDP:
 123                return RDMA_TRANSPORT_USNIC_UDP;
 124        default:
 125                BUG();
 126                return 0;
 127        }
 128}
 129EXPORT_SYMBOL(rdma_node_get_transport);
 130
 131enum rdma_link_layer rdma_port_get_link_layer(struct ib_device *device, u8 port_num)
 132{
 133        if (device->get_link_layer)
 134                return device->get_link_layer(device, port_num);
 135
 136        switch (rdma_node_get_transport(device->node_type)) {
 137        case RDMA_TRANSPORT_IB:
 138                return IB_LINK_LAYER_INFINIBAND;
 139        case RDMA_TRANSPORT_IWARP:
 140        case RDMA_TRANSPORT_USNIC:
 141        case RDMA_TRANSPORT_USNIC_UDP:
 142                return IB_LINK_LAYER_ETHERNET;
 143        default:
 144                return IB_LINK_LAYER_UNSPECIFIED;
 145        }
 146}
 147EXPORT_SYMBOL(rdma_port_get_link_layer);
 148
 149/* Protection domains */
 150
 151struct ib_pd *ib_alloc_pd(struct ib_device *device)
 152{
 153        struct ib_pd *pd;
 154
 155        pd = device->alloc_pd(device, NULL, NULL);
 156
 157        if (!IS_ERR(pd)) {
 158                pd->device  = device;
 159                pd->uobject = NULL;
 160                atomic_set(&pd->usecnt, 0);
 161        }
 162
 163        return pd;
 164}
 165EXPORT_SYMBOL(ib_alloc_pd);
 166
 167int ib_dealloc_pd(struct ib_pd *pd)
 168{
 169        if (atomic_read(&pd->usecnt))
 170                return -EBUSY;
 171
 172        return pd->device->dealloc_pd(pd);
 173}
 174EXPORT_SYMBOL(ib_dealloc_pd);
 175
 176/* Address handles */
 177
 178struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
 179{
 180        struct ib_ah *ah;
 181
 182        ah = pd->device->create_ah(pd, ah_attr);
 183
 184        if (!IS_ERR(ah)) {
 185                ah->device  = pd->device;
 186                ah->pd      = pd;
 187                ah->uobject = NULL;
 188                atomic_inc(&pd->usecnt);
 189        }
 190
 191        return ah;
 192}
 193EXPORT_SYMBOL(ib_create_ah);
 194
 195int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
 196                       struct ib_grh *grh, struct ib_ah_attr *ah_attr)
 197{
 198        u32 flow_class;
 199        u16 gid_index;
 200        int ret;
 201        int is_eth = (rdma_port_get_link_layer(device, port_num) ==
 202                        IB_LINK_LAYER_ETHERNET);
 203
 204        memset(ah_attr, 0, sizeof *ah_attr);
 205        if (is_eth) {
 206                if (!(wc->wc_flags & IB_WC_GRH))
 207                        return -EPROTOTYPE;
 208
 209                if (wc->wc_flags & IB_WC_WITH_SMAC &&
 210                    wc->wc_flags & IB_WC_WITH_VLAN) {
 211                        memcpy(ah_attr->dmac, wc->smac, ETH_ALEN);
 212                        ah_attr->vlan_id = wc->vlan_id;
 213                } else {
 214                        ret = rdma_addr_find_dmac_by_grh(&grh->dgid, &grh->sgid,
 215                                        ah_attr->dmac, &ah_attr->vlan_id);
 216                        if (ret)
 217                                return ret;
 218                }
 219        } else {
 220                ah_attr->vlan_id = 0xffff;
 221        }
 222
 223        ah_attr->dlid = wc->slid;
 224        ah_attr->sl = wc->sl;
 225        ah_attr->src_path_bits = wc->dlid_path_bits;
 226        ah_attr->port_num = port_num;
 227
 228        if (wc->wc_flags & IB_WC_GRH) {
 229                ah_attr->ah_flags = IB_AH_GRH;
 230                ah_attr->grh.dgid = grh->sgid;
 231
 232                ret = ib_find_cached_gid(device, &grh->dgid, &port_num,
 233                                         &gid_index);
 234                if (ret)
 235                        return ret;
 236
 237                ah_attr->grh.sgid_index = (u8) gid_index;
 238                flow_class = be32_to_cpu(grh->version_tclass_flow);
 239                ah_attr->grh.flow_label = flow_class & 0xFFFFF;
 240                ah_attr->grh.hop_limit = 0xFF;
 241                ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
 242        }
 243        return 0;
 244}
 245EXPORT_SYMBOL(ib_init_ah_from_wc);
 246
 247struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc,
 248                                   struct ib_grh *grh, u8 port_num)
 249{
 250        struct ib_ah_attr ah_attr;
 251        int ret;
 252
 253        ret = ib_init_ah_from_wc(pd->device, port_num, wc, grh, &ah_attr);
 254        if (ret)
 255                return ERR_PTR(ret);
 256
 257        return ib_create_ah(pd, &ah_attr);
 258}
 259EXPORT_SYMBOL(ib_create_ah_from_wc);
 260
 261int ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
 262{
 263        return ah->device->modify_ah ?
 264                ah->device->modify_ah(ah, ah_attr) :
 265                -ENOSYS;
 266}
 267EXPORT_SYMBOL(ib_modify_ah);
 268
 269int ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
 270{
 271        return ah->device->query_ah ?
 272                ah->device->query_ah(ah, ah_attr) :
 273                -ENOSYS;
 274}
 275EXPORT_SYMBOL(ib_query_ah);
 276
 277int ib_destroy_ah(struct ib_ah *ah)
 278{
 279        struct ib_pd *pd;
 280        int ret;
 281
 282        pd = ah->pd;
 283        ret = ah->device->destroy_ah(ah);
 284        if (!ret)
 285                atomic_dec(&pd->usecnt);
 286
 287        return ret;
 288}
 289EXPORT_SYMBOL(ib_destroy_ah);
 290
 291/* Shared receive queues */
 292
 293struct ib_srq *ib_create_srq(struct ib_pd *pd,
 294                             struct ib_srq_init_attr *srq_init_attr)
 295{
 296        struct ib_srq *srq;
 297
 298        if (!pd->device->create_srq)
 299                return ERR_PTR(-ENOSYS);
 300
 301        srq = pd->device->create_srq(pd, srq_init_attr, NULL);
 302
 303        if (!IS_ERR(srq)) {
 304                srq->device        = pd->device;
 305                srq->pd            = pd;
 306                srq->uobject       = NULL;
 307                srq->event_handler = srq_init_attr->event_handler;
 308                srq->srq_context   = srq_init_attr->srq_context;
 309                srq->srq_type      = srq_init_attr->srq_type;
 310                if (srq->srq_type == IB_SRQT_XRC) {
 311                        srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd;
 312                        srq->ext.xrc.cq   = srq_init_attr->ext.xrc.cq;
 313                        atomic_inc(&srq->ext.xrc.xrcd->usecnt);
 314                        atomic_inc(&srq->ext.xrc.cq->usecnt);
 315                }
 316                atomic_inc(&pd->usecnt);
 317                atomic_set(&srq->usecnt, 0);
 318        }
 319
 320        return srq;
 321}
 322EXPORT_SYMBOL(ib_create_srq);
 323
 324int ib_modify_srq(struct ib_srq *srq,
 325                  struct ib_srq_attr *srq_attr,
 326                  enum ib_srq_attr_mask srq_attr_mask)
 327{
 328        return srq->device->modify_srq ?
 329                srq->device->modify_srq(srq, srq_attr, srq_attr_mask, NULL) :
 330                -ENOSYS;
 331}
 332EXPORT_SYMBOL(ib_modify_srq);
 333
 334int ib_query_srq(struct ib_srq *srq,
 335                 struct ib_srq_attr *srq_attr)
 336{
 337        return srq->device->query_srq ?
 338                srq->device->query_srq(srq, srq_attr) : -ENOSYS;
 339}
 340EXPORT_SYMBOL(ib_query_srq);
 341
 342int ib_destroy_srq(struct ib_srq *srq)
 343{
 344        struct ib_pd *pd;
 345        enum ib_srq_type srq_type;
 346        struct ib_xrcd *uninitialized_var(xrcd);
 347        struct ib_cq *uninitialized_var(cq);
 348        int ret;
 349
 350        if (atomic_read(&srq->usecnt))
 351                return -EBUSY;
 352
 353        pd = srq->pd;
 354        srq_type = srq->srq_type;
 355        if (srq_type == IB_SRQT_XRC) {
 356                xrcd = srq->ext.xrc.xrcd;
 357                cq = srq->ext.xrc.cq;
 358        }
 359
 360        ret = srq->device->destroy_srq(srq);
 361        if (!ret) {
 362                atomic_dec(&pd->usecnt);
 363                if (srq_type == IB_SRQT_XRC) {
 364                        atomic_dec(&xrcd->usecnt);
 365                        atomic_dec(&cq->usecnt);
 366                }
 367        }
 368
 369        return ret;
 370}
 371EXPORT_SYMBOL(ib_destroy_srq);
 372
 373/* Queue pairs */
 374
 375static void __ib_shared_qp_event_handler(struct ib_event *event, void *context)
 376{
 377        struct ib_qp *qp = context;
 378        unsigned long flags;
 379
 380        spin_lock_irqsave(&qp->device->event_handler_lock, flags);
 381        list_for_each_entry(event->element.qp, &qp->open_list, open_list)
 382                if (event->element.qp->event_handler)
 383                        event->element.qp->event_handler(event, event->element.qp->qp_context);
 384        spin_unlock_irqrestore(&qp->device->event_handler_lock, flags);
 385}
 386
 387static void __ib_insert_xrcd_qp(struct ib_xrcd *xrcd, struct ib_qp *qp)
 388{
 389        mutex_lock(&xrcd->tgt_qp_mutex);
 390        list_add(&qp->xrcd_list, &xrcd->tgt_qp_list);
 391        mutex_unlock(&xrcd->tgt_qp_mutex);
 392}
 393
 394static struct ib_qp *__ib_open_qp(struct ib_qp *real_qp,
 395                                  void (*event_handler)(struct ib_event *, void *),
 396                                  void *qp_context)
 397{
 398        struct ib_qp *qp;
 399        unsigned long flags;
 400
 401        qp = kzalloc(sizeof *qp, GFP_KERNEL);
 402        if (!qp)
 403                return ERR_PTR(-ENOMEM);
 404
 405        qp->real_qp = real_qp;
 406        atomic_inc(&real_qp->usecnt);
 407        qp->device = real_qp->device;
 408        qp->event_handler = event_handler;
 409        qp->qp_context = qp_context;
 410        qp->qp_num = real_qp->qp_num;
 411        qp->qp_type = real_qp->qp_type;
 412
 413        spin_lock_irqsave(&real_qp->device->event_handler_lock, flags);
 414        list_add(&qp->open_list, &real_qp->open_list);
 415        spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags);
 416
 417        return qp;
 418}
 419
 420struct ib_qp *ib_open_qp(struct ib_xrcd *xrcd,
 421                         struct ib_qp_open_attr *qp_open_attr)
 422{
 423        struct ib_qp *qp, *real_qp;
 424
 425        if (qp_open_attr->qp_type != IB_QPT_XRC_TGT)
 426                return ERR_PTR(-EINVAL);
 427
 428        qp = ERR_PTR(-EINVAL);
 429        mutex_lock(&xrcd->tgt_qp_mutex);
 430        list_for_each_entry(real_qp, &xrcd->tgt_qp_list, xrcd_list) {
 431                if (real_qp->qp_num == qp_open_attr->qp_num) {
 432                        qp = __ib_open_qp(real_qp, qp_open_attr->event_handler,
 433                                          qp_open_attr->qp_context);
 434                        break;
 435                }
 436        }
 437        mutex_unlock(&xrcd->tgt_qp_mutex);
 438        return qp;
 439}
 440EXPORT_SYMBOL(ib_open_qp);
 441
 442struct ib_qp *ib_create_qp(struct ib_pd *pd,
 443                           struct ib_qp_init_attr *qp_init_attr)
 444{
 445        struct ib_qp *qp, *real_qp;
 446        struct ib_device *device;
 447
 448        device = pd ? pd->device : qp_init_attr->xrcd->device;
 449        qp = device->create_qp(pd, qp_init_attr, NULL);
 450
 451        if (!IS_ERR(qp)) {
 452                qp->device     = device;
 453                qp->real_qp    = qp;
 454                qp->uobject    = NULL;
 455                qp->qp_type    = qp_init_attr->qp_type;
 456
 457                atomic_set(&qp->usecnt, 0);
 458                if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {
 459                        qp->event_handler = __ib_shared_qp_event_handler;
 460                        qp->qp_context = qp;
 461                        qp->pd = NULL;
 462                        qp->send_cq = qp->recv_cq = NULL;
 463                        qp->srq = NULL;
 464                        qp->xrcd = qp_init_attr->xrcd;
 465                        atomic_inc(&qp_init_attr->xrcd->usecnt);
 466                        INIT_LIST_HEAD(&qp->open_list);
 467
 468                        real_qp = qp;
 469                        qp = __ib_open_qp(real_qp, qp_init_attr->event_handler,
 470                                          qp_init_attr->qp_context);
 471                        if (!IS_ERR(qp))
 472                                __ib_insert_xrcd_qp(qp_init_attr->xrcd, real_qp);
 473                        else
 474                                real_qp->device->destroy_qp(real_qp);
 475                } else {
 476                        qp->event_handler = qp_init_attr->event_handler;
 477                        qp->qp_context = qp_init_attr->qp_context;
 478                        if (qp_init_attr->qp_type == IB_QPT_XRC_INI) {
 479                                qp->recv_cq = NULL;
 480                                qp->srq = NULL;
 481                        } else {
 482                                qp->recv_cq = qp_init_attr->recv_cq;
 483                                atomic_inc(&qp_init_attr->recv_cq->usecnt);
 484                                qp->srq = qp_init_attr->srq;
 485                                if (qp->srq)
 486                                        atomic_inc(&qp_init_attr->srq->usecnt);
 487                        }
 488
 489                        qp->pd      = pd;
 490                        qp->send_cq = qp_init_attr->send_cq;
 491                        qp->xrcd    = NULL;
 492
 493                        atomic_inc(&pd->usecnt);
 494                        atomic_inc(&qp_init_attr->send_cq->usecnt);
 495                }
 496        }
 497
 498        return qp;
 499}
 500EXPORT_SYMBOL(ib_create_qp);
 501
 502static const struct {
 503        int                     valid;
 504        enum ib_qp_attr_mask    req_param[IB_QPT_MAX];
 505        enum ib_qp_attr_mask    req_param_add_eth[IB_QPT_MAX];
 506        enum ib_qp_attr_mask    opt_param[IB_QPT_MAX];
 507        enum ib_qp_attr_mask    opt_param_add_eth[IB_QPT_MAX];
 508} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
 509        [IB_QPS_RESET] = {
 510                [IB_QPS_RESET] = { .valid = 1 },
 511                [IB_QPS_INIT]  = {
 512                        .valid = 1,
 513                        .req_param = {
 514                                [IB_QPT_UD]  = (IB_QP_PKEY_INDEX                |
 515                                                IB_QP_PORT                      |
 516                                                IB_QP_QKEY),
 517                                [IB_QPT_RAW_PACKET] = IB_QP_PORT,
 518                                [IB_QPT_UC]  = (IB_QP_PKEY_INDEX                |
 519                                                IB_QP_PORT                      |
 520                                                IB_QP_ACCESS_FLAGS),
 521                                [IB_QPT_RC]  = (IB_QP_PKEY_INDEX                |
 522                                                IB_QP_PORT                      |
 523                                                IB_QP_ACCESS_FLAGS),
 524                                [IB_QPT_XRC_INI] = (IB_QP_PKEY_INDEX            |
 525                                                IB_QP_PORT                      |
 526                                                IB_QP_ACCESS_FLAGS),
 527                                [IB_QPT_XRC_TGT] = (IB_QP_PKEY_INDEX            |
 528                                                IB_QP_PORT                      |
 529                                                IB_QP_ACCESS_FLAGS),
 530                                [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                |
 531                                                IB_QP_QKEY),
 532                                [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                |
 533                                                IB_QP_QKEY),
 534                        }
 535                },
 536        },
 537        [IB_QPS_INIT]  = {
 538                [IB_QPS_RESET] = { .valid = 1 },
 539                [IB_QPS_ERR] =   { .valid = 1 },
 540                [IB_QPS_INIT]  = {
 541                        .valid = 1,
 542                        .opt_param = {
 543                                [IB_QPT_UD]  = (IB_QP_PKEY_INDEX                |
 544                                                IB_QP_PORT                      |
 545                                                IB_QP_QKEY),
 546                                [IB_QPT_UC]  = (IB_QP_PKEY_INDEX                |
 547                                                IB_QP_PORT                      |
 548                                                IB_QP_ACCESS_FLAGS),
 549                                [IB_QPT_RC]  = (IB_QP_PKEY_INDEX                |
 550                                                IB_QP_PORT                      |
 551                                                IB_QP_ACCESS_FLAGS),
 552                                [IB_QPT_XRC_INI] = (IB_QP_PKEY_INDEX            |
 553                                                IB_QP_PORT                      |
 554                                                IB_QP_ACCESS_FLAGS),
 555                                [IB_QPT_XRC_TGT] = (IB_QP_PKEY_INDEX            |
 556                                                IB_QP_PORT                      |
 557                                                IB_QP_ACCESS_FLAGS),
 558                                [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                |
 559                                                IB_QP_QKEY),
 560                                [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                |
 561                                                IB_QP_QKEY),
 562                        }
 563                },
 564                [IB_QPS_RTR]   = {
 565                        .valid = 1,
 566                        .req_param = {
 567                                [IB_QPT_UC]  = (IB_QP_AV                        |
 568                                                IB_QP_PATH_MTU                  |
 569                                                IB_QP_DEST_QPN                  |
 570                                                IB_QP_RQ_PSN),
 571                                [IB_QPT_RC]  = (IB_QP_AV                        |
 572                                                IB_QP_PATH_MTU                  |
 573                                                IB_QP_DEST_QPN                  |
 574                                                IB_QP_RQ_PSN                    |
 575                                                IB_QP_MAX_DEST_RD_ATOMIC        |
 576                                                IB_QP_MIN_RNR_TIMER),
 577                                [IB_QPT_XRC_INI] = (IB_QP_AV                    |
 578                                                IB_QP_PATH_MTU                  |
 579                                                IB_QP_DEST_QPN                  |
 580                                                IB_QP_RQ_PSN),
 581                                [IB_QPT_XRC_TGT] = (IB_QP_AV                    |
 582                                                IB_QP_PATH_MTU                  |
 583                                                IB_QP_DEST_QPN                  |
 584                                                IB_QP_RQ_PSN                    |
 585                                                IB_QP_MAX_DEST_RD_ATOMIC        |
 586                                                IB_QP_MIN_RNR_TIMER),
 587                        },
 588                        .req_param_add_eth = {
 589                                [IB_QPT_RC]  = (IB_QP_SMAC),
 590                                [IB_QPT_UC]  = (IB_QP_SMAC),
 591                                [IB_QPT_XRC_INI]  = (IB_QP_SMAC),
 592                                [IB_QPT_XRC_TGT]  = (IB_QP_SMAC)
 593                        },
 594                        .opt_param = {
 595                                 [IB_QPT_UD]  = (IB_QP_PKEY_INDEX               |
 596                                                 IB_QP_QKEY),
 597                                 [IB_QPT_UC]  = (IB_QP_ALT_PATH                 |
 598                                                 IB_QP_ACCESS_FLAGS             |
 599                                                 IB_QP_PKEY_INDEX),
 600                                 [IB_QPT_RC]  = (IB_QP_ALT_PATH                 |
 601                                                 IB_QP_ACCESS_FLAGS             |
 602                                                 IB_QP_PKEY_INDEX),
 603                                 [IB_QPT_XRC_INI] = (IB_QP_ALT_PATH             |
 604                                                 IB_QP_ACCESS_FLAGS             |
 605                                                 IB_QP_PKEY_INDEX),
 606                                 [IB_QPT_XRC_TGT] = (IB_QP_ALT_PATH             |
 607                                                 IB_QP_ACCESS_FLAGS             |
 608                                                 IB_QP_PKEY_INDEX),
 609                                 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX               |
 610                                                 IB_QP_QKEY),
 611                                 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX               |
 612                                                 IB_QP_QKEY),
 613                         },
 614                        .opt_param_add_eth = {
 615                                [IB_QPT_RC]  = (IB_QP_ALT_SMAC                  |
 616                                                IB_QP_VID                       |
 617                                                IB_QP_ALT_VID),
 618                                [IB_QPT_UC]  = (IB_QP_ALT_SMAC                  |
 619                                                IB_QP_VID                       |
 620                                                IB_QP_ALT_VID),
 621                                [IB_QPT_XRC_INI]  = (IB_QP_ALT_SMAC                     |
 622                                                IB_QP_VID                       |
 623                                                IB_QP_ALT_VID),
 624                                [IB_QPT_XRC_TGT]  = (IB_QP_ALT_SMAC                     |
 625                                                IB_QP_VID                       |
 626                                                IB_QP_ALT_VID)
 627                        }
 628                }
 629        },
 630        [IB_QPS_RTR]   = {
 631                [IB_QPS_RESET] = { .valid = 1 },
 632                [IB_QPS_ERR] =   { .valid = 1 },
 633                [IB_QPS_RTS]   = {
 634                        .valid = 1,
 635                        .req_param = {
 636                                [IB_QPT_UD]  = IB_QP_SQ_PSN,
 637                                [IB_QPT_UC]  = IB_QP_SQ_PSN,
 638                                [IB_QPT_RC]  = (IB_QP_TIMEOUT                   |
 639                                                IB_QP_RETRY_CNT                 |
 640                                                IB_QP_RNR_RETRY                 |
 641                                                IB_QP_SQ_PSN                    |
 642                                                IB_QP_MAX_QP_RD_ATOMIC),
 643                                [IB_QPT_XRC_INI] = (IB_QP_TIMEOUT               |
 644                                                IB_QP_RETRY_CNT                 |
 645                                                IB_QP_RNR_RETRY                 |
 646                                                IB_QP_SQ_PSN                    |
 647                                                IB_QP_MAX_QP_RD_ATOMIC),
 648                                [IB_QPT_XRC_TGT] = (IB_QP_TIMEOUT               |
 649                                                IB_QP_SQ_PSN),
 650                                [IB_QPT_SMI] = IB_QP_SQ_PSN,
 651                                [IB_QPT_GSI] = IB_QP_SQ_PSN,
 652                        },
 653                        .opt_param = {
 654                                 [IB_QPT_UD]  = (IB_QP_CUR_STATE                |
 655                                                 IB_QP_QKEY),
 656                                 [IB_QPT_UC]  = (IB_QP_CUR_STATE                |
 657                                                 IB_QP_ALT_PATH                 |
 658                                                 IB_QP_ACCESS_FLAGS             |
 659                                                 IB_QP_PATH_MIG_STATE),
 660                                 [IB_QPT_RC]  = (IB_QP_CUR_STATE                |
 661                                                 IB_QP_ALT_PATH                 |
 662                                                 IB_QP_ACCESS_FLAGS             |
 663                                                 IB_QP_MIN_RNR_TIMER            |
 664                                                 IB_QP_PATH_MIG_STATE),
 665                                 [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE            |
 666                                                 IB_QP_ALT_PATH                 |
 667                                                 IB_QP_ACCESS_FLAGS             |
 668                                                 IB_QP_PATH_MIG_STATE),
 669                                 [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE            |
 670                                                 IB_QP_ALT_PATH                 |
 671                                                 IB_QP_ACCESS_FLAGS             |
 672                                                 IB_QP_MIN_RNR_TIMER            |
 673                                                 IB_QP_PATH_MIG_STATE),
 674                                 [IB_QPT_SMI] = (IB_QP_CUR_STATE                |
 675                                                 IB_QP_QKEY),
 676                                 [IB_QPT_GSI] = (IB_QP_CUR_STATE                |
 677                                                 IB_QP_QKEY),
 678                         }
 679                }
 680        },
 681        [IB_QPS_RTS]   = {
 682                [IB_QPS_RESET] = { .valid = 1 },
 683                [IB_QPS_ERR] =   { .valid = 1 },
 684                [IB_QPS_RTS]   = {
 685                        .valid = 1,
 686                        .opt_param = {
 687                                [IB_QPT_UD]  = (IB_QP_CUR_STATE                 |
 688                                                IB_QP_QKEY),
 689                                [IB_QPT_UC]  = (IB_QP_CUR_STATE                 |
 690                                                IB_QP_ACCESS_FLAGS              |
 691                                                IB_QP_ALT_PATH                  |
 692                                                IB_QP_PATH_MIG_STATE),
 693                                [IB_QPT_RC]  = (IB_QP_CUR_STATE                 |
 694                                                IB_QP_ACCESS_FLAGS              |
 695                                                IB_QP_ALT_PATH                  |
 696                                                IB_QP_PATH_MIG_STATE            |
 697                                                IB_QP_MIN_RNR_TIMER),
 698                                [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE             |
 699                                                IB_QP_ACCESS_FLAGS              |
 700                                                IB_QP_ALT_PATH                  |
 701                                                IB_QP_PATH_MIG_STATE),
 702                                [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE             |
 703                                                IB_QP_ACCESS_FLAGS              |
 704                                                IB_QP_ALT_PATH                  |
 705                                                IB_QP_PATH_MIG_STATE            |
 706                                                IB_QP_MIN_RNR_TIMER),
 707                                [IB_QPT_SMI] = (IB_QP_CUR_STATE                 |
 708                                                IB_QP_QKEY),
 709                                [IB_QPT_GSI] = (IB_QP_CUR_STATE                 |
 710                                                IB_QP_QKEY),
 711                        }
 712                },
 713                [IB_QPS_SQD]   = {
 714                        .valid = 1,
 715                        .opt_param = {
 716                                [IB_QPT_UD]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
 717                                [IB_QPT_UC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
 718                                [IB_QPT_RC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
 719                                [IB_QPT_XRC_INI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
 720                                [IB_QPT_XRC_TGT] = IB_QP_EN_SQD_ASYNC_NOTIFY, /* ??? */
 721                                [IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
 722                                [IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY
 723                        }
 724                },
 725        },
 726        [IB_QPS_SQD]   = {
 727                [IB_QPS_RESET] = { .valid = 1 },
 728                [IB_QPS_ERR] =   { .valid = 1 },
 729                [IB_QPS_RTS]   = {
 730                        .valid = 1,
 731                        .opt_param = {
 732                                [IB_QPT_UD]  = (IB_QP_CUR_STATE                 |
 733                                                IB_QP_QKEY),
 734                                [IB_QPT_UC]  = (IB_QP_CUR_STATE                 |
 735                                                IB_QP_ALT_PATH                  |
 736                                                IB_QP_ACCESS_FLAGS              |
 737                                                IB_QP_PATH_MIG_STATE),
 738                                [IB_QPT_RC]  = (IB_QP_CUR_STATE                 |
 739                                                IB_QP_ALT_PATH                  |
 740                                                IB_QP_ACCESS_FLAGS              |
 741                                                IB_QP_MIN_RNR_TIMER             |
 742                                                IB_QP_PATH_MIG_STATE),
 743                                [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE             |
 744                                                IB_QP_ALT_PATH                  |
 745                                                IB_QP_ACCESS_FLAGS              |
 746                                                IB_QP_PATH_MIG_STATE),
 747                                [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE             |
 748                                                IB_QP_ALT_PATH                  |
 749                                                IB_QP_ACCESS_FLAGS              |
 750                                                IB_QP_MIN_RNR_TIMER             |
 751                                                IB_QP_PATH_MIG_STATE),
 752                                [IB_QPT_SMI] = (IB_QP_CUR_STATE                 |
 753                                                IB_QP_QKEY),
 754                                [IB_QPT_GSI] = (IB_QP_CUR_STATE                 |
 755                                                IB_QP_QKEY),
 756                        }
 757                },
 758                [IB_QPS_SQD]   = {
 759                        .valid = 1,
 760                        .opt_param = {
 761                                [IB_QPT_UD]  = (IB_QP_PKEY_INDEX                |
 762                                                IB_QP_QKEY),
 763                                [IB_QPT_UC]  = (IB_QP_AV                        |
 764                                                IB_QP_ALT_PATH                  |
 765                                                IB_QP_ACCESS_FLAGS              |
 766                                                IB_QP_PKEY_INDEX                |
 767                                                IB_QP_PATH_MIG_STATE),
 768                                [IB_QPT_RC]  = (IB_QP_PORT                      |
 769                                                IB_QP_AV                        |
 770                                                IB_QP_TIMEOUT                   |
 771                                                IB_QP_RETRY_CNT                 |
 772                                                IB_QP_RNR_RETRY                 |
 773                                                IB_QP_MAX_QP_RD_ATOMIC          |
 774                                                IB_QP_MAX_DEST_RD_ATOMIC        |
 775                                                IB_QP_ALT_PATH                  |
 776                                                IB_QP_ACCESS_FLAGS              |
 777                                                IB_QP_PKEY_INDEX                |
 778                                                IB_QP_MIN_RNR_TIMER             |
 779                                                IB_QP_PATH_MIG_STATE),
 780                                [IB_QPT_XRC_INI] = (IB_QP_PORT                  |
 781                                                IB_QP_AV                        |
 782                                                IB_QP_TIMEOUT                   |
 783                                                IB_QP_RETRY_CNT                 |
 784                                                IB_QP_RNR_RETRY                 |
 785                                                IB_QP_MAX_QP_RD_ATOMIC          |
 786                                                IB_QP_ALT_PATH                  |
 787                                                IB_QP_ACCESS_FLAGS              |
 788                                                IB_QP_PKEY_INDEX                |
 789                                                IB_QP_PATH_MIG_STATE),
 790                                [IB_QPT_XRC_TGT] = (IB_QP_PORT                  |
 791                                                IB_QP_AV                        |
 792                                                IB_QP_TIMEOUT                   |
 793                                                IB_QP_MAX_DEST_RD_ATOMIC        |
 794                                                IB_QP_ALT_PATH                  |
 795                                                IB_QP_ACCESS_FLAGS              |
 796                                                IB_QP_PKEY_INDEX                |
 797                                                IB_QP_MIN_RNR_TIMER             |
 798                                                IB_QP_PATH_MIG_STATE),
 799                                [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                |
 800                                                IB_QP_QKEY),
 801                                [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                |
 802                                                IB_QP_QKEY),
 803                        }
 804                }
 805        },
 806        [IB_QPS_SQE]   = {
 807                [IB_QPS_RESET] = { .valid = 1 },
 808                [IB_QPS_ERR] =   { .valid = 1 },
 809                [IB_QPS_RTS]   = {
 810                        .valid = 1,
 811                        .opt_param = {
 812                                [IB_QPT_UD]  = (IB_QP_CUR_STATE                 |
 813                                                IB_QP_QKEY),
 814                                [IB_QPT_UC]  = (IB_QP_CUR_STATE                 |
 815                                                IB_QP_ACCESS_FLAGS),
 816                                [IB_QPT_SMI] = (IB_QP_CUR_STATE                 |
 817                                                IB_QP_QKEY),
 818                                [IB_QPT_GSI] = (IB_QP_CUR_STATE                 |
 819                                                IB_QP_QKEY),
 820                        }
 821                }
 822        },
 823        [IB_QPS_ERR] = {
 824                [IB_QPS_RESET] = { .valid = 1 },
 825                [IB_QPS_ERR] =   { .valid = 1 }
 826        }
 827};
 828
 829int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
 830                       enum ib_qp_type type, enum ib_qp_attr_mask mask,
 831                       enum rdma_link_layer ll)
 832{
 833        enum ib_qp_attr_mask req_param, opt_param;
 834
 835        if (cur_state  < 0 || cur_state  > IB_QPS_ERR ||
 836            next_state < 0 || next_state > IB_QPS_ERR)
 837                return 0;
 838
 839        if (mask & IB_QP_CUR_STATE  &&
 840            cur_state != IB_QPS_RTR && cur_state != IB_QPS_RTS &&
 841            cur_state != IB_QPS_SQD && cur_state != IB_QPS_SQE)
 842                return 0;
 843
 844        if (!qp_state_table[cur_state][next_state].valid)
 845                return 0;
 846
 847        req_param = qp_state_table[cur_state][next_state].req_param[type];
 848        opt_param = qp_state_table[cur_state][next_state].opt_param[type];
 849
 850        if (ll == IB_LINK_LAYER_ETHERNET) {
 851                req_param |= qp_state_table[cur_state][next_state].
 852                        req_param_add_eth[type];
 853                opt_param |= qp_state_table[cur_state][next_state].
 854                        opt_param_add_eth[type];
 855        }
 856
 857        if ((mask & req_param) != req_param)
 858                return 0;
 859
 860        if (mask & ~(req_param | opt_param | IB_QP_STATE))
 861                return 0;
 862
 863        return 1;
 864}
 865EXPORT_SYMBOL(ib_modify_qp_is_ok);
 866
 867int ib_resolve_eth_l2_attrs(struct ib_qp *qp,
 868                            struct ib_qp_attr *qp_attr, int *qp_attr_mask)
 869{
 870        int           ret = 0;
 871        union ib_gid  sgid;
 872
 873        if ((*qp_attr_mask & IB_QP_AV)  &&
 874            (rdma_port_get_link_layer(qp->device, qp_attr->ah_attr.port_num) == IB_LINK_LAYER_ETHERNET)) {
 875                ret = ib_query_gid(qp->device, qp_attr->ah_attr.port_num,
 876                                   qp_attr->ah_attr.grh.sgid_index, &sgid);
 877                if (ret)
 878                        goto out;
 879                if (rdma_link_local_addr((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw)) {
 880                        rdma_get_ll_mac((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw, qp_attr->ah_attr.dmac);
 881                        rdma_get_ll_mac((struct in6_addr *)sgid.raw, qp_attr->smac);
 882                        qp_attr->vlan_id = rdma_get_vlan_id(&sgid);
 883                } else {
 884                        ret = rdma_addr_find_dmac_by_grh(&sgid, &qp_attr->ah_attr.grh.dgid,
 885                                        qp_attr->ah_attr.dmac, &qp_attr->vlan_id);
 886                        if (ret)
 887                                goto out;
 888                        ret = rdma_addr_find_smac_by_sgid(&sgid, qp_attr->smac, NULL);
 889                        if (ret)
 890                                goto out;
 891                }
 892                *qp_attr_mask |= IB_QP_SMAC;
 893                if (qp_attr->vlan_id < 0xFFFF)
 894                        *qp_attr_mask |= IB_QP_VID;
 895        }
 896out:
 897        return ret;
 898}
 899EXPORT_SYMBOL(ib_resolve_eth_l2_attrs);
 900
 901
 902int ib_modify_qp(struct ib_qp *qp,
 903                 struct ib_qp_attr *qp_attr,
 904                 int qp_attr_mask)
 905{
 906        int ret;
 907
 908        ret = ib_resolve_eth_l2_attrs(qp, qp_attr, &qp_attr_mask);
 909        if (ret)
 910                return ret;
 911
 912        return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
 913}
 914EXPORT_SYMBOL(ib_modify_qp);
 915
 916int ib_query_qp(struct ib_qp *qp,
 917                struct ib_qp_attr *qp_attr,
 918                int qp_attr_mask,
 919                struct ib_qp_init_attr *qp_init_attr)
 920{
 921        return qp->device->query_qp ?
 922                qp->device->query_qp(qp->real_qp, qp_attr, qp_attr_mask, qp_init_attr) :
 923                -ENOSYS;
 924}
 925EXPORT_SYMBOL(ib_query_qp);
 926
 927int ib_close_qp(struct ib_qp *qp)
 928{
 929        struct ib_qp *real_qp;
 930        unsigned long flags;
 931
 932        real_qp = qp->real_qp;
 933        if (real_qp == qp)
 934                return -EINVAL;
 935
 936        spin_lock_irqsave(&real_qp->device->event_handler_lock, flags);
 937        list_del(&qp->open_list);
 938        spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags);
 939
 940        atomic_dec(&real_qp->usecnt);
 941        kfree(qp);
 942
 943        return 0;
 944}
 945EXPORT_SYMBOL(ib_close_qp);
 946
 947static int __ib_destroy_shared_qp(struct ib_qp *qp)
 948{
 949        struct ib_xrcd *xrcd;
 950        struct ib_qp *real_qp;
 951        int ret;
 952
 953        real_qp = qp->real_qp;
 954        xrcd = real_qp->xrcd;
 955
 956        mutex_lock(&xrcd->tgt_qp_mutex);
 957        ib_close_qp(qp);
 958        if (atomic_read(&real_qp->usecnt) == 0)
 959                list_del(&real_qp->xrcd_list);
 960        else
 961                real_qp = NULL;
 962        mutex_unlock(&xrcd->tgt_qp_mutex);
 963
 964        if (real_qp) {
 965                ret = ib_destroy_qp(real_qp);
 966                if (!ret)
 967                        atomic_dec(&xrcd->usecnt);
 968                else
 969                        __ib_insert_xrcd_qp(xrcd, real_qp);
 970        }
 971
 972        return 0;
 973}
 974
 975int ib_destroy_qp(struct ib_qp *qp)
 976{
 977        struct ib_pd *pd;
 978        struct ib_cq *scq, *rcq;
 979        struct ib_srq *srq;
 980        int ret;
 981
 982        if (atomic_read(&qp->usecnt))
 983                return -EBUSY;
 984
 985        if (qp->real_qp != qp)
 986                return __ib_destroy_shared_qp(qp);
 987
 988        pd   = qp->pd;
 989        scq  = qp->send_cq;
 990        rcq  = qp->recv_cq;
 991        srq  = qp->srq;
 992
 993        ret = qp->device->destroy_qp(qp);
 994        if (!ret) {
 995                if (pd)
 996                        atomic_dec(&pd->usecnt);
 997                if (scq)
 998                        atomic_dec(&scq->usecnt);
 999                if (rcq)
1000                        atomic_dec(&rcq->usecnt);
1001                if (srq)
1002                        atomic_dec(&srq->usecnt);
1003        }
1004
1005        return ret;
1006}
1007EXPORT_SYMBOL(ib_destroy_qp);
1008
1009/* Completion queues */
1010
1011struct ib_cq *ib_create_cq(struct ib_device *device,
1012                           ib_comp_handler comp_handler,
1013                           void (*event_handler)(struct ib_event *, void *),
1014                           void *cq_context, int cqe, int comp_vector)
1015{
1016        struct ib_cq *cq;
1017
1018        cq = device->create_cq(device, cqe, comp_vector, NULL, NULL);
1019
1020        if (!IS_ERR(cq)) {
1021                cq->device        = device;
1022                cq->uobject       = NULL;
1023                cq->comp_handler  = comp_handler;
1024                cq->event_handler = event_handler;
1025                cq->cq_context    = cq_context;
1026                atomic_set(&cq->usecnt, 0);
1027        }
1028
1029        return cq;
1030}
1031EXPORT_SYMBOL(ib_create_cq);
1032
1033int ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
1034{
1035        return cq->device->modify_cq ?
1036                cq->device->modify_cq(cq, cq_count, cq_period) : -ENOSYS;
1037}
1038EXPORT_SYMBOL(ib_modify_cq);
1039
1040int ib_destroy_cq(struct ib_cq *cq)
1041{
1042        if (atomic_read(&cq->usecnt))
1043                return -EBUSY;
1044
1045        return cq->device->destroy_cq(cq);
1046}
1047EXPORT_SYMBOL(ib_destroy_cq);
1048
1049int ib_resize_cq(struct ib_cq *cq, int cqe)
1050{
1051        return cq->device->resize_cq ?
1052                cq->device->resize_cq(cq, cqe, NULL) : -ENOSYS;
1053}
1054EXPORT_SYMBOL(ib_resize_cq);
1055
1056/* Memory regions */
1057
1058struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
1059{
1060        struct ib_mr *mr;
1061        int err;
1062
1063        err = ib_check_mr_access(mr_access_flags);
1064        if (err)
1065                return ERR_PTR(err);
1066
1067        mr = pd->device->get_dma_mr(pd, mr_access_flags);
1068
1069        if (!IS_ERR(mr)) {
1070                mr->device  = pd->device;
1071                mr->pd      = pd;
1072                mr->uobject = NULL;
1073                atomic_inc(&pd->usecnt);
1074                atomic_set(&mr->usecnt, 0);
1075        }
1076
1077        return mr;
1078}
1079EXPORT_SYMBOL(ib_get_dma_mr);
1080
1081struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
1082                             struct ib_phys_buf *phys_buf_array,
1083                             int num_phys_buf,
1084                             int mr_access_flags,
1085                             u64 *iova_start)
1086{
1087        struct ib_mr *mr;
1088        int err;
1089
1090        err = ib_check_mr_access(mr_access_flags);
1091        if (err)
1092                return ERR_PTR(err);
1093
1094        if (!pd->device->reg_phys_mr)
1095                return ERR_PTR(-ENOSYS);
1096
1097        mr = pd->device->reg_phys_mr(pd, phys_buf_array, num_phys_buf,
1098                                     mr_access_flags, iova_start);
1099
1100        if (!IS_ERR(mr)) {
1101                mr->device  = pd->device;
1102                mr->pd      = pd;
1103                mr->uobject = NULL;
1104                atomic_inc(&pd->usecnt);
1105                atomic_set(&mr->usecnt, 0);
1106        }
1107
1108        return mr;
1109}
1110EXPORT_SYMBOL(ib_reg_phys_mr);
1111
1112int ib_rereg_phys_mr(struct ib_mr *mr,
1113                     int mr_rereg_mask,
1114                     struct ib_pd *pd,
1115                     struct ib_phys_buf *phys_buf_array,
1116                     int num_phys_buf,
1117                     int mr_access_flags,
1118                     u64 *iova_start)
1119{
1120        struct ib_pd *old_pd;
1121        int ret;
1122
1123        ret = ib_check_mr_access(mr_access_flags);
1124        if (ret)
1125                return ret;
1126
1127        if (!mr->device->rereg_phys_mr)
1128                return -ENOSYS;
1129
1130        if (atomic_read(&mr->usecnt))
1131                return -EBUSY;
1132
1133        old_pd = mr->pd;
1134
1135        ret = mr->device->rereg_phys_mr(mr, mr_rereg_mask, pd,
1136                                        phys_buf_array, num_phys_buf,
1137                                        mr_access_flags, iova_start);
1138
1139        if (!ret && (mr_rereg_mask & IB_MR_REREG_PD)) {
1140                atomic_dec(&old_pd->usecnt);
1141                atomic_inc(&pd->usecnt);
1142        }
1143
1144        return ret;
1145}
1146EXPORT_SYMBOL(ib_rereg_phys_mr);
1147
1148int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
1149{
1150        return mr->device->query_mr ?
1151                mr->device->query_mr(mr, mr_attr) : -ENOSYS;
1152}
1153EXPORT_SYMBOL(ib_query_mr);
1154
1155int ib_dereg_mr(struct ib_mr *mr)
1156{
1157        struct ib_pd *pd;
1158        int ret;
1159
1160        if (atomic_read(&mr->usecnt))
1161                return -EBUSY;
1162
1163        pd = mr->pd;
1164        ret = mr->device->dereg_mr(mr);
1165        if (!ret)
1166                atomic_dec(&pd->usecnt);
1167
1168        return ret;
1169}
1170EXPORT_SYMBOL(ib_dereg_mr);
1171
1172struct ib_mr *ib_alloc_fast_reg_mr(struct ib_pd *pd, int max_page_list_len)
1173{
1174        struct ib_mr *mr;
1175
1176        if (!pd->device->alloc_fast_reg_mr)
1177                return ERR_PTR(-ENOSYS);
1178
1179        mr = pd->device->alloc_fast_reg_mr(pd, max_page_list_len);
1180
1181        if (!IS_ERR(mr)) {
1182                mr->device  = pd->device;
1183                mr->pd      = pd;
1184                mr->uobject = NULL;
1185                atomic_inc(&pd->usecnt);
1186                atomic_set(&mr->usecnt, 0);
1187        }
1188
1189        return mr;
1190}
1191EXPORT_SYMBOL(ib_alloc_fast_reg_mr);
1192
1193struct ib_fast_reg_page_list *ib_alloc_fast_reg_page_list(struct ib_device *device,
1194                                                          int max_page_list_len)
1195{
1196        struct ib_fast_reg_page_list *page_list;
1197
1198        if (!device->alloc_fast_reg_page_list)
1199                return ERR_PTR(-ENOSYS);
1200
1201        page_list = device->alloc_fast_reg_page_list(device, max_page_list_len);
1202
1203        if (!IS_ERR(page_list)) {
1204                page_list->device = device;
1205                page_list->max_page_list_len = max_page_list_len;
1206        }
1207
1208        return page_list;
1209}
1210EXPORT_SYMBOL(ib_alloc_fast_reg_page_list);
1211
1212void ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list)
1213{
1214        page_list->device->free_fast_reg_page_list(page_list);
1215}
1216EXPORT_SYMBOL(ib_free_fast_reg_page_list);
1217
1218/* Memory windows */
1219
1220struct ib_mw *ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type)
1221{
1222        struct ib_mw *mw;
1223
1224        if (!pd->device->alloc_mw)
1225                return ERR_PTR(-ENOSYS);
1226
1227        mw = pd->device->alloc_mw(pd, type);
1228        if (!IS_ERR(mw)) {
1229                mw->device  = pd->device;
1230                mw->pd      = pd;
1231                mw->uobject = NULL;
1232                mw->type    = type;
1233                atomic_inc(&pd->usecnt);
1234        }
1235
1236        return mw;
1237}
1238EXPORT_SYMBOL(ib_alloc_mw);
1239
1240int ib_dealloc_mw(struct ib_mw *mw)
1241{
1242        struct ib_pd *pd;
1243        int ret;
1244
1245        pd = mw->pd;
1246        ret = mw->device->dealloc_mw(mw);
1247        if (!ret)
1248                atomic_dec(&pd->usecnt);
1249
1250        return ret;
1251}
1252EXPORT_SYMBOL(ib_dealloc_mw);
1253
1254/* "Fast" memory regions */
1255
1256struct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
1257                            int mr_access_flags,
1258                            struct ib_fmr_attr *fmr_attr)
1259{
1260        struct ib_fmr *fmr;
1261
1262        if (!pd->device->alloc_fmr)
1263                return ERR_PTR(-ENOSYS);
1264
1265        fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr);
1266        if (!IS_ERR(fmr)) {
1267                fmr->device = pd->device;
1268                fmr->pd     = pd;
1269                atomic_inc(&pd->usecnt);
1270        }
1271
1272        return fmr;
1273}
1274EXPORT_SYMBOL(ib_alloc_fmr);
1275
1276int ib_unmap_fmr(struct list_head *fmr_list)
1277{
1278        struct ib_fmr *fmr;
1279
1280        if (list_empty(fmr_list))
1281                return 0;
1282
1283        fmr = list_entry(fmr_list->next, struct ib_fmr, list);
1284        return fmr->device->unmap_fmr(fmr_list);
1285}
1286EXPORT_SYMBOL(ib_unmap_fmr);
1287
1288int ib_dealloc_fmr(struct ib_fmr *fmr)
1289{
1290        struct ib_pd *pd;
1291        int ret;
1292
1293        pd = fmr->pd;
1294        ret = fmr->device->dealloc_fmr(fmr);
1295        if (!ret)
1296                atomic_dec(&pd->usecnt);
1297
1298        return ret;
1299}
1300EXPORT_SYMBOL(ib_dealloc_fmr);
1301
1302/* Multicast groups */
1303
1304int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
1305{
1306        int ret;
1307
1308        if (!qp->device->attach_mcast)
1309                return -ENOSYS;
1310        if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
1311                return -EINVAL;
1312
1313        ret = qp->device->attach_mcast(qp, gid, lid);
1314        if (!ret)
1315                atomic_inc(&qp->usecnt);
1316        return ret;
1317}
1318EXPORT_SYMBOL(ib_attach_mcast);
1319
1320int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
1321{
1322        int ret;
1323
1324        if (!qp->device->detach_mcast)
1325                return -ENOSYS;
1326        if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
1327                return -EINVAL;
1328
1329        ret = qp->device->detach_mcast(qp, gid, lid);
1330        if (!ret)
1331                atomic_dec(&qp->usecnt);
1332        return ret;
1333}
1334EXPORT_SYMBOL(ib_detach_mcast);
1335
1336struct ib_xrcd *ib_alloc_xrcd(struct ib_device *device)
1337{
1338        struct ib_xrcd *xrcd;
1339
1340        if (!device->alloc_xrcd)
1341                return ERR_PTR(-ENOSYS);
1342
1343        xrcd = device->alloc_xrcd(device, NULL, NULL);
1344        if (!IS_ERR(xrcd)) {
1345                xrcd->device = device;
1346                xrcd->inode = NULL;
1347                atomic_set(&xrcd->usecnt, 0);
1348                mutex_init(&xrcd->tgt_qp_mutex);
1349                INIT_LIST_HEAD(&xrcd->tgt_qp_list);
1350        }
1351
1352        return xrcd;
1353}
1354EXPORT_SYMBOL(ib_alloc_xrcd);
1355
1356int ib_dealloc_xrcd(struct ib_xrcd *xrcd)
1357{
1358        struct ib_qp *qp;
1359        int ret;
1360
1361        if (atomic_read(&xrcd->usecnt))
1362                return -EBUSY;
1363
1364        while (!list_empty(&xrcd->tgt_qp_list)) {
1365                qp = list_entry(xrcd->tgt_qp_list.next, struct ib_qp, xrcd_list);
1366                ret = ib_destroy_qp(qp);
1367                if (ret)
1368                        return ret;
1369        }
1370
1371        return xrcd->device->dealloc_xrcd(xrcd);
1372}
1373EXPORT_SYMBOL(ib_dealloc_xrcd);
1374
1375struct ib_flow *ib_create_flow(struct ib_qp *qp,
1376                               struct ib_flow_attr *flow_attr,
1377                               int domain)
1378{
1379        struct ib_flow *flow_id;
1380        if (!qp->device->create_flow)
1381                return ERR_PTR(-ENOSYS);
1382
1383        flow_id = qp->device->create_flow(qp, flow_attr, domain);
1384        if (!IS_ERR(flow_id))
1385                atomic_inc(&qp->usecnt);
1386        return flow_id;
1387}
1388EXPORT_SYMBOL(ib_create_flow);
1389
1390int ib_destroy_flow(struct ib_flow *flow_id)
1391{
1392        int err;
1393        struct ib_qp *qp = flow_id->qp;
1394
1395        err = qp->device->destroy_flow(flow_id);
1396        if (!err)
1397                atomic_dec(&qp->usecnt);
1398        return err;
1399}
1400EXPORT_SYMBOL(ib_destroy_flow);
1401