verbs.c revision d3d72d909e783d048ee39046aa7b4fa798a4dda8
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2004 Mellanox Technologies Ltd.  All rights reserved.
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2004 Infinicon Corporation.  All rights reserved.
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2004 Intel Corporation.  All rights reserved.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
72a1d9b7f09aaaacf235656cb32a40ba2c79590b3Roland Dreier * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
833b9b3ee9709b19c4f02ab91571d53540d05c3d1Roland Dreier * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software is available to you under a choice of one of two
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * licenses.  You may choose to be licensed under the terms of the GNU
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * General Public License (GPL) Version 2, available from the file
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * COPYING in the main directory of this source tree, or the
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OpenIB.org BSD license below:
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     Redistribution and use in source and binary forms, with or
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     without modification, are permitted provided that the following
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *     conditions are met:
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      - Redistributions of source code must retain the above
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        copyright notice, this list of conditions and the following
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        disclaimer.
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      - Redistributions in binary form must reproduce the above
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        copyright notice, this list of conditions and the following
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        disclaimer in the documentation and/or other materials
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        provided with the distribution.
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SOFTWARE.
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/err.h>
418c65b4a60450590e79a28e9717ceffa9e4debb3fTim Schmielau#include <linux/string.h>
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
43a4d61e84804f3b14cc35c5e2af768a07c0f64ef6Roland Dreier#include <rdma/ib_verbs.h>
44a4d61e84804f3b14cc35c5e2af768a07c0f64ef6Roland Dreier#include <rdma/ib_cache.h>
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
46bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinint ib_rate_to_mult(enum ib_rate rate)
47bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{
48bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	switch (rate) {
49bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_2_5_GBPS: return  1;
50bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_5_GBPS:   return  2;
51bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_10_GBPS:  return  4;
52bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_20_GBPS:  return  8;
53bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_30_GBPS:  return 12;
54bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_40_GBPS:  return 16;
55bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_60_GBPS:  return 24;
56bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_80_GBPS:  return 32;
57bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_120_GBPS: return 48;
58bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	default:	       return -1;
59bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	}
60bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein}
61bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack MorgensteinEXPORT_SYMBOL(ib_rate_to_mult);
62bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein
63bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinenum ib_rate mult_to_ib_rate(int mult)
64bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{
65bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	switch (mult) {
66bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 1:  return IB_RATE_2_5_GBPS;
67bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 2:  return IB_RATE_5_GBPS;
68bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 4:  return IB_RATE_10_GBPS;
69bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 8:  return IB_RATE_20_GBPS;
70bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 12: return IB_RATE_30_GBPS;
71bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 16: return IB_RATE_40_GBPS;
72bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 24: return IB_RATE_60_GBPS;
73bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 32: return IB_RATE_80_GBPS;
74bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 48: return IB_RATE_120_GBPS;
75bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	default: return IB_RATE_PORT_CURRENT;
76bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	}
77bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein}
78bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack MorgensteinEXPORT_SYMBOL(mult_to_ib_rate);
79bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein
8007ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tuckerenum rdma_transport_type
8107ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tuckerrdma_node_get_transport(enum rdma_node_type node_type)
8207ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker{
8307ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	switch (node_type) {
8407ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_IB_CA:
8507ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_IB_SWITCH:
8607ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_IB_ROUTER:
8707ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		return RDMA_TRANSPORT_IB;
8807ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_RNIC:
8907ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		return RDMA_TRANSPORT_IWARP;
9007ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	default:
9107ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		BUG();
9207ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		return 0;
9307ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	}
9407ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker}
9507ebafbaaa72aa6a35472879008f5a1d1d469a0cTom TuckerEXPORT_SYMBOL(rdma_node_get_transport);
9607ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker
97a3f5adaf491490089215f863a61b9422fae902f8Eli Cohenenum rdma_link_layer rdma_port_get_link_layer(struct ib_device *device, u8 port_num)
98a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen{
99a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	if (device->get_link_layer)
100a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen		return device->get_link_layer(device, port_num);
101a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen
102a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	switch (rdma_node_get_transport(device->node_type)) {
103a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	case RDMA_TRANSPORT_IB:
104a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen		return IB_LINK_LAYER_INFINIBAND;
105a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	case RDMA_TRANSPORT_IWARP:
106a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen		return IB_LINK_LAYER_ETHERNET;
107a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	default:
108a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen		return IB_LINK_LAYER_UNSPECIFIED;
109a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	}
110a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen}
111a3f5adaf491490089215f863a61b9422fae902f8Eli CohenEXPORT_SYMBOL(rdma_port_get_link_layer);
112a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Protection domains */
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_pd *ib_alloc_pd(struct ib_device *device)
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
119b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier	pd = device->alloc_pd(device, NULL, NULL);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(pd)) {
122b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		pd->device  = device;
123b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		pd->uobject = NULL;
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&pd->usecnt, 0);
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pd;
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_pd);
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_pd(struct ib_pd *pd)
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&pd->usecnt))
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pd->device->dealloc_pd(pd);
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_pd);
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Address handles */
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_ah *ah;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ah = pd->device->create_ah(pd, ah_attr);
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(ah)) {
149b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->device  = pd->device;
150b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->pd      = pd;
151b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->uobject = NULL;
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah;
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_ah);
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1594e00d69454a8747798de11dc4eeef1edeee5ce98Sean Heftyint ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
1604e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		       struct ib_grh *grh, struct ib_ah_attr *ah_attr)
161513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock{
162513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	u32 flow_class;
163513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	u16 gid_index;
164513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	int ret;
165513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
1664e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	memset(ah_attr, 0, sizeof *ah_attr);
1674e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->dlid = wc->slid;
1684e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->sl = wc->sl;
1694e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->src_path_bits = wc->dlid_path_bits;
1704e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->port_num = port_num;
171513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
172513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	if (wc->wc_flags & IB_WC_GRH) {
1734e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->ah_flags = IB_AH_GRH;
1744e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.dgid = grh->sgid;
175513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
1764e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ret = ib_find_cached_gid(device, &grh->dgid, &port_num,
177513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock					 &gid_index);
178513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		if (ret)
1794e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty			return ret;
180513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
1814e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.sgid_index = (u8) gid_index;
182497677ab940e637a41351dca6610bc4320abc8f1Hal Rosenstock		flow_class = be32_to_cpu(grh->version_tclass_flow);
1834e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.flow_label = flow_class & 0xFFFFF;
18447645d8d25387c08bb3ccd84e1405c3776f21d24Sean Hefty		ah_attr->grh.hop_limit = 0xFF;
1854e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
186513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	}
1874e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	return 0;
1884e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty}
1894e00d69454a8747798de11dc4eeef1edeee5ce98Sean HeftyEXPORT_SYMBOL(ib_init_ah_from_wc);
1904e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty
1914e00d69454a8747798de11dc4eeef1edeee5ce98Sean Heftystruct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc,
1924e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty				   struct ib_grh *grh, u8 port_num)
1934e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty{
1944e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	struct ib_ah_attr ah_attr;
1954e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	int ret;
1964e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty
1974e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ret = ib_init_ah_from_wc(pd->device, port_num, wc, grh, &ah_attr);
1984e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	if (ret)
1994e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		return ERR_PTR(ret);
200513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
201513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	return ib_create_ah(pd, &ah_attr);
202513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock}
203513789ed995fb2ba72ba2a5bee53ea11d1170580Hal RosenstockEXPORT_SYMBOL(ib_create_ah_from_wc);
204513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah->device->modify_ah ?
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ah->device->modify_ah(ah, ah_attr) :
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_modify_ah);
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah->device->query_ah ?
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ah->device->query_ah(ah, ah_attr) :
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_ah);
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_ah(struct ib_ah *ah)
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = ah->pd;
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = ah->device->destroy_ah(ah);
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_ah);
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
235d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier/* Shared receive queues */
236d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
237d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierstruct ib_srq *ib_create_srq(struct ib_pd *pd,
238d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier			     struct ib_srq_init_attr *srq_init_attr)
239d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
240d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	struct ib_srq *srq;
241d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
242d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (!pd->device->create_srq)
243d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		return ERR_PTR(-ENOSYS);
244d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
245d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	srq = pd->device->create_srq(pd, srq_init_attr, NULL);
246d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
247d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (!IS_ERR(srq)) {
248d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->device    	   = pd->device;
249d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->pd        	   = pd;
250d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->uobject       = NULL;
251d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->event_handler = srq_init_attr->event_handler;
252d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->srq_context   = srq_init_attr->srq_context;
25396104eda01695a26da2c8f7423ec0ba3509c8c97Sean Hefty		srq->srq_type      = srq_init_attr->srq_type;
254418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		if (srq->srq_type == IB_SRQT_XRC) {
255418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd;
256418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			srq->ext.xrc.cq   = srq_init_attr->ext.xrc.cq;
257418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			atomic_inc(&srq->ext.xrc.xrcd->usecnt);
258418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			atomic_inc(&srq->ext.xrc.cq->usecnt);
259418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		}
260d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_inc(&pd->usecnt);
261d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_set(&srq->usecnt, 0);
262d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	}
263d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
264d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return srq;
265d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
266d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_create_srq);
267d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
268d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_modify_srq(struct ib_srq *srq,
269d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		  struct ib_srq_attr *srq_attr,
270d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		  enum ib_srq_attr_mask srq_attr_mask)
271d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
2727ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak	return srq->device->modify_srq ?
2737ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak		srq->device->modify_srq(srq, srq_attr, srq_attr_mask, NULL) :
2747ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak		-ENOSYS;
275d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
276d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_modify_srq);
277d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
278d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_query_srq(struct ib_srq *srq,
279d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		 struct ib_srq_attr *srq_attr)
280d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
281d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return srq->device->query_srq ?
282d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->device->query_srq(srq, srq_attr) : -ENOSYS;
283d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
284d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_query_srq);
285d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
286d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_destroy_srq(struct ib_srq *srq)
287d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
288d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	struct ib_pd *pd;
289418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	enum ib_srq_type srq_type;
290418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	struct ib_xrcd *uninitialized_var(xrcd);
291418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	struct ib_cq *uninitialized_var(cq);
292d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	int ret;
293d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
294d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (atomic_read(&srq->usecnt))
295d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		return -EBUSY;
296d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
297d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	pd = srq->pd;
298418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	srq_type = srq->srq_type;
299418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	if (srq_type == IB_SRQT_XRC) {
300418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		xrcd = srq->ext.xrc.xrcd;
301418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		cq = srq->ext.xrc.cq;
302418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	}
303d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
304d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	ret = srq->device->destroy_srq(srq);
305418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	if (!ret) {
306d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_dec(&pd->usecnt);
307418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		if (srq_type == IB_SRQT_XRC) {
308418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			atomic_dec(&xrcd->usecnt);
309418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			atomic_dec(&cq->usecnt);
310418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		}
311418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	}
312d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
313d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return ret;
314d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
315d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_destroy_srq);
316d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Queue pairs */
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
319d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Heftystatic void __ib_insert_xrcd_qp(struct ib_xrcd *xrcd, struct ib_qp *qp)
320d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty{
321d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	mutex_lock(&xrcd->tgt_qp_mutex);
322d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	list_add(&qp->xrcd_list, &xrcd->tgt_qp_list);
323d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	mutex_unlock(&xrcd->tgt_qp_mutex);
324d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty}
325d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
326d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Heftystatic void __ib_remove_xrcd_qp(struct ib_xrcd *xrcd, struct ib_qp *qp)
327d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty{
328d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	mutex_lock(&xrcd->tgt_qp_mutex);
329d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	list_del(&qp->xrcd_list);
330d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	mutex_unlock(&xrcd->tgt_qp_mutex);
331d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty}
332d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_qp *ib_create_qp(struct ib_pd *pd,
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct ib_qp_init_attr *qp_init_attr)
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_qp *qp;
337b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	struct ib_device *device;
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
339b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	device = pd ? pd->device : qp_init_attr->xrcd->device;
340b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	qp = device->create_qp(pd, qp_init_attr, NULL);
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(qp)) {
343b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		qp->device = device;
344b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty
345b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {
346b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->pd = NULL;
347b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->send_cq = qp->recv_cq = NULL;
348b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->srq = NULL;
349b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->xrcd = qp_init_attr->xrcd;
350b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_inc(&qp_init_attr->xrcd->usecnt);
351d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty			__ib_insert_xrcd_qp(qp_init_attr->xrcd, qp);
352b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		} else {
353b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			if (qp_init_attr->qp_type == IB_QPT_XRC_INI) {
354b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				qp->recv_cq = NULL;
355b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				qp->srq = NULL;
356b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			} else {
357b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				qp->recv_cq = qp_init_attr->recv_cq;
358b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				atomic_inc(&qp_init_attr->recv_cq->usecnt);
359b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				qp->srq = qp_init_attr->srq;
360b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				if (qp->srq)
361b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty					atomic_inc(&qp_init_attr->srq->usecnt);
362b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			}
363b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty
364b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->pd	    = pd;
365b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->send_cq = qp_init_attr->send_cq;
366b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->xrcd    = NULL;
367b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty
368b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_inc(&pd->usecnt);
369b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_inc(&qp_init_attr->send_cq->usecnt);
370b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		}
371b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty
372b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		qp->uobject       = NULL;
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->event_handler = qp_init_attr->event_handler;
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->qp_context    = qp_init_attr->qp_context;
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->qp_type	  = qp_init_attr->qp_type;
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp;
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_qp);
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3828a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreierstatic const struct {
3838a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	int			valid;
384b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	enum ib_qp_attr_mask	req_param[IB_QPT_MAX];
385b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	enum ib_qp_attr_mask	opt_param[IB_QPT_MAX];
3868a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
3878a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_RESET] = {
3888a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
3898a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_INIT]  = {
3908a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
3918a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.req_param = {
3928a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
3938a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
3948a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
3958a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_PKEY_INDEX		|
3968a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
3978a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
3988a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_PKEY_INDEX		|
3998a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
4008a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
401b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_PKEY_INDEX		|
402b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PORT			|
403b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS),
404b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_PKEY_INDEX		|
405b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PORT			|
406b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS),
4078a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
4088a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4098a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
4108a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
4128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
4138a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
4148a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_INIT]  = {
4158a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
4168a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
4178a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_INIT]  = {
4188a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
4198a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
4208a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
4218a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
4228a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4238a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_PKEY_INDEX		|
4248a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
4258a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
4268a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_PKEY_INDEX		|
4278a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
4288a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
429b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_PKEY_INDEX		|
430b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PORT			|
431b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS),
432b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_PKEY_INDEX		|
433b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PORT			|
434b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS),
4358a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
4368a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4378a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
4388a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4398a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
4408a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
4418a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTR]   = {
4428a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
4438a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.req_param = {
4448a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_AV			|
4458a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MTU			|
4468a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_DEST_QPN			|
4478a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RQ_PSN),
4488a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_AV			|
4498a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MTU			|
4508a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_DEST_QPN			|
4518a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RQ_PSN			|
4528a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_DEST_RD_ATOMIC	|
4538a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER),
454b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_AV			|
455b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MTU			|
456b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_DEST_QPN			|
457b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RQ_PSN),
458b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_AV			|
459b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MTU			|
460b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_DEST_QPN			|
461b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RQ_PSN			|
462b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MAX_DEST_RD_ATOMIC	|
463b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MIN_RNR_TIMER),
4648a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			},
4658a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
4668a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
4678a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
4688a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UC]  = (IB_QP_ALT_PATH			|
4698a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
4708a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PKEY_INDEX),
4718a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_RC]  = (IB_QP_ALT_PATH			|
4728a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
4738a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PKEY_INDEX),
474b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				 [IB_QPT_XRC_INI] = (IB_QP_ALT_PATH		|
475b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ACCESS_FLAGS		|
476b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_PKEY_INDEX),
477b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				 [IB_QPT_XRC_TGT] = (IB_QP_ALT_PATH		|
478b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ACCESS_FLAGS		|
479b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_PKEY_INDEX),
4808a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
4818a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
4828a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
4838a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
4848a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			 }
4858a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
4868a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
4878a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_RTR]   = {
4888a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
4898a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
4908a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
4918a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
4928a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.req_param = {
4938a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = IB_QP_SQ_PSN,
4948a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = IB_QP_SQ_PSN,
4958a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_TIMEOUT			|
4968a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RETRY_CNT			|
4978a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RNR_RETRY			|
4988a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_SQ_PSN			|
4998a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_QP_RD_ATOMIC),
500b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_TIMEOUT		|
501b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RETRY_CNT			|
502b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RNR_RETRY			|
503b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_SQ_PSN			|
504b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MAX_QP_RD_ATOMIC),
505b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_TIMEOUT		|
506b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_SQ_PSN),
5078a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = IB_QP_SQ_PSN,
5088a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = IB_QP_SQ_PSN,
5098a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			},
5108a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
5118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UD]  = (IB_QP_CUR_STATE		|
5128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
5138a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UC]  = (IB_QP_CUR_STATE		|
5148a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ALT_PATH			|
5158a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
5168a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PATH_MIG_STATE),
5178a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_RC]  = (IB_QP_CUR_STATE		|
5188a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ALT_PATH			|
5198a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
5208a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_MIN_RNR_TIMER		|
5218a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PATH_MIG_STATE),
522b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				 [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE		|
523b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ALT_PATH			|
524b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ACCESS_FLAGS		|
525b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_PATH_MIG_STATE),
526b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				 [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE		|
527b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ALT_PATH			|
528b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ACCESS_FLAGS		|
529b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_MIN_RNR_TIMER		|
530b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_PATH_MIG_STATE),
5318a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_SMI] = (IB_QP_CUR_STATE		|
5328a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
5338a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_GSI] = (IB_QP_CUR_STATE		|
5348a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
5358a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			 }
5368a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
5378a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
5388a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_RTS]   = {
5398a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
5408a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
5418a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
5428a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
5438a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
5448a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_CUR_STATE			|
5458a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5464546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak				[IB_QPT_UC]  = (IB_QP_CUR_STATE			|
5474546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak						IB_QP_ACCESS_FLAGS		|
5488a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
5498a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
5504546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak				[IB_QPT_RC]  = (IB_QP_CUR_STATE			|
5514546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak						IB_QP_ACCESS_FLAGS		|
5528a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
5538a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE		|
5548a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER),
555b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_CUR_STATE		|
556b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
557b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
558b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE),
559b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE		|
560b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
561b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
562b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE		|
563b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MIN_RNR_TIMER),
5648a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_CUR_STATE			|
5658a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5668a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_CUR_STATE			|
5678a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5688a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
5698a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
5708a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_SQD]   = {
5718a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
5728a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
5738a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
5748a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
5758a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
576b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
577b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = IB_QP_EN_SQD_ASYNC_NOTIFY, /* ??? */
5788a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
5798a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY
5808a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
5818a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
5828a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
5838a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_SQD]   = {
5848a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
5858a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
5868a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
5878a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
5888a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
5898a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_CUR_STATE			|
5908a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5918a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_CUR_STATE			|
5928a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
5938a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
5948a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
5958a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_CUR_STATE			|
5968a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
5978a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
5988a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER		|
5998a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
600b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_CUR_STATE		|
601b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
602b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
603b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE),
604b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE		|
605b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
606b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
607b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MIN_RNR_TIMER		|
608b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE),
6098a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_CUR_STATE			|
6108a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
6118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_CUR_STATE			|
6128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
6138a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
6148a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
6158a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_SQD]   = {
6168a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
6178a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
6188a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
6198a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
6208a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_AV			|
6218a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
6228a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
6238a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PKEY_INDEX		|
6248a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
6258a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_PORT			|
6268a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_AV			|
6278a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_TIMEOUT			|
6288a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RETRY_CNT			|
6298a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RNR_RETRY			|
6308a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_QP_RD_ATOMIC		|
6318a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_DEST_RD_ATOMIC	|
6328a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
6338a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
6348a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PKEY_INDEX		|
6358a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER		|
6368a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
637b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_PORT			|
638b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_AV			|
639b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_TIMEOUT			|
640b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RETRY_CNT			|
641b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RNR_RETRY			|
642b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MAX_QP_RD_ATOMIC		|
643b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
644b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
645b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PKEY_INDEX		|
646b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE),
647b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_PORT			|
648b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_AV			|
649b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_TIMEOUT			|
650b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MAX_DEST_RD_ATOMIC	|
651b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
652b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
653b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PKEY_INDEX		|
654b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MIN_RNR_TIMER		|
655b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE),
6568a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
6578a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
6588a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
6598a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
6608a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
6618a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
6628a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
6638a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_SQE]   = {
6648a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
6658a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
6668a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
6678a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
6688a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
6698a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_CUR_STATE			|
6708a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
6718a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_CUR_STATE			|
6728a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
6738a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_CUR_STATE			|
6748a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
6758a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_CUR_STATE			|
6768a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
6778a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
6788a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
6798a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
6808a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_ERR] = {
6818a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
6828a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 }
6838a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	}
6848a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier};
6858a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
6868a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreierint ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
6878a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		       enum ib_qp_type type, enum ib_qp_attr_mask mask)
6888a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier{
6898a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	enum ib_qp_attr_mask req_param, opt_param;
6908a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
6918a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (cur_state  < 0 || cur_state  > IB_QPS_ERR ||
6928a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	    next_state < 0 || next_state > IB_QPS_ERR)
6938a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
6948a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
6958a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (mask & IB_QP_CUR_STATE  &&
6968a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	    cur_state != IB_QPS_RTR && cur_state != IB_QPS_RTS &&
6978a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	    cur_state != IB_QPS_SQD && cur_state != IB_QPS_SQE)
6988a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
6998a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
7008a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (!qp_state_table[cur_state][next_state].valid)
7018a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
7028a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
7038a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	req_param = qp_state_table[cur_state][next_state].req_param[type];
7048a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	opt_param = qp_state_table[cur_state][next_state].opt_param[type];
7058a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
7068a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if ((mask & req_param) != req_param)
7078a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
7088a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
7098a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (mask & ~(req_param | opt_param | IB_QP_STATE))
7108a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
7118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
7128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	return 1;
7138a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier}
7148a51866f08103ba04894ce0f65eef567ddc3ed40Roland DreierEXPORT_SYMBOL(ib_modify_qp_is_ok);
7158a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_modify_qp(struct ib_qp *qp,
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 struct ib_qp_attr *qp_attr,
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 int qp_attr_mask)
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7209bc57e2d19db4da81c1150120658cc3658a99ed4Ralph Campbell	return qp->device->modify_qp(qp, qp_attr, qp_attr_mask, NULL);
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_modify_qp);
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_qp(struct ib_qp *qp,
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ib_qp_attr *qp_attr,
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int qp_attr_mask,
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ib_qp_init_attr *qp_init_attr)
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp->device->query_qp ?
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->device->query_qp(qp, qp_attr, qp_attr_mask, qp_init_attr) :
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_qp);
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_qp(struct ib_qp *qp)
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_cq *scq, *rcq;
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_srq *srq;
740b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	struct ib_xrcd *xrcd;
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
743b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	pd   = qp->pd;
744b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	scq  = qp->send_cq;
745b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	rcq  = qp->recv_cq;
746b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	srq  = qp->srq;
747b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	xrcd = qp->xrcd;
748d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	if (xrcd)
749d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		__ib_remove_xrcd_qp(xrcd, qp);
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = qp->device->destroy_qp(qp);
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret) {
753b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		if (pd)
754b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_dec(&pd->usecnt);
755b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		if (scq)
756b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_dec(&scq->usecnt);
757b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		if (rcq)
758b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_dec(&rcq->usecnt);
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (srq)
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			atomic_dec(&srq->usecnt);
761b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		if (xrcd)
762b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_dec(&xrcd->usecnt);
763d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	} else if (xrcd) {
764d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		__ib_insert_xrcd_qp(xrcd, qp);
7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_qp);
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
771d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Heftyint ib_release_qp(struct ib_qp *qp)
772d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty{
773d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	unsigned long flags;
774d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
775d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	if (qp->qp_type != IB_QPT_XRC_TGT)
776d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		return -EINVAL;
777d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
778d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	spin_lock_irqsave(&qp->device->event_handler_lock, flags);
779d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	qp->event_handler = NULL;
780d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	spin_unlock_irqrestore(&qp->device->event_handler_lock, flags);
781d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
782d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	atomic_dec(&qp->xrcd->usecnt);
783d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	return 0;
784d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty}
785d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean HeftyEXPORT_SYMBOL(ib_release_qp);
786d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Completion queues */
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_cq *ib_create_cq(struct ib_device *device,
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   ib_comp_handler comp_handler,
7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   void (*event_handler)(struct ib_event *, void *),
792f4fd0b224d60044d2da5ca02f8f2b5150c1d8731Michael S. Tsirkin			   void *cq_context, int cqe, int comp_vector)
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_cq *cq;
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
796f4fd0b224d60044d2da5ca02f8f2b5150c1d8731Michael S. Tsirkin	cq = device->create_cq(device, cqe, comp_vector, NULL, NULL);
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(cq)) {
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->device        = device;
800b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		cq->uobject       = NULL;
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->comp_handler  = comp_handler;
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->event_handler = event_handler;
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->cq_context    = cq_context;
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&cq->usecnt, 0);
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return cq;
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_cq);
8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8112dd5716227878d5950988514a2cbabf72f7fc888Eli Cohenint ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
8122dd5716227878d5950988514a2cbabf72f7fc888Eli Cohen{
8132dd5716227878d5950988514a2cbabf72f7fc888Eli Cohen	return cq->device->modify_cq ?
8142dd5716227878d5950988514a2cbabf72f7fc888Eli Cohen		cq->device->modify_cq(cq, cq_count, cq_period) : -ENOSYS;
8152dd5716227878d5950988514a2cbabf72f7fc888Eli Cohen}
8162dd5716227878d5950988514a2cbabf72f7fc888Eli CohenEXPORT_SYMBOL(ib_modify_cq);
8172dd5716227878d5950988514a2cbabf72f7fc888Eli Cohen
8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_cq(struct ib_cq *cq)
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&cq->usecnt))
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return cq->device->destroy_cq(cq);
8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_cq);
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
827a74cd4af0bfa9578594acbb711a958104c93b772Roland Dreierint ib_resize_cq(struct ib_cq *cq, int cqe)
8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
82940de2e548c225e3ef859e3c60de9785e37e1b5b1Roland Dreier	return cq->device->resize_cq ?
83033b9b3ee9709b19c4f02ab91571d53540d05c3d1Roland Dreier		cq->device->resize_cq(cq, cqe, NULL) : -ENOSYS;
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_resize_cq);
8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Memory regions */
8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mr *mr;
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mr = pd->device->get_dma_mr(pd, mr_access_flags);
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mr)) {
843b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->device  = pd->device;
844b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->pd      = pd;
845b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->uobject = NULL;
8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&mr->usecnt, 0);
8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr;
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_get_dma_mr);
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     struct ib_phys_buf *phys_buf_array,
8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int num_phys_buf,
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int mr_access_flags,
8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     u64 *iova_start)
8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mr *mr;
8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8627ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak	if (!pd->device->reg_phys_mr)
8637ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak		return ERR_PTR(-ENOSYS);
8647ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mr = pd->device->reg_phys_mr(pd, phys_buf_array, num_phys_buf,
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				     mr_access_flags, iova_start);
8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mr)) {
869b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->device  = pd->device;
870b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->pd      = pd;
871b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->uobject = NULL;
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&mr->usecnt, 0);
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr;
8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_reg_phys_mr);
8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_rereg_phys_mr(struct ib_mr *mr,
8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int mr_rereg_mask,
8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     struct ib_pd *pd,
8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     struct ib_phys_buf *phys_buf_array,
8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int num_phys_buf,
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int mr_access_flags,
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     u64 *iova_start)
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *old_pd;
8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!mr->device->rereg_phys_mr)
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOSYS;
8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&mr->usecnt))
8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	old_pd = mr->pd;
8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mr->device->rereg_phys_mr(mr, mr_rereg_mask, pd,
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					phys_buf_array, num_phys_buf,
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mr_access_flags, iova_start);
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret && (mr_rereg_mask & IB_MR_REREG_PD)) {
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&old_pd->usecnt);
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_rereg_phys_mr);
9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr->device->query_mr ?
9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mr->device->query_mr(mr, mr_attr) : -ENOSYS;
9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_mr);
9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dereg_mr(struct ib_mr *mr)
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&mr->usecnt))
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = mr->pd;
9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mr->device->dereg_mr(mr);
9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dereg_mr);
9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
93600f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wisestruct ib_mr *ib_alloc_fast_reg_mr(struct ib_pd *pd, int max_page_list_len)
93700f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise{
93800f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	struct ib_mr *mr;
93900f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
94000f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	if (!pd->device->alloc_fast_reg_mr)
94100f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		return ERR_PTR(-ENOSYS);
94200f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
94300f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	mr = pd->device->alloc_fast_reg_mr(pd, max_page_list_len);
94400f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
94500f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	if (!IS_ERR(mr)) {
94600f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		mr->device  = pd->device;
94700f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		mr->pd      = pd;
94800f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		mr->uobject = NULL;
94900f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		atomic_inc(&pd->usecnt);
95000f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		atomic_set(&mr->usecnt, 0);
95100f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	}
95200f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
95300f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	return mr;
95400f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise}
95500f7ec36c9324928e4cd23f02e6d8550f30c32caSteve WiseEXPORT_SYMBOL(ib_alloc_fast_reg_mr);
95600f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
95700f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wisestruct ib_fast_reg_page_list *ib_alloc_fast_reg_page_list(struct ib_device *device,
95800f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise							  int max_page_list_len)
95900f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise{
96000f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	struct ib_fast_reg_page_list *page_list;
96100f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
96200f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	if (!device->alloc_fast_reg_page_list)
96300f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		return ERR_PTR(-ENOSYS);
96400f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
96500f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	page_list = device->alloc_fast_reg_page_list(device, max_page_list_len);
96600f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
96700f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	if (!IS_ERR(page_list)) {
96800f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		page_list->device = device;
96900f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		page_list->max_page_list_len = max_page_list_len;
97000f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	}
97100f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
97200f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	return page_list;
97300f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise}
97400f7ec36c9324928e4cd23f02e6d8550f30c32caSteve WiseEXPORT_SYMBOL(ib_alloc_fast_reg_page_list);
97500f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
97600f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wisevoid ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list)
97700f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise{
97800f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	page_list->device->free_fast_reg_page_list(page_list);
97900f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise}
98000f7ec36c9324928e4cd23f02e6d8550f30c32caSteve WiseEXPORT_SYMBOL(ib_free_fast_reg_page_list);
98100f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Memory windows */
9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mw *ib_alloc_mw(struct ib_pd *pd)
9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mw *mw;
9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!pd->device->alloc_mw)
9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOSYS);
9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mw = pd->device->alloc_mw(pd);
9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mw)) {
993b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->device  = pd->device;
994b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->pd      = pd;
995b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->uobject = NULL;
9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mw;
10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_mw);
10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_mw(struct ib_mw *mw)
10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = mw->pd;
10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mw->device->dealloc_mw(mw);
10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_mw);
10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* "Fast" memory regions */
10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    int mr_access_flags,
10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    struct ib_fmr_attr *fmr_attr)
10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_fmr *fmr;
10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!pd->device->alloc_fmr)
10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOSYS);
10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr);
10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(fmr)) {
10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fmr->device = pd->device;
10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fmr->pd     = pd;
10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return fmr;
10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_fmr);
10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_unmap_fmr(struct list_head *fmr_list)
10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_fmr *fmr;
10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (list_empty(fmr_list))
10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fmr = list_entry(fmr_list->next, struct ib_fmr, list);
10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return fmr->device->unmap_fmr(fmr_list);
10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_unmap_fmr);
10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_fmr(struct ib_fmr *fmr)
10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = fmr->pd;
10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = fmr->device->dealloc_fmr(fmr);
10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_fmr);
10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Multicast groups */
10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10690c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (!qp->device->attach_mcast)
10700c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -ENOSYS;
10710c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
10720c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -EINVAL;
10730c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein
10740c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	return qp->device->attach_mcast(qp, gid, lid);
10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_attach_mcast);
10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10800c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (!qp->device->detach_mcast)
10810c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -ENOSYS;
10820c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
10830c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -EINVAL;
10840c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein
10850c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	return qp->device->detach_mcast(qp, gid, lid);
10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_detach_mcast);
108859991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
108959991f94eb32e954aa767f659eb642461e9e8b37Sean Heftystruct ib_xrcd *ib_alloc_xrcd(struct ib_device *device)
109059991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty{
109159991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	struct ib_xrcd *xrcd;
109259991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
109359991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	if (!device->alloc_xrcd)
109459991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty		return ERR_PTR(-ENOSYS);
109559991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
109659991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	xrcd = device->alloc_xrcd(device, NULL, NULL);
109759991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	if (!IS_ERR(xrcd)) {
109859991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty		xrcd->device = device;
109959991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty		atomic_set(&xrcd->usecnt, 0);
1100d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		mutex_init(&xrcd->tgt_qp_mutex);
1101d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		INIT_LIST_HEAD(&xrcd->tgt_qp_list);
110259991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	}
110359991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
110459991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	return xrcd;
110559991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty}
110659991f94eb32e954aa767f659eb642461e9e8b37Sean HeftyEXPORT_SYMBOL(ib_alloc_xrcd);
110759991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
110859991f94eb32e954aa767f659eb642461e9e8b37Sean Heftyint ib_dealloc_xrcd(struct ib_xrcd *xrcd)
110959991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty{
1110d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	struct ib_qp *qp;
1111d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	int ret;
1112d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
111359991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	if (atomic_read(&xrcd->usecnt))
111459991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty		return -EBUSY;
111559991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
1116d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	while (!list_empty(&xrcd->tgt_qp_list)) {
1117d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		qp = list_entry(xrcd->tgt_qp_list.next, struct ib_qp, xrcd_list);
1118d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		ret = ib_destroy_qp(qp);
1119d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		if (ret)
1120d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty			return ret;
1121d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	}
1122d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
112359991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	return xrcd->device->dealloc_xrcd(xrcd);
112459991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty}
112559991f94eb32e954aa767f659eb642461e9e8b37Sean HeftyEXPORT_SYMBOL(ib_dealloc_xrcd);
1126