qp.c revision a3cdcbfa8fb1fccfe48d359da86e99546610c562
1225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier/*
2225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * Copyright (c) 2004 Topspin Communications.  All rights reserved.
3225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * Copyright (c) 2005, 2006, 2007 Cisco Systems, Inc. All rights reserved.
451a379d0c8f7a6db7c9e3c9c770d90a6d2d1ef9bJack Morgenstein * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. All rights reserved.
5225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * Copyright (c) 2004 Voltaire, Inc. All rights reserved.
6225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *
7225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * This software is available to you under a choice of one of two
8225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * licenses.  You may choose to be licensed under the terms of the GNU
9225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * General Public License (GPL) Version 2, available from the file
10225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * COPYING in the main directory of this source tree, or the
11225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * OpenIB.org BSD license below:
12225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *
13225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *     Redistribution and use in source and binary forms, with or
14225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *     without modification, are permitted provided that the following
15225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *     conditions are met:
16225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *
17225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *      - Redistributions of source code must retain the above
18225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *        copyright notice, this list of conditions and the following
19225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *        disclaimer.
20225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *
21225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *      - Redistributions in binary form must reproduce the above
22225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *        copyright notice, this list of conditions and the following
23225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *        disclaimer in the documentation and/or other materials
24225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *        provided with the distribution.
25225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier *
26225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier * SOFTWARE.
34225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier */
35225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
36225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier#include <linux/init.h>
37225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
38225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier#include <linux/mlx4/cmd.h>
39225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier#include <linux/mlx4/qp.h>
40225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
41225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier#include "mlx4.h"
42225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier#include "icm.h"
43225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
44225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiervoid mlx4_qp_event(struct mlx4_dev *dev, u32 qpn, int event_type)
45225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
46225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
47225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_qp *qp;
48225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
49225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_lock(&qp_table->lock);
50225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
51225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	qp = __mlx4_qp_lookup(dev, qpn);
52225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (qp)
53225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		atomic_inc(&qp->refcount);
54225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
55225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_unlock(&qp_table->lock);
56225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
57225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (!qp) {
58225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		mlx4_warn(dev, "Async event for bogus QP %08x\n", qpn);
59225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		return;
60225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	}
61225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
62225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	qp->event(qp, event_type);
63225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
64225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (atomic_dec_and_test(&qp->refcount))
65225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		complete(&qp->free);
66225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
67225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
68225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreierint mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
69225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		   enum mlx4_qp_state cur_state, enum mlx4_qp_state new_state,
70225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		   struct mlx4_qp_context *context, enum mlx4_qp_optpar optpar,
71225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		   int sqd_event, struct mlx4_qp *qp)
72225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
73225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	static const u16 op[MLX4_QP_NUM_STATE][MLX4_QP_NUM_STATE] = {
74225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		[MLX4_QP_STATE_RST] = {
75225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RST]	= MLX4_CMD_2RST_QP,
76225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_ERR]	= MLX4_CMD_2ERR_QP,
77225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_INIT]	= MLX4_CMD_RST2INIT_QP,
78225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		},
79225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		[MLX4_QP_STATE_INIT]  = {
80225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RST]	= MLX4_CMD_2RST_QP,
81225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_ERR]	= MLX4_CMD_2ERR_QP,
82225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_INIT]	= MLX4_CMD_INIT2INIT_QP,
83225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RTR]	= MLX4_CMD_INIT2RTR_QP,
84225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		},
85225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		[MLX4_QP_STATE_RTR]   = {
86225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RST]	= MLX4_CMD_2RST_QP,
87225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_ERR]	= MLX4_CMD_2ERR_QP,
88225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RTS]	= MLX4_CMD_RTR2RTS_QP,
89225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		},
90225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		[MLX4_QP_STATE_RTS]   = {
91225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RST]	= MLX4_CMD_2RST_QP,
92225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_ERR]	= MLX4_CMD_2ERR_QP,
93225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RTS]	= MLX4_CMD_RTS2RTS_QP,
94225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_SQD]	= MLX4_CMD_RTS2SQD_QP,
95225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		},
96225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		[MLX4_QP_STATE_SQD] = {
97225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RST]	= MLX4_CMD_2RST_QP,
98225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_ERR]	= MLX4_CMD_2ERR_QP,
99225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RTS]	= MLX4_CMD_SQD2RTS_QP,
100225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_SQD]	= MLX4_CMD_SQD2SQD_QP,
101225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		},
102225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		[MLX4_QP_STATE_SQER] = {
103225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RST]	= MLX4_CMD_2RST_QP,
104225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_ERR]	= MLX4_CMD_2ERR_QP,
105225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RTS]	= MLX4_CMD_SQERR2RTS_QP,
106225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		},
107225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		[MLX4_QP_STATE_ERR] = {
108225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_RST]	= MLX4_CMD_2RST_QP,
109225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			[MLX4_QP_STATE_ERR]	= MLX4_CMD_2ERR_QP,
110225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		}
111225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	};
112225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
113225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_cmd_mailbox *mailbox;
114225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	int ret = 0;
115225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
1169ed87fd34c97a998e63505718ce7e107a23c84c3Jack Morgenstein	if (cur_state >= MLX4_QP_NUM_STATE || new_state >= MLX4_QP_NUM_STATE ||
117225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	    !op[cur_state][new_state])
118225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		return -EINVAL;
119225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
120225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (op[cur_state][new_state] == MLX4_CMD_2RST_QP)
121225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		return mlx4_cmd(dev, 0, qp->qpn, 2,
122225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier				MLX4_CMD_2RST_QP, MLX4_CMD_TIME_CLASS_A);
123225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
124225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mailbox = mlx4_alloc_cmd_mailbox(dev);
125225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (IS_ERR(mailbox))
126225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		return PTR_ERR(mailbox);
127225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
128225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (cur_state == MLX4_QP_STATE_RST && new_state == MLX4_QP_STATE_INIT) {
129225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		u64 mtt_addr = mlx4_mtt_addr(dev, mtt);
130225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		context->mtt_base_addr_h = mtt_addr >> 32;
131225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff);
132225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		context->log_page_size   = mtt->page_shift - MLX4_ICM_PAGE_SHIFT;
133225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	}
134225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
135225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	*(__be32 *) mailbox->buf = cpu_to_be32(optpar);
136225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	memcpy(mailbox->buf + 8, context, sizeof *context);
137225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
138225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	((struct mlx4_qp_context *) (mailbox->buf + 8))->local_qpn =
139225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		cpu_to_be32(qp->qpn);
140225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
141225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	ret = mlx4_cmd(dev, mailbox->dma, qp->qpn | (!!sqd_event << 31),
142225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		       new_state == MLX4_QP_STATE_RST ? 2 : 0,
143225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		       op[cur_state][new_state], MLX4_CMD_TIME_CLASS_C);
144225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
145225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_free_cmd_mailbox(dev, mailbox);
146225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	return ret;
147225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
148225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland DreierEXPORT_SYMBOL_GPL(mlx4_qp_modify);
149225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
150a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilinint mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base)
151a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin{
152a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	struct mlx4_priv *priv = mlx4_priv(dev);
153a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	struct mlx4_qp_table *qp_table = &priv->qp_table;
154a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	int qpn;
155a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin
156a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	qpn = mlx4_bitmap_alloc_range(&qp_table->bitmap, cnt, align);
157a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	if (qpn == -1)
158a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin		return -ENOMEM;
159a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin
160a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	*base = qpn;
161a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	return 0;
162a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin}
163a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny PetrilinEXPORT_SYMBOL_GPL(mlx4_qp_reserve_range);
164a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin
165a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilinvoid mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
166a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin{
167a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	struct mlx4_priv *priv = mlx4_priv(dev);
168a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	struct mlx4_qp_table *qp_table = &priv->qp_table;
169a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	if (base_qpn < dev->caps.sqp_start + 8)
170a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin		return;
171a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin
172a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	mlx4_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt);
173a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin}
174a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny PetrilinEXPORT_SYMBOL_GPL(mlx4_qp_release_range);
175a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin
176a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilinint mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp)
177225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
178225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_priv *priv = mlx4_priv(dev);
179225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_qp_table *qp_table = &priv->qp_table;
180225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	int err;
181225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
182a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	if (!qpn)
183a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin		return -EINVAL;
184a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin
185a3cdcbfa8fb1fccfe48d359da86e99546610c562Yevgeny Petrilin	qp->qpn = qpn;
186225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
187225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_table_get(dev, &qp_table->qp_table, qp->qpn);
188225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
189225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_out;
190225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
191225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_table_get(dev, &qp_table->auxc_table, qp->qpn);
192225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
193225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_put_qp;
194225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
195225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_table_get(dev, &qp_table->altc_table, qp->qpn);
196225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
197225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_put_auxc;
198225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
199225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_table_get(dev, &qp_table->rdmarc_table, qp->qpn);
200225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
201225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_put_altc;
202225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
203225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_table_get(dev, &qp_table->cmpt_table, qp->qpn);
204225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
205225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_put_rdmarc;
206225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
207225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_lock_irq(&qp_table->lock);
208225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = radix_tree_insert(&dev->qp_table_tree, qp->qpn & (dev->caps.num_qps - 1), qp);
209225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_unlock_irq(&qp_table->lock);
210225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
211225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_put_cmpt;
212225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
213225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	atomic_set(&qp->refcount, 1);
214225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	init_completion(&qp->free);
215225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
216225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	return 0;
217225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
218225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_put_cmpt:
219225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->cmpt_table, qp->qpn);
220225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
221225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_put_rdmarc:
222225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->rdmarc_table, qp->qpn);
223225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
224225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_put_altc:
225225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->altc_table, qp->qpn);
226225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
227225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_put_auxc:
228225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->auxc_table, qp->qpn);
229225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
230225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_put_qp:
231225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->qp_table, qp->qpn);
232225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
233225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_out:
234225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	return err;
235225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
236225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland DreierEXPORT_SYMBOL_GPL(mlx4_qp_alloc);
237225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
238225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiervoid mlx4_qp_remove(struct mlx4_dev *dev, struct mlx4_qp *qp)
239225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
240225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
241225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	unsigned long flags;
242225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
243225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_lock_irqsave(&qp_table->lock, flags);
244225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	radix_tree_delete(&dev->qp_table_tree, qp->qpn & (dev->caps.num_qps - 1));
245225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_unlock_irqrestore(&qp_table->lock, flags);
246225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
247225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland DreierEXPORT_SYMBOL_GPL(mlx4_qp_remove);
248225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
249225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiervoid mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp)
250225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
251225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
252225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
253225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (atomic_dec_and_test(&qp->refcount))
254225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		complete(&qp->free);
255225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	wait_for_completion(&qp->free);
256225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
257225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->cmpt_table, qp->qpn);
258225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->rdmarc_table, qp->qpn);
259225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->altc_table, qp->qpn);
260225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->auxc_table, qp->qpn);
261225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->qp_table, qp->qpn);
262225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
263225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland DreierEXPORT_SYMBOL_GPL(mlx4_qp_free);
264225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
265225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreierstatic int mlx4_CONF_SPECIAL_QP(struct mlx4_dev *dev, u32 base_qpn)
266225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
267225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	return mlx4_cmd(dev, 0, base_qpn, 0, MLX4_CMD_CONF_SPECIAL_QP,
268225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			MLX4_CMD_TIME_CLASS_B);
269225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
270225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
2713d73c2884f45f9a297cbc956cea101405a9703f2Roland Dreierint mlx4_init_qp_table(struct mlx4_dev *dev)
272225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
273225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
274225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	int err;
275225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
276225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_lock_init(&qp_table->lock);
277225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	INIT_RADIX_TREE(&dev->qp_table_tree, GFP_ATOMIC);
278225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
279225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	/*
280225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	 * We reserve 2 extra QPs per port for the special QPs.  The
281225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	 * block of special QPs must be aligned to a multiple of 8, so
282225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	 * round up.
283225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	 */
284225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	dev->caps.sqp_start = ALIGN(dev->caps.reserved_qps, 8);
285225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps,
286225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			       (1 << 24) - 1, dev->caps.sqp_start + 8);
287225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
288225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		return err;
289225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
290225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	return mlx4_CONF_SPECIAL_QP(dev, dev->caps.sqp_start);
291225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
292225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
293225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiervoid mlx4_cleanup_qp_table(struct mlx4_dev *dev)
294225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
295225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_CONF_SPECIAL_QP(dev, 0);
296225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_bitmap_cleanup(&mlx4_priv(dev)->qp_table.bitmap);
297225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
2986a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein
2996a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgensteinint mlx4_qp_query(struct mlx4_dev *dev, struct mlx4_qp *qp,
3006a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein		  struct mlx4_qp_context *context)
3016a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein{
3026a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	struct mlx4_cmd_mailbox *mailbox;
3036a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	int err;
3046a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein
3056a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	mailbox = mlx4_alloc_cmd_mailbox(dev);
3066a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	if (IS_ERR(mailbox))
3076a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein		return PTR_ERR(mailbox);
3086a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein
3096a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	err = mlx4_cmd_box(dev, 0, mailbox->dma, qp->qpn, 0,
3106a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein			   MLX4_CMD_QUERY_QP, MLX4_CMD_TIME_CLASS_A);
3116a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	if (!err)
3126a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein		memcpy(context, mailbox->buf + 8, sizeof *context);
3136a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein
3146a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	mlx4_free_cmd_mailbox(dev, mailbox);
3156a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	return err;
3166a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein}
3176a775e2ba4f7635849ade628e64723ab2beef0bcJack MorgensteinEXPORT_SYMBOL_GPL(mlx4_qp_query);
3186a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein
319ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilinint mlx4_qp_to_ready(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
320ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		     struct mlx4_qp_context *context,
321ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		     struct mlx4_qp *qp, enum mlx4_qp_state *qp_state)
322ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin{
323ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	int err;
324ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	int i;
325ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	enum mlx4_qp_state states[] = {
326ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		MLX4_QP_STATE_RST,
327ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		MLX4_QP_STATE_INIT,
328ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		MLX4_QP_STATE_RTR,
329ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		MLX4_QP_STATE_RTS
330ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	};
331ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin
332ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	for (i = 0; i < ARRAY_SIZE(states) - 1; i++) {
333ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		context->flags &= cpu_to_be32(~(0xf << 28));
334ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		context->flags |= cpu_to_be32(states[i + 1] << 28);
335ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		err = mlx4_qp_modify(dev, mtt, states[i], states[i + 1],
336ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin				     context, 0, 0, qp);
337ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		if (err) {
338ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin			mlx4_err(dev, "Failed to bring QP to state: "
339ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin				 "%d with error: %d\n",
340ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin				 states[i + 1], err);
341ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin			return err;
342ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		}
343ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin
344ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		*qp_state = states[i + 1];
345ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	}
346ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin
347ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	return 0;
348ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin}
349ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny PetrilinEXPORT_SYMBOL_GPL(mlx4_qp_to_ready);
350