11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved. 31da177e4SLinus Torvalds * Copyright (c) 2004 Infinicon Corporation. All rights reserved. 41da177e4SLinus Torvalds * Copyright (c) 2004 Intel Corporation. All rights reserved. 51da177e4SLinus Torvalds * Copyright (c) 2004 Topspin Corporation. All rights reserved. 61da177e4SLinus Torvalds * Copyright (c) 2004 Voltaire Corporation. All rights reserved. 72a1d9b7fSRoland Dreier * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 833b9b3eeSRoland Dreier * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * This software is available to you under a choice of one of two 111da177e4SLinus Torvalds * licenses. You may choose to be licensed under the terms of the GNU 121da177e4SLinus Torvalds * General Public License (GPL) Version 2, available from the file 131da177e4SLinus Torvalds * COPYING in the main directory of this source tree, or the 141da177e4SLinus Torvalds * OpenIB.org BSD license below: 151da177e4SLinus Torvalds * 161da177e4SLinus Torvalds * Redistribution and use in source and binary forms, with or 171da177e4SLinus Torvalds * without modification, are permitted provided that the following 181da177e4SLinus Torvalds * conditions are met: 191da177e4SLinus Torvalds * 201da177e4SLinus Torvalds * - Redistributions of source code must retain the above 211da177e4SLinus Torvalds * copyright notice, this list of conditions and the following 221da177e4SLinus Torvalds * disclaimer. 231da177e4SLinus Torvalds * 241da177e4SLinus Torvalds * - Redistributions in binary form must reproduce the above 251da177e4SLinus Torvalds * copyright notice, this list of conditions and the following 261da177e4SLinus Torvalds * disclaimer in the documentation and/or other materials 271da177e4SLinus Torvalds * provided with the distribution. 281da177e4SLinus Torvalds * 291da177e4SLinus Torvalds * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 301da177e4SLinus Torvalds * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 311da177e4SLinus Torvalds * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 321da177e4SLinus Torvalds * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 331da177e4SLinus Torvalds * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 341da177e4SLinus Torvalds * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 351da177e4SLinus Torvalds * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 361da177e4SLinus Torvalds * SOFTWARE. 371da177e4SLinus Torvalds * 381da177e4SLinus Torvalds * $Id: verbs.c 1349 2004-12-16 21:09:43Z roland $ 391da177e4SLinus Torvalds */ 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds #include <linux/errno.h> 421da177e4SLinus Torvalds #include <linux/err.h> 438c65b4a6STim Schmielau #include <linux/string.h> 441da177e4SLinus Torvalds 45a4d61e84SRoland Dreier #include <rdma/ib_verbs.h> 46a4d61e84SRoland Dreier #include <rdma/ib_cache.h> 471da177e4SLinus Torvalds 48bf6a9e31SJack Morgenstein int ib_rate_to_mult(enum ib_rate rate) 49bf6a9e31SJack Morgenstein { 50bf6a9e31SJack Morgenstein switch (rate) { 51bf6a9e31SJack Morgenstein case IB_RATE_2_5_GBPS: return 1; 52bf6a9e31SJack Morgenstein case IB_RATE_5_GBPS: return 2; 53bf6a9e31SJack Morgenstein case IB_RATE_10_GBPS: return 4; 54bf6a9e31SJack Morgenstein case IB_RATE_20_GBPS: return 8; 55bf6a9e31SJack Morgenstein case IB_RATE_30_GBPS: return 12; 56bf6a9e31SJack Morgenstein case IB_RATE_40_GBPS: return 16; 57bf6a9e31SJack Morgenstein case IB_RATE_60_GBPS: return 24; 58bf6a9e31SJack Morgenstein case IB_RATE_80_GBPS: return 32; 59bf6a9e31SJack Morgenstein case IB_RATE_120_GBPS: return 48; 60bf6a9e31SJack Morgenstein default: return -1; 61bf6a9e31SJack Morgenstein } 62bf6a9e31SJack Morgenstein } 63bf6a9e31SJack Morgenstein EXPORT_SYMBOL(ib_rate_to_mult); 64bf6a9e31SJack Morgenstein 65bf6a9e31SJack Morgenstein enum ib_rate mult_to_ib_rate(int mult) 66bf6a9e31SJack Morgenstein { 67bf6a9e31SJack Morgenstein switch (mult) { 68bf6a9e31SJack Morgenstein case 1: return IB_RATE_2_5_GBPS; 69bf6a9e31SJack Morgenstein case 2: return IB_RATE_5_GBPS; 70bf6a9e31SJack Morgenstein case 4: return IB_RATE_10_GBPS; 71bf6a9e31SJack Morgenstein case 8: return IB_RATE_20_GBPS; 72bf6a9e31SJack Morgenstein case 12: return IB_RATE_30_GBPS; 73bf6a9e31SJack Morgenstein case 16: return IB_RATE_40_GBPS; 74bf6a9e31SJack Morgenstein case 24: return IB_RATE_60_GBPS; 75bf6a9e31SJack Morgenstein case 32: return IB_RATE_80_GBPS; 76bf6a9e31SJack Morgenstein case 48: return IB_RATE_120_GBPS; 77bf6a9e31SJack Morgenstein default: return IB_RATE_PORT_CURRENT; 78bf6a9e31SJack Morgenstein } 79bf6a9e31SJack Morgenstein } 80bf6a9e31SJack Morgenstein EXPORT_SYMBOL(mult_to_ib_rate); 81bf6a9e31SJack Morgenstein 8207ebafbaSTom Tucker enum rdma_transport_type 8307ebafbaSTom Tucker rdma_node_get_transport(enum rdma_node_type node_type) 8407ebafbaSTom Tucker { 8507ebafbaSTom Tucker switch (node_type) { 8607ebafbaSTom Tucker case RDMA_NODE_IB_CA: 8707ebafbaSTom Tucker case RDMA_NODE_IB_SWITCH: 8807ebafbaSTom Tucker case RDMA_NODE_IB_ROUTER: 8907ebafbaSTom Tucker return RDMA_TRANSPORT_IB; 9007ebafbaSTom Tucker case RDMA_NODE_RNIC: 9107ebafbaSTom Tucker return RDMA_TRANSPORT_IWARP; 9207ebafbaSTom Tucker default: 9307ebafbaSTom Tucker BUG(); 9407ebafbaSTom Tucker return 0; 9507ebafbaSTom Tucker } 9607ebafbaSTom Tucker } 9707ebafbaSTom Tucker EXPORT_SYMBOL(rdma_node_get_transport); 9807ebafbaSTom Tucker 991da177e4SLinus Torvalds /* Protection domains */ 1001da177e4SLinus Torvalds 1011da177e4SLinus Torvalds struct ib_pd *ib_alloc_pd(struct ib_device *device) 1021da177e4SLinus Torvalds { 1031da177e4SLinus Torvalds struct ib_pd *pd; 1041da177e4SLinus Torvalds 105b5e81bf5SRoland Dreier pd = device->alloc_pd(device, NULL, NULL); 1061da177e4SLinus Torvalds 1071da177e4SLinus Torvalds if (!IS_ERR(pd)) { 1081da177e4SLinus Torvalds pd->device = device; 109b5e81bf5SRoland Dreier pd->uobject = NULL; 1101da177e4SLinus Torvalds atomic_set(&pd->usecnt, 0); 1111da177e4SLinus Torvalds } 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds return pd; 1141da177e4SLinus Torvalds } 1151da177e4SLinus Torvalds EXPORT_SYMBOL(ib_alloc_pd); 1161da177e4SLinus Torvalds 1171da177e4SLinus Torvalds int ib_dealloc_pd(struct ib_pd *pd) 1181da177e4SLinus Torvalds { 1191da177e4SLinus Torvalds if (atomic_read(&pd->usecnt)) 1201da177e4SLinus Torvalds return -EBUSY; 1211da177e4SLinus Torvalds 1221da177e4SLinus Torvalds return pd->device->dealloc_pd(pd); 1231da177e4SLinus Torvalds } 1241da177e4SLinus Torvalds EXPORT_SYMBOL(ib_dealloc_pd); 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds /* Address handles */ 1271da177e4SLinus Torvalds 1281da177e4SLinus Torvalds struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) 1291da177e4SLinus Torvalds { 1301da177e4SLinus Torvalds struct ib_ah *ah; 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds ah = pd->device->create_ah(pd, ah_attr); 1331da177e4SLinus Torvalds 1341da177e4SLinus Torvalds if (!IS_ERR(ah)) { 1351da177e4SLinus Torvalds ah->device = pd->device; 1361da177e4SLinus Torvalds ah->pd = pd; 137b5e81bf5SRoland Dreier ah->uobject = NULL; 1381da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 1391da177e4SLinus Torvalds } 1401da177e4SLinus Torvalds 1411da177e4SLinus Torvalds return ah; 1421da177e4SLinus Torvalds } 1431da177e4SLinus Torvalds EXPORT_SYMBOL(ib_create_ah); 1441da177e4SLinus Torvalds 1454e00d694SSean Hefty int ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc, 1464e00d694SSean Hefty struct ib_grh *grh, struct ib_ah_attr *ah_attr) 147513789edSHal Rosenstock { 148513789edSHal Rosenstock u32 flow_class; 149513789edSHal Rosenstock u16 gid_index; 150513789edSHal Rosenstock int ret; 151513789edSHal Rosenstock 1524e00d694SSean Hefty memset(ah_attr, 0, sizeof *ah_attr); 1534e00d694SSean Hefty ah_attr->dlid = wc->slid; 1544e00d694SSean Hefty ah_attr->sl = wc->sl; 1554e00d694SSean Hefty ah_attr->src_path_bits = wc->dlid_path_bits; 1564e00d694SSean Hefty ah_attr->port_num = port_num; 157513789edSHal Rosenstock 158513789edSHal Rosenstock if (wc->wc_flags & IB_WC_GRH) { 1594e00d694SSean Hefty ah_attr->ah_flags = IB_AH_GRH; 1604e00d694SSean Hefty ah_attr->grh.dgid = grh->sgid; 161513789edSHal Rosenstock 1624e00d694SSean Hefty ret = ib_find_cached_gid(device, &grh->dgid, &port_num, 163513789edSHal Rosenstock &gid_index); 164513789edSHal Rosenstock if (ret) 1654e00d694SSean Hefty return ret; 166513789edSHal Rosenstock 1674e00d694SSean Hefty ah_attr->grh.sgid_index = (u8) gid_index; 168497677abSHal Rosenstock flow_class = be32_to_cpu(grh->version_tclass_flow); 1694e00d694SSean Hefty ah_attr->grh.flow_label = flow_class & 0xFFFFF; 17047645d8dSSean Hefty ah_attr->grh.hop_limit = 0xFF; 1714e00d694SSean Hefty ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF; 172513789edSHal Rosenstock } 1734e00d694SSean Hefty return 0; 1744e00d694SSean Hefty } 1754e00d694SSean Hefty EXPORT_SYMBOL(ib_init_ah_from_wc); 1764e00d694SSean Hefty 1774e00d694SSean Hefty struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc, 1784e00d694SSean Hefty struct ib_grh *grh, u8 port_num) 1794e00d694SSean Hefty { 1804e00d694SSean Hefty struct ib_ah_attr ah_attr; 1814e00d694SSean Hefty int ret; 1824e00d694SSean Hefty 1834e00d694SSean Hefty ret = ib_init_ah_from_wc(pd->device, port_num, wc, grh, &ah_attr); 1844e00d694SSean Hefty if (ret) 1854e00d694SSean Hefty return ERR_PTR(ret); 186513789edSHal Rosenstock 187513789edSHal Rosenstock return ib_create_ah(pd, &ah_attr); 188513789edSHal Rosenstock } 189513789edSHal Rosenstock EXPORT_SYMBOL(ib_create_ah_from_wc); 190513789edSHal Rosenstock 1911da177e4SLinus Torvalds int ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr) 1921da177e4SLinus Torvalds { 1931da177e4SLinus Torvalds return ah->device->modify_ah ? 1941da177e4SLinus Torvalds ah->device->modify_ah(ah, ah_attr) : 1951da177e4SLinus Torvalds -ENOSYS; 1961da177e4SLinus Torvalds } 1971da177e4SLinus Torvalds EXPORT_SYMBOL(ib_modify_ah); 1981da177e4SLinus Torvalds 1991da177e4SLinus Torvalds int ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr) 2001da177e4SLinus Torvalds { 2011da177e4SLinus Torvalds return ah->device->query_ah ? 2021da177e4SLinus Torvalds ah->device->query_ah(ah, ah_attr) : 2031da177e4SLinus Torvalds -ENOSYS; 2041da177e4SLinus Torvalds } 2051da177e4SLinus Torvalds EXPORT_SYMBOL(ib_query_ah); 2061da177e4SLinus Torvalds 2071da177e4SLinus Torvalds int ib_destroy_ah(struct ib_ah *ah) 2081da177e4SLinus Torvalds { 2091da177e4SLinus Torvalds struct ib_pd *pd; 2101da177e4SLinus Torvalds int ret; 2111da177e4SLinus Torvalds 2121da177e4SLinus Torvalds pd = ah->pd; 2131da177e4SLinus Torvalds ret = ah->device->destroy_ah(ah); 2141da177e4SLinus Torvalds if (!ret) 2151da177e4SLinus Torvalds atomic_dec(&pd->usecnt); 2161da177e4SLinus Torvalds 2171da177e4SLinus Torvalds return ret; 2181da177e4SLinus Torvalds } 2191da177e4SLinus Torvalds EXPORT_SYMBOL(ib_destroy_ah); 2201da177e4SLinus Torvalds 221d41fcc67SRoland Dreier /* Shared receive queues */ 222d41fcc67SRoland Dreier 223d41fcc67SRoland Dreier struct ib_srq *ib_create_srq(struct ib_pd *pd, 224d41fcc67SRoland Dreier struct ib_srq_init_attr *srq_init_attr) 225d41fcc67SRoland Dreier { 226d41fcc67SRoland Dreier struct ib_srq *srq; 227d41fcc67SRoland Dreier 228d41fcc67SRoland Dreier if (!pd->device->create_srq) 229d41fcc67SRoland Dreier return ERR_PTR(-ENOSYS); 230d41fcc67SRoland Dreier 231d41fcc67SRoland Dreier srq = pd->device->create_srq(pd, srq_init_attr, NULL); 232d41fcc67SRoland Dreier 233d41fcc67SRoland Dreier if (!IS_ERR(srq)) { 234d41fcc67SRoland Dreier srq->device = pd->device; 235d41fcc67SRoland Dreier srq->pd = pd; 236d41fcc67SRoland Dreier srq->uobject = NULL; 237d41fcc67SRoland Dreier srq->event_handler = srq_init_attr->event_handler; 238d41fcc67SRoland Dreier srq->srq_context = srq_init_attr->srq_context; 239d41fcc67SRoland Dreier atomic_inc(&pd->usecnt); 240d41fcc67SRoland Dreier atomic_set(&srq->usecnt, 0); 241d41fcc67SRoland Dreier } 242d41fcc67SRoland Dreier 243d41fcc67SRoland Dreier return srq; 244d41fcc67SRoland Dreier } 245d41fcc67SRoland Dreier EXPORT_SYMBOL(ib_create_srq); 246d41fcc67SRoland Dreier 247d41fcc67SRoland Dreier int ib_modify_srq(struct ib_srq *srq, 248d41fcc67SRoland Dreier struct ib_srq_attr *srq_attr, 249d41fcc67SRoland Dreier enum ib_srq_attr_mask srq_attr_mask) 250d41fcc67SRoland Dreier { 2519bc57e2dSRalph Campbell return srq->device->modify_srq(srq, srq_attr, srq_attr_mask, NULL); 252d41fcc67SRoland Dreier } 253d41fcc67SRoland Dreier EXPORT_SYMBOL(ib_modify_srq); 254d41fcc67SRoland Dreier 255d41fcc67SRoland Dreier int ib_query_srq(struct ib_srq *srq, 256d41fcc67SRoland Dreier struct ib_srq_attr *srq_attr) 257d41fcc67SRoland Dreier { 258d41fcc67SRoland Dreier return srq->device->query_srq ? 259d41fcc67SRoland Dreier srq->device->query_srq(srq, srq_attr) : -ENOSYS; 260d41fcc67SRoland Dreier } 261d41fcc67SRoland Dreier EXPORT_SYMBOL(ib_query_srq); 262d41fcc67SRoland Dreier 263d41fcc67SRoland Dreier int ib_destroy_srq(struct ib_srq *srq) 264d41fcc67SRoland Dreier { 265d41fcc67SRoland Dreier struct ib_pd *pd; 266d41fcc67SRoland Dreier int ret; 267d41fcc67SRoland Dreier 268d41fcc67SRoland Dreier if (atomic_read(&srq->usecnt)) 269d41fcc67SRoland Dreier return -EBUSY; 270d41fcc67SRoland Dreier 271d41fcc67SRoland Dreier pd = srq->pd; 272d41fcc67SRoland Dreier 273d41fcc67SRoland Dreier ret = srq->device->destroy_srq(srq); 274d41fcc67SRoland Dreier if (!ret) 275d41fcc67SRoland Dreier atomic_dec(&pd->usecnt); 276d41fcc67SRoland Dreier 277d41fcc67SRoland Dreier return ret; 278d41fcc67SRoland Dreier } 279d41fcc67SRoland Dreier EXPORT_SYMBOL(ib_destroy_srq); 280d41fcc67SRoland Dreier 2811da177e4SLinus Torvalds /* Queue pairs */ 2821da177e4SLinus Torvalds 2831da177e4SLinus Torvalds struct ib_qp *ib_create_qp(struct ib_pd *pd, 2841da177e4SLinus Torvalds struct ib_qp_init_attr *qp_init_attr) 2851da177e4SLinus Torvalds { 2861da177e4SLinus Torvalds struct ib_qp *qp; 2871da177e4SLinus Torvalds 288b5e81bf5SRoland Dreier qp = pd->device->create_qp(pd, qp_init_attr, NULL); 2891da177e4SLinus Torvalds 2901da177e4SLinus Torvalds if (!IS_ERR(qp)) { 2911da177e4SLinus Torvalds qp->device = pd->device; 2921da177e4SLinus Torvalds qp->pd = pd; 2931da177e4SLinus Torvalds qp->send_cq = qp_init_attr->send_cq; 2941da177e4SLinus Torvalds qp->recv_cq = qp_init_attr->recv_cq; 2951da177e4SLinus Torvalds qp->srq = qp_init_attr->srq; 296b5e81bf5SRoland Dreier qp->uobject = NULL; 2971da177e4SLinus Torvalds qp->event_handler = qp_init_attr->event_handler; 2981da177e4SLinus Torvalds qp->qp_context = qp_init_attr->qp_context; 2991da177e4SLinus Torvalds qp->qp_type = qp_init_attr->qp_type; 3001da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 3011da177e4SLinus Torvalds atomic_inc(&qp_init_attr->send_cq->usecnt); 3021da177e4SLinus Torvalds atomic_inc(&qp_init_attr->recv_cq->usecnt); 3031da177e4SLinus Torvalds if (qp_init_attr->srq) 3041da177e4SLinus Torvalds atomic_inc(&qp_init_attr->srq->usecnt); 3051da177e4SLinus Torvalds } 3061da177e4SLinus Torvalds 3071da177e4SLinus Torvalds return qp; 3081da177e4SLinus Torvalds } 3091da177e4SLinus Torvalds EXPORT_SYMBOL(ib_create_qp); 3101da177e4SLinus Torvalds 3118a51866fSRoland Dreier static const struct { 3128a51866fSRoland Dreier int valid; 3138a51866fSRoland Dreier enum ib_qp_attr_mask req_param[IB_QPT_RAW_ETY + 1]; 3148a51866fSRoland Dreier enum ib_qp_attr_mask opt_param[IB_QPT_RAW_ETY + 1]; 3158a51866fSRoland Dreier } qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { 3168a51866fSRoland Dreier [IB_QPS_RESET] = { 3178a51866fSRoland Dreier [IB_QPS_RESET] = { .valid = 1 }, 3188a51866fSRoland Dreier [IB_QPS_ERR] = { .valid = 1 }, 3198a51866fSRoland Dreier [IB_QPS_INIT] = { 3208a51866fSRoland Dreier .valid = 1, 3218a51866fSRoland Dreier .req_param = { 3228a51866fSRoland Dreier [IB_QPT_UD] = (IB_QP_PKEY_INDEX | 3238a51866fSRoland Dreier IB_QP_PORT | 3248a51866fSRoland Dreier IB_QP_QKEY), 3258a51866fSRoland Dreier [IB_QPT_UC] = (IB_QP_PKEY_INDEX | 3268a51866fSRoland Dreier IB_QP_PORT | 3278a51866fSRoland Dreier IB_QP_ACCESS_FLAGS), 3288a51866fSRoland Dreier [IB_QPT_RC] = (IB_QP_PKEY_INDEX | 3298a51866fSRoland Dreier IB_QP_PORT | 3308a51866fSRoland Dreier IB_QP_ACCESS_FLAGS), 3318a51866fSRoland Dreier [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | 3328a51866fSRoland Dreier IB_QP_QKEY), 3338a51866fSRoland Dreier [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | 3348a51866fSRoland Dreier IB_QP_QKEY), 3358a51866fSRoland Dreier } 3368a51866fSRoland Dreier }, 3378a51866fSRoland Dreier }, 3388a51866fSRoland Dreier [IB_QPS_INIT] = { 3398a51866fSRoland Dreier [IB_QPS_RESET] = { .valid = 1 }, 3408a51866fSRoland Dreier [IB_QPS_ERR] = { .valid = 1 }, 3418a51866fSRoland Dreier [IB_QPS_INIT] = { 3428a51866fSRoland Dreier .valid = 1, 3438a51866fSRoland Dreier .opt_param = { 3448a51866fSRoland Dreier [IB_QPT_UD] = (IB_QP_PKEY_INDEX | 3458a51866fSRoland Dreier IB_QP_PORT | 3468a51866fSRoland Dreier IB_QP_QKEY), 3478a51866fSRoland Dreier [IB_QPT_UC] = (IB_QP_PKEY_INDEX | 3488a51866fSRoland Dreier IB_QP_PORT | 3498a51866fSRoland Dreier IB_QP_ACCESS_FLAGS), 3508a51866fSRoland Dreier [IB_QPT_RC] = (IB_QP_PKEY_INDEX | 3518a51866fSRoland Dreier IB_QP_PORT | 3528a51866fSRoland Dreier IB_QP_ACCESS_FLAGS), 3538a51866fSRoland Dreier [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | 3548a51866fSRoland Dreier IB_QP_QKEY), 3558a51866fSRoland Dreier [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | 3568a51866fSRoland Dreier IB_QP_QKEY), 3578a51866fSRoland Dreier } 3588a51866fSRoland Dreier }, 3598a51866fSRoland Dreier [IB_QPS_RTR] = { 3608a51866fSRoland Dreier .valid = 1, 3618a51866fSRoland Dreier .req_param = { 3628a51866fSRoland Dreier [IB_QPT_UC] = (IB_QP_AV | 3638a51866fSRoland Dreier IB_QP_PATH_MTU | 3648a51866fSRoland Dreier IB_QP_DEST_QPN | 3658a51866fSRoland Dreier IB_QP_RQ_PSN), 3668a51866fSRoland Dreier [IB_QPT_RC] = (IB_QP_AV | 3678a51866fSRoland Dreier IB_QP_PATH_MTU | 3688a51866fSRoland Dreier IB_QP_DEST_QPN | 3698a51866fSRoland Dreier IB_QP_RQ_PSN | 3708a51866fSRoland Dreier IB_QP_MAX_DEST_RD_ATOMIC | 3718a51866fSRoland Dreier IB_QP_MIN_RNR_TIMER), 3728a51866fSRoland Dreier }, 3738a51866fSRoland Dreier .opt_param = { 3748a51866fSRoland Dreier [IB_QPT_UD] = (IB_QP_PKEY_INDEX | 3758a51866fSRoland Dreier IB_QP_QKEY), 3768a51866fSRoland Dreier [IB_QPT_UC] = (IB_QP_ALT_PATH | 3778a51866fSRoland Dreier IB_QP_ACCESS_FLAGS | 3788a51866fSRoland Dreier IB_QP_PKEY_INDEX), 3798a51866fSRoland Dreier [IB_QPT_RC] = (IB_QP_ALT_PATH | 3808a51866fSRoland Dreier IB_QP_ACCESS_FLAGS | 3818a51866fSRoland Dreier IB_QP_PKEY_INDEX), 3828a51866fSRoland Dreier [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | 3838a51866fSRoland Dreier IB_QP_QKEY), 3848a51866fSRoland Dreier [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | 3858a51866fSRoland Dreier IB_QP_QKEY), 3868a51866fSRoland Dreier } 3878a51866fSRoland Dreier } 3888a51866fSRoland Dreier }, 3898a51866fSRoland Dreier [IB_QPS_RTR] = { 3908a51866fSRoland Dreier [IB_QPS_RESET] = { .valid = 1 }, 3918a51866fSRoland Dreier [IB_QPS_ERR] = { .valid = 1 }, 3928a51866fSRoland Dreier [IB_QPS_RTS] = { 3938a51866fSRoland Dreier .valid = 1, 3948a51866fSRoland Dreier .req_param = { 3958a51866fSRoland Dreier [IB_QPT_UD] = IB_QP_SQ_PSN, 3968a51866fSRoland Dreier [IB_QPT_UC] = IB_QP_SQ_PSN, 3978a51866fSRoland Dreier [IB_QPT_RC] = (IB_QP_TIMEOUT | 3988a51866fSRoland Dreier IB_QP_RETRY_CNT | 3998a51866fSRoland Dreier IB_QP_RNR_RETRY | 4008a51866fSRoland Dreier IB_QP_SQ_PSN | 4018a51866fSRoland Dreier IB_QP_MAX_QP_RD_ATOMIC), 4028a51866fSRoland Dreier [IB_QPT_SMI] = IB_QP_SQ_PSN, 4038a51866fSRoland Dreier [IB_QPT_GSI] = IB_QP_SQ_PSN, 4048a51866fSRoland Dreier }, 4058a51866fSRoland Dreier .opt_param = { 4068a51866fSRoland Dreier [IB_QPT_UD] = (IB_QP_CUR_STATE | 4078a51866fSRoland Dreier IB_QP_QKEY), 4088a51866fSRoland Dreier [IB_QPT_UC] = (IB_QP_CUR_STATE | 4098a51866fSRoland Dreier IB_QP_ALT_PATH | 4108a51866fSRoland Dreier IB_QP_ACCESS_FLAGS | 4118a51866fSRoland Dreier IB_QP_PATH_MIG_STATE), 4128a51866fSRoland Dreier [IB_QPT_RC] = (IB_QP_CUR_STATE | 4138a51866fSRoland Dreier IB_QP_ALT_PATH | 4148a51866fSRoland Dreier IB_QP_ACCESS_FLAGS | 4158a51866fSRoland Dreier IB_QP_MIN_RNR_TIMER | 4168a51866fSRoland Dreier IB_QP_PATH_MIG_STATE), 4178a51866fSRoland Dreier [IB_QPT_SMI] = (IB_QP_CUR_STATE | 4188a51866fSRoland Dreier IB_QP_QKEY), 4198a51866fSRoland Dreier [IB_QPT_GSI] = (IB_QP_CUR_STATE | 4208a51866fSRoland Dreier IB_QP_QKEY), 4218a51866fSRoland Dreier } 4228a51866fSRoland Dreier } 4238a51866fSRoland Dreier }, 4248a51866fSRoland Dreier [IB_QPS_RTS] = { 4258a51866fSRoland Dreier [IB_QPS_RESET] = { .valid = 1 }, 4268a51866fSRoland Dreier [IB_QPS_ERR] = { .valid = 1 }, 4278a51866fSRoland Dreier [IB_QPS_RTS] = { 4288a51866fSRoland Dreier .valid = 1, 4298a51866fSRoland Dreier .opt_param = { 4308a51866fSRoland Dreier [IB_QPT_UD] = (IB_QP_CUR_STATE | 4318a51866fSRoland Dreier IB_QP_QKEY), 4324546d31dSDotan Barak [IB_QPT_UC] = (IB_QP_CUR_STATE | 4334546d31dSDotan Barak IB_QP_ACCESS_FLAGS | 4348a51866fSRoland Dreier IB_QP_ALT_PATH | 4358a51866fSRoland Dreier IB_QP_PATH_MIG_STATE), 4364546d31dSDotan Barak [IB_QPT_RC] = (IB_QP_CUR_STATE | 4374546d31dSDotan Barak IB_QP_ACCESS_FLAGS | 4388a51866fSRoland Dreier IB_QP_ALT_PATH | 4398a51866fSRoland Dreier IB_QP_PATH_MIG_STATE | 4408a51866fSRoland Dreier IB_QP_MIN_RNR_TIMER), 4418a51866fSRoland Dreier [IB_QPT_SMI] = (IB_QP_CUR_STATE | 4428a51866fSRoland Dreier IB_QP_QKEY), 4438a51866fSRoland Dreier [IB_QPT_GSI] = (IB_QP_CUR_STATE | 4448a51866fSRoland Dreier IB_QP_QKEY), 4458a51866fSRoland Dreier } 4468a51866fSRoland Dreier }, 4478a51866fSRoland Dreier [IB_QPS_SQD] = { 4488a51866fSRoland Dreier .valid = 1, 4498a51866fSRoland Dreier .opt_param = { 4508a51866fSRoland Dreier [IB_QPT_UD] = IB_QP_EN_SQD_ASYNC_NOTIFY, 4518a51866fSRoland Dreier [IB_QPT_UC] = IB_QP_EN_SQD_ASYNC_NOTIFY, 4528a51866fSRoland Dreier [IB_QPT_RC] = IB_QP_EN_SQD_ASYNC_NOTIFY, 4538a51866fSRoland Dreier [IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY, 4548a51866fSRoland Dreier [IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY 4558a51866fSRoland Dreier } 4568a51866fSRoland Dreier }, 4578a51866fSRoland Dreier }, 4588a51866fSRoland Dreier [IB_QPS_SQD] = { 4598a51866fSRoland Dreier [IB_QPS_RESET] = { .valid = 1 }, 4608a51866fSRoland Dreier [IB_QPS_ERR] = { .valid = 1 }, 4618a51866fSRoland Dreier [IB_QPS_RTS] = { 4628a51866fSRoland Dreier .valid = 1, 4638a51866fSRoland Dreier .opt_param = { 4648a51866fSRoland Dreier [IB_QPT_UD] = (IB_QP_CUR_STATE | 4658a51866fSRoland Dreier IB_QP_QKEY), 4668a51866fSRoland Dreier [IB_QPT_UC] = (IB_QP_CUR_STATE | 4678a51866fSRoland Dreier IB_QP_ALT_PATH | 4688a51866fSRoland Dreier IB_QP_ACCESS_FLAGS | 4698a51866fSRoland Dreier IB_QP_PATH_MIG_STATE), 4708a51866fSRoland Dreier [IB_QPT_RC] = (IB_QP_CUR_STATE | 4718a51866fSRoland Dreier IB_QP_ALT_PATH | 4728a51866fSRoland Dreier IB_QP_ACCESS_FLAGS | 4738a51866fSRoland Dreier IB_QP_MIN_RNR_TIMER | 4748a51866fSRoland Dreier IB_QP_PATH_MIG_STATE), 4758a51866fSRoland Dreier [IB_QPT_SMI] = (IB_QP_CUR_STATE | 4768a51866fSRoland Dreier IB_QP_QKEY), 4778a51866fSRoland Dreier [IB_QPT_GSI] = (IB_QP_CUR_STATE | 4788a51866fSRoland Dreier IB_QP_QKEY), 4798a51866fSRoland Dreier } 4808a51866fSRoland Dreier }, 4818a51866fSRoland Dreier [IB_QPS_SQD] = { 4828a51866fSRoland Dreier .valid = 1, 4838a51866fSRoland Dreier .opt_param = { 4848a51866fSRoland Dreier [IB_QPT_UD] = (IB_QP_PKEY_INDEX | 4858a51866fSRoland Dreier IB_QP_QKEY), 4868a51866fSRoland Dreier [IB_QPT_UC] = (IB_QP_AV | 4878a51866fSRoland Dreier IB_QP_ALT_PATH | 4888a51866fSRoland Dreier IB_QP_ACCESS_FLAGS | 4898a51866fSRoland Dreier IB_QP_PKEY_INDEX | 4908a51866fSRoland Dreier IB_QP_PATH_MIG_STATE), 4918a51866fSRoland Dreier [IB_QPT_RC] = (IB_QP_PORT | 4928a51866fSRoland Dreier IB_QP_AV | 4938a51866fSRoland Dreier IB_QP_TIMEOUT | 4948a51866fSRoland Dreier IB_QP_RETRY_CNT | 4958a51866fSRoland Dreier IB_QP_RNR_RETRY | 4968a51866fSRoland Dreier IB_QP_MAX_QP_RD_ATOMIC | 4978a51866fSRoland Dreier IB_QP_MAX_DEST_RD_ATOMIC | 4988a51866fSRoland Dreier IB_QP_ALT_PATH | 4998a51866fSRoland Dreier IB_QP_ACCESS_FLAGS | 5008a51866fSRoland Dreier IB_QP_PKEY_INDEX | 5018a51866fSRoland Dreier IB_QP_MIN_RNR_TIMER | 5028a51866fSRoland Dreier IB_QP_PATH_MIG_STATE), 5038a51866fSRoland Dreier [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | 5048a51866fSRoland Dreier IB_QP_QKEY), 5058a51866fSRoland Dreier [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | 5068a51866fSRoland Dreier IB_QP_QKEY), 5078a51866fSRoland Dreier } 5088a51866fSRoland Dreier } 5098a51866fSRoland Dreier }, 5108a51866fSRoland Dreier [IB_QPS_SQE] = { 5118a51866fSRoland Dreier [IB_QPS_RESET] = { .valid = 1 }, 5128a51866fSRoland Dreier [IB_QPS_ERR] = { .valid = 1 }, 5138a51866fSRoland Dreier [IB_QPS_RTS] = { 5148a51866fSRoland Dreier .valid = 1, 5158a51866fSRoland Dreier .opt_param = { 5168a51866fSRoland Dreier [IB_QPT_UD] = (IB_QP_CUR_STATE | 5178a51866fSRoland Dreier IB_QP_QKEY), 5188a51866fSRoland Dreier [IB_QPT_UC] = (IB_QP_CUR_STATE | 5198a51866fSRoland Dreier IB_QP_ACCESS_FLAGS), 5208a51866fSRoland Dreier [IB_QPT_SMI] = (IB_QP_CUR_STATE | 5218a51866fSRoland Dreier IB_QP_QKEY), 5228a51866fSRoland Dreier [IB_QPT_GSI] = (IB_QP_CUR_STATE | 5238a51866fSRoland Dreier IB_QP_QKEY), 5248a51866fSRoland Dreier } 5258a51866fSRoland Dreier } 5268a51866fSRoland Dreier }, 5278a51866fSRoland Dreier [IB_QPS_ERR] = { 5288a51866fSRoland Dreier [IB_QPS_RESET] = { .valid = 1 }, 5298a51866fSRoland Dreier [IB_QPS_ERR] = { .valid = 1 } 5308a51866fSRoland Dreier } 5318a51866fSRoland Dreier }; 5328a51866fSRoland Dreier 5338a51866fSRoland Dreier int ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state, 5348a51866fSRoland Dreier enum ib_qp_type type, enum ib_qp_attr_mask mask) 5358a51866fSRoland Dreier { 5368a51866fSRoland Dreier enum ib_qp_attr_mask req_param, opt_param; 5378a51866fSRoland Dreier 5388a51866fSRoland Dreier if (cur_state < 0 || cur_state > IB_QPS_ERR || 5398a51866fSRoland Dreier next_state < 0 || next_state > IB_QPS_ERR) 5408a51866fSRoland Dreier return 0; 5418a51866fSRoland Dreier 5428a51866fSRoland Dreier if (mask & IB_QP_CUR_STATE && 5438a51866fSRoland Dreier cur_state != IB_QPS_RTR && cur_state != IB_QPS_RTS && 5448a51866fSRoland Dreier cur_state != IB_QPS_SQD && cur_state != IB_QPS_SQE) 5458a51866fSRoland Dreier return 0; 5468a51866fSRoland Dreier 5478a51866fSRoland Dreier if (!qp_state_table[cur_state][next_state].valid) 5488a51866fSRoland Dreier return 0; 5498a51866fSRoland Dreier 5508a51866fSRoland Dreier req_param = qp_state_table[cur_state][next_state].req_param[type]; 5518a51866fSRoland Dreier opt_param = qp_state_table[cur_state][next_state].opt_param[type]; 5528a51866fSRoland Dreier 5538a51866fSRoland Dreier if ((mask & req_param) != req_param) 5548a51866fSRoland Dreier return 0; 5558a51866fSRoland Dreier 5568a51866fSRoland Dreier if (mask & ~(req_param | opt_param | IB_QP_STATE)) 5578a51866fSRoland Dreier return 0; 5588a51866fSRoland Dreier 5598a51866fSRoland Dreier return 1; 5608a51866fSRoland Dreier } 5618a51866fSRoland Dreier EXPORT_SYMBOL(ib_modify_qp_is_ok); 5628a51866fSRoland Dreier 5631da177e4SLinus Torvalds int ib_modify_qp(struct ib_qp *qp, 5641da177e4SLinus Torvalds struct ib_qp_attr *qp_attr, 5651da177e4SLinus Torvalds int qp_attr_mask) 5661da177e4SLinus Torvalds { 5679bc57e2dSRalph Campbell return qp->device->modify_qp(qp, qp_attr, qp_attr_mask, NULL); 5681da177e4SLinus Torvalds } 5691da177e4SLinus Torvalds EXPORT_SYMBOL(ib_modify_qp); 5701da177e4SLinus Torvalds 5711da177e4SLinus Torvalds int ib_query_qp(struct ib_qp *qp, 5721da177e4SLinus Torvalds struct ib_qp_attr *qp_attr, 5731da177e4SLinus Torvalds int qp_attr_mask, 5741da177e4SLinus Torvalds struct ib_qp_init_attr *qp_init_attr) 5751da177e4SLinus Torvalds { 5761da177e4SLinus Torvalds return qp->device->query_qp ? 5771da177e4SLinus Torvalds qp->device->query_qp(qp, qp_attr, qp_attr_mask, qp_init_attr) : 5781da177e4SLinus Torvalds -ENOSYS; 5791da177e4SLinus Torvalds } 5801da177e4SLinus Torvalds EXPORT_SYMBOL(ib_query_qp); 5811da177e4SLinus Torvalds 5821da177e4SLinus Torvalds int ib_destroy_qp(struct ib_qp *qp) 5831da177e4SLinus Torvalds { 5841da177e4SLinus Torvalds struct ib_pd *pd; 5851da177e4SLinus Torvalds struct ib_cq *scq, *rcq; 5861da177e4SLinus Torvalds struct ib_srq *srq; 5871da177e4SLinus Torvalds int ret; 5881da177e4SLinus Torvalds 5891da177e4SLinus Torvalds pd = qp->pd; 5901da177e4SLinus Torvalds scq = qp->send_cq; 5911da177e4SLinus Torvalds rcq = qp->recv_cq; 5921da177e4SLinus Torvalds srq = qp->srq; 5931da177e4SLinus Torvalds 5941da177e4SLinus Torvalds ret = qp->device->destroy_qp(qp); 5951da177e4SLinus Torvalds if (!ret) { 5961da177e4SLinus Torvalds atomic_dec(&pd->usecnt); 5971da177e4SLinus Torvalds atomic_dec(&scq->usecnt); 5981da177e4SLinus Torvalds atomic_dec(&rcq->usecnt); 5991da177e4SLinus Torvalds if (srq) 6001da177e4SLinus Torvalds atomic_dec(&srq->usecnt); 6011da177e4SLinus Torvalds } 6021da177e4SLinus Torvalds 6031da177e4SLinus Torvalds return ret; 6041da177e4SLinus Torvalds } 6051da177e4SLinus Torvalds EXPORT_SYMBOL(ib_destroy_qp); 6061da177e4SLinus Torvalds 6071da177e4SLinus Torvalds /* Completion queues */ 6081da177e4SLinus Torvalds 6091da177e4SLinus Torvalds struct ib_cq *ib_create_cq(struct ib_device *device, 6101da177e4SLinus Torvalds ib_comp_handler comp_handler, 6111da177e4SLinus Torvalds void (*event_handler)(struct ib_event *, void *), 612f4fd0b22SMichael S. Tsirkin void *cq_context, int cqe, int comp_vector) 6131da177e4SLinus Torvalds { 6141da177e4SLinus Torvalds struct ib_cq *cq; 6151da177e4SLinus Torvalds 616f4fd0b22SMichael S. Tsirkin cq = device->create_cq(device, cqe, comp_vector, NULL, NULL); 6171da177e4SLinus Torvalds 6181da177e4SLinus Torvalds if (!IS_ERR(cq)) { 6191da177e4SLinus Torvalds cq->device = device; 620b5e81bf5SRoland Dreier cq->uobject = NULL; 6211da177e4SLinus Torvalds cq->comp_handler = comp_handler; 6221da177e4SLinus Torvalds cq->event_handler = event_handler; 6231da177e4SLinus Torvalds cq->cq_context = cq_context; 6241da177e4SLinus Torvalds atomic_set(&cq->usecnt, 0); 6251da177e4SLinus Torvalds } 6261da177e4SLinus Torvalds 6271da177e4SLinus Torvalds return cq; 6281da177e4SLinus Torvalds } 6291da177e4SLinus Torvalds EXPORT_SYMBOL(ib_create_cq); 6301da177e4SLinus Torvalds 6311da177e4SLinus Torvalds int ib_destroy_cq(struct ib_cq *cq) 6321da177e4SLinus Torvalds { 6331da177e4SLinus Torvalds if (atomic_read(&cq->usecnt)) 6341da177e4SLinus Torvalds return -EBUSY; 6351da177e4SLinus Torvalds 6361da177e4SLinus Torvalds return cq->device->destroy_cq(cq); 6371da177e4SLinus Torvalds } 6381da177e4SLinus Torvalds EXPORT_SYMBOL(ib_destroy_cq); 6391da177e4SLinus Torvalds 640a74cd4afSRoland Dreier int ib_resize_cq(struct ib_cq *cq, int cqe) 6411da177e4SLinus Torvalds { 64240de2e54SRoland Dreier return cq->device->resize_cq ? 64333b9b3eeSRoland Dreier cq->device->resize_cq(cq, cqe, NULL) : -ENOSYS; 6441da177e4SLinus Torvalds } 6451da177e4SLinus Torvalds EXPORT_SYMBOL(ib_resize_cq); 6461da177e4SLinus Torvalds 6471da177e4SLinus Torvalds /* Memory regions */ 6481da177e4SLinus Torvalds 6491da177e4SLinus Torvalds struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags) 6501da177e4SLinus Torvalds { 6511da177e4SLinus Torvalds struct ib_mr *mr; 6521da177e4SLinus Torvalds 6531da177e4SLinus Torvalds mr = pd->device->get_dma_mr(pd, mr_access_flags); 6541da177e4SLinus Torvalds 6551da177e4SLinus Torvalds if (!IS_ERR(mr)) { 6561da177e4SLinus Torvalds mr->device = pd->device; 6571da177e4SLinus Torvalds mr->pd = pd; 658b5e81bf5SRoland Dreier mr->uobject = NULL; 6591da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 6601da177e4SLinus Torvalds atomic_set(&mr->usecnt, 0); 6611da177e4SLinus Torvalds } 6621da177e4SLinus Torvalds 6631da177e4SLinus Torvalds return mr; 6641da177e4SLinus Torvalds } 6651da177e4SLinus Torvalds EXPORT_SYMBOL(ib_get_dma_mr); 6661da177e4SLinus Torvalds 6671da177e4SLinus Torvalds struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd, 6681da177e4SLinus Torvalds struct ib_phys_buf *phys_buf_array, 6691da177e4SLinus Torvalds int num_phys_buf, 6701da177e4SLinus Torvalds int mr_access_flags, 6711da177e4SLinus Torvalds u64 *iova_start) 6721da177e4SLinus Torvalds { 6731da177e4SLinus Torvalds struct ib_mr *mr; 6741da177e4SLinus Torvalds 6751da177e4SLinus Torvalds mr = pd->device->reg_phys_mr(pd, phys_buf_array, num_phys_buf, 6761da177e4SLinus Torvalds mr_access_flags, iova_start); 6771da177e4SLinus Torvalds 6781da177e4SLinus Torvalds if (!IS_ERR(mr)) { 6791da177e4SLinus Torvalds mr->device = pd->device; 6801da177e4SLinus Torvalds mr->pd = pd; 681b5e81bf5SRoland Dreier mr->uobject = NULL; 6821da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 6831da177e4SLinus Torvalds atomic_set(&mr->usecnt, 0); 6841da177e4SLinus Torvalds } 6851da177e4SLinus Torvalds 6861da177e4SLinus Torvalds return mr; 6871da177e4SLinus Torvalds } 6881da177e4SLinus Torvalds EXPORT_SYMBOL(ib_reg_phys_mr); 6891da177e4SLinus Torvalds 6901da177e4SLinus Torvalds int ib_rereg_phys_mr(struct ib_mr *mr, 6911da177e4SLinus Torvalds int mr_rereg_mask, 6921da177e4SLinus Torvalds struct ib_pd *pd, 6931da177e4SLinus Torvalds struct ib_phys_buf *phys_buf_array, 6941da177e4SLinus Torvalds int num_phys_buf, 6951da177e4SLinus Torvalds int mr_access_flags, 6961da177e4SLinus Torvalds u64 *iova_start) 6971da177e4SLinus Torvalds { 6981da177e4SLinus Torvalds struct ib_pd *old_pd; 6991da177e4SLinus Torvalds int ret; 7001da177e4SLinus Torvalds 7011da177e4SLinus Torvalds if (!mr->device->rereg_phys_mr) 7021da177e4SLinus Torvalds return -ENOSYS; 7031da177e4SLinus Torvalds 7041da177e4SLinus Torvalds if (atomic_read(&mr->usecnt)) 7051da177e4SLinus Torvalds return -EBUSY; 7061da177e4SLinus Torvalds 7071da177e4SLinus Torvalds old_pd = mr->pd; 7081da177e4SLinus Torvalds 7091da177e4SLinus Torvalds ret = mr->device->rereg_phys_mr(mr, mr_rereg_mask, pd, 7101da177e4SLinus Torvalds phys_buf_array, num_phys_buf, 7111da177e4SLinus Torvalds mr_access_flags, iova_start); 7121da177e4SLinus Torvalds 7131da177e4SLinus Torvalds if (!ret && (mr_rereg_mask & IB_MR_REREG_PD)) { 7141da177e4SLinus Torvalds atomic_dec(&old_pd->usecnt); 7151da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 7161da177e4SLinus Torvalds } 7171da177e4SLinus Torvalds 7181da177e4SLinus Torvalds return ret; 7191da177e4SLinus Torvalds } 7201da177e4SLinus Torvalds EXPORT_SYMBOL(ib_rereg_phys_mr); 7211da177e4SLinus Torvalds 7221da177e4SLinus Torvalds int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr) 7231da177e4SLinus Torvalds { 7241da177e4SLinus Torvalds return mr->device->query_mr ? 7251da177e4SLinus Torvalds mr->device->query_mr(mr, mr_attr) : -ENOSYS; 7261da177e4SLinus Torvalds } 7271da177e4SLinus Torvalds EXPORT_SYMBOL(ib_query_mr); 7281da177e4SLinus Torvalds 7291da177e4SLinus Torvalds int ib_dereg_mr(struct ib_mr *mr) 7301da177e4SLinus Torvalds { 7311da177e4SLinus Torvalds struct ib_pd *pd; 7321da177e4SLinus Torvalds int ret; 7331da177e4SLinus Torvalds 7341da177e4SLinus Torvalds if (atomic_read(&mr->usecnt)) 7351da177e4SLinus Torvalds return -EBUSY; 7361da177e4SLinus Torvalds 7371da177e4SLinus Torvalds pd = mr->pd; 7381da177e4SLinus Torvalds ret = mr->device->dereg_mr(mr); 7391da177e4SLinus Torvalds if (!ret) 7401da177e4SLinus Torvalds atomic_dec(&pd->usecnt); 7411da177e4SLinus Torvalds 7421da177e4SLinus Torvalds return ret; 7431da177e4SLinus Torvalds } 7441da177e4SLinus Torvalds EXPORT_SYMBOL(ib_dereg_mr); 7451da177e4SLinus Torvalds 7461da177e4SLinus Torvalds /* Memory windows */ 7471da177e4SLinus Torvalds 7481da177e4SLinus Torvalds struct ib_mw *ib_alloc_mw(struct ib_pd *pd) 7491da177e4SLinus Torvalds { 7501da177e4SLinus Torvalds struct ib_mw *mw; 7511da177e4SLinus Torvalds 7521da177e4SLinus Torvalds if (!pd->device->alloc_mw) 7531da177e4SLinus Torvalds return ERR_PTR(-ENOSYS); 7541da177e4SLinus Torvalds 7551da177e4SLinus Torvalds mw = pd->device->alloc_mw(pd); 7561da177e4SLinus Torvalds if (!IS_ERR(mw)) { 7571da177e4SLinus Torvalds mw->device = pd->device; 7581da177e4SLinus Torvalds mw->pd = pd; 759b5e81bf5SRoland Dreier mw->uobject = NULL; 7601da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 7611da177e4SLinus Torvalds } 7621da177e4SLinus Torvalds 7631da177e4SLinus Torvalds return mw; 7641da177e4SLinus Torvalds } 7651da177e4SLinus Torvalds EXPORT_SYMBOL(ib_alloc_mw); 7661da177e4SLinus Torvalds 7671da177e4SLinus Torvalds int ib_dealloc_mw(struct ib_mw *mw) 7681da177e4SLinus Torvalds { 7691da177e4SLinus Torvalds struct ib_pd *pd; 7701da177e4SLinus Torvalds int ret; 7711da177e4SLinus Torvalds 7721da177e4SLinus Torvalds pd = mw->pd; 7731da177e4SLinus Torvalds ret = mw->device->dealloc_mw(mw); 7741da177e4SLinus Torvalds if (!ret) 7751da177e4SLinus Torvalds atomic_dec(&pd->usecnt); 7761da177e4SLinus Torvalds 7771da177e4SLinus Torvalds return ret; 7781da177e4SLinus Torvalds } 7791da177e4SLinus Torvalds EXPORT_SYMBOL(ib_dealloc_mw); 7801da177e4SLinus Torvalds 7811da177e4SLinus Torvalds /* "Fast" memory regions */ 7821da177e4SLinus Torvalds 7831da177e4SLinus Torvalds struct ib_fmr *ib_alloc_fmr(struct ib_pd *pd, 7841da177e4SLinus Torvalds int mr_access_flags, 7851da177e4SLinus Torvalds struct ib_fmr_attr *fmr_attr) 7861da177e4SLinus Torvalds { 7871da177e4SLinus Torvalds struct ib_fmr *fmr; 7881da177e4SLinus Torvalds 7891da177e4SLinus Torvalds if (!pd->device->alloc_fmr) 7901da177e4SLinus Torvalds return ERR_PTR(-ENOSYS); 7911da177e4SLinus Torvalds 7921da177e4SLinus Torvalds fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr); 7931da177e4SLinus Torvalds if (!IS_ERR(fmr)) { 7941da177e4SLinus Torvalds fmr->device = pd->device; 7951da177e4SLinus Torvalds fmr->pd = pd; 7961da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 7971da177e4SLinus Torvalds } 7981da177e4SLinus Torvalds 7991da177e4SLinus Torvalds return fmr; 8001da177e4SLinus Torvalds } 8011da177e4SLinus Torvalds EXPORT_SYMBOL(ib_alloc_fmr); 8021da177e4SLinus Torvalds 8031da177e4SLinus Torvalds int ib_unmap_fmr(struct list_head *fmr_list) 8041da177e4SLinus Torvalds { 8051da177e4SLinus Torvalds struct ib_fmr *fmr; 8061da177e4SLinus Torvalds 8071da177e4SLinus Torvalds if (list_empty(fmr_list)) 8081da177e4SLinus Torvalds return 0; 8091da177e4SLinus Torvalds 8101da177e4SLinus Torvalds fmr = list_entry(fmr_list->next, struct ib_fmr, list); 8111da177e4SLinus Torvalds return fmr->device->unmap_fmr(fmr_list); 8121da177e4SLinus Torvalds } 8131da177e4SLinus Torvalds EXPORT_SYMBOL(ib_unmap_fmr); 8141da177e4SLinus Torvalds 8151da177e4SLinus Torvalds int ib_dealloc_fmr(struct ib_fmr *fmr) 8161da177e4SLinus Torvalds { 8171da177e4SLinus Torvalds struct ib_pd *pd; 8181da177e4SLinus Torvalds int ret; 8191da177e4SLinus Torvalds 8201da177e4SLinus Torvalds pd = fmr->pd; 8211da177e4SLinus Torvalds ret = fmr->device->dealloc_fmr(fmr); 8221da177e4SLinus Torvalds if (!ret) 8231da177e4SLinus Torvalds atomic_dec(&pd->usecnt); 8241da177e4SLinus Torvalds 8251da177e4SLinus Torvalds return ret; 8261da177e4SLinus Torvalds } 8271da177e4SLinus Torvalds EXPORT_SYMBOL(ib_dealloc_fmr); 8281da177e4SLinus Torvalds 8291da177e4SLinus Torvalds /* Multicast groups */ 8301da177e4SLinus Torvalds 8311da177e4SLinus Torvalds int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) 8321da177e4SLinus Torvalds { 8330c33aeedSJack Morgenstein if (!qp->device->attach_mcast) 8340c33aeedSJack Morgenstein return -ENOSYS; 8350c33aeedSJack Morgenstein if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) 8360c33aeedSJack Morgenstein return -EINVAL; 8370c33aeedSJack Morgenstein 8380c33aeedSJack Morgenstein return qp->device->attach_mcast(qp, gid, lid); 8391da177e4SLinus Torvalds } 8401da177e4SLinus Torvalds EXPORT_SYMBOL(ib_attach_mcast); 8411da177e4SLinus Torvalds 8421da177e4SLinus Torvalds int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) 8431da177e4SLinus Torvalds { 8440c33aeedSJack Morgenstein if (!qp->device->detach_mcast) 8450c33aeedSJack Morgenstein return -ENOSYS; 8460c33aeedSJack Morgenstein if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) 8470c33aeedSJack Morgenstein return -EINVAL; 8480c33aeedSJack Morgenstein 8490c33aeedSJack Morgenstein return qp->device->detach_mcast(qp, gid, lid); 8501da177e4SLinus Torvalds } 8511da177e4SLinus Torvalds EXPORT_SYMBOL(ib_detach_mcast); 852