qp.c revision 51a379d0c8f7a6db7c9e3c9c770d90a6d2d1ef9b
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
150225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreierint mlx4_qp_alloc(struct mlx4_dev *dev, int sqpn, struct mlx4_qp *qp)
151225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
152225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_priv *priv = mlx4_priv(dev);
153225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_qp_table *qp_table = &priv->qp_table;
154225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	int err;
155225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
156225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (sqpn)
157225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		qp->qpn = sqpn;
158225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	else {
159225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		qp->qpn = mlx4_bitmap_alloc(&qp_table->bitmap);
160225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		if (qp->qpn == -1)
161225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			return -ENOMEM;
162225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	}
163225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
164225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_table_get(dev, &qp_table->qp_table, qp->qpn);
165225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
166225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_out;
167225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
168225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_table_get(dev, &qp_table->auxc_table, qp->qpn);
169225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
170225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_put_qp;
171225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
172225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_table_get(dev, &qp_table->altc_table, qp->qpn);
173225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
174225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_put_auxc;
175225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
176225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_table_get(dev, &qp_table->rdmarc_table, qp->qpn);
177225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
178225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_put_altc;
179225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
180225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_table_get(dev, &qp_table->cmpt_table, qp->qpn);
181225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
182225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_put_rdmarc;
183225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
184225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_lock_irq(&qp_table->lock);
185225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = radix_tree_insert(&dev->qp_table_tree, qp->qpn & (dev->caps.num_qps - 1), qp);
186225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_unlock_irq(&qp_table->lock);
187225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
188225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		goto err_put_cmpt;
189225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
190225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	atomic_set(&qp->refcount, 1);
191225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	init_completion(&qp->free);
192225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
193225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	return 0;
194225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
195225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_put_cmpt:
196225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->cmpt_table, qp->qpn);
197225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
198225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_put_rdmarc:
199225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->rdmarc_table, qp->qpn);
200225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
201225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_put_altc:
202225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->altc_table, qp->qpn);
203225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
204225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_put_auxc:
205225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->auxc_table, qp->qpn);
206225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
207225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_put_qp:
208225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->qp_table, qp->qpn);
209225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
210225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiererr_out:
211225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (!sqpn)
212225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		mlx4_bitmap_free(&qp_table->bitmap, qp->qpn);
213225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
214225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	return err;
215225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
216225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland DreierEXPORT_SYMBOL_GPL(mlx4_qp_alloc);
217225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
218225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiervoid mlx4_qp_remove(struct mlx4_dev *dev, struct mlx4_qp *qp)
219225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
220225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
221225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	unsigned long flags;
222225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
223225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_lock_irqsave(&qp_table->lock, flags);
224225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	radix_tree_delete(&dev->qp_table_tree, qp->qpn & (dev->caps.num_qps - 1));
225225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_unlock_irqrestore(&qp_table->lock, flags);
226225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
227225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland DreierEXPORT_SYMBOL_GPL(mlx4_qp_remove);
228225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
229225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiervoid mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp)
230225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
231225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
232225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
233225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (atomic_dec_and_test(&qp->refcount))
234225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		complete(&qp->free);
235225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	wait_for_completion(&qp->free);
236225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
237225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->cmpt_table, qp->qpn);
238225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->rdmarc_table, qp->qpn);
239225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->altc_table, qp->qpn);
240225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->auxc_table, qp->qpn);
241225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_table_put(dev, &qp_table->qp_table, qp->qpn);
242225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
243e383d19e90cfbbf8e00512d44194ce175b3f60a2Jack Morgenstein	if (qp->qpn >= dev->caps.sqp_start + 8)
244eaf559bf566f76887533c077d425adce847f06c8Roland Dreier		mlx4_bitmap_free(&qp_table->bitmap, qp->qpn);
245225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
246225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland DreierEXPORT_SYMBOL_GPL(mlx4_qp_free);
247225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
248225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreierstatic int mlx4_CONF_SPECIAL_QP(struct mlx4_dev *dev, u32 base_qpn)
249225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
250225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	return mlx4_cmd(dev, 0, base_qpn, 0, MLX4_CMD_CONF_SPECIAL_QP,
251225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			MLX4_CMD_TIME_CLASS_B);
252225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
253225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
2543d73c2884f45f9a297cbc956cea101405a9703f2Roland Dreierint mlx4_init_qp_table(struct mlx4_dev *dev)
255225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
256225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
257225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	int err;
258225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
259225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	spin_lock_init(&qp_table->lock);
260225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	INIT_RADIX_TREE(&dev->qp_table_tree, GFP_ATOMIC);
261225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
262225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	/*
263225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	 * We reserve 2 extra QPs per port for the special QPs.  The
264225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	 * block of special QPs must be aligned to a multiple of 8, so
265225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	 * round up.
266225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	 */
267225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	dev->caps.sqp_start = ALIGN(dev->caps.reserved_qps, 8);
268225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	err = mlx4_bitmap_init(&qp_table->bitmap, dev->caps.num_qps,
269225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier			       (1 << 24) - 1, dev->caps.sqp_start + 8);
270225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	if (err)
271225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier		return err;
272225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
273225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	return mlx4_CONF_SPECIAL_QP(dev, dev->caps.sqp_start);
274225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
275225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier
276225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreiervoid mlx4_cleanup_qp_table(struct mlx4_dev *dev)
277225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier{
278225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_CONF_SPECIAL_QP(dev, 0);
279225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier	mlx4_bitmap_cleanup(&mlx4_priv(dev)->qp_table.bitmap);
280225c7b1feef1b41170f7037a5b10a65cd8a42c54Roland Dreier}
2816a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein
2826a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgensteinint mlx4_qp_query(struct mlx4_dev *dev, struct mlx4_qp *qp,
2836a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein		  struct mlx4_qp_context *context)
2846a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein{
2856a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	struct mlx4_cmd_mailbox *mailbox;
2866a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	int err;
2876a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein
2886a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	mailbox = mlx4_alloc_cmd_mailbox(dev);
2896a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	if (IS_ERR(mailbox))
2906a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein		return PTR_ERR(mailbox);
2916a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein
2926a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	err = mlx4_cmd_box(dev, 0, mailbox->dma, qp->qpn, 0,
2936a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein			   MLX4_CMD_QUERY_QP, MLX4_CMD_TIME_CLASS_A);
2946a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	if (!err)
2956a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein		memcpy(context, mailbox->buf + 8, sizeof *context);
2966a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein
2976a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	mlx4_free_cmd_mailbox(dev, mailbox);
2986a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein	return err;
2996a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein}
3006a775e2ba4f7635849ade628e64723ab2beef0bcJack MorgensteinEXPORT_SYMBOL_GPL(mlx4_qp_query);
3016a775e2ba4f7635849ade628e64723ab2beef0bcJack Morgenstein
302ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilinint mlx4_qp_to_ready(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
303ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		     struct mlx4_qp_context *context,
304ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		     struct mlx4_qp *qp, enum mlx4_qp_state *qp_state)
305ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin{
306ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	int err;
307ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	int i;
308ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	enum mlx4_qp_state states[] = {
309ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		MLX4_QP_STATE_RST,
310ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		MLX4_QP_STATE_INIT,
311ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		MLX4_QP_STATE_RTR,
312ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		MLX4_QP_STATE_RTS
313ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	};
314ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin
315ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	for (i = 0; i < ARRAY_SIZE(states) - 1; i++) {
316ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		context->flags &= cpu_to_be32(~(0xf << 28));
317ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		context->flags |= cpu_to_be32(states[i + 1] << 28);
318ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		err = mlx4_qp_modify(dev, mtt, states[i], states[i + 1],
319ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin				     context, 0, 0, qp);
320ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		if (err) {
321ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin			mlx4_err(dev, "Failed to bring QP to state: "
322ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin				 "%d with error: %d\n",
323ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin				 states[i + 1], err);
324ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin			return err;
325ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		}
326ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin
327ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin		*qp_state = states[i + 1];
328ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	}
329ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin
330ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin	return 0;
331ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny Petrilin}
332ed4d3c1061d6f367a4ef5e1656c25af3314fe2b7Yevgeny PetrilinEXPORT_SYMBOL_GPL(mlx4_qp_to_ready);
333