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>
41b108d9764cff25262bf764542ed1998d3e568962Paul Gortmaker#include <linux/export.h>
428c65b4a60450590e79a28e9717ceffa9e4debb3fTim Schmielau#include <linux/string.h>
430e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty#include <linux/slab.h>
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
45a4d61e84804f3b14cc35c5e2af768a07c0f64ef6Roland Dreier#include <rdma/ib_verbs.h>
46a4d61e84804f3b14cc35c5e2af768a07c0f64ef6Roland Dreier#include <rdma/ib_cache.h>
47dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak#include <rdma/ib_addr.h>
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
49ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz#include "core_priv.h"
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
518385fd841468868e0b37a722530d75b0e8bfc5a8Roland Dreier__attribute_const__ int ib_rate_to_mult(enum ib_rate rate)
52bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{
53bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	switch (rate) {
54bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_2_5_GBPS: return  1;
55bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_5_GBPS:   return  2;
56bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_10_GBPS:  return  4;
57bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_20_GBPS:  return  8;
58bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_30_GBPS:  return 12;
59bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_40_GBPS:  return 16;
60bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_60_GBPS:  return 24;
61bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_80_GBPS:  return 32;
62bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_120_GBPS: return 48;
63bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	default:	       return -1;
64bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	}
65bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein}
66bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack MorgensteinEXPORT_SYMBOL(ib_rate_to_mult);
67bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein
688385fd841468868e0b37a722530d75b0e8bfc5a8Roland Dreier__attribute_const__ enum ib_rate mult_to_ib_rate(int mult)
69bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{
70bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	switch (mult) {
71bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 1:  return IB_RATE_2_5_GBPS;
72bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 2:  return IB_RATE_5_GBPS;
73bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 4:  return IB_RATE_10_GBPS;
74bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 8:  return IB_RATE_20_GBPS;
75bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 12: return IB_RATE_30_GBPS;
76bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 16: return IB_RATE_40_GBPS;
77bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 24: return IB_RATE_60_GBPS;
78bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 32: return IB_RATE_80_GBPS;
79bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 48: return IB_RATE_120_GBPS;
80bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	default: return IB_RATE_PORT_CURRENT;
81bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	}
82bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein}
83bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack MorgensteinEXPORT_SYMBOL(mult_to_ib_rate);
84bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein
858385fd841468868e0b37a722530d75b0e8bfc5a8Roland Dreier__attribute_const__ int ib_rate_to_mbps(enum ib_rate rate)
8671eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum{
8771eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	switch (rate) {
8871eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_2_5_GBPS: return 2500;
8971eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_5_GBPS:   return 5000;
9071eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_10_GBPS:  return 10000;
9171eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_20_GBPS:  return 20000;
9271eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_30_GBPS:  return 30000;
9371eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_40_GBPS:  return 40000;
9471eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_60_GBPS:  return 60000;
9571eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_80_GBPS:  return 80000;
9671eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_120_GBPS: return 120000;
9771eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_14_GBPS:  return 14062;
9871eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_56_GBPS:  return 56250;
9971eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_112_GBPS: return 112500;
10071eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_168_GBPS: return 168750;
10171eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_25_GBPS:  return 25781;
10271eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_100_GBPS: return 103125;
10371eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_200_GBPS: return 206250;
10471eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	case IB_RATE_300_GBPS: return 309375;
10571eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	default:	       return -1;
10671eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum	}
10771eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum}
10871eeba161d7611238ecb6f525a82325aa35339f0Marcel ApfelbaumEXPORT_SYMBOL(ib_rate_to_mbps);
10971eeba161d7611238ecb6f525a82325aa35339f0Marcel Apfelbaum
1108385fd841468868e0b37a722530d75b0e8bfc5a8Roland Dreier__attribute_const__ enum rdma_transport_type
11107ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tuckerrdma_node_get_transport(enum rdma_node_type node_type)
11207ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker{
11307ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	switch (node_type) {
11407ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_IB_CA:
11507ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_IB_SWITCH:
11607ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_IB_ROUTER:
11707ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		return RDMA_TRANSPORT_IB;
11807ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_RNIC:
11907ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		return RDMA_TRANSPORT_IWARP;
120180771a3707a4c0577cbf4f830c754dbabfdfccbUpinder Malhi \(umalhi\)	case RDMA_NODE_USNIC:
1215db5765e255de4072eb0e35facfeafce53af001bUpinder Malhi		return RDMA_TRANSPORT_USNIC;
1225db5765e255de4072eb0e35facfeafce53af001bUpinder Malhi	case RDMA_NODE_USNIC_UDP:
123248567f79304b953ea492fb92ade097b62ed09b2Upinder Malhi		return RDMA_TRANSPORT_USNIC_UDP;
12407ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	default:
12507ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		BUG();
12607ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		return 0;
12707ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	}
12807ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker}
12907ebafbaaa72aa6a35472879008f5a1d1d469a0cTom TuckerEXPORT_SYMBOL(rdma_node_get_transport);
13007ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker
131a3f5adaf491490089215f863a61b9422fae902f8Eli Cohenenum rdma_link_layer rdma_port_get_link_layer(struct ib_device *device, u8 port_num)
132a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen{
133a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	if (device->get_link_layer)
134a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen		return device->get_link_layer(device, port_num);
135a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen
136a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	switch (rdma_node_get_transport(device->node_type)) {
137a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	case RDMA_TRANSPORT_IB:
138a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen		return IB_LINK_LAYER_INFINIBAND;
139a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	case RDMA_TRANSPORT_IWARP:
140180771a3707a4c0577cbf4f830c754dbabfdfccbUpinder Malhi \(umalhi\)	case RDMA_TRANSPORT_USNIC:
141248567f79304b953ea492fb92ade097b62ed09b2Upinder Malhi	case RDMA_TRANSPORT_USNIC_UDP:
142a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen		return IB_LINK_LAYER_ETHERNET;
143a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	default:
144a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen		return IB_LINK_LAYER_UNSPECIFIED;
145a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen	}
146a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen}
147a3f5adaf491490089215f863a61b9422fae902f8Eli CohenEXPORT_SYMBOL(rdma_port_get_link_layer);
148a3f5adaf491490089215f863a61b9422fae902f8Eli Cohen
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Protection domains */
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_pd *ib_alloc_pd(struct ib_device *device)
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
155b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier	pd = device->alloc_pd(device, NULL, NULL);
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(pd)) {
158b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		pd->device  = device;
159b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		pd->uobject = NULL;
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&pd->usecnt, 0);
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pd;
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_pd);
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_pd(struct ib_pd *pd)
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&pd->usecnt))
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pd->device->dealloc_pd(pd);
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_pd);
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Address handles */
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_ah *ah;
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ah = pd->device->create_ah(pd, ah_attr);
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(ah)) {
185b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->device  = pd->device;
186b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->pd      = pd;
187b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->uobject = NULL;
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah;
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_ah);
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1954e00d69454a8747798de11dc4eeef1edeee5ce98Sean Heftyint ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
1964e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		       struct ib_grh *grh, struct ib_ah_attr *ah_attr)
197513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock{
198513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	u32 flow_class;
199513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	u16 gid_index;
200513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	int ret;
201dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak	int is_eth = (rdma_port_get_link_layer(device, port_num) ==
202dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			IB_LINK_LAYER_ETHERNET);
203513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
2044e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	memset(ah_attr, 0, sizeof *ah_attr);
205dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak	if (is_eth) {
206dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak		if (!(wc->wc_flags & IB_WC_GRH))
207dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			return -EPROTOTYPE;
208dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak
209dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak		if (wc->wc_flags & IB_WC_WITH_SMAC &&
210dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak		    wc->wc_flags & IB_WC_WITH_VLAN) {
211dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			memcpy(ah_attr->dmac, wc->smac, ETH_ALEN);
212dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			ah_attr->vlan_id = wc->vlan_id;
213dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak		} else {
214dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			ret = rdma_addr_find_dmac_by_grh(&grh->dgid, &grh->sgid,
215dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak					ah_attr->dmac, &ah_attr->vlan_id);
216dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			if (ret)
217dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak				return ret;
218dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak		}
219dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak	} else {
220dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak		ah_attr->vlan_id = 0xffff;
221dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak	}
222dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak
2234e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->dlid = wc->slid;
2244e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->sl = wc->sl;
2254e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->src_path_bits = wc->dlid_path_bits;
2264e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->port_num = port_num;
227513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
228513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	if (wc->wc_flags & IB_WC_GRH) {
2294e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->ah_flags = IB_AH_GRH;
2304e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.dgid = grh->sgid;
231513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
2324e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ret = ib_find_cached_gid(device, &grh->dgid, &port_num,
233513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock					 &gid_index);
234513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		if (ret)
2354e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty			return ret;
236513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
2374e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.sgid_index = (u8) gid_index;
238497677ab940e637a41351dca6610bc4320abc8f1Hal Rosenstock		flow_class = be32_to_cpu(grh->version_tclass_flow);
2394e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.flow_label = flow_class & 0xFFFFF;
24047645d8d25387c08bb3ccd84e1405c3776f21d24Sean Hefty		ah_attr->grh.hop_limit = 0xFF;
2414e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
242513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	}
2434e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	return 0;
2444e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty}
2454e00d69454a8747798de11dc4eeef1edeee5ce98Sean HeftyEXPORT_SYMBOL(ib_init_ah_from_wc);
2464e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty
2474e00d69454a8747798de11dc4eeef1edeee5ce98Sean Heftystruct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc,
2484e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty				   struct ib_grh *grh, u8 port_num)
2494e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty{
2504e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	struct ib_ah_attr ah_attr;
2514e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	int ret;
2524e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty
2534e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ret = ib_init_ah_from_wc(pd->device, port_num, wc, grh, &ah_attr);
2544e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	if (ret)
2554e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		return ERR_PTR(ret);
256513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
257513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	return ib_create_ah(pd, &ah_attr);
258513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock}
259513789ed995fb2ba72ba2a5bee53ea11d1170580Hal RosenstockEXPORT_SYMBOL(ib_create_ah_from_wc);
260513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah->device->modify_ah ?
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ah->device->modify_ah(ah, ah_attr) :
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_modify_ah);
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah->device->query_ah ?
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ah->device->query_ah(ah, ah_attr) :
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_ah);
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_ah(struct ib_ah *ah)
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = ah->pd;
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = ah->device->destroy_ah(ah);
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_ah);
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
291d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier/* Shared receive queues */
292d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
293d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierstruct ib_srq *ib_create_srq(struct ib_pd *pd,
294d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier			     struct ib_srq_init_attr *srq_init_attr)
295d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
296d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	struct ib_srq *srq;
297d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
298d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (!pd->device->create_srq)
299d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		return ERR_PTR(-ENOSYS);
300d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
301d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	srq = pd->device->create_srq(pd, srq_init_attr, NULL);
302d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
303d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (!IS_ERR(srq)) {
304d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->device    	   = pd->device;
305d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->pd        	   = pd;
306d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->uobject       = NULL;
307d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->event_handler = srq_init_attr->event_handler;
308d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->srq_context   = srq_init_attr->srq_context;
30996104eda01695a26da2c8f7423ec0ba3509c8c97Sean Hefty		srq->srq_type      = srq_init_attr->srq_type;
310418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		if (srq->srq_type == IB_SRQT_XRC) {
311418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			srq->ext.xrc.xrcd = srq_init_attr->ext.xrc.xrcd;
312418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			srq->ext.xrc.cq   = srq_init_attr->ext.xrc.cq;
313418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			atomic_inc(&srq->ext.xrc.xrcd->usecnt);
314418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			atomic_inc(&srq->ext.xrc.cq->usecnt);
315418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		}
316d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_inc(&pd->usecnt);
317d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_set(&srq->usecnt, 0);
318d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	}
319d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
320d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return srq;
321d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
322d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_create_srq);
323d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
324d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_modify_srq(struct ib_srq *srq,
325d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		  struct ib_srq_attr *srq_attr,
326d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		  enum ib_srq_attr_mask srq_attr_mask)
327d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
3287ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak	return srq->device->modify_srq ?
3297ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak		srq->device->modify_srq(srq, srq_attr, srq_attr_mask, NULL) :
3307ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak		-ENOSYS;
331d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
332d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_modify_srq);
333d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
334d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_query_srq(struct ib_srq *srq,
335d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		 struct ib_srq_attr *srq_attr)
336d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
337d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return srq->device->query_srq ?
338d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->device->query_srq(srq, srq_attr) : -ENOSYS;
339d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
340d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_query_srq);
341d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
342d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_destroy_srq(struct ib_srq *srq)
343d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
344d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	struct ib_pd *pd;
345418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	enum ib_srq_type srq_type;
346418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	struct ib_xrcd *uninitialized_var(xrcd);
347418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	struct ib_cq *uninitialized_var(cq);
348d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	int ret;
349d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
350d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (atomic_read(&srq->usecnt))
351d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		return -EBUSY;
352d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
353d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	pd = srq->pd;
354418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	srq_type = srq->srq_type;
355418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	if (srq_type == IB_SRQT_XRC) {
356418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		xrcd = srq->ext.xrc.xrcd;
357418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		cq = srq->ext.xrc.cq;
358418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	}
359d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
360d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	ret = srq->device->destroy_srq(srq);
361418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	if (!ret) {
362d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_dec(&pd->usecnt);
363418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		if (srq_type == IB_SRQT_XRC) {
364418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			atomic_dec(&xrcd->usecnt);
365418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty			atomic_dec(&cq->usecnt);
366418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty		}
367418d51307d102e72e745031adb4f5ba0ddb646e2Sean Hefty	}
368d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
369d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return ret;
370d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
371d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_destroy_srq);
372d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Queue pairs */
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3750e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Heftystatic void __ib_shared_qp_event_handler(struct ib_event *event, void *context)
3760e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty{
3770e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	struct ib_qp *qp = context;
37873c40c616a33fcb7961b3c90a91b550813129b3eYishai Hadas	unsigned long flags;
3790e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
38073c40c616a33fcb7961b3c90a91b550813129b3eYishai Hadas	spin_lock_irqsave(&qp->device->event_handler_lock, flags);
3810e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	list_for_each_entry(event->element.qp, &qp->open_list, open_list)
382eec9e29fc5e9b417649830ab76a3aa10b90d2e9fShlomo Pongratz		if (event->element.qp->event_handler)
383eec9e29fc5e9b417649830ab76a3aa10b90d2e9fShlomo Pongratz			event->element.qp->event_handler(event, event->element.qp->qp_context);
38473c40c616a33fcb7961b3c90a91b550813129b3eYishai Hadas	spin_unlock_irqrestore(&qp->device->event_handler_lock, flags);
3850e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty}
3860e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
387d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Heftystatic void __ib_insert_xrcd_qp(struct ib_xrcd *xrcd, struct ib_qp *qp)
388d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty{
389d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	mutex_lock(&xrcd->tgt_qp_mutex);
390d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	list_add(&qp->xrcd_list, &xrcd->tgt_qp_list);
391d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	mutex_unlock(&xrcd->tgt_qp_mutex);
392d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty}
393d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
3940e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Heftystatic struct ib_qp *__ib_open_qp(struct ib_qp *real_qp,
3950e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty				  void (*event_handler)(struct ib_event *, void *),
3960e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty				  void *qp_context)
397d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty{
3980e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	struct ib_qp *qp;
3990e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	unsigned long flags;
4000e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
4010e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	qp = kzalloc(sizeof *qp, GFP_KERNEL);
4020e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	if (!qp)
4030e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		return ERR_PTR(-ENOMEM);
4040e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
4050e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	qp->real_qp = real_qp;
4060e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	atomic_inc(&real_qp->usecnt);
4070e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	qp->device = real_qp->device;
4080e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	qp->event_handler = event_handler;
4090e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	qp->qp_context = qp_context;
4100e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	qp->qp_num = real_qp->qp_num;
4110e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	qp->qp_type = real_qp->qp_type;
4120e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
4130e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	spin_lock_irqsave(&real_qp->device->event_handler_lock, flags);
4140e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	list_add(&qp->open_list, &real_qp->open_list);
4150e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags);
4160e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
4170e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	return qp;
4180e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty}
4190e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
4200e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Heftystruct ib_qp *ib_open_qp(struct ib_xrcd *xrcd,
4210e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			 struct ib_qp_open_attr *qp_open_attr)
4220e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty{
4230e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	struct ib_qp *qp, *real_qp;
4240e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
4250e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	if (qp_open_attr->qp_type != IB_QPT_XRC_TGT)
4260e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		return ERR_PTR(-EINVAL);
4270e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
4280e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	qp = ERR_PTR(-EINVAL);
429d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	mutex_lock(&xrcd->tgt_qp_mutex);
4300e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	list_for_each_entry(real_qp, &xrcd->tgt_qp_list, xrcd_list) {
4310e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		if (real_qp->qp_num == qp_open_attr->qp_num) {
4320e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			qp = __ib_open_qp(real_qp, qp_open_attr->event_handler,
4330e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty					  qp_open_attr->qp_context);
4340e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			break;
4350e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		}
4360e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	}
437d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	mutex_unlock(&xrcd->tgt_qp_mutex);
4380e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	return qp;
439d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty}
4400e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean HeftyEXPORT_SYMBOL(ib_open_qp);
441d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_qp *ib_create_qp(struct ib_pd *pd,
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct ib_qp_init_attr *qp_init_attr)
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4450e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	struct ib_qp *qp, *real_qp;
446b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	struct ib_device *device;
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
448b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	device = pd ? pd->device : qp_init_attr->xrcd->device;
449b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	qp = device->create_qp(pd, qp_init_attr, NULL);
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(qp)) {
4520e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		qp->device     = device;
4530e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		qp->real_qp    = qp;
4540e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		qp->uobject    = NULL;
4550e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		qp->qp_type    = qp_init_attr->qp_type;
456b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty
457e47e321a35c741ee41b67976f8c6a3a7a42bc5c0Bernd Schubert		atomic_set(&qp->usecnt, 0);
458b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {
4590e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			qp->event_handler = __ib_shared_qp_event_handler;
4600e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			qp->qp_context = qp;
461b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->pd = NULL;
462b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->send_cq = qp->recv_cq = NULL;
463b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->srq = NULL;
464b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->xrcd = qp_init_attr->xrcd;
465b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_inc(&qp_init_attr->xrcd->usecnt);
4660e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			INIT_LIST_HEAD(&qp->open_list);
4670e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
4680e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			real_qp = qp;
4690e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			qp = __ib_open_qp(real_qp, qp_init_attr->event_handler,
4700e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty					  qp_init_attr->qp_context);
4710e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			if (!IS_ERR(qp))
4720e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty				__ib_insert_xrcd_qp(qp_init_attr->xrcd, real_qp);
4730e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			else
4740e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty				real_qp->device->destroy_qp(real_qp);
475b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		} else {
4760e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			qp->event_handler = qp_init_attr->event_handler;
4770e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			qp->qp_context = qp_init_attr->qp_context;
478b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			if (qp_init_attr->qp_type == IB_QPT_XRC_INI) {
479b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				qp->recv_cq = NULL;
480b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				qp->srq = NULL;
481b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			} else {
482b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				qp->recv_cq = qp_init_attr->recv_cq;
483b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				atomic_inc(&qp_init_attr->recv_cq->usecnt);
484b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				qp->srq = qp_init_attr->srq;
485b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				if (qp->srq)
486b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty					atomic_inc(&qp_init_attr->srq->usecnt);
487b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			}
488b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty
489b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->pd	    = pd;
490b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->send_cq = qp_init_attr->send_cq;
491b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			qp->xrcd    = NULL;
492b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty
493b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_inc(&pd->usecnt);
494b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_inc(&qp_init_attr->send_cq->usecnt);
495b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		}
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp;
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_qp);
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5028a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreierstatic const struct {
5038a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	int			valid;
504b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	enum ib_qp_attr_mask	req_param[IB_QPT_MAX];
505dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak	enum ib_qp_attr_mask	req_param_add_eth[IB_QPT_MAX];
506b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	enum ib_qp_attr_mask	opt_param[IB_QPT_MAX];
507dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak	enum ib_qp_attr_mask	opt_param_add_eth[IB_QPT_MAX];
5088a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
5098a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_RESET] = {
5108a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
5118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_INIT]  = {
5128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
5138a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.req_param = {
5148a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
5158a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
5168a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
517c938a616aadb621b8e26b0ac09ac13d053c7ed1cOr Gerlitz				[IB_QPT_RAW_PACKET] = IB_QP_PORT,
5188a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_PKEY_INDEX		|
5198a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
5208a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
5218a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_PKEY_INDEX		|
5228a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
5238a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
524b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_PKEY_INDEX		|
525b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PORT			|
526b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS),
527b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_PKEY_INDEX		|
528b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PORT			|
529b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS),
5308a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
5318a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5328a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
5338a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5348a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
5358a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
5368a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
5378a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_INIT]  = {
5388a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
5398a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
5408a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_INIT]  = {
5418a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
5428a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
5438a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
5448a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
5458a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5468a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_PKEY_INDEX		|
5478a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
5488a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
5498a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_PKEY_INDEX		|
5508a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
5518a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
552b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_PKEY_INDEX		|
553b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PORT			|
554b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS),
555b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_PKEY_INDEX		|
556b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PORT			|
557b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS),
5588a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
5598a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5608a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
5618a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5628a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
5638a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
5648a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTR]   = {
5658a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
5668a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.req_param = {
5678a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_AV			|
5688a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MTU			|
5698a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_DEST_QPN			|
5708a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RQ_PSN),
5718a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_AV			|
5728a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MTU			|
5738a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_DEST_QPN			|
5748a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RQ_PSN			|
5758a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_DEST_RD_ATOMIC	|
5768a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER),
577b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_AV			|
578b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MTU			|
579b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_DEST_QPN			|
580b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RQ_PSN),
581b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_AV			|
582b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MTU			|
583b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_DEST_QPN			|
584b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RQ_PSN			|
585b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MAX_DEST_RD_ATOMIC	|
586b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MIN_RNR_TIMER),
5878a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			},
588dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			.req_param_add_eth = {
589dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak				[IB_QPT_RC]  = (IB_QP_SMAC),
590dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak				[IB_QPT_UC]  = (IB_QP_SMAC),
591dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak				[IB_QPT_XRC_INI]  = (IB_QP_SMAC),
592dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak				[IB_QPT_XRC_TGT]  = (IB_QP_SMAC)
593dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			},
5948a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
5958a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
5968a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
5978a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UC]  = (IB_QP_ALT_PATH			|
5988a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
5998a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PKEY_INDEX),
6008a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_RC]  = (IB_QP_ALT_PATH			|
6018a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
6028a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PKEY_INDEX),
603b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				 [IB_QPT_XRC_INI] = (IB_QP_ALT_PATH		|
604b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ACCESS_FLAGS		|
605b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_PKEY_INDEX),
606b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				 [IB_QPT_XRC_TGT] = (IB_QP_ALT_PATH		|
607b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ACCESS_FLAGS		|
608b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_PKEY_INDEX),
6098a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
6108a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
6118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
6128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
613dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			 },
614dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			.opt_param_add_eth = {
615dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak				[IB_QPT_RC]  = (IB_QP_ALT_SMAC			|
616dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak						IB_QP_VID			|
617dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak						IB_QP_ALT_VID),
618dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak				[IB_QPT_UC]  = (IB_QP_ALT_SMAC			|
619dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak						IB_QP_VID			|
620dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak						IB_QP_ALT_VID),
621dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak				[IB_QPT_XRC_INI]  = (IB_QP_ALT_SMAC			|
622dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak						IB_QP_VID			|
623dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak						IB_QP_ALT_VID),
624dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak				[IB_QPT_XRC_TGT]  = (IB_QP_ALT_SMAC			|
625dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak						IB_QP_VID			|
626dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak						IB_QP_ALT_VID)
627dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			}
6288a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
6298a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
6308a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_RTR]   = {
6318a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
6328a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
6338a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
6348a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
6358a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.req_param = {
6368a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = IB_QP_SQ_PSN,
6378a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = IB_QP_SQ_PSN,
6388a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_TIMEOUT			|
6398a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RETRY_CNT			|
6408a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RNR_RETRY			|
6418a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_SQ_PSN			|
6428a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_QP_RD_ATOMIC),
643b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_TIMEOUT		|
644b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RETRY_CNT			|
645b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RNR_RETRY			|
646b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_SQ_PSN			|
647b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MAX_QP_RD_ATOMIC),
648b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_TIMEOUT		|
649b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_SQ_PSN),
6508a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = IB_QP_SQ_PSN,
6518a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = IB_QP_SQ_PSN,
6528a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			},
6538a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
6548a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UD]  = (IB_QP_CUR_STATE		|
6558a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
6568a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UC]  = (IB_QP_CUR_STATE		|
6578a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ALT_PATH			|
6588a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
6598a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PATH_MIG_STATE),
6608a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_RC]  = (IB_QP_CUR_STATE		|
6618a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ALT_PATH			|
6628a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
6638a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_MIN_RNR_TIMER		|
6648a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PATH_MIG_STATE),
665b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				 [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE		|
666b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ALT_PATH			|
667b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ACCESS_FLAGS		|
668b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_PATH_MIG_STATE),
669b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				 [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE		|
670b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ALT_PATH			|
671b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_ACCESS_FLAGS		|
672b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_MIN_RNR_TIMER		|
673b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						 IB_QP_PATH_MIG_STATE),
6748a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_SMI] = (IB_QP_CUR_STATE		|
6758a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
6768a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_GSI] = (IB_QP_CUR_STATE		|
6778a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
6788a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			 }
6798a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
6808a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
6818a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_RTS]   = {
6828a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
6838a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
6848a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
6858a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
6868a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
6878a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_CUR_STATE			|
6888a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
6894546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak				[IB_QPT_UC]  = (IB_QP_CUR_STATE			|
6904546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak						IB_QP_ACCESS_FLAGS		|
6918a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
6928a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
6934546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak				[IB_QPT_RC]  = (IB_QP_CUR_STATE			|
6944546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak						IB_QP_ACCESS_FLAGS		|
6958a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
6968a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE		|
6978a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER),
698b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_CUR_STATE		|
699b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
700b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
701b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE),
702b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE		|
703b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
704b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
705b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE		|
706b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MIN_RNR_TIMER),
7078a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_CUR_STATE			|
7088a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
7098a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_CUR_STATE			|
7108a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
7118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
7128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
7138a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_SQD]   = {
7148a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
7158a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
7168a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
7178a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
7188a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
719b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
720b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = IB_QP_EN_SQD_ASYNC_NOTIFY, /* ??? */
7218a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
7228a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY
7238a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
7248a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
7258a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
7268a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_SQD]   = {
7278a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
7288a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
7298a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
7308a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
7318a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
7328a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_CUR_STATE			|
7338a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
7348a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_CUR_STATE			|
7358a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
7368a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
7378a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
7388a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_CUR_STATE			|
7398a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
7408a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
7418a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER		|
7428a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
743b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_CUR_STATE		|
744b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
745b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
746b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE),
747b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE		|
748b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
749b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
750b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MIN_RNR_TIMER		|
751b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE),
7528a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_CUR_STATE			|
7538a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
7548a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_CUR_STATE			|
7558a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
7568a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
7578a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
7588a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_SQD]   = {
7598a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
7608a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
7618a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
7628a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
7638a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_AV			|
7648a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
7658a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
7668a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PKEY_INDEX		|
7678a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
7688a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_PORT			|
7698a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_AV			|
7708a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_TIMEOUT			|
7718a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RETRY_CNT			|
7728a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RNR_RETRY			|
7738a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_QP_RD_ATOMIC		|
7748a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_DEST_RD_ATOMIC	|
7758a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
7768a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
7778a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PKEY_INDEX		|
7788a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER		|
7798a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
780b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_INI] = (IB_QP_PORT			|
781b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_AV			|
782b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_TIMEOUT			|
783b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RETRY_CNT			|
784b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_RNR_RETRY			|
785b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MAX_QP_RD_ATOMIC		|
786b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
787b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
788b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PKEY_INDEX		|
789b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE),
790b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty				[IB_QPT_XRC_TGT] = (IB_QP_PORT			|
791b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_AV			|
792b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_TIMEOUT			|
793b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MAX_DEST_RD_ATOMIC	|
794b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ALT_PATH			|
795b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_ACCESS_FLAGS		|
796b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PKEY_INDEX		|
797b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_MIN_RNR_TIMER		|
798b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty						IB_QP_PATH_MIG_STATE),
7998a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
8008a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
8018a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
8028a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
8038a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
8048a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
8058a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
8068a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_SQE]   = {
8078a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
8088a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
8098a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
8108a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
8118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
8128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_CUR_STATE			|
8138a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
8148a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_CUR_STATE			|
8158a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
8168a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_CUR_STATE			|
8178a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
8188a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_CUR_STATE			|
8198a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
8208a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
8218a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
8228a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
8238a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_ERR] = {
8248a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
8258a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 }
8268a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	}
8278a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier};
8288a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
8298a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreierint ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
830dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak		       enum ib_qp_type type, enum ib_qp_attr_mask mask,
831dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak		       enum rdma_link_layer ll)
8328a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier{
8338a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	enum ib_qp_attr_mask req_param, opt_param;
8348a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
8358a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (cur_state  < 0 || cur_state  > IB_QPS_ERR ||
8368a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	    next_state < 0 || next_state > IB_QPS_ERR)
8378a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
8388a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
8398a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (mask & IB_QP_CUR_STATE  &&
8408a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	    cur_state != IB_QPS_RTR && cur_state != IB_QPS_RTS &&
8418a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	    cur_state != IB_QPS_SQD && cur_state != IB_QPS_SQE)
8428a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
8438a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
8448a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (!qp_state_table[cur_state][next_state].valid)
8458a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
8468a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
8478a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	req_param = qp_state_table[cur_state][next_state].req_param[type];
8488a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	opt_param = qp_state_table[cur_state][next_state].opt_param[type];
8498a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
850dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak	if (ll == IB_LINK_LAYER_ETHERNET) {
851dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak		req_param |= qp_state_table[cur_state][next_state].
852dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			req_param_add_eth[type];
853dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak		opt_param |= qp_state_table[cur_state][next_state].
854dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak			opt_param_add_eth[type];
855dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak	}
856dd5f03beb4f76ae65d76d8c22a8815e424fc607cMatan Barak
8578a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if ((mask & req_param) != req_param)
8588a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
8598a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
8608a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (mask & ~(req_param | opt_param | IB_QP_STATE))
8618a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
8628a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
8638a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	return 1;
8648a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier}
8658a51866f08103ba04894ce0f65eef567ddc3ed40Roland DreierEXPORT_SYMBOL(ib_modify_qp_is_ok);
8668a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
867ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitzint ib_resolve_eth_l2_attrs(struct ib_qp *qp,
868ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz			    struct ib_qp_attr *qp_attr, int *qp_attr_mask)
869ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz{
870ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz	int           ret = 0;
871ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz	union ib_gid  sgid;
872ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz
873ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz	if ((*qp_attr_mask & IB_QP_AV)  &&
874ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz	    (rdma_port_get_link_layer(qp->device, qp_attr->ah_attr.port_num) == IB_LINK_LAYER_ETHERNET)) {
875ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz		ret = ib_query_gid(qp->device, qp_attr->ah_attr.port_num,
876ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz				   qp_attr->ah_attr.grh.sgid_index, &sgid);
877ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz		if (ret)
878ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz			goto out;
879ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz		if (rdma_link_local_addr((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw)) {
880ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz			rdma_get_ll_mac((struct in6_addr *)qp_attr->ah_attr.grh.dgid.raw, qp_attr->ah_attr.dmac);
881ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz			rdma_get_ll_mac((struct in6_addr *)sgid.raw, qp_attr->smac);
882ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz			qp_attr->vlan_id = rdma_get_vlan_id(&sgid);
883ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz		} else {
884ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz			ret = rdma_addr_find_dmac_by_grh(&sgid, &qp_attr->ah_attr.grh.dgid,
885ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz					qp_attr->ah_attr.dmac, &qp_attr->vlan_id);
886ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz			if (ret)
887ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz				goto out;
888ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz			ret = rdma_addr_find_smac_by_sgid(&sgid, qp_attr->smac, NULL);
889ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz			if (ret)
890ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz				goto out;
891ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz		}
892ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz		*qp_attr_mask |= IB_QP_SMAC;
893ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz		if (qp_attr->vlan_id < 0xFFFF)
894ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz			*qp_attr_mask |= IB_QP_VID;
895ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz	}
896ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitzout:
897ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz	return ret;
898ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz}
899ed4c54e5b4baf55a7a67a80fa766334855c94854Or GerlitzEXPORT_SYMBOL(ib_resolve_eth_l2_attrs);
900ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz
901ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_modify_qp(struct ib_qp *qp,
9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 struct ib_qp_attr *qp_attr,
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 int qp_attr_mask)
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
906ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz	int ret;
907ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz
908ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz	ret = ib_resolve_eth_l2_attrs(qp, qp_attr, &qp_attr_mask);
909ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz	if (ret)
910ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz		return ret;
911ed4c54e5b4baf55a7a67a80fa766334855c94854Or Gerlitz
9120e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_modify_qp);
9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_qp(struct ib_qp *qp,
9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ib_qp_attr *qp_attr,
9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int qp_attr_mask,
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ib_qp_init_attr *qp_init_attr)
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp->device->query_qp ?
9220e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		qp->device->query_qp(qp->real_qp, qp_attr, qp_attr_mask, qp_init_attr) :
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_qp);
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9270e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Heftyint ib_close_qp(struct ib_qp *qp)
9280e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty{
9290e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	struct ib_qp *real_qp;
9300e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	unsigned long flags;
9310e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9320e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	real_qp = qp->real_qp;
9330e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	if (real_qp == qp)
9340e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		return -EINVAL;
9350e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9360e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	spin_lock_irqsave(&real_qp->device->event_handler_lock, flags);
9370e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	list_del(&qp->open_list);
9380e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags);
9390e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9400e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	atomic_dec(&real_qp->usecnt);
9410e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	kfree(qp);
9420e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9430e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	return 0;
9440e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty}
9450e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean HeftyEXPORT_SYMBOL(ib_close_qp);
9460e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9470e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Heftystatic int __ib_destroy_shared_qp(struct ib_qp *qp)
9480e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty{
9490e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	struct ib_xrcd *xrcd;
9500e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	struct ib_qp *real_qp;
9510e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	int ret;
9520e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9530e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	real_qp = qp->real_qp;
9540e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	xrcd = real_qp->xrcd;
9550e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9560e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	mutex_lock(&xrcd->tgt_qp_mutex);
9570e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	ib_close_qp(qp);
9580e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	if (atomic_read(&real_qp->usecnt) == 0)
9590e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		list_del(&real_qp->xrcd_list);
9600e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	else
9610e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		real_qp = NULL;
9620e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	mutex_unlock(&xrcd->tgt_qp_mutex);
9630e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9640e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	if (real_qp) {
9650e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		ret = ib_destroy_qp(real_qp);
9660e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		if (!ret)
9670e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			atomic_dec(&xrcd->usecnt);
9680e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		else
9690e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty			__ib_insert_xrcd_qp(xrcd, real_qp);
9700e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	}
9710e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9720e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	return 0;
9730e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty}
9740e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_qp(struct ib_qp *qp)
9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_cq *scq, *rcq;
9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_srq *srq;
9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9820e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	if (atomic_read(&qp->usecnt))
9830e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		return -EBUSY;
9840e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
9850e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty	if (qp->real_qp != qp)
9860e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty		return __ib_destroy_shared_qp(qp);
9870e0ec7e0638ef48e0c661873dfcc8caccab984c6Sean Hefty
988b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	pd   = qp->pd;
989b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	scq  = qp->send_cq;
990b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	rcq  = qp->recv_cq;
991b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty	srq  = qp->srq;
9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = qp->device->destroy_qp(qp);
9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret) {
995b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		if (pd)
996b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_dec(&pd->usecnt);
997b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		if (scq)
998b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_dec(&scq->usecnt);
999b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty		if (rcq)
1000b42b63cf0dde2af6eec462b2d6cca7d938702a28Sean Hefty			atomic_dec(&rcq->usecnt);
10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (srq)
10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			atomic_dec(&srq->usecnt);
10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_qp);
10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Completion queues */
10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_cq *ib_create_cq(struct ib_device *device,
10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   ib_comp_handler comp_handler,
10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   void (*event_handler)(struct ib_event *, void *),
1014f4fd0b224d60044d2da5ca02f8f2b5150c1d8731Michael S. Tsirkin			   void *cq_context, int cqe, int comp_vector)
10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_cq *cq;
10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1018f4fd0b224d60044d2da5ca02f8f2b5150c1d8731Michael S. Tsirkin	cq = device->create_cq(device, cqe, comp_vector, NULL, NULL);
10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(cq)) {
10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->device        = device;
1022b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		cq->uobject       = NULL;
10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->comp_handler  = comp_handler;
10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->event_handler = event_handler;
10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->cq_context    = cq_context;
10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&cq->usecnt, 0);
10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return cq;
10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_cq);
10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10332dd5716227878d5950988514a2cbabf72f7fc888Eli Cohenint ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
10342dd5716227878d5950988514a2cbabf72f7fc888Eli Cohen{
10352dd5716227878d5950988514a2cbabf72f7fc888Eli Cohen	return cq->device->modify_cq ?
10362dd5716227878d5950988514a2cbabf72f7fc888Eli Cohen		cq->device->modify_cq(cq, cq_count, cq_period) : -ENOSYS;
10372dd5716227878d5950988514a2cbabf72f7fc888Eli Cohen}
10382dd5716227878d5950988514a2cbabf72f7fc888Eli CohenEXPORT_SYMBOL(ib_modify_cq);
10392dd5716227878d5950988514a2cbabf72f7fc888Eli Cohen
10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_cq(struct ib_cq *cq)
10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&cq->usecnt))
10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return cq->device->destroy_cq(cq);
10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_cq);
10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1049a74cd4af0bfa9578594acbb711a958104c93b772Roland Dreierint ib_resize_cq(struct ib_cq *cq, int cqe)
10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
105140de2e548c225e3ef859e3c60de9785e37e1b5b1Roland Dreier	return cq->device->resize_cq ?
105233b9b3ee9709b19c4f02ab91571d53540d05c3d1Roland Dreier		cq->device->resize_cq(cq, cqe, NULL) : -ENOSYS;
10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_resize_cq);
10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Memory regions */
10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mr *mr;
10611c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen	int err;
10621c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen
10631c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen	err = ib_check_mr_access(mr_access_flags);
10641c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen	if (err)
10651c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen		return ERR_PTR(err);
10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mr = pd->device->get_dma_mr(pd, mr_access_flags);
10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mr)) {
1070b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->device  = pd->device;
1071b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->pd      = pd;
1072b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->uobject = NULL;
10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&mr->usecnt, 0);
10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr;
10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_get_dma_mr);
10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     struct ib_phys_buf *phys_buf_array,
10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int num_phys_buf,
10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int mr_access_flags,
10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     u64 *iova_start)
10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mr *mr;
10881c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen	int err;
10891c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen
10901c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen	err = ib_check_mr_access(mr_access_flags);
10911c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen	if (err)
10921c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen		return ERR_PTR(err);
10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10947ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak	if (!pd->device->reg_phys_mr)
10957ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak		return ERR_PTR(-ENOSYS);
10967ce5eacb45a7c819a6bec6ed486f27db9aab6ab6Dotan Barak
10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mr = pd->device->reg_phys_mr(pd, phys_buf_array, num_phys_buf,
10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				     mr_access_flags, iova_start);
10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mr)) {
1101b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->device  = pd->device;
1102b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->pd      = pd;
1103b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->uobject = NULL;
11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&mr->usecnt, 0);
11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr;
11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_reg_phys_mr);
11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_rereg_phys_mr(struct ib_mr *mr,
11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int mr_rereg_mask,
11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     struct ib_pd *pd,
11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     struct ib_phys_buf *phys_buf_array,
11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int num_phys_buf,
11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int mr_access_flags,
11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     u64 *iova_start)
11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *old_pd;
11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11231c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen	ret = ib_check_mr_access(mr_access_flags);
11241c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen	if (ret)
11251c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen		return ret;
11261c636f801615bdfc9b1d46904e8258c7a025670bEli Cohen
11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!mr->device->rereg_phys_mr)
11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOSYS;
11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&mr->usecnt))
11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	old_pd = mr->pd;
11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mr->device->rereg_phys_mr(mr, mr_rereg_mask, pd,
11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					phys_buf_array, num_phys_buf,
11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mr_access_flags, iova_start);
11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret && (mr_rereg_mask & IB_MR_REREG_PD)) {
11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&old_pd->usecnt);
11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_rereg_phys_mr);
11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr->device->query_mr ?
11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mr->device->query_mr(mr, mr_attr) : -ENOSYS;
11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_mr);
11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dereg_mr(struct ib_mr *mr)
11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&mr->usecnt))
11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = mr->pd;
11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mr->device->dereg_mr(mr);
11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dereg_mr);
11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
117217cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimbergstruct ib_mr *ib_create_mr(struct ib_pd *pd,
117317cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg			   struct ib_mr_init_attr *mr_init_attr)
117417cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg{
117517cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	struct ib_mr *mr;
117617cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg
117717cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	if (!pd->device->create_mr)
117817cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg		return ERR_PTR(-ENOSYS);
117917cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg
118017cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	mr = pd->device->create_mr(pd, mr_init_attr);
118117cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg
118217cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	if (!IS_ERR(mr)) {
118317cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg		mr->device  = pd->device;
118417cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg		mr->pd      = pd;
118517cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg		mr->uobject = NULL;
118617cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg		atomic_inc(&pd->usecnt);
118717cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg		atomic_set(&mr->usecnt, 0);
118817cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	}
118917cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg
119017cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	return mr;
119117cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg}
119217cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi GrimbergEXPORT_SYMBOL(ib_create_mr);
119317cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg
119417cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimbergint ib_destroy_mr(struct ib_mr *mr)
119517cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg{
119617cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	struct ib_pd *pd;
119717cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	int ret;
119817cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg
119917cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	if (atomic_read(&mr->usecnt))
120017cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg		return -EBUSY;
120117cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg
120217cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	pd = mr->pd;
120317cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	ret = mr->device->destroy_mr(mr);
120417cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	if (!ret)
120517cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg		atomic_dec(&pd->usecnt);
120617cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg
120717cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg	return ret;
120817cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg}
120917cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi GrimbergEXPORT_SYMBOL(ib_destroy_mr);
121017cd3a2db825506c3e3bb9548ad20f67e2f8d0e7Sagi Grimberg
121100f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wisestruct ib_mr *ib_alloc_fast_reg_mr(struct ib_pd *pd, int max_page_list_len)
121200f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise{
121300f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	struct ib_mr *mr;
121400f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
121500f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	if (!pd->device->alloc_fast_reg_mr)
121600f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		return ERR_PTR(-ENOSYS);
121700f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
121800f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	mr = pd->device->alloc_fast_reg_mr(pd, max_page_list_len);
121900f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
122000f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	if (!IS_ERR(mr)) {
122100f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		mr->device  = pd->device;
122200f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		mr->pd      = pd;
122300f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		mr->uobject = NULL;
122400f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		atomic_inc(&pd->usecnt);
122500f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		atomic_set(&mr->usecnt, 0);
122600f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	}
122700f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
122800f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	return mr;
122900f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise}
123000f7ec36c9324928e4cd23f02e6d8550f30c32caSteve WiseEXPORT_SYMBOL(ib_alloc_fast_reg_mr);
123100f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
123200f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wisestruct ib_fast_reg_page_list *ib_alloc_fast_reg_page_list(struct ib_device *device,
123300f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise							  int max_page_list_len)
123400f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise{
123500f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	struct ib_fast_reg_page_list *page_list;
123600f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
123700f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	if (!device->alloc_fast_reg_page_list)
123800f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		return ERR_PTR(-ENOSYS);
123900f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
124000f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	page_list = device->alloc_fast_reg_page_list(device, max_page_list_len);
124100f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
124200f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	if (!IS_ERR(page_list)) {
124300f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		page_list->device = device;
124400f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise		page_list->max_page_list_len = max_page_list_len;
124500f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	}
124600f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
124700f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	return page_list;
124800f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise}
124900f7ec36c9324928e4cd23f02e6d8550f30c32caSteve WiseEXPORT_SYMBOL(ib_alloc_fast_reg_page_list);
125000f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
125100f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wisevoid ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list)
125200f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise{
125300f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise	page_list->device->free_fast_reg_page_list(page_list);
125400f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise}
125500f7ec36c9324928e4cd23f02e6d8550f30c32caSteve WiseEXPORT_SYMBOL(ib_free_fast_reg_page_list);
125600f7ec36c9324928e4cd23f02e6d8550f30c32caSteve Wise
12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Memory windows */
12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12597083e42ee2ff43a11481e0e7211ec4f9ac68cb79Shani Michaelistruct ib_mw *ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type)
12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mw *mw;
12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!pd->device->alloc_mw)
12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOSYS);
12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12667083e42ee2ff43a11481e0e7211ec4f9ac68cb79Shani Michaeli	mw = pd->device->alloc_mw(pd, type);
12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mw)) {
1268b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->device  = pd->device;
1269b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->pd      = pd;
1270b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->uobject = NULL;
12717083e42ee2ff43a11481e0e7211ec4f9ac68cb79Shani Michaeli		mw->type    = type;
12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mw;
12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_mw);
12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_mw(struct ib_mw *mw)
12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = mw->pd;
12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mw->device->dealloc_mw(mw);
12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_mw);
12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* "Fast" memory regions */
12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    int mr_access_flags,
12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    struct ib_fmr_attr *fmr_attr)
12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_fmr *fmr;
13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!pd->device->alloc_fmr)
13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOSYS);
13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr);
13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(fmr)) {
13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fmr->device = pd->device;
13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fmr->pd     = pd;
13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return fmr;
13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_fmr);
13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_unmap_fmr(struct list_head *fmr_list)
13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_fmr *fmr;
13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (list_empty(fmr_list))
13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fmr = list_entry(fmr_list->next, struct ib_fmr, list);
13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return fmr->device->unmap_fmr(fmr_list);
13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_unmap_fmr);
13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_fmr(struct ib_fmr *fmr)
13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = fmr->pd;
13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = fmr->device->dealloc_fmr(fmr);
13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_fmr);
13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Multicast groups */
13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1345c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz	int ret;
1346c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz
13470c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (!qp->device->attach_mcast)
13480c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -ENOSYS;
13490c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
13500c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -EINVAL;
13510c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein
1352c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz	ret = qp->device->attach_mcast(qp, gid, lid);
1353c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz	if (!ret)
1354c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz		atomic_inc(&qp->usecnt);
1355c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz	return ret;
13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_attach_mcast);
13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1361c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz	int ret;
1362c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz
13630c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (!qp->device->detach_mcast)
13640c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -ENOSYS;
13650c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
13660c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -EINVAL;
13670c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein
1368c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz	ret = qp->device->detach_mcast(qp, gid, lid);
1369c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz	if (!ret)
1370c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz		atomic_dec(&qp->usecnt);
1371c3bccbfbb71f5e8a77129c7a069f5c5648cc9cf1Or Gerlitz	return ret;
13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_detach_mcast);
137459991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
137559991f94eb32e954aa767f659eb642461e9e8b37Sean Heftystruct ib_xrcd *ib_alloc_xrcd(struct ib_device *device)
137659991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty{
137759991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	struct ib_xrcd *xrcd;
137859991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
137959991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	if (!device->alloc_xrcd)
138059991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty		return ERR_PTR(-ENOSYS);
138159991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
138259991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	xrcd = device->alloc_xrcd(device, NULL, NULL);
138359991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	if (!IS_ERR(xrcd)) {
138459991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty		xrcd->device = device;
138553d0bd1e7ff2fc626321f337c609fb76ae5d12c9Sean Hefty		xrcd->inode = NULL;
138659991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty		atomic_set(&xrcd->usecnt, 0);
1387d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		mutex_init(&xrcd->tgt_qp_mutex);
1388d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		INIT_LIST_HEAD(&xrcd->tgt_qp_list);
138959991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	}
139059991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
139159991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	return xrcd;
139259991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty}
139359991f94eb32e954aa767f659eb642461e9e8b37Sean HeftyEXPORT_SYMBOL(ib_alloc_xrcd);
139459991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
139559991f94eb32e954aa767f659eb642461e9e8b37Sean Heftyint ib_dealloc_xrcd(struct ib_xrcd *xrcd)
139659991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty{
1397d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	struct ib_qp *qp;
1398d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	int ret;
1399d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
140059991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	if (atomic_read(&xrcd->usecnt))
140159991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty		return -EBUSY;
140259991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty
1403d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	while (!list_empty(&xrcd->tgt_qp_list)) {
1404d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		qp = list_entry(xrcd->tgt_qp_list.next, struct ib_qp, xrcd_list);
1405d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		ret = ib_destroy_qp(qp);
1406d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty		if (ret)
1407d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty			return ret;
1408d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty	}
1409d3d72d909e783d048ee39046aa7b4fa798a4dda8Sean Hefty
141059991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty	return xrcd->device->dealloc_xrcd(xrcd);
141159991f94eb32e954aa767f659eb642461e9e8b37Sean Hefty}
141259991f94eb32e954aa767f659eb642461e9e8b37Sean HeftyEXPORT_SYMBOL(ib_dealloc_xrcd);
1413319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion
1414319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zionstruct ib_flow *ib_create_flow(struct ib_qp *qp,
1415319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion			       struct ib_flow_attr *flow_attr,
1416319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion			       int domain)
1417319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion{
1418319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion	struct ib_flow *flow_id;
1419319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion	if (!qp->device->create_flow)
1420319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion		return ERR_PTR(-ENOSYS);
1421319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion
1422319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion	flow_id = qp->device->create_flow(qp, flow_attr, domain);
1423319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion	if (!IS_ERR(flow_id))
1424319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion		atomic_inc(&qp->usecnt);
1425319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion	return flow_id;
1426319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion}
1427319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen ZionEXPORT_SYMBOL(ib_create_flow);
1428319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion
1429319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zionint ib_destroy_flow(struct ib_flow *flow_id)
1430319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion{
1431319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion	int err;
1432319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion	struct ib_qp *qp = flow_id->qp;
1433319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion
1434319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion	err = qp->device->destroy_flow(flow_id);
1435319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion	if (!err)
1436319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion		atomic_dec(&qp->usecnt);
1437319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion	return err;
1438319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen Zion}
1439319a441d1361ea703b091caf92418f8121eadfc5Hadar Hen ZionEXPORT_SYMBOL(ib_destroy_flow);
14401b01d33560e78417334c2dc673bbfac6c644424cSagi Grimberg
14411b01d33560e78417334c2dc673bbfac6c644424cSagi Grimbergint ib_check_mr_status(struct ib_mr *mr, u32 check_mask,
14421b01d33560e78417334c2dc673bbfac6c644424cSagi Grimberg		       struct ib_mr_status *mr_status)
14431b01d33560e78417334c2dc673bbfac6c644424cSagi Grimberg{
14441b01d33560e78417334c2dc673bbfac6c644424cSagi Grimberg	return mr->device->check_mr_status ?
14451b01d33560e78417334c2dc673bbfac6c644424cSagi Grimberg		mr->device->check_mr_status(mr, check_mask, mr_status) : -ENOSYS;
14461b01d33560e78417334c2dc673bbfac6c644424cSagi Grimberg}
14471b01d33560e78417334c2dc673bbfac6c644424cSagi GrimbergEXPORT_SYMBOL(ib_check_mr_status);
1448