brintos

brintos / linux-shallow public Read only

0
0
Text · 158.8 KiB · 10ce3b4 Raw
5844 lines · c
1/*2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.3 *4 * This software is available to you under a choice of one of two5 * licenses.  You may choose to be licensed under the terms of the GNU6 * General Public License (GPL) Version 2, available from the file7 * COPYING in the main directory of this source tree, or the8 * OpenIB.org BSD license below:9 *10 *     Redistribution and use in source and binary forms, with or11 *     without modification, are permitted provided that the following12 *     conditions are met:13 *14 *      - Redistributions of source code must retain the above15 *        copyright notice, this list of conditions and the following16 *        disclaimer.17 *18 *      - Redistributions in binary form must reproduce the above19 *        copyright notice, this list of conditions and the following20 *        disclaimer in the documentation and/or other materials21 *        provided with the distribution.22 *23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE30 * SOFTWARE.31 */32 33#include <linux/etherdevice.h>34#include <rdma/ib_umem.h>35#include <rdma/ib_cache.h>36#include <rdma/ib_user_verbs.h>37#include <rdma/rdma_counter.h>38#include <linux/mlx5/fs.h>39#include "mlx5_ib.h"40#include "ib_rep.h"41#include "counters.h"42#include "cmd.h"43#include "umr.h"44#include "qp.h"45#include "wr.h"46 47enum {48	MLX5_IB_ACK_REQ_FREQ	= 8,49};50 51enum {52	MLX5_IB_DEFAULT_SCHED_QUEUE	= 0x83,53	MLX5_IB_DEFAULT_QP0_SCHED_QUEUE	= 0x3f,54	MLX5_IB_LINK_TYPE_IB		= 0,55	MLX5_IB_LINK_TYPE_ETH		= 156};57 58enum raw_qp_set_mask_map {59	MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID		= 1UL << 0,60	MLX5_RAW_QP_RATE_LIMIT			= 1UL << 1,61};62 63enum {64	MLX5_QP_RM_GO_BACK_N			= 0x1,65};66 67struct mlx5_modify_raw_qp_param {68	u16 operation;69 70	u32 set_mask; /* raw_qp_set_mask_map */71 72	struct mlx5_rate_limit rl;73 74	u8 rq_q_ctr_id;75	u32 port;76};77 78struct mlx5_ib_qp_event_work {79	struct work_struct work;80	struct mlx5_core_qp *qp;81	int type;82};83 84static struct workqueue_struct *mlx5_ib_qp_event_wq;85 86static void get_cqs(enum ib_qp_type qp_type,87		    struct ib_cq *ib_send_cq, struct ib_cq *ib_recv_cq,88		    struct mlx5_ib_cq **send_cq, struct mlx5_ib_cq **recv_cq);89 90static int is_qp0(enum ib_qp_type qp_type)91{92	return qp_type == IB_QPT_SMI;93}94 95static int is_sqp(enum ib_qp_type qp_type)96{97	return is_qp0(qp_type) || is_qp1(qp_type);98}99 100/**101 * mlx5_ib_read_user_wqe_common() - Copy a WQE (or part of) from user WQ102 * to kernel buffer103 *104 * @umem: User space memory where the WQ is105 * @buffer: buffer to copy to106 * @buflen: buffer length107 * @wqe_index: index of WQE to copy from108 * @wq_offset: offset to start of WQ109 * @wq_wqe_cnt: number of WQEs in WQ110 * @wq_wqe_shift: log2 of WQE size111 * @bcnt: number of bytes to copy112 * @bytes_copied: number of bytes to copy (return value)113 *114 * Copies from start of WQE bcnt or less bytes.115 * Does not gurantee to copy the entire WQE.116 *117 * Return: zero on success, or an error code.118 */119static int mlx5_ib_read_user_wqe_common(struct ib_umem *umem, void *buffer,120					size_t buflen, int wqe_index,121					int wq_offset, int wq_wqe_cnt,122					int wq_wqe_shift, int bcnt,123					size_t *bytes_copied)124{125	size_t offset = wq_offset + ((wqe_index % wq_wqe_cnt) << wq_wqe_shift);126	size_t wq_end = wq_offset + (wq_wqe_cnt << wq_wqe_shift);127	size_t copy_length;128	int ret;129 130	/* don't copy more than requested, more than buffer length or131	 * beyond WQ end132	 */133	copy_length = min_t(u32, buflen, wq_end - offset);134	copy_length = min_t(u32, copy_length, bcnt);135 136	ret = ib_umem_copy_from(buffer, umem, offset, copy_length);137	if (ret)138		return ret;139 140	if (!ret && bytes_copied)141		*bytes_copied = copy_length;142 143	return 0;144}145 146static int mlx5_ib_read_kernel_wqe_sq(struct mlx5_ib_qp *qp, int wqe_index,147				      void *buffer, size_t buflen, size_t *bc)148{149	struct mlx5_wqe_ctrl_seg *ctrl;150	size_t bytes_copied = 0;151	size_t wqe_length;152	void *p;153	int ds;154 155	wqe_index = wqe_index & qp->sq.fbc.sz_m1;156 157	/* read the control segment first */158	p = mlx5_frag_buf_get_wqe(&qp->sq.fbc, wqe_index);159	ctrl = p;160	ds = be32_to_cpu(ctrl->qpn_ds) & MLX5_WQE_CTRL_DS_MASK;161	wqe_length = ds * MLX5_WQE_DS_UNITS;162 163	/* read rest of WQE if it spreads over more than one stride */164	while (bytes_copied < wqe_length) {165		size_t copy_length =166			min_t(size_t, buflen - bytes_copied, MLX5_SEND_WQE_BB);167 168		if (!copy_length)169			break;170 171		memcpy(buffer + bytes_copied, p, copy_length);172		bytes_copied += copy_length;173 174		wqe_index = (wqe_index + 1) & qp->sq.fbc.sz_m1;175		p = mlx5_frag_buf_get_wqe(&qp->sq.fbc, wqe_index);176	}177	*bc = bytes_copied;178	return 0;179}180 181static int mlx5_ib_read_user_wqe_sq(struct mlx5_ib_qp *qp, int wqe_index,182				    void *buffer, size_t buflen, size_t *bc)183{184	struct mlx5_ib_qp_base *base = &qp->trans_qp.base;185	struct ib_umem *umem = base->ubuffer.umem;186	struct mlx5_ib_wq *wq = &qp->sq;187	struct mlx5_wqe_ctrl_seg *ctrl;188	size_t bytes_copied;189	size_t bytes_copied2;190	size_t wqe_length;191	int ret;192	int ds;193 194	/* at first read as much as possible */195	ret = mlx5_ib_read_user_wqe_common(umem, buffer, buflen, wqe_index,196					   wq->offset, wq->wqe_cnt,197					   wq->wqe_shift, buflen,198					   &bytes_copied);199	if (ret)200		return ret;201 202	/* we need at least control segment size to proceed */203	if (bytes_copied < sizeof(*ctrl))204		return -EINVAL;205 206	ctrl = buffer;207	ds = be32_to_cpu(ctrl->qpn_ds) & MLX5_WQE_CTRL_DS_MASK;208	wqe_length = ds * MLX5_WQE_DS_UNITS;209 210	/* if we copied enough then we are done */211	if (bytes_copied >= wqe_length) {212		*bc = bytes_copied;213		return 0;214	}215 216	/* otherwise this a wrapped around wqe217	 * so read the remaining bytes starting218	 * from  wqe_index 0219	 */220	ret = mlx5_ib_read_user_wqe_common(umem, buffer + bytes_copied,221					   buflen - bytes_copied, 0, wq->offset,222					   wq->wqe_cnt, wq->wqe_shift,223					   wqe_length - bytes_copied,224					   &bytes_copied2);225 226	if (ret)227		return ret;228	*bc = bytes_copied + bytes_copied2;229	return 0;230}231 232int mlx5_ib_read_wqe_sq(struct mlx5_ib_qp *qp, int wqe_index, void *buffer,233			size_t buflen, size_t *bc)234{235	struct mlx5_ib_qp_base *base = &qp->trans_qp.base;236	struct ib_umem *umem = base->ubuffer.umem;237 238	if (buflen < sizeof(struct mlx5_wqe_ctrl_seg))239		return -EINVAL;240 241	if (!umem)242		return mlx5_ib_read_kernel_wqe_sq(qp, wqe_index, buffer,243						  buflen, bc);244 245	return mlx5_ib_read_user_wqe_sq(qp, wqe_index, buffer, buflen, bc);246}247 248static int mlx5_ib_read_user_wqe_rq(struct mlx5_ib_qp *qp, int wqe_index,249				    void *buffer, size_t buflen, size_t *bc)250{251	struct mlx5_ib_qp_base *base = &qp->trans_qp.base;252	struct ib_umem *umem = base->ubuffer.umem;253	struct mlx5_ib_wq *wq = &qp->rq;254	size_t bytes_copied;255	int ret;256 257	ret = mlx5_ib_read_user_wqe_common(umem, buffer, buflen, wqe_index,258					   wq->offset, wq->wqe_cnt,259					   wq->wqe_shift, buflen,260					   &bytes_copied);261 262	if (ret)263		return ret;264	*bc = bytes_copied;265	return 0;266}267 268int mlx5_ib_read_wqe_rq(struct mlx5_ib_qp *qp, int wqe_index, void *buffer,269			size_t buflen, size_t *bc)270{271	struct mlx5_ib_qp_base *base = &qp->trans_qp.base;272	struct ib_umem *umem = base->ubuffer.umem;273	struct mlx5_ib_wq *wq = &qp->rq;274	size_t wqe_size = 1 << wq->wqe_shift;275 276	if (buflen < wqe_size)277		return -EINVAL;278 279	if (!umem)280		return -EOPNOTSUPP;281 282	return mlx5_ib_read_user_wqe_rq(qp, wqe_index, buffer, buflen, bc);283}284 285static int mlx5_ib_read_user_wqe_srq(struct mlx5_ib_srq *srq, int wqe_index,286				     void *buffer, size_t buflen, size_t *bc)287{288	struct ib_umem *umem = srq->umem;289	size_t bytes_copied;290	int ret;291 292	ret = mlx5_ib_read_user_wqe_common(umem, buffer, buflen, wqe_index, 0,293					   srq->msrq.max, srq->msrq.wqe_shift,294					   buflen, &bytes_copied);295 296	if (ret)297		return ret;298	*bc = bytes_copied;299	return 0;300}301 302int mlx5_ib_read_wqe_srq(struct mlx5_ib_srq *srq, int wqe_index, void *buffer,303			 size_t buflen, size_t *bc)304{305	struct ib_umem *umem = srq->umem;306	size_t wqe_size = 1 << srq->msrq.wqe_shift;307 308	if (buflen < wqe_size)309		return -EINVAL;310 311	if (!umem)312		return -EOPNOTSUPP;313 314	return mlx5_ib_read_user_wqe_srq(srq, wqe_index, buffer, buflen, bc);315}316 317static void mlx5_ib_qp_err_syndrome(struct ib_qp *ibqp)318{319	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);320	int outlen = MLX5_ST_SZ_BYTES(query_qp_out);321	struct mlx5_ib_qp *qp = to_mqp(ibqp);322	void *pas_ext_union, *err_syn;323	u32 *outb;324	int err;325 326	if (!MLX5_CAP_GEN(dev->mdev, qpc_extension) ||327	    !MLX5_CAP_GEN(dev->mdev, qp_error_syndrome))328		return;329 330	outb = kzalloc(outlen, GFP_KERNEL);331	if (!outb)332		return;333 334	err = mlx5_core_qp_query(dev, &qp->trans_qp.base.mqp, outb, outlen,335				 true);336	if (err)337		goto out;338 339	pas_ext_union =340		MLX5_ADDR_OF(query_qp_out, outb, qp_pas_or_qpc_ext_and_pas);341	err_syn = MLX5_ADDR_OF(qpc_extension_and_pas_list_in, pas_ext_union,342			       qpc_data_extension.error_syndrome);343 344	pr_err("%s/%d: QP %d error: %s (0x%x 0x%x 0x%x)\n",345	       ibqp->device->name, ibqp->port, ibqp->qp_num,346	       ib_wc_status_msg(347		       MLX5_GET(cqe_error_syndrome, err_syn, syndrome)),348	       MLX5_GET(cqe_error_syndrome, err_syn, vendor_error_syndrome),349	       MLX5_GET(cqe_error_syndrome, err_syn, hw_syndrome_type),350	       MLX5_GET(cqe_error_syndrome, err_syn, hw_error_syndrome));351out:352	kfree(outb);353}354 355static void mlx5_ib_handle_qp_event(struct work_struct *_work)356{357	struct mlx5_ib_qp_event_work *qpe_work =358		container_of(_work, struct mlx5_ib_qp_event_work, work);359	struct ib_qp *ibqp = &to_mibqp(qpe_work->qp)->ibqp;360	struct ib_event event = {};361 362	event.device = ibqp->device;363	event.element.qp = ibqp;364	switch (qpe_work->type) {365	case MLX5_EVENT_TYPE_PATH_MIG:366		event.event = IB_EVENT_PATH_MIG;367		break;368	case MLX5_EVENT_TYPE_COMM_EST:369		event.event = IB_EVENT_COMM_EST;370		break;371	case MLX5_EVENT_TYPE_SQ_DRAINED:372		event.event = IB_EVENT_SQ_DRAINED;373		break;374	case MLX5_EVENT_TYPE_SRQ_LAST_WQE:375		event.event = IB_EVENT_QP_LAST_WQE_REACHED;376		break;377	case MLX5_EVENT_TYPE_WQ_CATAS_ERROR:378		event.event = IB_EVENT_QP_FATAL;379		break;380	case MLX5_EVENT_TYPE_PATH_MIG_FAILED:381		event.event = IB_EVENT_PATH_MIG_ERR;382		break;383	case MLX5_EVENT_TYPE_WQ_INVAL_REQ_ERROR:384		event.event = IB_EVENT_QP_REQ_ERR;385		break;386	case MLX5_EVENT_TYPE_WQ_ACCESS_ERROR:387		event.event = IB_EVENT_QP_ACCESS_ERR;388		break;389	default:390		pr_warn("mlx5_ib: Unexpected event type %d on QP %06x\n",391			qpe_work->type, qpe_work->qp->qpn);392		goto out;393	}394 395	if ((event.event == IB_EVENT_QP_FATAL) ||396	    (event.event == IB_EVENT_QP_ACCESS_ERR))397		mlx5_ib_qp_err_syndrome(ibqp);398 399	ibqp->event_handler(&event, ibqp->qp_context);400 401out:402	mlx5_core_res_put(&qpe_work->qp->common);403	kfree(qpe_work);404}405 406static void mlx5_ib_qp_event(struct mlx5_core_qp *qp, int type)407{408	struct ib_qp *ibqp = &to_mibqp(qp)->ibqp;409	struct mlx5_ib_qp_event_work *qpe_work;410 411	if (type == MLX5_EVENT_TYPE_PATH_MIG) {412		/* This event is only valid for trans_qps */413		to_mibqp(qp)->port = to_mibqp(qp)->trans_qp.alt_port;414	}415 416	if (!ibqp->event_handler)417		goto out_no_handler;418 419	qpe_work = kzalloc(sizeof(*qpe_work), GFP_ATOMIC);420	if (!qpe_work)421		goto out_no_handler;422 423	qpe_work->qp = qp;424	qpe_work->type = type;425	INIT_WORK(&qpe_work->work, mlx5_ib_handle_qp_event);426	queue_work(mlx5_ib_qp_event_wq, &qpe_work->work);427	return;428 429out_no_handler:430	mlx5_core_res_put(&qp->common);431}432 433static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap,434		       int has_rq, struct mlx5_ib_qp *qp, struct mlx5_ib_create_qp *ucmd)435{436	int wqe_size;437	int wq_size;438 439	/* Sanity check RQ size before proceeding */440	if (cap->max_recv_wr > (1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz)))441		return -EINVAL;442 443	if (!has_rq) {444		qp->rq.max_gs = 0;445		qp->rq.wqe_cnt = 0;446		qp->rq.wqe_shift = 0;447		cap->max_recv_wr = 0;448		cap->max_recv_sge = 0;449	} else {450		int wq_sig = !!(qp->flags_en & MLX5_QP_FLAG_SIGNATURE);451 452		if (ucmd) {453			qp->rq.wqe_cnt = ucmd->rq_wqe_count;454			if (ucmd->rq_wqe_shift > BITS_PER_BYTE * sizeof(ucmd->rq_wqe_shift))455				return -EINVAL;456			qp->rq.wqe_shift = ucmd->rq_wqe_shift;457			if ((1 << qp->rq.wqe_shift) /458				    sizeof(struct mlx5_wqe_data_seg) <459			    wq_sig)460				return -EINVAL;461			qp->rq.max_gs =462				(1 << qp->rq.wqe_shift) /463					sizeof(struct mlx5_wqe_data_seg) -464				wq_sig;465			qp->rq.max_post = qp->rq.wqe_cnt;466		} else {467			wqe_size =468				wq_sig ? sizeof(struct mlx5_wqe_signature_seg) :469					 0;470			wqe_size += cap->max_recv_sge * sizeof(struct mlx5_wqe_data_seg);471			wqe_size = roundup_pow_of_two(wqe_size);472			wq_size = roundup_pow_of_two(cap->max_recv_wr) * wqe_size;473			wq_size = max_t(int, wq_size, MLX5_SEND_WQE_BB);474			qp->rq.wqe_cnt = wq_size / wqe_size;475			if (wqe_size > MLX5_CAP_GEN(dev->mdev, max_wqe_sz_rq)) {476				mlx5_ib_dbg(dev, "wqe_size %d, max %d\n",477					    wqe_size,478					    MLX5_CAP_GEN(dev->mdev,479							 max_wqe_sz_rq));480				return -EINVAL;481			}482			qp->rq.wqe_shift = ilog2(wqe_size);483			qp->rq.max_gs =484				(1 << qp->rq.wqe_shift) /485					sizeof(struct mlx5_wqe_data_seg) -486				wq_sig;487			qp->rq.max_post = qp->rq.wqe_cnt;488		}489	}490 491	return 0;492}493 494static int sq_overhead(struct ib_qp_init_attr *attr)495{496	int size = 0;497 498	switch (attr->qp_type) {499	case IB_QPT_XRC_INI:500		size += sizeof(struct mlx5_wqe_xrc_seg);501		fallthrough;502	case IB_QPT_RC:503		size += sizeof(struct mlx5_wqe_ctrl_seg) +504			max(sizeof(struct mlx5_wqe_atomic_seg) +505			    sizeof(struct mlx5_wqe_raddr_seg),506			    sizeof(struct mlx5_wqe_umr_ctrl_seg) +507			    sizeof(struct mlx5_mkey_seg) +508			    MLX5_IB_SQ_UMR_INLINE_THRESHOLD /509			    MLX5_IB_UMR_OCTOWORD);510		break;511 512	case IB_QPT_XRC_TGT:513		return 0;514 515	case IB_QPT_UC:516		size += sizeof(struct mlx5_wqe_ctrl_seg) +517			max(sizeof(struct mlx5_wqe_raddr_seg),518			    sizeof(struct mlx5_wqe_umr_ctrl_seg) +519			    sizeof(struct mlx5_mkey_seg));520		break;521 522	case IB_QPT_UD:523		if (attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO)524			size += sizeof(struct mlx5_wqe_eth_pad) +525				sizeof(struct mlx5_wqe_eth_seg);526		fallthrough;527	case IB_QPT_SMI:528	case MLX5_IB_QPT_HW_GSI:529		size += sizeof(struct mlx5_wqe_ctrl_seg) +530			sizeof(struct mlx5_wqe_datagram_seg);531		break;532 533	case MLX5_IB_QPT_REG_UMR:534		size += sizeof(struct mlx5_wqe_ctrl_seg) +535			sizeof(struct mlx5_wqe_umr_ctrl_seg) +536			sizeof(struct mlx5_mkey_seg);537		break;538 539	default:540		return -EINVAL;541	}542 543	return size;544}545 546static int calc_send_wqe(struct ib_qp_init_attr *attr)547{548	int inl_size = 0;549	int size;550 551	size = sq_overhead(attr);552	if (size < 0)553		return size;554 555	if (attr->cap.max_inline_data) {556		inl_size = size + sizeof(struct mlx5_wqe_inline_seg) +557			attr->cap.max_inline_data;558	}559 560	size += attr->cap.max_send_sge * sizeof(struct mlx5_wqe_data_seg);561	if (attr->create_flags & IB_QP_CREATE_INTEGRITY_EN &&562	    ALIGN(max_t(int, inl_size, size), MLX5_SEND_WQE_BB) < MLX5_SIG_WQE_SIZE)563		return MLX5_SIG_WQE_SIZE;564	else565		return ALIGN(max_t(int, inl_size, size), MLX5_SEND_WQE_BB);566}567 568static int get_send_sge(struct ib_qp_init_attr *attr, int wqe_size)569{570	int max_sge;571 572	if (attr->qp_type == IB_QPT_RC)573		max_sge = (min_t(int, wqe_size, 512) -574			   sizeof(struct mlx5_wqe_ctrl_seg) -575			   sizeof(struct mlx5_wqe_raddr_seg)) /576			sizeof(struct mlx5_wqe_data_seg);577	else if (attr->qp_type == IB_QPT_XRC_INI)578		max_sge = (min_t(int, wqe_size, 512) -579			   sizeof(struct mlx5_wqe_ctrl_seg) -580			   sizeof(struct mlx5_wqe_xrc_seg) -581			   sizeof(struct mlx5_wqe_raddr_seg)) /582			sizeof(struct mlx5_wqe_data_seg);583	else584		max_sge = (wqe_size - sq_overhead(attr)) /585			sizeof(struct mlx5_wqe_data_seg);586 587	return min_t(int, max_sge, wqe_size - sq_overhead(attr) /588		     sizeof(struct mlx5_wqe_data_seg));589}590 591static int calc_sq_size(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,592			struct mlx5_ib_qp *qp)593{594	int wqe_size;595	int wq_size;596 597	if (!attr->cap.max_send_wr)598		return 0;599 600	wqe_size = calc_send_wqe(attr);601	mlx5_ib_dbg(dev, "wqe_size %d\n", wqe_size);602	if (wqe_size < 0)603		return wqe_size;604 605	if (wqe_size > MLX5_CAP_GEN(dev->mdev, max_wqe_sz_sq)) {606		mlx5_ib_dbg(dev, "wqe_size(%d) > max_sq_desc_sz(%d)\n",607			    wqe_size, MLX5_CAP_GEN(dev->mdev, max_wqe_sz_sq));608		return -EINVAL;609	}610 611	qp->max_inline_data = wqe_size - sq_overhead(attr) -612			      sizeof(struct mlx5_wqe_inline_seg);613	attr->cap.max_inline_data = qp->max_inline_data;614 615	wq_size = roundup_pow_of_two(attr->cap.max_send_wr * wqe_size);616	qp->sq.wqe_cnt = wq_size / MLX5_SEND_WQE_BB;617	if (qp->sq.wqe_cnt > (1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz))) {618		mlx5_ib_dbg(dev, "send queue size (%d * %d / %d -> %d) exceeds limits(%d)\n",619			    attr->cap.max_send_wr, wqe_size, MLX5_SEND_WQE_BB,620			    qp->sq.wqe_cnt,621			    1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz));622		return -ENOMEM;623	}624	qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB);625	qp->sq.max_gs = get_send_sge(attr, wqe_size);626	if (qp->sq.max_gs < attr->cap.max_send_sge)627		return -ENOMEM;628 629	attr->cap.max_send_sge = qp->sq.max_gs;630	qp->sq.max_post = wq_size / wqe_size;631	attr->cap.max_send_wr = qp->sq.max_post;632 633	return wq_size;634}635 636static int set_user_buf_size(struct mlx5_ib_dev *dev,637			    struct mlx5_ib_qp *qp,638			    struct mlx5_ib_create_qp *ucmd,639			    struct mlx5_ib_qp_base *base,640			    struct ib_qp_init_attr *attr)641{642	int desc_sz = 1 << qp->sq.wqe_shift;643 644	if (desc_sz > MLX5_CAP_GEN(dev->mdev, max_wqe_sz_sq)) {645		mlx5_ib_warn(dev, "desc_sz %d, max_sq_desc_sz %d\n",646			     desc_sz, MLX5_CAP_GEN(dev->mdev, max_wqe_sz_sq));647		return -EINVAL;648	}649 650	if (ucmd->sq_wqe_count && !is_power_of_2(ucmd->sq_wqe_count)) {651		mlx5_ib_warn(dev, "sq_wqe_count %d is not a power of two\n",652			     ucmd->sq_wqe_count);653		return -EINVAL;654	}655 656	qp->sq.wqe_cnt = ucmd->sq_wqe_count;657 658	if (qp->sq.wqe_cnt > (1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz))) {659		mlx5_ib_warn(dev, "wqe_cnt %d, max_wqes %d\n",660			     qp->sq.wqe_cnt,661			     1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz));662		return -EINVAL;663	}664 665	if (attr->qp_type == IB_QPT_RAW_PACKET ||666	    qp->flags & IB_QP_CREATE_SOURCE_QPN) {667		base->ubuffer.buf_size = qp->rq.wqe_cnt << qp->rq.wqe_shift;668		qp->raw_packet_qp.sq.ubuffer.buf_size = qp->sq.wqe_cnt << 6;669	} else {670		base->ubuffer.buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +671					 (qp->sq.wqe_cnt << 6);672	}673 674	return 0;675}676 677static int qp_has_rq(struct ib_qp_init_attr *attr)678{679	if (attr->qp_type == IB_QPT_XRC_INI ||680	    attr->qp_type == IB_QPT_XRC_TGT || attr->srq ||681	    attr->qp_type == MLX5_IB_QPT_REG_UMR ||682	    !attr->cap.max_recv_wr)683		return 0;684 685	return 1;686}687 688enum {689	/* this is the first blue flame register in the array of bfregs assigned690	 * to a processes. Since we do not use it for blue flame but rather691	 * regular 64 bit doorbells, we do not need a lock for maintaiing692	 * "odd/even" order693	 */694	NUM_NON_BLUE_FLAME_BFREGS = 1,695};696 697static int max_bfregs(struct mlx5_ib_dev *dev, struct mlx5_bfreg_info *bfregi)698{699	return get_uars_per_sys_page(dev, bfregi->lib_uar_4k) *700	       bfregi->num_static_sys_pages * MLX5_NON_FP_BFREGS_PER_UAR;701}702 703static int num_med_bfreg(struct mlx5_ib_dev *dev,704			 struct mlx5_bfreg_info *bfregi)705{706	int n;707 708	n = max_bfregs(dev, bfregi) - bfregi->num_low_latency_bfregs -709	    NUM_NON_BLUE_FLAME_BFREGS;710 711	return n >= 0 ? n : 0;712}713 714static int first_med_bfreg(struct mlx5_ib_dev *dev,715			   struct mlx5_bfreg_info *bfregi)716{717	return num_med_bfreg(dev, bfregi) ? 1 : -ENOMEM;718}719 720static int first_hi_bfreg(struct mlx5_ib_dev *dev,721			  struct mlx5_bfreg_info *bfregi)722{723	int med;724 725	med = num_med_bfreg(dev, bfregi);726	return ++med;727}728 729static int alloc_high_class_bfreg(struct mlx5_ib_dev *dev,730				  struct mlx5_bfreg_info *bfregi)731{732	int i;733 734	for (i = first_hi_bfreg(dev, bfregi); i < max_bfregs(dev, bfregi); i++) {735		if (!bfregi->count[i]) {736			bfregi->count[i]++;737			return i;738		}739	}740 741	return -ENOMEM;742}743 744static int alloc_med_class_bfreg(struct mlx5_ib_dev *dev,745				 struct mlx5_bfreg_info *bfregi)746{747	int minidx = first_med_bfreg(dev, bfregi);748	int i;749 750	if (minidx < 0)751		return minidx;752 753	for (i = minidx; i < first_hi_bfreg(dev, bfregi); i++) {754		if (bfregi->count[i] < bfregi->count[minidx])755			minidx = i;756		if (!bfregi->count[minidx])757			break;758	}759 760	bfregi->count[minidx]++;761	return minidx;762}763 764static int alloc_bfreg(struct mlx5_ib_dev *dev,765		       struct mlx5_bfreg_info *bfregi)766{767	int bfregn = -ENOMEM;768 769	if (bfregi->lib_uar_dyn)770		return -EINVAL;771 772	mutex_lock(&bfregi->lock);773	if (bfregi->ver >= 2) {774		bfregn = alloc_high_class_bfreg(dev, bfregi);775		if (bfregn < 0)776			bfregn = alloc_med_class_bfreg(dev, bfregi);777	}778 779	if (bfregn < 0) {780		BUILD_BUG_ON(NUM_NON_BLUE_FLAME_BFREGS != 1);781		bfregn = 0;782		bfregi->count[bfregn]++;783	}784	mutex_unlock(&bfregi->lock);785 786	return bfregn;787}788 789void mlx5_ib_free_bfreg(struct mlx5_ib_dev *dev, struct mlx5_bfreg_info *bfregi, int bfregn)790{791	mutex_lock(&bfregi->lock);792	bfregi->count[bfregn]--;793	mutex_unlock(&bfregi->lock);794}795 796static enum mlx5_qp_state to_mlx5_state(enum ib_qp_state state)797{798	switch (state) {799	case IB_QPS_RESET:	return MLX5_QP_STATE_RST;800	case IB_QPS_INIT:	return MLX5_QP_STATE_INIT;801	case IB_QPS_RTR:	return MLX5_QP_STATE_RTR;802	case IB_QPS_RTS:	return MLX5_QP_STATE_RTS;803	case IB_QPS_SQD:	return MLX5_QP_STATE_SQD;804	case IB_QPS_SQE:	return MLX5_QP_STATE_SQER;805	case IB_QPS_ERR:	return MLX5_QP_STATE_ERR;806	default:		return -1;807	}808}809 810static int to_mlx5_st(enum ib_qp_type type)811{812	switch (type) {813	case IB_QPT_RC:			return MLX5_QP_ST_RC;814	case IB_QPT_UC:			return MLX5_QP_ST_UC;815	case IB_QPT_UD:			return MLX5_QP_ST_UD;816	case MLX5_IB_QPT_REG_UMR:	return MLX5_QP_ST_REG_UMR;817	case IB_QPT_XRC_INI:818	case IB_QPT_XRC_TGT:		return MLX5_QP_ST_XRC;819	case IB_QPT_SMI:		return MLX5_QP_ST_QP0;820	case MLX5_IB_QPT_HW_GSI:	return MLX5_QP_ST_QP1;821	case MLX5_IB_QPT_DCI:		return MLX5_QP_ST_DCI;822	case IB_QPT_RAW_PACKET:		return MLX5_QP_ST_RAW_ETHERTYPE;823	default:		return -EINVAL;824	}825}826 827static void mlx5_ib_lock_cqs(struct mlx5_ib_cq *send_cq,828			     struct mlx5_ib_cq *recv_cq);829static void mlx5_ib_unlock_cqs(struct mlx5_ib_cq *send_cq,830			       struct mlx5_ib_cq *recv_cq);831 832int bfregn_to_uar_index(struct mlx5_ib_dev *dev,833			struct mlx5_bfreg_info *bfregi, u32 bfregn,834			bool dyn_bfreg)835{836	unsigned int bfregs_per_sys_page;837	u32 index_of_sys_page;838	u32 offset;839 840	if (bfregi->lib_uar_dyn)841		return -EINVAL;842 843	bfregs_per_sys_page = get_uars_per_sys_page(dev, bfregi->lib_uar_4k) *844				MLX5_NON_FP_BFREGS_PER_UAR;845	index_of_sys_page = bfregn / bfregs_per_sys_page;846 847	if (dyn_bfreg) {848		index_of_sys_page += bfregi->num_static_sys_pages;849 850		if (index_of_sys_page >= bfregi->num_sys_pages)851			return -EINVAL;852 853		if (bfregn > bfregi->num_dyn_bfregs ||854		    bfregi->sys_pages[index_of_sys_page] == MLX5_IB_INVALID_UAR_INDEX) {855			mlx5_ib_dbg(dev, "Invalid dynamic uar index\n");856			return -EINVAL;857		}858	}859 860	offset = bfregn % bfregs_per_sys_page / MLX5_NON_FP_BFREGS_PER_UAR;861	return bfregi->sys_pages[index_of_sys_page] + offset;862}863 864static void destroy_user_rq(struct mlx5_ib_dev *dev, struct ib_pd *pd,865			    struct mlx5_ib_rwq *rwq, struct ib_udata *udata)866{867	struct mlx5_ib_ucontext *context =868		rdma_udata_to_drv_context(869			udata,870			struct mlx5_ib_ucontext,871			ibucontext);872 873	if (rwq->create_flags & MLX5_IB_WQ_FLAGS_DELAY_DROP)874		atomic_dec(&dev->delay_drop.rqs_cnt);875 876	mlx5_ib_db_unmap_user(context, &rwq->db);877	ib_umem_release(rwq->umem);878}879 880static int create_user_rq(struct mlx5_ib_dev *dev, struct ib_pd *pd,881			  struct ib_udata *udata, struct mlx5_ib_rwq *rwq,882			  struct mlx5_ib_create_wq *ucmd)883{884	struct mlx5_ib_ucontext *ucontext = rdma_udata_to_drv_context(885		udata, struct mlx5_ib_ucontext, ibucontext);886	unsigned long page_size = 0;887	u32 offset = 0;888	int err;889 890	if (!ucmd->buf_addr)891		return -EINVAL;892 893	rwq->umem = ib_umem_get(&dev->ib_dev, ucmd->buf_addr, rwq->buf_size, 0);894	if (IS_ERR(rwq->umem)) {895		mlx5_ib_dbg(dev, "umem_get failed\n");896		err = PTR_ERR(rwq->umem);897		return err;898	}899 900	page_size = mlx5_umem_find_best_quantized_pgoff(901		rwq->umem, wq, log_wq_pg_sz, MLX5_ADAPTER_PAGE_SHIFT,902		page_offset, 64, &rwq->rq_page_offset);903	if (!page_size) {904		mlx5_ib_warn(dev, "bad offset\n");905		err = -EINVAL;906		goto err_umem;907	}908 909	rwq->rq_num_pas = ib_umem_num_dma_blocks(rwq->umem, page_size);910	rwq->page_shift = order_base_2(page_size);911	rwq->log_page_size =  rwq->page_shift - MLX5_ADAPTER_PAGE_SHIFT;912	rwq->wq_sig = !!(ucmd->flags & MLX5_WQ_FLAG_SIGNATURE);913 914	mlx5_ib_dbg(915		dev,916		"addr 0x%llx, size %zd, npages %zu, page_size %ld, ncont %d, offset %d\n",917		(unsigned long long)ucmd->buf_addr, rwq->buf_size,918		ib_umem_num_pages(rwq->umem), page_size, rwq->rq_num_pas,919		offset);920 921	err = mlx5_ib_db_map_user(ucontext, ucmd->db_addr, &rwq->db);922	if (err) {923		mlx5_ib_dbg(dev, "map failed\n");924		goto err_umem;925	}926 927	return 0;928 929err_umem:930	ib_umem_release(rwq->umem);931	return err;932}933 934static int adjust_bfregn(struct mlx5_ib_dev *dev,935			 struct mlx5_bfreg_info *bfregi, int bfregn)936{937	return bfregn / MLX5_NON_FP_BFREGS_PER_UAR * MLX5_BFREGS_PER_UAR +938				bfregn % MLX5_NON_FP_BFREGS_PER_UAR;939}940 941static int _create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,942			   struct mlx5_ib_qp *qp, struct ib_udata *udata,943			   struct ib_qp_init_attr *attr, u32 **in,944			   struct mlx5_ib_create_qp_resp *resp, int *inlen,945			   struct mlx5_ib_qp_base *base,946			   struct mlx5_ib_create_qp *ucmd)947{948	struct mlx5_ib_ucontext *context;949	struct mlx5_ib_ubuffer *ubuffer = &base->ubuffer;950	unsigned int page_offset_quantized = 0;951	unsigned long page_size = 0;952	int uar_index = 0;953	int bfregn;954	int ncont = 0;955	__be64 *pas;956	void *qpc;957	int err;958	u16 uid;959	u32 uar_flags;960 961	context = rdma_udata_to_drv_context(udata, struct mlx5_ib_ucontext,962					    ibucontext);963	uar_flags = qp->flags_en &964		    (MLX5_QP_FLAG_UAR_PAGE_INDEX | MLX5_QP_FLAG_BFREG_INDEX);965	switch (uar_flags) {966	case MLX5_QP_FLAG_UAR_PAGE_INDEX:967		uar_index = ucmd->bfreg_index;968		bfregn = MLX5_IB_INVALID_BFREG;969		break;970	case MLX5_QP_FLAG_BFREG_INDEX:971		uar_index = bfregn_to_uar_index(dev, &context->bfregi,972						ucmd->bfreg_index, true);973		if (uar_index < 0)974			return uar_index;975		bfregn = MLX5_IB_INVALID_BFREG;976		break;977	case 0:978		if (qp->flags & IB_QP_CREATE_CROSS_CHANNEL)979			return -EINVAL;980		bfregn = alloc_bfreg(dev, &context->bfregi);981		if (bfregn < 0)982			return bfregn;983		break;984	default:985		return -EINVAL;986	}987 988	mlx5_ib_dbg(dev, "bfregn 0x%x, uar_index 0x%x\n", bfregn, uar_index);989	if (bfregn != MLX5_IB_INVALID_BFREG)990		uar_index = bfregn_to_uar_index(dev, &context->bfregi, bfregn,991						false);992 993	qp->rq.offset = 0;994	qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB);995	qp->sq.offset = qp->rq.wqe_cnt << qp->rq.wqe_shift;996 997	err = set_user_buf_size(dev, qp, ucmd, base, attr);998	if (err)999		goto err_bfreg;1000 1001	if (ucmd->buf_addr && ubuffer->buf_size) {1002		ubuffer->buf_addr = ucmd->buf_addr;1003		ubuffer->umem = ib_umem_get(&dev->ib_dev, ubuffer->buf_addr,1004					    ubuffer->buf_size, 0);1005		if (IS_ERR(ubuffer->umem)) {1006			err = PTR_ERR(ubuffer->umem);1007			goto err_bfreg;1008		}1009		page_size = mlx5_umem_find_best_quantized_pgoff(1010			ubuffer->umem, qpc, log_page_size,1011			MLX5_ADAPTER_PAGE_SHIFT, page_offset, 64,1012			&page_offset_quantized);1013		if (!page_size) {1014			err = -EINVAL;1015			goto err_umem;1016		}1017		ncont = ib_umem_num_dma_blocks(ubuffer->umem, page_size);1018	} else {1019		ubuffer->umem = NULL;1020	}1021 1022	*inlen = MLX5_ST_SZ_BYTES(create_qp_in) +1023		 MLX5_FLD_SZ_BYTES(create_qp_in, pas[0]) * ncont;1024	*in = kvzalloc(*inlen, GFP_KERNEL);1025	if (!*in) {1026		err = -ENOMEM;1027		goto err_umem;1028	}1029 1030	uid = (attr->qp_type != IB_QPT_XRC_INI) ? to_mpd(pd)->uid : 0;1031	MLX5_SET(create_qp_in, *in, uid, uid);1032	qpc = MLX5_ADDR_OF(create_qp_in, *in, qpc);1033	pas = (__be64 *)MLX5_ADDR_OF(create_qp_in, *in, pas);1034	if (ubuffer->umem) {1035		mlx5_ib_populate_pas(ubuffer->umem, page_size, pas, 0);1036		MLX5_SET(qpc, qpc, log_page_size,1037			 order_base_2(page_size) - MLX5_ADAPTER_PAGE_SHIFT);1038		MLX5_SET(qpc, qpc, page_offset, page_offset_quantized);1039	}1040	MLX5_SET(qpc, qpc, uar_page, uar_index);1041	if (bfregn != MLX5_IB_INVALID_BFREG)1042		resp->bfreg_index = adjust_bfregn(dev, &context->bfregi, bfregn);1043	else1044		resp->bfreg_index = MLX5_IB_INVALID_BFREG;1045	qp->bfregn = bfregn;1046 1047	err = mlx5_ib_db_map_user(context, ucmd->db_addr, &qp->db);1048	if (err) {1049		mlx5_ib_dbg(dev, "map failed\n");1050		goto err_free;1051	}1052 1053	return 0;1054 1055err_free:1056	kvfree(*in);1057 1058err_umem:1059	ib_umem_release(ubuffer->umem);1060 1061err_bfreg:1062	if (bfregn != MLX5_IB_INVALID_BFREG)1063		mlx5_ib_free_bfreg(dev, &context->bfregi, bfregn);1064	return err;1065}1066 1067static void destroy_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,1068		       struct mlx5_ib_qp_base *base, struct ib_udata *udata)1069{1070	struct mlx5_ib_ucontext *context = rdma_udata_to_drv_context(1071		udata, struct mlx5_ib_ucontext, ibucontext);1072 1073	if (udata) {1074		/* User QP */1075		mlx5_ib_db_unmap_user(context, &qp->db);1076		ib_umem_release(base->ubuffer.umem);1077 1078		/*1079		 * Free only the BFREGs which are handled by the kernel.1080		 * BFREGs of UARs allocated dynamically are handled by user.1081		 */1082		if (qp->bfregn != MLX5_IB_INVALID_BFREG)1083			mlx5_ib_free_bfreg(dev, &context->bfregi, qp->bfregn);1084		return;1085	}1086 1087	/* Kernel QP */1088	kvfree(qp->sq.wqe_head);1089	kvfree(qp->sq.w_list);1090	kvfree(qp->sq.wrid);1091	kvfree(qp->sq.wr_data);1092	kvfree(qp->rq.wrid);1093	if (qp->db.db)1094		mlx5_db_free(dev->mdev, &qp->db);1095	if (qp->buf.frags)1096		mlx5_frag_buf_free(dev->mdev, &qp->buf);1097}1098 1099static int _create_kernel_qp(struct mlx5_ib_dev *dev,1100			     struct ib_qp_init_attr *init_attr,1101			     struct mlx5_ib_qp *qp, u32 **in, int *inlen,1102			     struct mlx5_ib_qp_base *base)1103{1104	int uar_index;1105	void *qpc;1106	int err;1107 1108	if (init_attr->qp_type == MLX5_IB_QPT_REG_UMR)1109		qp->bf.bfreg = &dev->fp_bfreg;1110	else1111		qp->bf.bfreg = &dev->bfreg;1112 1113	/* We need to divide by two since each register is comprised of1114	 * two buffers of identical size, namely odd and even1115	 */1116	qp->bf.buf_size = (1 << MLX5_CAP_GEN(dev->mdev, log_bf_reg_size)) / 2;1117	uar_index = qp->bf.bfreg->index;1118 1119	err = calc_sq_size(dev, init_attr, qp);1120	if (err < 0) {1121		mlx5_ib_dbg(dev, "err %d\n", err);1122		return err;1123	}1124 1125	qp->rq.offset = 0;1126	qp->sq.offset = qp->rq.wqe_cnt << qp->rq.wqe_shift;1127	base->ubuffer.buf_size = err + (qp->rq.wqe_cnt << qp->rq.wqe_shift);1128 1129	err = mlx5_frag_buf_alloc_node(dev->mdev, base->ubuffer.buf_size,1130				       &qp->buf, dev->mdev->priv.numa_node);1131	if (err) {1132		mlx5_ib_dbg(dev, "err %d\n", err);1133		return err;1134	}1135 1136	if (qp->rq.wqe_cnt)1137		mlx5_init_fbc(qp->buf.frags, qp->rq.wqe_shift,1138			      ilog2(qp->rq.wqe_cnt), &qp->rq.fbc);1139 1140	if (qp->sq.wqe_cnt) {1141		int sq_strides_offset = (qp->sq.offset  & (PAGE_SIZE - 1)) /1142					MLX5_SEND_WQE_BB;1143		mlx5_init_fbc_offset(qp->buf.frags +1144				     (qp->sq.offset / PAGE_SIZE),1145				     ilog2(MLX5_SEND_WQE_BB),1146				     ilog2(qp->sq.wqe_cnt),1147				     sq_strides_offset, &qp->sq.fbc);1148 1149		qp->sq.cur_edge = get_sq_edge(&qp->sq, 0);1150	}1151 1152	*inlen = MLX5_ST_SZ_BYTES(create_qp_in) +1153		 MLX5_FLD_SZ_BYTES(create_qp_in, pas[0]) * qp->buf.npages;1154	*in = kvzalloc(*inlen, GFP_KERNEL);1155	if (!*in) {1156		err = -ENOMEM;1157		goto err_buf;1158	}1159 1160	qpc = MLX5_ADDR_OF(create_qp_in, *in, qpc);1161	MLX5_SET(qpc, qpc, uar_page, uar_index);1162	MLX5_SET(qpc, qpc, ts_format, mlx5_get_qp_default_ts(dev->mdev));1163	MLX5_SET(qpc, qpc, log_page_size, qp->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);1164 1165	/* Set "fast registration enabled" for all kernel QPs */1166	MLX5_SET(qpc, qpc, fre, 1);1167	MLX5_SET(qpc, qpc, rlky, 1);1168 1169	if (qp->flags & MLX5_IB_QP_CREATE_SQPN_QP1)1170		MLX5_SET(qpc, qpc, deth_sqpn, 1);1171 1172	mlx5_fill_page_frag_array(&qp->buf,1173				  (__be64 *)MLX5_ADDR_OF(create_qp_in,1174							 *in, pas));1175 1176	err = mlx5_db_alloc(dev->mdev, &qp->db);1177	if (err) {1178		mlx5_ib_dbg(dev, "err %d\n", err);1179		goto err_free;1180	}1181 1182	qp->sq.wrid = kvmalloc_array(qp->sq.wqe_cnt,1183				     sizeof(*qp->sq.wrid), GFP_KERNEL);1184	qp->sq.wr_data = kvmalloc_array(qp->sq.wqe_cnt,1185					sizeof(*qp->sq.wr_data), GFP_KERNEL);1186	qp->rq.wrid = kvmalloc_array(qp->rq.wqe_cnt,1187				     sizeof(*qp->rq.wrid), GFP_KERNEL);1188	qp->sq.w_list = kvmalloc_array(qp->sq.wqe_cnt,1189				       sizeof(*qp->sq.w_list), GFP_KERNEL);1190	qp->sq.wqe_head = kvmalloc_array(qp->sq.wqe_cnt,1191					 sizeof(*qp->sq.wqe_head), GFP_KERNEL);1192 1193	if (!qp->sq.wrid || !qp->sq.wr_data || !qp->rq.wrid ||1194	    !qp->sq.w_list || !qp->sq.wqe_head) {1195		err = -ENOMEM;1196		goto err_wrid;1197	}1198 1199	return 0;1200 1201err_wrid:1202	kvfree(qp->sq.wqe_head);1203	kvfree(qp->sq.w_list);1204	kvfree(qp->sq.wrid);1205	kvfree(qp->sq.wr_data);1206	kvfree(qp->rq.wrid);1207	mlx5_db_free(dev->mdev, &qp->db);1208 1209err_free:1210	kvfree(*in);1211 1212err_buf:1213	mlx5_frag_buf_free(dev->mdev, &qp->buf);1214	return err;1215}1216 1217static u32 get_rx_type(struct mlx5_ib_qp *qp, struct ib_qp_init_attr *attr)1218{1219	if (attr->srq || (qp->type == IB_QPT_XRC_TGT) ||1220	    (qp->type == MLX5_IB_QPT_DCI) || (qp->type == IB_QPT_XRC_INI))1221		return MLX5_SRQ_RQ;1222	else if (!qp->has_rq)1223		return MLX5_ZERO_LEN_RQ;1224 1225	return MLX5_NON_ZERO_RQ;1226}1227 1228static int create_raw_packet_qp_tis(struct mlx5_ib_dev *dev,1229				    struct mlx5_ib_qp *qp,1230				    struct mlx5_ib_sq *sq, u32 tdn,1231				    struct ib_pd *pd)1232{1233	u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {};1234	void *tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);1235 1236	MLX5_SET(create_tis_in, in, uid, to_mpd(pd)->uid);1237	MLX5_SET(tisc, tisc, transport_domain, tdn);1238	if (!mlx5_ib_lag_should_assign_affinity(dev) &&1239	    mlx5_lag_is_lacp_owner(dev->mdev))1240		MLX5_SET(tisc, tisc, strict_lag_tx_port_affinity, 1);1241	if (qp->flags & IB_QP_CREATE_SOURCE_QPN)1242		MLX5_SET(tisc, tisc, underlay_qpn, qp->underlay_qpn);1243 1244	return mlx5_core_create_tis(dev->mdev, in, &sq->tisn);1245}1246 1247static void destroy_raw_packet_qp_tis(struct mlx5_ib_dev *dev,1248				      struct mlx5_ib_sq *sq, struct ib_pd *pd)1249{1250	mlx5_cmd_destroy_tis(dev->mdev, sq->tisn, to_mpd(pd)->uid);1251}1252 1253static void destroy_flow_rule_vport_sq(struct mlx5_ib_sq *sq)1254{1255	if (sq->flow_rule)1256		mlx5_del_flow_rules(sq->flow_rule);1257	sq->flow_rule = NULL;1258}1259 1260static bool fr_supported(int ts_cap)1261{1262	return ts_cap == MLX5_TIMESTAMP_FORMAT_CAP_FREE_RUNNING ||1263	       ts_cap == MLX5_TIMESTAMP_FORMAT_CAP_FREE_RUNNING_AND_REAL_TIME;1264}1265 1266static int get_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,1267			 bool fr_sup, bool rt_sup)1268{1269	if (cq->private_flags & MLX5_IB_CQ_PR_FLAGS_REAL_TIME_TS) {1270		if (!rt_sup) {1271			mlx5_ib_dbg(dev,1272				    "Real time TS format is not supported\n");1273			return -EOPNOTSUPP;1274		}1275		return MLX5_TIMESTAMP_FORMAT_REAL_TIME;1276	}1277	if (cq->create_flags & IB_UVERBS_CQ_FLAGS_TIMESTAMP_COMPLETION) {1278		if (!fr_sup) {1279			mlx5_ib_dbg(dev,1280				    "Free running TS format is not supported\n");1281			return -EOPNOTSUPP;1282		}1283		return MLX5_TIMESTAMP_FORMAT_FREE_RUNNING;1284	}1285	return fr_sup ? MLX5_TIMESTAMP_FORMAT_FREE_RUNNING :1286			MLX5_TIMESTAMP_FORMAT_DEFAULT;1287}1288 1289static int get_rq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *recv_cq)1290{1291	u8 ts_cap = MLX5_CAP_GEN(dev->mdev, rq_ts_format);1292 1293	return get_ts_format(dev, recv_cq, fr_supported(ts_cap),1294			     rt_supported(ts_cap));1295}1296 1297static int get_sq_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq)1298{1299	u8 ts_cap = MLX5_CAP_GEN(dev->mdev, sq_ts_format);1300 1301	return get_ts_format(dev, send_cq, fr_supported(ts_cap),1302			     rt_supported(ts_cap));1303}1304 1305static int get_qp_ts_format(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *send_cq,1306			    struct mlx5_ib_cq *recv_cq)1307{1308	u8 ts_cap = MLX5_CAP_ROCE(dev->mdev, qp_ts_format);1309	bool fr_sup = fr_supported(ts_cap);1310	bool rt_sup = rt_supported(ts_cap);1311	u8 default_ts = fr_sup ? MLX5_TIMESTAMP_FORMAT_FREE_RUNNING :1312				 MLX5_TIMESTAMP_FORMAT_DEFAULT;1313	int send_ts_format =1314		send_cq ? get_ts_format(dev, send_cq, fr_sup, rt_sup) :1315			  default_ts;1316	int recv_ts_format =1317		recv_cq ? get_ts_format(dev, recv_cq, fr_sup, rt_sup) :1318			  default_ts;1319 1320	if (send_ts_format < 0 || recv_ts_format < 0)1321		return -EOPNOTSUPP;1322 1323	if (send_ts_format != MLX5_TIMESTAMP_FORMAT_DEFAULT &&1324	    recv_ts_format != MLX5_TIMESTAMP_FORMAT_DEFAULT &&1325	    send_ts_format != recv_ts_format) {1326		mlx5_ib_dbg(1327			dev,1328			"The send ts_format does not match the receive ts_format\n");1329		return -EOPNOTSUPP;1330	}1331 1332	return send_ts_format == default_ts ? recv_ts_format : send_ts_format;1333}1334 1335static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,1336				   struct ib_udata *udata,1337				   struct mlx5_ib_sq *sq, void *qpin,1338				   struct ib_pd *pd, struct mlx5_ib_cq *cq)1339{1340	struct mlx5_ib_ubuffer *ubuffer = &sq->ubuffer;1341	__be64 *pas;1342	void *in;1343	void *sqc;1344	void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc);1345	void *wq;1346	int inlen;1347	int err;1348	unsigned int page_offset_quantized;1349	unsigned long page_size;1350	int ts_format;1351 1352	ts_format = get_sq_ts_format(dev, cq);1353	if (ts_format < 0)1354		return ts_format;1355 1356	sq->ubuffer.umem = ib_umem_get(&dev->ib_dev, ubuffer->buf_addr,1357				       ubuffer->buf_size, 0);1358	if (IS_ERR(sq->ubuffer.umem))1359		return PTR_ERR(sq->ubuffer.umem);1360	page_size = mlx5_umem_find_best_quantized_pgoff(1361		ubuffer->umem, wq, log_wq_pg_sz, MLX5_ADAPTER_PAGE_SHIFT,1362		page_offset, 64, &page_offset_quantized);1363	if (!page_size) {1364		err = -EINVAL;1365		goto err_umem;1366	}1367 1368	inlen = MLX5_ST_SZ_BYTES(create_sq_in) +1369		sizeof(u64) *1370			ib_umem_num_dma_blocks(sq->ubuffer.umem, page_size);1371	in = kvzalloc(inlen, GFP_KERNEL);1372	if (!in) {1373		err = -ENOMEM;1374		goto err_umem;1375	}1376 1377	MLX5_SET(create_sq_in, in, uid, to_mpd(pd)->uid);1378	sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);1379	MLX5_SET(sqc, sqc, flush_in_error_en, 1);1380	if (MLX5_CAP_ETH(dev->mdev, multi_pkt_send_wqe))1381		MLX5_SET(sqc, sqc, allow_multi_pkt_send_wqe, 1);1382	MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST);1383	MLX5_SET(sqc, sqc, ts_format, ts_format);1384	MLX5_SET(sqc, sqc, user_index, MLX5_GET(qpc, qpc, user_index));1385	MLX5_SET(sqc, sqc, cqn, MLX5_GET(qpc, qpc, cqn_snd));1386	MLX5_SET(sqc, sqc, tis_lst_sz, 1);1387	MLX5_SET(sqc, sqc, tis_num_0, sq->tisn);1388	if (MLX5_CAP_GEN(dev->mdev, eth_net_offloads) &&1389	    MLX5_CAP_ETH(dev->mdev, swp))1390		MLX5_SET(sqc, sqc, allow_swp, 1);1391 1392	wq = MLX5_ADDR_OF(sqc, sqc, wq);1393	MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);1394	MLX5_SET(wq, wq, pd, MLX5_GET(qpc, qpc, pd));1395	MLX5_SET(wq, wq, uar_page, MLX5_GET(qpc, qpc, uar_page));1396	MLX5_SET64(wq, wq, dbr_addr, MLX5_GET64(qpc, qpc, dbr_addr));1397	MLX5_SET(wq, wq, log_wq_stride, ilog2(MLX5_SEND_WQE_BB));1398	MLX5_SET(wq, wq, log_wq_sz, MLX5_GET(qpc, qpc, log_sq_size));1399	MLX5_SET(wq, wq, log_wq_pg_sz,1400		 order_base_2(page_size) - MLX5_ADAPTER_PAGE_SHIFT);1401	MLX5_SET(wq, wq, page_offset, page_offset_quantized);1402 1403	pas = (__be64 *)MLX5_ADDR_OF(wq, wq, pas);1404	mlx5_ib_populate_pas(sq->ubuffer.umem, page_size, pas, 0);1405 1406	err = mlx5_core_create_sq_tracked(dev, in, inlen, &sq->base.mqp);1407 1408	kvfree(in);1409 1410	if (err)1411		goto err_umem;1412 1413	return 0;1414 1415err_umem:1416	ib_umem_release(sq->ubuffer.umem);1417	sq->ubuffer.umem = NULL;1418 1419	return err;1420}1421 1422static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev,1423				     struct mlx5_ib_sq *sq)1424{1425	destroy_flow_rule_vport_sq(sq);1426	mlx5_core_destroy_sq_tracked(dev, &sq->base.mqp);1427	ib_umem_release(sq->ubuffer.umem);1428}1429 1430static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,1431				   struct mlx5_ib_rq *rq, void *qpin,1432				   struct ib_pd *pd, struct mlx5_ib_cq *cq)1433{1434	struct mlx5_ib_qp *mqp = rq->base.container_mibqp;1435	__be64 *pas;1436	void *in;1437	void *rqc;1438	void *wq;1439	void *qpc = MLX5_ADDR_OF(create_qp_in, qpin, qpc);1440	struct ib_umem *umem = rq->base.ubuffer.umem;1441	unsigned int page_offset_quantized;1442	unsigned long page_size = 0;1443	int ts_format;1444	size_t inlen;1445	int err;1446 1447	ts_format = get_rq_ts_format(dev, cq);1448	if (ts_format < 0)1449		return ts_format;1450 1451	page_size = mlx5_umem_find_best_quantized_pgoff(umem, wq, log_wq_pg_sz,1452							MLX5_ADAPTER_PAGE_SHIFT,1453							page_offset, 64,1454							&page_offset_quantized);1455	if (!page_size)1456		return -EINVAL;1457 1458	inlen = MLX5_ST_SZ_BYTES(create_rq_in) +1459		sizeof(u64) * ib_umem_num_dma_blocks(umem, page_size);1460	in = kvzalloc(inlen, GFP_KERNEL);1461	if (!in)1462		return -ENOMEM;1463 1464	MLX5_SET(create_rq_in, in, uid, to_mpd(pd)->uid);1465	rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);1466	if (!(rq->flags & MLX5_IB_RQ_CVLAN_STRIPPING))1467		MLX5_SET(rqc, rqc, vsd, 1);1468	MLX5_SET(rqc, rqc, mem_rq_type, MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE);1469	MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST);1470	MLX5_SET(rqc, rqc, ts_format, ts_format);1471	MLX5_SET(rqc, rqc, flush_in_error_en, 1);1472	MLX5_SET(rqc, rqc, user_index, MLX5_GET(qpc, qpc, user_index));1473	MLX5_SET(rqc, rqc, cqn, MLX5_GET(qpc, qpc, cqn_rcv));1474 1475	if (mqp->flags & IB_QP_CREATE_SCATTER_FCS)1476		MLX5_SET(rqc, rqc, scatter_fcs, 1);1477 1478	wq = MLX5_ADDR_OF(rqc, rqc, wq);1479	MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);1480	if (rq->flags & MLX5_IB_RQ_PCI_WRITE_END_PADDING)1481		MLX5_SET(wq, wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN);1482	MLX5_SET(wq, wq, page_offset, page_offset_quantized);1483	MLX5_SET(wq, wq, pd, MLX5_GET(qpc, qpc, pd));1484	MLX5_SET64(wq, wq, dbr_addr, MLX5_GET64(qpc, qpc, dbr_addr));1485	MLX5_SET(wq, wq, log_wq_stride, MLX5_GET(qpc, qpc, log_rq_stride) + 4);1486	MLX5_SET(wq, wq, log_wq_pg_sz,1487		 order_base_2(page_size) - MLX5_ADAPTER_PAGE_SHIFT);1488	MLX5_SET(wq, wq, log_wq_sz, MLX5_GET(qpc, qpc, log_rq_size));1489 1490	pas = (__be64 *)MLX5_ADDR_OF(wq, wq, pas);1491	mlx5_ib_populate_pas(umem, page_size, pas, 0);1492 1493	err = mlx5_core_create_rq_tracked(dev, in, inlen, &rq->base.mqp);1494 1495	kvfree(in);1496 1497	return err;1498}1499 1500static void destroy_raw_packet_qp_rq(struct mlx5_ib_dev *dev,1501				     struct mlx5_ib_rq *rq)1502{1503	mlx5_core_destroy_rq_tracked(dev, &rq->base.mqp);1504}1505 1506static void destroy_raw_packet_qp_tir(struct mlx5_ib_dev *dev,1507				      struct mlx5_ib_rq *rq,1508				      u32 qp_flags_en,1509				      struct ib_pd *pd)1510{1511	if (qp_flags_en & (MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC |1512			   MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_MC))1513		mlx5_ib_disable_lb(dev, false, true);1514	mlx5_cmd_destroy_tir(dev->mdev, rq->tirn, to_mpd(pd)->uid);1515}1516 1517static int create_raw_packet_qp_tir(struct mlx5_ib_dev *dev,1518				    struct mlx5_ib_rq *rq, u32 tdn,1519				    u32 *qp_flags_en, struct ib_pd *pd,1520				    u32 *out)1521{1522	u8 lb_flag = 0;1523	u32 *in;1524	void *tirc;1525	int inlen;1526	int err;1527 1528	inlen = MLX5_ST_SZ_BYTES(create_tir_in);1529	in = kvzalloc(inlen, GFP_KERNEL);1530	if (!in)1531		return -ENOMEM;1532 1533	MLX5_SET(create_tir_in, in, uid, to_mpd(pd)->uid);1534	tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);1535	MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_DIRECT);1536	MLX5_SET(tirc, tirc, inline_rqn, rq->base.mqp.qpn);1537	MLX5_SET(tirc, tirc, transport_domain, tdn);1538	if (*qp_flags_en & MLX5_QP_FLAG_TUNNEL_OFFLOADS)1539		MLX5_SET(tirc, tirc, tunneled_offload_en, 1);1540 1541	if (*qp_flags_en & MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC)1542		lb_flag |= MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST;1543 1544	if (*qp_flags_en & MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_MC)1545		lb_flag |= MLX5_TIRC_SELF_LB_BLOCK_BLOCK_MULTICAST;1546 1547	if (dev->is_rep) {1548		lb_flag |= MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST;1549		*qp_flags_en |= MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC;1550	}1551 1552	MLX5_SET(tirc, tirc, self_lb_block, lb_flag);1553	MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR);1554	err = mlx5_cmd_exec_inout(dev->mdev, create_tir, in, out);1555	rq->tirn = MLX5_GET(create_tir_out, out, tirn);1556	if (!err && MLX5_GET(tirc, tirc, self_lb_block)) {1557		err = mlx5_ib_enable_lb(dev, false, true);1558 1559		if (err)1560			destroy_raw_packet_qp_tir(dev, rq, 0, pd);1561	}1562	kvfree(in);1563 1564	return err;1565}1566 1567static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,1568				u32 *in, size_t inlen, struct ib_pd *pd,1569				struct ib_udata *udata,1570				struct mlx5_ib_create_qp_resp *resp,1571				struct ib_qp_init_attr *init_attr)1572{1573	struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;1574	struct mlx5_ib_sq *sq = &raw_packet_qp->sq;1575	struct mlx5_ib_rq *rq = &raw_packet_qp->rq;1576	struct mlx5_ib_ucontext *mucontext = rdma_udata_to_drv_context(1577		udata, struct mlx5_ib_ucontext, ibucontext);1578	int err;1579	u32 tdn = mucontext->tdn;1580	u16 uid = to_mpd(pd)->uid;1581	u32 out[MLX5_ST_SZ_DW(create_tir_out)] = {};1582 1583	if (!qp->sq.wqe_cnt && !qp->rq.wqe_cnt)1584		return -EINVAL;1585	if (qp->sq.wqe_cnt) {1586		err = create_raw_packet_qp_tis(dev, qp, sq, tdn, pd);1587		if (err)1588			return err;1589 1590		err = create_raw_packet_qp_sq(dev, udata, sq, in, pd,1591					      to_mcq(init_attr->send_cq));1592		if (err)1593			goto err_destroy_tis;1594 1595		if (uid) {1596			resp->tisn = sq->tisn;1597			resp->comp_mask |= MLX5_IB_CREATE_QP_RESP_MASK_TISN;1598			resp->sqn = sq->base.mqp.qpn;1599			resp->comp_mask |= MLX5_IB_CREATE_QP_RESP_MASK_SQN;1600		}1601 1602		sq->base.container_mibqp = qp;1603		sq->base.mqp.event = mlx5_ib_qp_event;1604	}1605 1606	if (qp->rq.wqe_cnt) {1607		rq->base.container_mibqp = qp;1608 1609		if (qp->flags & IB_QP_CREATE_CVLAN_STRIPPING)1610			rq->flags |= MLX5_IB_RQ_CVLAN_STRIPPING;1611		if (qp->flags & IB_QP_CREATE_PCI_WRITE_END_PADDING)1612			rq->flags |= MLX5_IB_RQ_PCI_WRITE_END_PADDING;1613		err = create_raw_packet_qp_rq(dev, rq, in, pd,1614					      to_mcq(init_attr->recv_cq));1615		if (err)1616			goto err_destroy_sq;1617 1618		err = create_raw_packet_qp_tir(dev, rq, tdn, &qp->flags_en, pd,1619					       out);1620		if (err)1621			goto err_destroy_rq;1622 1623		if (uid) {1624			resp->rqn = rq->base.mqp.qpn;1625			resp->comp_mask |= MLX5_IB_CREATE_QP_RESP_MASK_RQN;1626			resp->tirn = rq->tirn;1627			resp->comp_mask |= MLX5_IB_CREATE_QP_RESP_MASK_TIRN;1628			if (MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, sw_owner) ||1629			    MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, sw_owner_v2)) {1630				resp->tir_icm_addr = MLX5_GET(1631					create_tir_out, out, icm_address_31_0);1632				resp->tir_icm_addr |=1633					(u64)MLX5_GET(create_tir_out, out,1634						      icm_address_39_32)1635					<< 32;1636				resp->tir_icm_addr |=1637					(u64)MLX5_GET(create_tir_out, out,1638						      icm_address_63_40)1639					<< 40;1640				resp->comp_mask |=1641					MLX5_IB_CREATE_QP_RESP_MASK_TIR_ICM_ADDR;1642			}1643		}1644	}1645 1646	qp->trans_qp.base.mqp.qpn = qp->sq.wqe_cnt ? sq->base.mqp.qpn :1647						     rq->base.mqp.qpn;1648	return 0;1649 1650err_destroy_rq:1651	destroy_raw_packet_qp_rq(dev, rq);1652err_destroy_sq:1653	if (!qp->sq.wqe_cnt)1654		return err;1655	destroy_raw_packet_qp_sq(dev, sq);1656err_destroy_tis:1657	destroy_raw_packet_qp_tis(dev, sq, pd);1658 1659	return err;1660}1661 1662static void destroy_raw_packet_qp(struct mlx5_ib_dev *dev,1663				  struct mlx5_ib_qp *qp)1664{1665	struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;1666	struct mlx5_ib_sq *sq = &raw_packet_qp->sq;1667	struct mlx5_ib_rq *rq = &raw_packet_qp->rq;1668 1669	if (qp->rq.wqe_cnt) {1670		destroy_raw_packet_qp_tir(dev, rq, qp->flags_en, qp->ibqp.pd);1671		destroy_raw_packet_qp_rq(dev, rq);1672	}1673 1674	if (qp->sq.wqe_cnt) {1675		destroy_raw_packet_qp_sq(dev, sq);1676		destroy_raw_packet_qp_tis(dev, sq, qp->ibqp.pd);1677	}1678}1679 1680static void raw_packet_qp_copy_info(struct mlx5_ib_qp *qp,1681				    struct mlx5_ib_raw_packet_qp *raw_packet_qp)1682{1683	struct mlx5_ib_sq *sq = &raw_packet_qp->sq;1684	struct mlx5_ib_rq *rq = &raw_packet_qp->rq;1685 1686	sq->sq = &qp->sq;1687	rq->rq = &qp->rq;1688	sq->doorbell = &qp->db;1689	rq->doorbell = &qp->db;1690}1691 1692static void destroy_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)1693{1694	if (qp->flags_en & (MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC |1695			    MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_MC))1696		mlx5_ib_disable_lb(dev, false, true);1697	mlx5_cmd_destroy_tir(dev->mdev, qp->rss_qp.tirn,1698			     to_mpd(qp->ibqp.pd)->uid);1699}1700 1701struct mlx5_create_qp_params {1702	struct ib_udata *udata;1703	size_t inlen;1704	size_t outlen;1705	size_t ucmd_size;1706	void *ucmd;1707	u8 is_rss_raw : 1;1708	struct ib_qp_init_attr *attr;1709	u32 uidx;1710	struct mlx5_ib_create_qp_resp resp;1711};1712 1713static int create_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct ib_pd *pd,1714				 struct mlx5_ib_qp *qp,1715				 struct mlx5_create_qp_params *params)1716{1717	struct ib_qp_init_attr *init_attr = params->attr;1718	struct mlx5_ib_create_qp_rss *ucmd = params->ucmd;1719	struct ib_udata *udata = params->udata;1720	struct mlx5_ib_ucontext *mucontext = rdma_udata_to_drv_context(1721		udata, struct mlx5_ib_ucontext, ibucontext);1722	int inlen;1723	int outlen;1724	int err;1725	u32 *in;1726	u32 *out;1727	void *tirc;1728	void *hfso;1729	u32 selected_fields = 0;1730	u32 outer_l4;1731	u32 tdn = mucontext->tdn;1732	u8 lb_flag = 0;1733 1734	if (ucmd->comp_mask) {1735		mlx5_ib_dbg(dev, "invalid comp mask\n");1736		return -EOPNOTSUPP;1737	}1738 1739	if (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_INNER &&1740	    !(ucmd->flags & MLX5_QP_FLAG_TUNNEL_OFFLOADS)) {1741		mlx5_ib_dbg(dev, "Tunnel offloads must be set for inner RSS\n");1742		return -EOPNOTSUPP;1743	}1744 1745	if (dev->is_rep)1746		qp->flags_en |= MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC;1747 1748	if (qp->flags_en & MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC)1749		lb_flag |= MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST;1750 1751	if (qp->flags_en & MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_MC)1752		lb_flag |= MLX5_TIRC_SELF_LB_BLOCK_BLOCK_MULTICAST;1753 1754	inlen = MLX5_ST_SZ_BYTES(create_tir_in);1755	outlen = MLX5_ST_SZ_BYTES(create_tir_out);1756	in = kvzalloc(inlen + outlen, GFP_KERNEL);1757	if (!in)1758		return -ENOMEM;1759 1760	out = in + MLX5_ST_SZ_DW(create_tir_in);1761	MLX5_SET(create_tir_in, in, uid, to_mpd(pd)->uid);1762	tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);1763	MLX5_SET(tirc, tirc, disp_type,1764		 MLX5_TIRC_DISP_TYPE_INDIRECT);1765	MLX5_SET(tirc, tirc, indirect_table,1766		 init_attr->rwq_ind_tbl->ind_tbl_num);1767	MLX5_SET(tirc, tirc, transport_domain, tdn);1768 1769	hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);1770 1771	if (ucmd->flags & MLX5_QP_FLAG_TUNNEL_OFFLOADS)1772		MLX5_SET(tirc, tirc, tunneled_offload_en, 1);1773 1774	MLX5_SET(tirc, tirc, self_lb_block, lb_flag);1775 1776	if (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_INNER)1777		hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_inner);1778	else1779		hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);1780 1781	switch (ucmd->rx_hash_function) {1782	case MLX5_RX_HASH_FUNC_TOEPLITZ:1783	{1784		void *rss_key = MLX5_ADDR_OF(tirc, tirc, rx_hash_toeplitz_key);1785		size_t len = MLX5_FLD_SZ_BYTES(tirc, rx_hash_toeplitz_key);1786 1787		if (len != ucmd->rx_key_len) {1788			err = -EINVAL;1789			goto err;1790		}1791 1792		MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_TOEPLITZ);1793		memcpy(rss_key, ucmd->rx_hash_key, len);1794		break;1795	}1796	default:1797		err = -EOPNOTSUPP;1798		goto err;1799	}1800 1801	if (!ucmd->rx_hash_fields_mask) {1802		/* special case when this TIR serves as steering entry without hashing */1803		if (!init_attr->rwq_ind_tbl->log_ind_tbl_size)1804			goto create_tir;1805		err = -EINVAL;1806		goto err;1807	}1808 1809	if (((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV4) ||1810	     (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV4)) &&1811	     ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV6) ||1812	     (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV6))) {1813		err = -EINVAL;1814		goto err;1815	}1816 1817	/* If none of IPV4 & IPV6 SRC/DST was set - this bit field is ignored */1818	if ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV4) ||1819	    (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV4))1820		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,1821			 MLX5_L3_PROT_TYPE_IPV4);1822	else if ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV6) ||1823		 (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV6))1824		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,1825			 MLX5_L3_PROT_TYPE_IPV6);1826 1827	outer_l4 = ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_TCP) ||1828		    (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_TCP))1829			   << 0 |1830		   ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_UDP) ||1831		    (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_UDP))1832			   << 1 |1833		   (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_IPSEC_SPI) << 2;1834 1835	/* Check that only one l4 protocol is set */1836	if (outer_l4 & (outer_l4 - 1)) {1837		err = -EINVAL;1838		goto err;1839	}1840 1841	/* If none of TCP & UDP SRC/DST was set - this bit field is ignored */1842	if ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_TCP) ||1843	    (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_TCP))1844		MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,1845			 MLX5_L4_PROT_TYPE_TCP);1846	else if ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_UDP) ||1847		 (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_UDP))1848		MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,1849			 MLX5_L4_PROT_TYPE_UDP);1850 1851	if ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV4) ||1852	    (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_IPV6))1853		selected_fields |= MLX5_HASH_FIELD_SEL_SRC_IP;1854 1855	if ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV4) ||1856	    (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_IPV6))1857		selected_fields |= MLX5_HASH_FIELD_SEL_DST_IP;1858 1859	if ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_TCP) ||1860	    (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_SRC_PORT_UDP))1861		selected_fields |= MLX5_HASH_FIELD_SEL_L4_SPORT;1862 1863	if ((ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_TCP) ||1864	    (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_DST_PORT_UDP))1865		selected_fields |= MLX5_HASH_FIELD_SEL_L4_DPORT;1866 1867	if (ucmd->rx_hash_fields_mask & MLX5_RX_HASH_IPSEC_SPI)1868		selected_fields |= MLX5_HASH_FIELD_SEL_IPSEC_SPI;1869 1870	MLX5_SET(rx_hash_field_select, hfso, selected_fields, selected_fields);1871 1872create_tir:1873	MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR);1874	err = mlx5_cmd_exec_inout(dev->mdev, create_tir, in, out);1875 1876	qp->rss_qp.tirn = MLX5_GET(create_tir_out, out, tirn);1877	if (!err && MLX5_GET(tirc, tirc, self_lb_block)) {1878		err = mlx5_ib_enable_lb(dev, false, true);1879 1880		if (err)1881			mlx5_cmd_destroy_tir(dev->mdev, qp->rss_qp.tirn,1882					     to_mpd(pd)->uid);1883	}1884 1885	if (err)1886		goto err;1887 1888	if (mucontext->devx_uid) {1889		params->resp.comp_mask |= MLX5_IB_CREATE_QP_RESP_MASK_TIRN;1890		params->resp.tirn = qp->rss_qp.tirn;1891		if (MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, sw_owner) ||1892		    MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, sw_owner_v2)) {1893			params->resp.tir_icm_addr =1894				MLX5_GET(create_tir_out, out, icm_address_31_0);1895			params->resp.tir_icm_addr |=1896				(u64)MLX5_GET(create_tir_out, out,1897					      icm_address_39_32)1898				<< 32;1899			params->resp.tir_icm_addr |=1900				(u64)MLX5_GET(create_tir_out, out,1901					      icm_address_63_40)1902				<< 40;1903			params->resp.comp_mask |=1904				MLX5_IB_CREATE_QP_RESP_MASK_TIR_ICM_ADDR;1905		}1906	}1907 1908	kvfree(in);1909	/* qpn is reserved for that QP */1910	qp->trans_qp.base.mqp.qpn = 0;1911	qp->is_rss = true;1912	return 0;1913 1914err:1915	kvfree(in);1916	return err;1917}1918 1919static void configure_requester_scat_cqe(struct mlx5_ib_dev *dev,1920					 struct mlx5_ib_qp *qp,1921					 struct ib_qp_init_attr *init_attr,1922					 void *qpc)1923{1924	int scqe_sz;1925	bool allow_scat_cqe = false;1926 1927	allow_scat_cqe = qp->flags_en & MLX5_QP_FLAG_ALLOW_SCATTER_CQE;1928 1929	if (!allow_scat_cqe && init_attr->sq_sig_type != IB_SIGNAL_ALL_WR)1930		return;1931 1932	scqe_sz = mlx5_ib_get_cqe_size(init_attr->send_cq);1933	if (scqe_sz == 128) {1934		MLX5_SET(qpc, qpc, cs_req, MLX5_REQ_SCAT_DATA64_CQE);1935		return;1936	}1937 1938	if (init_attr->qp_type != MLX5_IB_QPT_DCI ||1939	    MLX5_CAP_GEN(dev->mdev, dc_req_scat_data_cqe))1940		MLX5_SET(qpc, qpc, cs_req, MLX5_REQ_SCAT_DATA32_CQE);1941}1942 1943static int atomic_size_to_mode(int size_mask)1944{1945	/* driver does not support atomic_size > 256B1946	 * and does not know how to translate bigger sizes1947	 */1948	int supported_size_mask = size_mask & 0x1ff;1949	int log_max_size;1950 1951	if (!supported_size_mask)1952		return -EOPNOTSUPP;1953 1954	log_max_size = __fls(supported_size_mask);1955 1956	if (log_max_size > 3)1957		return log_max_size;1958 1959	return MLX5_ATOMIC_MODE_8B;1960}1961 1962static int get_atomic_mode(struct mlx5_ib_dev *dev,1963			   enum ib_qp_type qp_type)1964{1965	u8 atomic_operations = MLX5_CAP_ATOMIC(dev->mdev, atomic_operations);1966	u8 atomic = MLX5_CAP_GEN(dev->mdev, atomic);1967	int atomic_mode = -EOPNOTSUPP;1968	int atomic_size_mask;1969 1970	if (!atomic)1971		return -EOPNOTSUPP;1972 1973	if (qp_type == MLX5_IB_QPT_DCT)1974		atomic_size_mask = MLX5_CAP_ATOMIC(dev->mdev, atomic_size_dc);1975	else1976		atomic_size_mask = MLX5_CAP_ATOMIC(dev->mdev, atomic_size_qp);1977 1978	if ((atomic_operations & MLX5_ATOMIC_OPS_EXTENDED_CMP_SWAP) ||1979	    (atomic_operations & MLX5_ATOMIC_OPS_EXTENDED_FETCH_ADD))1980		atomic_mode = atomic_size_to_mode(atomic_size_mask);1981 1982	if (atomic_mode <= 0 &&1983	    (atomic_operations & MLX5_ATOMIC_OPS_CMP_SWAP &&1984	     atomic_operations & MLX5_ATOMIC_OPS_FETCH_ADD))1985		atomic_mode = MLX5_ATOMIC_MODE_IB_COMP;1986 1987	return atomic_mode;1988}1989 1990static int create_xrc_tgt_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,1991			     struct mlx5_create_qp_params *params)1992{1993	struct ib_qp_init_attr *attr = params->attr;1994	u32 uidx = params->uidx;1995	struct mlx5_ib_resources *devr = &dev->devr;1996	u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {};1997	int inlen = MLX5_ST_SZ_BYTES(create_qp_in);1998	struct mlx5_core_dev *mdev = dev->mdev;1999	struct mlx5_ib_qp_base *base;2000	unsigned long flags;2001	void *qpc;2002	u32 *in;2003	int err;2004 2005	if (attr->sq_sig_type == IB_SIGNAL_ALL_WR)2006		qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;2007 2008	in = kvzalloc(inlen, GFP_KERNEL);2009	if (!in)2010		return -ENOMEM;2011 2012	qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);2013 2014	MLX5_SET(qpc, qpc, st, MLX5_QP_ST_XRC);2015	MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);2016	MLX5_SET(qpc, qpc, pd, to_mpd(devr->p0)->pdn);2017 2018	if (qp->flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)2019		MLX5_SET(qpc, qpc, block_lb_mc, 1);2020	if (qp->flags & IB_QP_CREATE_CROSS_CHANNEL)2021		MLX5_SET(qpc, qpc, cd_master, 1);2022	if (qp->flags & IB_QP_CREATE_MANAGED_SEND)2023		MLX5_SET(qpc, qpc, cd_slave_send, 1);2024	if (qp->flags & IB_QP_CREATE_MANAGED_RECV)2025		MLX5_SET(qpc, qpc, cd_slave_receive, 1);2026 2027	MLX5_SET(qpc, qpc, ts_format, mlx5_get_qp_default_ts(dev->mdev));2028	MLX5_SET(qpc, qpc, rq_type, MLX5_SRQ_RQ);2029	MLX5_SET(qpc, qpc, no_sq, 1);2030	MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(devr->c0)->mcq.cqn);2031	MLX5_SET(qpc, qpc, cqn_snd, to_mcq(devr->c0)->mcq.cqn);2032	MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(devr->s0)->msrq.srqn);2033	MLX5_SET(qpc, qpc, xrcd, to_mxrcd(attr->xrcd)->xrcdn);2034	MLX5_SET64(qpc, qpc, dbr_addr, qp->db.dma);2035 2036	/* 0xffffff means we ask to work with cqe version 0 */2037	if (MLX5_CAP_GEN(mdev, cqe_version) == MLX5_CQE_VERSION_V1)2038		MLX5_SET(qpc, qpc, user_index, uidx);2039 2040	if (qp->flags & IB_QP_CREATE_PCI_WRITE_END_PADDING) {2041		MLX5_SET(qpc, qpc, end_padding_mode,2042			 MLX5_WQ_END_PAD_MODE_ALIGN);2043		/* Special case to clean flag */2044		qp->flags &= ~IB_QP_CREATE_PCI_WRITE_END_PADDING;2045	}2046 2047	base = &qp->trans_qp.base;2048	err = mlx5_qpc_create_qp(dev, &base->mqp, in, inlen, out);2049	kvfree(in);2050	if (err)2051		return err;2052 2053	base->container_mibqp = qp;2054	base->mqp.event = mlx5_ib_qp_event;2055	if (MLX5_CAP_GEN(mdev, ece_support))2056		params->resp.ece_options = MLX5_GET(create_qp_out, out, ece);2057 2058	spin_lock_irqsave(&dev->reset_flow_resource_lock, flags);2059	list_add_tail(&qp->qps_list, &dev->qp_list);2060	spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags);2061 2062	qp->trans_qp.xrcdn = to_mxrcd(attr->xrcd)->xrcdn;2063	return 0;2064}2065 2066static int create_dci(struct mlx5_ib_dev *dev, struct ib_pd *pd,2067		      struct mlx5_ib_qp *qp,2068		      struct mlx5_create_qp_params *params)2069{2070	struct ib_qp_init_attr *init_attr = params->attr;2071	struct mlx5_ib_create_qp *ucmd = params->ucmd;2072	u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {};2073	struct ib_udata *udata = params->udata;2074	u32 uidx = params->uidx;2075	struct mlx5_ib_resources *devr = &dev->devr;2076	int inlen = MLX5_ST_SZ_BYTES(create_qp_in);2077	struct mlx5_core_dev *mdev = dev->mdev;2078	struct mlx5_ib_cq *send_cq;2079	struct mlx5_ib_cq *recv_cq;2080	unsigned long flags;2081	struct mlx5_ib_qp_base *base;2082	int ts_format;2083	int mlx5_st;2084	void *qpc;2085	u32 *in;2086	int err;2087 2088	spin_lock_init(&qp->sq.lock);2089	spin_lock_init(&qp->rq.lock);2090 2091	mlx5_st = to_mlx5_st(qp->type);2092	if (mlx5_st < 0)2093		return -EINVAL;2094 2095	if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)2096		qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;2097 2098	base = &qp->trans_qp.base;2099 2100	qp->has_rq = qp_has_rq(init_attr);2101	err = set_rq_size(dev, &init_attr->cap, qp->has_rq, qp, ucmd);2102	if (err) {2103		mlx5_ib_dbg(dev, "err %d\n", err);2104		return err;2105	}2106 2107	if (ucmd->rq_wqe_shift != qp->rq.wqe_shift ||2108	    ucmd->rq_wqe_count != qp->rq.wqe_cnt)2109		return -EINVAL;2110 2111	if (ucmd->sq_wqe_count > (1 << MLX5_CAP_GEN(mdev, log_max_qp_sz)))2112		return -EINVAL;2113 2114	ts_format = get_qp_ts_format(dev, to_mcq(init_attr->send_cq),2115				     to_mcq(init_attr->recv_cq));2116 2117	if (ts_format < 0)2118		return ts_format;2119 2120	err = _create_user_qp(dev, pd, qp, udata, init_attr, &in, &params->resp,2121			      &inlen, base, ucmd);2122	if (err)2123		return err;2124 2125	if (MLX5_CAP_GEN(mdev, ece_support))2126		MLX5_SET(create_qp_in, in, ece, ucmd->ece_options);2127	qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);2128 2129	MLX5_SET(qpc, qpc, st, mlx5_st);2130	MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);2131	MLX5_SET(qpc, qpc, pd, to_mpd(pd)->pdn);2132 2133	if (qp->flags_en & MLX5_QP_FLAG_SIGNATURE)2134		MLX5_SET(qpc, qpc, wq_signature, 1);2135 2136	if (qp->flags & IB_QP_CREATE_CROSS_CHANNEL)2137		MLX5_SET(qpc, qpc, cd_master, 1);2138	if (qp->flags & IB_QP_CREATE_MANAGED_SEND)2139		MLX5_SET(qpc, qpc, cd_slave_send, 1);2140	if (qp->flags_en & MLX5_QP_FLAG_SCATTER_CQE)2141		configure_requester_scat_cqe(dev, qp, init_attr, qpc);2142 2143	if (qp->rq.wqe_cnt) {2144		MLX5_SET(qpc, qpc, log_rq_stride, qp->rq.wqe_shift - 4);2145		MLX5_SET(qpc, qpc, log_rq_size, ilog2(qp->rq.wqe_cnt));2146	}2147 2148	if (qp->flags_en & MLX5_QP_FLAG_DCI_STREAM) {2149		MLX5_SET(qpc, qpc, log_num_dci_stream_channels,2150			 ucmd->dci_streams.log_num_concurent);2151		MLX5_SET(qpc, qpc, log_num_dci_errored_streams,2152			 ucmd->dci_streams.log_num_errored);2153	}2154 2155	MLX5_SET(qpc, qpc, ts_format, ts_format);2156	MLX5_SET(qpc, qpc, rq_type, get_rx_type(qp, init_attr));2157 2158	MLX5_SET(qpc, qpc, log_sq_size, ilog2(qp->sq.wqe_cnt));2159 2160	/* Set default resources */2161	if (init_attr->srq) {2162		MLX5_SET(qpc, qpc, xrcd, devr->xrcdn0);2163		MLX5_SET(qpc, qpc, srqn_rmpn_xrqn,2164			 to_msrq(init_attr->srq)->msrq.srqn);2165	} else {2166		MLX5_SET(qpc, qpc, xrcd, devr->xrcdn1);2167		MLX5_SET(qpc, qpc, srqn_rmpn_xrqn,2168			 to_msrq(devr->s1)->msrq.srqn);2169	}2170 2171	if (init_attr->send_cq)2172		MLX5_SET(qpc, qpc, cqn_snd,2173			 to_mcq(init_attr->send_cq)->mcq.cqn);2174 2175	if (init_attr->recv_cq)2176		MLX5_SET(qpc, qpc, cqn_rcv,2177			 to_mcq(init_attr->recv_cq)->mcq.cqn);2178 2179	MLX5_SET64(qpc, qpc, dbr_addr, qp->db.dma);2180 2181	/* 0xffffff means we ask to work with cqe version 0 */2182	if (MLX5_CAP_GEN(mdev, cqe_version) == MLX5_CQE_VERSION_V1)2183		MLX5_SET(qpc, qpc, user_index, uidx);2184 2185	if (qp->flags & IB_QP_CREATE_PCI_WRITE_END_PADDING) {2186		MLX5_SET(qpc, qpc, end_padding_mode,2187			 MLX5_WQ_END_PAD_MODE_ALIGN);2188		/* Special case to clean flag */2189		qp->flags &= ~IB_QP_CREATE_PCI_WRITE_END_PADDING;2190	}2191 2192	err = mlx5_qpc_create_qp(dev, &base->mqp, in, inlen, out);2193 2194	kvfree(in);2195	if (err)2196		goto err_create;2197 2198	base->container_mibqp = qp;2199	base->mqp.event = mlx5_ib_qp_event;2200	if (MLX5_CAP_GEN(mdev, ece_support))2201		params->resp.ece_options = MLX5_GET(create_qp_out, out, ece);2202 2203	get_cqs(qp->type, init_attr->send_cq, init_attr->recv_cq,2204		&send_cq, &recv_cq);2205	spin_lock_irqsave(&dev->reset_flow_resource_lock, flags);2206	mlx5_ib_lock_cqs(send_cq, recv_cq);2207	/* Maintain device to QPs access, needed for further handling via reset2208	 * flow2209	 */2210	list_add_tail(&qp->qps_list, &dev->qp_list);2211	/* Maintain CQ to QPs access, needed for further handling via reset flow2212	 */2213	if (send_cq)2214		list_add_tail(&qp->cq_send_list, &send_cq->list_send_qp);2215	if (recv_cq)2216		list_add_tail(&qp->cq_recv_list, &recv_cq->list_recv_qp);2217	mlx5_ib_unlock_cqs(send_cq, recv_cq);2218	spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags);2219 2220	return 0;2221 2222err_create:2223	destroy_qp(dev, qp, base, udata);2224	return err;2225}2226 2227static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,2228			  struct mlx5_ib_qp *qp,2229			  struct mlx5_create_qp_params *params)2230{2231	struct ib_qp_init_attr *init_attr = params->attr;2232	struct mlx5_ib_create_qp *ucmd = params->ucmd;2233	u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {};2234	struct ib_udata *udata = params->udata;2235	u32 uidx = params->uidx;2236	struct mlx5_ib_resources *devr = &dev->devr;2237	int inlen = MLX5_ST_SZ_BYTES(create_qp_in);2238	struct mlx5_core_dev *mdev = dev->mdev;2239	struct mlx5_ib_cq *send_cq;2240	struct mlx5_ib_cq *recv_cq;2241	unsigned long flags;2242	struct mlx5_ib_qp_base *base;2243	int ts_format;2244	int mlx5_st;2245	void *qpc;2246	u32 *in;2247	int err;2248 2249	spin_lock_init(&qp->sq.lock);2250	spin_lock_init(&qp->rq.lock);2251 2252	mlx5_st = to_mlx5_st(qp->type);2253	if (mlx5_st < 0)2254		return -EINVAL;2255 2256	if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)2257		qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;2258 2259	if (qp->flags & IB_QP_CREATE_SOURCE_QPN)2260		qp->underlay_qpn = init_attr->source_qpn;2261 2262	base = (init_attr->qp_type == IB_QPT_RAW_PACKET ||2263		qp->flags & IB_QP_CREATE_SOURCE_QPN) ?2264	       &qp->raw_packet_qp.rq.base :2265	       &qp->trans_qp.base;2266 2267	qp->has_rq = qp_has_rq(init_attr);2268	err = set_rq_size(dev, &init_attr->cap, qp->has_rq, qp, ucmd);2269	if (err) {2270		mlx5_ib_dbg(dev, "err %d\n", err);2271		return err;2272	}2273 2274	if (ucmd->rq_wqe_shift != qp->rq.wqe_shift ||2275	    ucmd->rq_wqe_count != qp->rq.wqe_cnt)2276		return -EINVAL;2277 2278	if (ucmd->sq_wqe_count > (1 << MLX5_CAP_GEN(mdev, log_max_qp_sz)))2279		return -EINVAL;2280 2281	if (init_attr->qp_type != IB_QPT_RAW_PACKET) {2282		ts_format = get_qp_ts_format(dev, to_mcq(init_attr->send_cq),2283					     to_mcq(init_attr->recv_cq));2284		if (ts_format < 0)2285			return ts_format;2286	}2287 2288	err = _create_user_qp(dev, pd, qp, udata, init_attr, &in, &params->resp,2289			      &inlen, base, ucmd);2290	if (err)2291		return err;2292 2293	if (is_sqp(init_attr->qp_type))2294		qp->port = init_attr->port_num;2295 2296	if (MLX5_CAP_GEN(mdev, ece_support))2297		MLX5_SET(create_qp_in, in, ece, ucmd->ece_options);2298	qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);2299 2300	MLX5_SET(qpc, qpc, st, mlx5_st);2301	MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);2302	MLX5_SET(qpc, qpc, pd, to_mpd(pd)->pdn);2303 2304	if (qp->flags_en & MLX5_QP_FLAG_SIGNATURE)2305		MLX5_SET(qpc, qpc, wq_signature, 1);2306 2307	if (qp->flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)2308		MLX5_SET(qpc, qpc, block_lb_mc, 1);2309 2310	if (qp->flags & IB_QP_CREATE_CROSS_CHANNEL)2311		MLX5_SET(qpc, qpc, cd_master, 1);2312	if (qp->flags & IB_QP_CREATE_MANAGED_SEND)2313		MLX5_SET(qpc, qpc, cd_slave_send, 1);2314	if (qp->flags & IB_QP_CREATE_MANAGED_RECV)2315		MLX5_SET(qpc, qpc, cd_slave_receive, 1);2316	if (qp->flags_en & MLX5_QP_FLAG_PACKET_BASED_CREDIT_MODE)2317		MLX5_SET(qpc, qpc, req_e2e_credit_mode, 1);2318	if ((qp->flags_en & MLX5_QP_FLAG_SCATTER_CQE) &&2319	    (init_attr->qp_type == IB_QPT_RC ||2320	     init_attr->qp_type == IB_QPT_UC)) {2321		int rcqe_sz = mlx5_ib_get_cqe_size(init_attr->recv_cq);2322 2323		MLX5_SET(qpc, qpc, cs_res,2324			 rcqe_sz == 128 ? MLX5_RES_SCAT_DATA64_CQE :2325					  MLX5_RES_SCAT_DATA32_CQE);2326	}2327	if ((qp->flags_en & MLX5_QP_FLAG_SCATTER_CQE) &&2328	    (qp->type == MLX5_IB_QPT_DCI || qp->type == IB_QPT_RC))2329		configure_requester_scat_cqe(dev, qp, init_attr, qpc);2330 2331	if (qp->rq.wqe_cnt) {2332		MLX5_SET(qpc, qpc, log_rq_stride, qp->rq.wqe_shift - 4);2333		MLX5_SET(qpc, qpc, log_rq_size, ilog2(qp->rq.wqe_cnt));2334	}2335 2336	if (init_attr->qp_type != IB_QPT_RAW_PACKET)2337		MLX5_SET(qpc, qpc, ts_format, ts_format);2338 2339	MLX5_SET(qpc, qpc, rq_type, get_rx_type(qp, init_attr));2340 2341	if (qp->sq.wqe_cnt) {2342		MLX5_SET(qpc, qpc, log_sq_size, ilog2(qp->sq.wqe_cnt));2343	} else {2344		MLX5_SET(qpc, qpc, no_sq, 1);2345		if (init_attr->srq &&2346		    init_attr->srq->srq_type == IB_SRQT_TM)2347			MLX5_SET(qpc, qpc, offload_type,2348				 MLX5_QPC_OFFLOAD_TYPE_RNDV);2349	}2350 2351	/* Set default resources */2352	switch (init_attr->qp_type) {2353	case IB_QPT_XRC_INI:2354		MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(devr->c0)->mcq.cqn);2355		MLX5_SET(qpc, qpc, xrcd, devr->xrcdn1);2356		MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(devr->s0)->msrq.srqn);2357		break;2358	default:2359		if (init_attr->srq) {2360			MLX5_SET(qpc, qpc, xrcd, devr->xrcdn0);2361			MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(init_attr->srq)->msrq.srqn);2362		} else {2363			MLX5_SET(qpc, qpc, xrcd, devr->xrcdn1);2364			MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(devr->s1)->msrq.srqn);2365		}2366	}2367 2368	if (init_attr->send_cq)2369		MLX5_SET(qpc, qpc, cqn_snd, to_mcq(init_attr->send_cq)->mcq.cqn);2370 2371	if (init_attr->recv_cq)2372		MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(init_attr->recv_cq)->mcq.cqn);2373 2374	MLX5_SET64(qpc, qpc, dbr_addr, qp->db.dma);2375 2376	/* 0xffffff means we ask to work with cqe version 0 */2377	if (MLX5_CAP_GEN(mdev, cqe_version) == MLX5_CQE_VERSION_V1)2378		MLX5_SET(qpc, qpc, user_index, uidx);2379 2380	if (qp->flags & IB_QP_CREATE_PCI_WRITE_END_PADDING &&2381	    init_attr->qp_type != IB_QPT_RAW_PACKET) {2382		MLX5_SET(qpc, qpc, end_padding_mode,2383			 MLX5_WQ_END_PAD_MODE_ALIGN);2384		/* Special case to clean flag */2385		qp->flags &= ~IB_QP_CREATE_PCI_WRITE_END_PADDING;2386	}2387 2388	if (init_attr->qp_type == IB_QPT_RAW_PACKET ||2389	    qp->flags & IB_QP_CREATE_SOURCE_QPN) {2390		qp->raw_packet_qp.sq.ubuffer.buf_addr = ucmd->sq_buf_addr;2391		raw_packet_qp_copy_info(qp, &qp->raw_packet_qp);2392		err = create_raw_packet_qp(dev, qp, in, inlen, pd, udata,2393					   &params->resp, init_attr);2394	} else2395		err = mlx5_qpc_create_qp(dev, &base->mqp, in, inlen, out);2396 2397	kvfree(in);2398	if (err)2399		goto err_create;2400 2401	base->container_mibqp = qp;2402	base->mqp.event = mlx5_ib_qp_event;2403	if (MLX5_CAP_GEN(mdev, ece_support))2404		params->resp.ece_options = MLX5_GET(create_qp_out, out, ece);2405 2406	get_cqs(qp->type, init_attr->send_cq, init_attr->recv_cq,2407		&send_cq, &recv_cq);2408	spin_lock_irqsave(&dev->reset_flow_resource_lock, flags);2409	mlx5_ib_lock_cqs(send_cq, recv_cq);2410	/* Maintain device to QPs access, needed for further handling via reset2411	 * flow2412	 */2413	list_add_tail(&qp->qps_list, &dev->qp_list);2414	/* Maintain CQ to QPs access, needed for further handling via reset flow2415	 */2416	if (send_cq)2417		list_add_tail(&qp->cq_send_list, &send_cq->list_send_qp);2418	if (recv_cq)2419		list_add_tail(&qp->cq_recv_list, &recv_cq->list_recv_qp);2420	mlx5_ib_unlock_cqs(send_cq, recv_cq);2421	spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags);2422 2423	return 0;2424 2425err_create:2426	destroy_qp(dev, qp, base, udata);2427	return err;2428}2429 2430static int create_kernel_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,2431			    struct mlx5_ib_qp *qp,2432			    struct mlx5_create_qp_params *params)2433{2434	struct ib_qp_init_attr *attr = params->attr;2435	u32 uidx = params->uidx;2436	struct mlx5_ib_resources *devr = &dev->devr;2437	u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {};2438	int inlen = MLX5_ST_SZ_BYTES(create_qp_in);2439	struct mlx5_core_dev *mdev = dev->mdev;2440	struct mlx5_ib_cq *send_cq;2441	struct mlx5_ib_cq *recv_cq;2442	unsigned long flags;2443	struct mlx5_ib_qp_base *base;2444	int mlx5_st;2445	void *qpc;2446	u32 *in;2447	int err;2448 2449	spin_lock_init(&qp->sq.lock);2450	spin_lock_init(&qp->rq.lock);2451 2452	mlx5_st = to_mlx5_st(qp->type);2453	if (mlx5_st < 0)2454		return -EINVAL;2455 2456	if (attr->sq_sig_type == IB_SIGNAL_ALL_WR)2457		qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;2458 2459	base = &qp->trans_qp.base;2460 2461	qp->has_rq = qp_has_rq(attr);2462	err = set_rq_size(dev, &attr->cap, qp->has_rq, qp, NULL);2463	if (err) {2464		mlx5_ib_dbg(dev, "err %d\n", err);2465		return err;2466	}2467 2468	err = _create_kernel_qp(dev, attr, qp, &in, &inlen, base);2469	if (err)2470		return err;2471 2472	if (is_sqp(attr->qp_type))2473		qp->port = attr->port_num;2474 2475	qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);2476 2477	MLX5_SET(qpc, qpc, st, mlx5_st);2478	MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);2479 2480	if (attr->qp_type != MLX5_IB_QPT_REG_UMR)2481		MLX5_SET(qpc, qpc, pd, to_mpd(pd ? pd : devr->p0)->pdn);2482	else2483		MLX5_SET(qpc, qpc, latency_sensitive, 1);2484 2485 2486	if (qp->flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK)2487		MLX5_SET(qpc, qpc, block_lb_mc, 1);2488 2489	if (qp->rq.wqe_cnt) {2490		MLX5_SET(qpc, qpc, log_rq_stride, qp->rq.wqe_shift - 4);2491		MLX5_SET(qpc, qpc, log_rq_size, ilog2(qp->rq.wqe_cnt));2492	}2493 2494	MLX5_SET(qpc, qpc, rq_type, get_rx_type(qp, attr));2495 2496	if (qp->sq.wqe_cnt)2497		MLX5_SET(qpc, qpc, log_sq_size, ilog2(qp->sq.wqe_cnt));2498	else2499		MLX5_SET(qpc, qpc, no_sq, 1);2500 2501	if (attr->srq) {2502		MLX5_SET(qpc, qpc, xrcd, devr->xrcdn0);2503		MLX5_SET(qpc, qpc, srqn_rmpn_xrqn,2504			 to_msrq(attr->srq)->msrq.srqn);2505	} else {2506		MLX5_SET(qpc, qpc, xrcd, devr->xrcdn1);2507		MLX5_SET(qpc, qpc, srqn_rmpn_xrqn,2508			 to_msrq(devr->s1)->msrq.srqn);2509	}2510 2511	if (attr->send_cq)2512		MLX5_SET(qpc, qpc, cqn_snd, to_mcq(attr->send_cq)->mcq.cqn);2513 2514	if (attr->recv_cq)2515		MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(attr->recv_cq)->mcq.cqn);2516 2517	MLX5_SET64(qpc, qpc, dbr_addr, qp->db.dma);2518 2519	/* 0xffffff means we ask to work with cqe version 0 */2520	if (MLX5_CAP_GEN(mdev, cqe_version) == MLX5_CQE_VERSION_V1)2521		MLX5_SET(qpc, qpc, user_index, uidx);2522 2523	/* we use IB_QP_CREATE_IPOIB_UD_LSO to indicates ipoib qp */2524	if (qp->flags & IB_QP_CREATE_IPOIB_UD_LSO)2525		MLX5_SET(qpc, qpc, ulp_stateless_offload_mode, 1);2526 2527	if (qp->flags & IB_QP_CREATE_INTEGRITY_EN &&2528	    MLX5_CAP_GEN(mdev, go_back_n))2529		MLX5_SET(qpc, qpc, retry_mode, MLX5_QP_RM_GO_BACK_N);2530 2531	err = mlx5_qpc_create_qp(dev, &base->mqp, in, inlen, out);2532	kvfree(in);2533	if (err)2534		goto err_create;2535 2536	base->container_mibqp = qp;2537	base->mqp.event = mlx5_ib_qp_event;2538 2539	get_cqs(qp->type, attr->send_cq, attr->recv_cq,2540		&send_cq, &recv_cq);2541	spin_lock_irqsave(&dev->reset_flow_resource_lock, flags);2542	mlx5_ib_lock_cqs(send_cq, recv_cq);2543	/* Maintain device to QPs access, needed for further handling via reset2544	 * flow2545	 */2546	list_add_tail(&qp->qps_list, &dev->qp_list);2547	/* Maintain CQ to QPs access, needed for further handling via reset flow2548	 */2549	if (send_cq)2550		list_add_tail(&qp->cq_send_list, &send_cq->list_send_qp);2551	if (recv_cq)2552		list_add_tail(&qp->cq_recv_list, &recv_cq->list_recv_qp);2553	mlx5_ib_unlock_cqs(send_cq, recv_cq);2554	spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags);2555 2556	return 0;2557 2558err_create:2559	destroy_qp(dev, qp, base, NULL);2560	return err;2561}2562 2563static void mlx5_ib_lock_cqs(struct mlx5_ib_cq *send_cq, struct mlx5_ib_cq *recv_cq)2564	__acquires(&send_cq->lock) __acquires(&recv_cq->lock)2565{2566	if (send_cq) {2567		if (recv_cq) {2568			if (send_cq->mcq.cqn < recv_cq->mcq.cqn)  {2569				spin_lock(&send_cq->lock);2570				spin_lock_nested(&recv_cq->lock,2571						 SINGLE_DEPTH_NESTING);2572			} else if (send_cq->mcq.cqn == recv_cq->mcq.cqn) {2573				spin_lock(&send_cq->lock);2574				__acquire(&recv_cq->lock);2575			} else {2576				spin_lock(&recv_cq->lock);2577				spin_lock_nested(&send_cq->lock,2578						 SINGLE_DEPTH_NESTING);2579			}2580		} else {2581			spin_lock(&send_cq->lock);2582			__acquire(&recv_cq->lock);2583		}2584	} else if (recv_cq) {2585		spin_lock(&recv_cq->lock);2586		__acquire(&send_cq->lock);2587	} else {2588		__acquire(&send_cq->lock);2589		__acquire(&recv_cq->lock);2590	}2591}2592 2593static void mlx5_ib_unlock_cqs(struct mlx5_ib_cq *send_cq, struct mlx5_ib_cq *recv_cq)2594	__releases(&send_cq->lock) __releases(&recv_cq->lock)2595{2596	if (send_cq) {2597		if (recv_cq) {2598			if (send_cq->mcq.cqn < recv_cq->mcq.cqn)  {2599				spin_unlock(&recv_cq->lock);2600				spin_unlock(&send_cq->lock);2601			} else if (send_cq->mcq.cqn == recv_cq->mcq.cqn) {2602				__release(&recv_cq->lock);2603				spin_unlock(&send_cq->lock);2604			} else {2605				spin_unlock(&send_cq->lock);2606				spin_unlock(&recv_cq->lock);2607			}2608		} else {2609			__release(&recv_cq->lock);2610			spin_unlock(&send_cq->lock);2611		}2612	} else if (recv_cq) {2613		__release(&send_cq->lock);2614		spin_unlock(&recv_cq->lock);2615	} else {2616		__release(&recv_cq->lock);2617		__release(&send_cq->lock);2618	}2619}2620 2621static void get_cqs(enum ib_qp_type qp_type,2622		    struct ib_cq *ib_send_cq, struct ib_cq *ib_recv_cq,2623		    struct mlx5_ib_cq **send_cq, struct mlx5_ib_cq **recv_cq)2624{2625	switch (qp_type) {2626	case IB_QPT_XRC_TGT:2627		*send_cq = NULL;2628		*recv_cq = NULL;2629		break;2630	case MLX5_IB_QPT_REG_UMR:2631	case IB_QPT_XRC_INI:2632		*send_cq = ib_send_cq ? to_mcq(ib_send_cq) : NULL;2633		*recv_cq = NULL;2634		break;2635 2636	case IB_QPT_SMI:2637	case MLX5_IB_QPT_HW_GSI:2638	case IB_QPT_RC:2639	case IB_QPT_UC:2640	case IB_QPT_UD:2641	case IB_QPT_RAW_PACKET:2642		*send_cq = ib_send_cq ? to_mcq(ib_send_cq) : NULL;2643		*recv_cq = ib_recv_cq ? to_mcq(ib_recv_cq) : NULL;2644		break;2645	default:2646		*send_cq = NULL;2647		*recv_cq = NULL;2648		break;2649	}2650}2651 2652static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,2653				const struct mlx5_modify_raw_qp_param *raw_qp_param,2654				u8 lag_tx_affinity);2655 2656static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,2657			      struct ib_udata *udata)2658{2659	struct mlx5_ib_cq *send_cq, *recv_cq;2660	struct mlx5_ib_qp_base *base;2661	unsigned long flags;2662	int err;2663 2664	if (qp->is_rss) {2665		destroy_rss_raw_qp_tir(dev, qp);2666		return;2667	}2668 2669	base = (qp->type == IB_QPT_RAW_PACKET ||2670		qp->flags & IB_QP_CREATE_SOURCE_QPN) ?2671		       &qp->raw_packet_qp.rq.base :2672		       &qp->trans_qp.base;2673 2674	if (qp->state != IB_QPS_RESET) {2675		if (qp->type != IB_QPT_RAW_PACKET &&2676		    !(qp->flags & IB_QP_CREATE_SOURCE_QPN)) {2677			err = mlx5_core_qp_modify(dev, MLX5_CMD_OP_2RST_QP, 0,2678						  NULL, &base->mqp, NULL);2679		} else {2680			struct mlx5_modify_raw_qp_param raw_qp_param = {2681				.operation = MLX5_CMD_OP_2RST_QP2682			};2683 2684			err = modify_raw_packet_qp(dev, qp, &raw_qp_param, 0);2685		}2686		if (err)2687			mlx5_ib_warn(dev, "mlx5_ib: modify QP 0x%06x to RESET failed\n",2688				     base->mqp.qpn);2689	}2690 2691	get_cqs(qp->type, qp->ibqp.send_cq, qp->ibqp.recv_cq, &send_cq,2692		&recv_cq);2693 2694	spin_lock_irqsave(&dev->reset_flow_resource_lock, flags);2695	mlx5_ib_lock_cqs(send_cq, recv_cq);2696	/* del from lists under both locks above to protect reset flow paths */2697	list_del(&qp->qps_list);2698	if (send_cq)2699		list_del(&qp->cq_send_list);2700 2701	if (recv_cq)2702		list_del(&qp->cq_recv_list);2703 2704	if (!udata) {2705		__mlx5_ib_cq_clean(recv_cq, base->mqp.qpn,2706				   qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL);2707		if (send_cq != recv_cq)2708			__mlx5_ib_cq_clean(send_cq, base->mqp.qpn,2709					   NULL);2710	}2711	mlx5_ib_unlock_cqs(send_cq, recv_cq);2712	spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags);2713 2714	if (qp->type == IB_QPT_RAW_PACKET ||2715	    qp->flags & IB_QP_CREATE_SOURCE_QPN) {2716		destroy_raw_packet_qp(dev, qp);2717	} else {2718		err = mlx5_core_destroy_qp(dev, &base->mqp);2719		if (err)2720			mlx5_ib_warn(dev, "failed to destroy QP 0x%x\n",2721				     base->mqp.qpn);2722	}2723 2724	destroy_qp(dev, qp, base, udata);2725}2726 2727static int create_dct(struct mlx5_ib_dev *dev, struct ib_pd *pd,2728		      struct mlx5_ib_qp *qp,2729		      struct mlx5_create_qp_params *params)2730{2731	struct ib_qp_init_attr *attr = params->attr;2732	struct mlx5_ib_create_qp *ucmd = params->ucmd;2733	u32 uidx = params->uidx;2734	void *dctc;2735 2736	if (mlx5_lag_is_active(dev->mdev) && !MLX5_CAP_GEN(dev->mdev, lag_dct))2737		return -EOPNOTSUPP;2738 2739	qp->dct.in = kzalloc(MLX5_ST_SZ_BYTES(create_dct_in), GFP_KERNEL);2740	if (!qp->dct.in)2741		return -ENOMEM;2742 2743	MLX5_SET(create_dct_in, qp->dct.in, uid, to_mpd(pd)->uid);2744	dctc = MLX5_ADDR_OF(create_dct_in, qp->dct.in, dct_context_entry);2745	MLX5_SET(dctc, dctc, pd, to_mpd(pd)->pdn);2746	MLX5_SET(dctc, dctc, srqn_xrqn, to_msrq(attr->srq)->msrq.srqn);2747	MLX5_SET(dctc, dctc, cqn, to_mcq(attr->recv_cq)->mcq.cqn);2748	MLX5_SET64(dctc, dctc, dc_access_key, ucmd->access_key);2749	MLX5_SET(dctc, dctc, user_index, uidx);2750	if (MLX5_CAP_GEN(dev->mdev, ece_support))2751		MLX5_SET(dctc, dctc, ece, ucmd->ece_options);2752 2753	if (qp->flags_en & MLX5_QP_FLAG_SCATTER_CQE) {2754		int rcqe_sz = mlx5_ib_get_cqe_size(attr->recv_cq);2755 2756		if (rcqe_sz == 128)2757			MLX5_SET(dctc, dctc, cs_res, MLX5_RES_SCAT_DATA64_CQE);2758	}2759 2760	qp->state = IB_QPS_RESET;2761	return 0;2762}2763 2764static int check_qp_type(struct mlx5_ib_dev *dev, struct ib_qp_init_attr *attr,2765			 enum ib_qp_type *type)2766{2767	if (attr->qp_type == IB_QPT_DRIVER && !MLX5_CAP_GEN(dev->mdev, dct))2768		goto out;2769 2770	switch (attr->qp_type) {2771	case IB_QPT_XRC_TGT:2772	case IB_QPT_XRC_INI:2773		if (!MLX5_CAP_GEN(dev->mdev, xrc))2774			goto out;2775		fallthrough;2776	case IB_QPT_RC:2777	case IB_QPT_UC:2778	case IB_QPT_SMI:2779	case MLX5_IB_QPT_HW_GSI:2780	case IB_QPT_DRIVER:2781	case IB_QPT_GSI:2782	case IB_QPT_RAW_PACKET:2783	case IB_QPT_UD:2784	case MLX5_IB_QPT_REG_UMR:2785		break;2786	default:2787		goto out;2788	}2789 2790	*type = attr->qp_type;2791	return 0;2792 2793out:2794	mlx5_ib_dbg(dev, "Unsupported QP type %d\n", attr->qp_type);2795	return -EOPNOTSUPP;2796}2797 2798static int check_valid_flow(struct mlx5_ib_dev *dev, struct ib_pd *pd,2799			    struct ib_qp_init_attr *attr,2800			    struct ib_udata *udata)2801{2802	struct mlx5_ib_ucontext *ucontext = rdma_udata_to_drv_context(2803		udata, struct mlx5_ib_ucontext, ibucontext);2804 2805	if (!udata) {2806		/* Kernel create_qp callers */2807		if (attr->rwq_ind_tbl)2808			return -EOPNOTSUPP;2809 2810		switch (attr->qp_type) {2811		case IB_QPT_RAW_PACKET:2812		case IB_QPT_DRIVER:2813			return -EOPNOTSUPP;2814		default:2815			return 0;2816		}2817	}2818 2819	/* Userspace create_qp callers */2820	if (attr->qp_type == IB_QPT_RAW_PACKET && !ucontext->cqe_version) {2821		mlx5_ib_dbg(dev,2822			"Raw Packet QP is only supported for CQE version > 0\n");2823		return -EINVAL;2824	}2825 2826	if (attr->qp_type != IB_QPT_RAW_PACKET && attr->rwq_ind_tbl) {2827		mlx5_ib_dbg(dev,2828			    "Wrong QP type %d for the RWQ indirect table\n",2829			    attr->qp_type);2830		return -EINVAL;2831	}2832 2833	/*2834	 * We don't need to see this warning, it means that kernel code2835	 * missing ib_pd. Placed here to catch developer's mistakes.2836	 */2837	WARN_ONCE(!pd && attr->qp_type != IB_QPT_XRC_TGT,2838		  "There is a missing PD pointer assignment\n");2839	return 0;2840}2841 2842static void process_vendor_flag(struct mlx5_ib_dev *dev, int *flags, int flag,2843				bool cond, struct mlx5_ib_qp *qp)2844{2845	if (!(*flags & flag))2846		return;2847 2848	if (cond) {2849		qp->flags_en |= flag;2850		*flags &= ~flag;2851		return;2852	}2853 2854	switch (flag) {2855	case MLX5_QP_FLAG_SCATTER_CQE:2856	case MLX5_QP_FLAG_ALLOW_SCATTER_CQE:2857		/*2858		 * We don't return error if these flags were provided,2859		 * and mlx5 doesn't have right capability.2860		 */2861		*flags &= ~(MLX5_QP_FLAG_SCATTER_CQE |2862			    MLX5_QP_FLAG_ALLOW_SCATTER_CQE);2863		return;2864	default:2865		break;2866	}2867	mlx5_ib_dbg(dev, "Vendor create QP flag 0x%X is not supported\n", flag);2868}2869 2870static int process_vendor_flags(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,2871				void *ucmd, struct ib_qp_init_attr *attr)2872{2873	struct mlx5_core_dev *mdev = dev->mdev;2874	bool cond;2875	int flags;2876 2877	if (attr->rwq_ind_tbl)2878		flags = ((struct mlx5_ib_create_qp_rss *)ucmd)->flags;2879	else2880		flags = ((struct mlx5_ib_create_qp *)ucmd)->flags;2881 2882	switch (flags & (MLX5_QP_FLAG_TYPE_DCT | MLX5_QP_FLAG_TYPE_DCI)) {2883	case MLX5_QP_FLAG_TYPE_DCI:2884		qp->type = MLX5_IB_QPT_DCI;2885		break;2886	case MLX5_QP_FLAG_TYPE_DCT:2887		qp->type = MLX5_IB_QPT_DCT;2888		break;2889	default:2890		if (qp->type != IB_QPT_DRIVER)2891			break;2892		/*2893		 * It is IB_QPT_DRIVER and or no subtype or2894		 * wrong subtype were provided.2895		 */2896		return -EINVAL;2897	}2898 2899	process_vendor_flag(dev, &flags, MLX5_QP_FLAG_TYPE_DCI, true, qp);2900	process_vendor_flag(dev, &flags, MLX5_QP_FLAG_TYPE_DCT, true, qp);2901	process_vendor_flag(dev, &flags, MLX5_QP_FLAG_DCI_STREAM,2902			    MLX5_CAP_GEN(mdev, log_max_dci_stream_channels),2903			    qp);2904 2905	process_vendor_flag(dev, &flags, MLX5_QP_FLAG_SIGNATURE, true, qp);2906	process_vendor_flag(dev, &flags, MLX5_QP_FLAG_SCATTER_CQE,2907			    MLX5_CAP_GEN(mdev, sctr_data_cqe), qp);2908	process_vendor_flag(dev, &flags, MLX5_QP_FLAG_ALLOW_SCATTER_CQE,2909			    MLX5_CAP_GEN(mdev, sctr_data_cqe), qp);2910 2911	if (qp->type == IB_QPT_RAW_PACKET) {2912		cond = MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) ||2913		       MLX5_CAP_ETH(mdev, tunnel_stateless_gre) ||2914		       MLX5_CAP_ETH(mdev, tunnel_stateless_geneve_rx);2915		process_vendor_flag(dev, &flags, MLX5_QP_FLAG_TUNNEL_OFFLOADS,2916				    cond, qp);2917		process_vendor_flag(dev, &flags,2918				    MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC, true,2919				    qp);2920		process_vendor_flag(dev, &flags,2921				    MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_MC, true,2922				    qp);2923	}2924 2925	if (qp->type == IB_QPT_RC)2926		process_vendor_flag(dev, &flags,2927				    MLX5_QP_FLAG_PACKET_BASED_CREDIT_MODE,2928				    MLX5_CAP_GEN(mdev, qp_packet_based), qp);2929 2930	process_vendor_flag(dev, &flags, MLX5_QP_FLAG_BFREG_INDEX, true, qp);2931	process_vendor_flag(dev, &flags, MLX5_QP_FLAG_UAR_PAGE_INDEX, true, qp);2932 2933	cond = qp->flags_en & ~(MLX5_QP_FLAG_TUNNEL_OFFLOADS |2934				MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_UC |2935				MLX5_QP_FLAG_TIR_ALLOW_SELF_LB_MC);2936	if (attr->rwq_ind_tbl && cond) {2937		mlx5_ib_dbg(dev, "RSS RAW QP has unsupported flags 0x%X\n",2938			    cond);2939		return -EINVAL;2940	}2941 2942	if (flags)2943		mlx5_ib_dbg(dev, "udata has unsupported flags 0x%X\n", flags);2944 2945	return (flags) ? -EINVAL : 0;2946	}2947 2948static void process_create_flag(struct mlx5_ib_dev *dev, int *flags, int flag,2949				bool cond, struct mlx5_ib_qp *qp)2950{2951	if (!(*flags & flag))2952		return;2953 2954	if (cond) {2955		qp->flags |= flag;2956		*flags &= ~flag;2957		return;2958	}2959 2960	mlx5_ib_dbg(dev, "Verbs create QP flag 0x%X is not supported\n", flag);2961}2962 2963static int process_create_flags(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,2964				struct ib_qp_init_attr *attr)2965{2966	enum ib_qp_type qp_type = qp->type;2967	struct mlx5_core_dev *mdev = dev->mdev;2968	int create_flags = attr->create_flags;2969	bool cond;2970 2971	if (qp_type == MLX5_IB_QPT_DCT)2972		return (create_flags) ? -EINVAL : 0;2973 2974	if (qp_type == IB_QPT_RAW_PACKET && attr->rwq_ind_tbl)2975		return (create_flags) ? -EINVAL : 0;2976 2977	process_create_flag(dev, &create_flags, IB_QP_CREATE_NETIF_QP,2978			    mlx5_get_flow_namespace(dev->mdev,2979						    MLX5_FLOW_NAMESPACE_BYPASS),2980			    qp);2981	process_create_flag(dev, &create_flags,2982			    IB_QP_CREATE_INTEGRITY_EN,2983			    MLX5_CAP_GEN(mdev, sho), qp);2984	process_create_flag(dev, &create_flags,2985			    IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK,2986			    MLX5_CAP_GEN(mdev, block_lb_mc), qp);2987	process_create_flag(dev, &create_flags, IB_QP_CREATE_CROSS_CHANNEL,2988			    MLX5_CAP_GEN(mdev, cd), qp);2989	process_create_flag(dev, &create_flags, IB_QP_CREATE_MANAGED_SEND,2990			    MLX5_CAP_GEN(mdev, cd), qp);2991	process_create_flag(dev, &create_flags, IB_QP_CREATE_MANAGED_RECV,2992			    MLX5_CAP_GEN(mdev, cd), qp);2993 2994	if (qp_type == IB_QPT_UD) {2995		process_create_flag(dev, &create_flags,2996				    IB_QP_CREATE_IPOIB_UD_LSO,2997				    MLX5_CAP_GEN(mdev, ipoib_basic_offloads),2998				    qp);2999		cond = MLX5_CAP_GEN(mdev, port_type) == MLX5_CAP_PORT_TYPE_IB;3000		process_create_flag(dev, &create_flags, IB_QP_CREATE_SOURCE_QPN,3001				    cond, qp);3002	}3003 3004	if (qp_type == IB_QPT_RAW_PACKET) {3005		cond = MLX5_CAP_GEN(mdev, eth_net_offloads) &&3006		       MLX5_CAP_ETH(mdev, scatter_fcs);3007		process_create_flag(dev, &create_flags,3008				    IB_QP_CREATE_SCATTER_FCS, cond, qp);3009 3010		cond = MLX5_CAP_GEN(mdev, eth_net_offloads) &&3011		       MLX5_CAP_ETH(mdev, vlan_cap);3012		process_create_flag(dev, &create_flags,3013				    IB_QP_CREATE_CVLAN_STRIPPING, cond, qp);3014	}3015 3016	process_create_flag(dev, &create_flags,3017			    IB_QP_CREATE_PCI_WRITE_END_PADDING,3018			    MLX5_CAP_GEN(mdev, end_pad), qp);3019 3020	process_create_flag(dev, &create_flags, MLX5_IB_QP_CREATE_SQPN_QP1,3021			    true, qp);3022 3023	if (create_flags) {3024		mlx5_ib_dbg(dev, "Create QP has unsupported flags 0x%X\n",3025			    create_flags);3026		return -EOPNOTSUPP;3027	}3028	return 0;3029}3030 3031static int process_udata_size(struct mlx5_ib_dev *dev,3032			      struct mlx5_create_qp_params *params)3033{3034	size_t ucmd = sizeof(struct mlx5_ib_create_qp);3035	struct ib_udata *udata = params->udata;3036	size_t outlen = udata->outlen;3037	size_t inlen = udata->inlen;3038 3039	params->outlen = min(outlen, sizeof(struct mlx5_ib_create_qp_resp));3040	params->ucmd_size = ucmd;3041	if (!params->is_rss_raw) {3042		/* User has old rdma-core, which doesn't support ECE */3043		size_t min_inlen =3044			offsetof(struct mlx5_ib_create_qp, ece_options);3045 3046		/*3047		 * We will check in check_ucmd_data() that user3048		 * cleared everything after inlen.3049		 */3050		params->inlen = (inlen < min_inlen) ? 0 : min(inlen, ucmd);3051		goto out;3052	}3053 3054	/* RSS RAW QP */3055	if (inlen < offsetofend(struct mlx5_ib_create_qp_rss, flags))3056		return -EINVAL;3057 3058	if (outlen < offsetofend(struct mlx5_ib_create_qp_resp, bfreg_index))3059		return -EINVAL;3060 3061	ucmd = sizeof(struct mlx5_ib_create_qp_rss);3062	params->ucmd_size = ucmd;3063	if (inlen > ucmd && !ib_is_udata_cleared(udata, ucmd, inlen - ucmd))3064		return -EINVAL;3065 3066	params->inlen = min(ucmd, inlen);3067out:3068	if (!params->inlen)3069		mlx5_ib_dbg(dev, "udata is too small\n");3070 3071	return (params->inlen) ? 0 : -EINVAL;3072}3073 3074static int create_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,3075		     struct mlx5_ib_qp *qp,3076		     struct mlx5_create_qp_params *params)3077{3078	int err;3079 3080	if (params->is_rss_raw) {3081		err = create_rss_raw_qp_tir(dev, pd, qp, params);3082		goto out;3083	}3084 3085	switch (qp->type) {3086	case MLX5_IB_QPT_DCT:3087		err = create_dct(dev, pd, qp, params);3088		break;3089	case MLX5_IB_QPT_DCI:3090		err = create_dci(dev, pd, qp, params);3091		break;3092	case IB_QPT_XRC_TGT:3093		err = create_xrc_tgt_qp(dev, qp, params);3094		break;3095	case IB_QPT_GSI:3096		err = mlx5_ib_create_gsi(pd, qp, params->attr);3097		break;3098	case MLX5_IB_QPT_HW_GSI:3099		rdma_restrack_no_track(&qp->ibqp.res);3100		fallthrough;3101	case MLX5_IB_QPT_REG_UMR:3102	default:3103		if (params->udata)3104			err = create_user_qp(dev, pd, qp, params);3105		else3106			err = create_kernel_qp(dev, pd, qp, params);3107	}3108 3109out:3110	if (err) {3111		mlx5_ib_err(dev, "Create QP type %d failed\n", qp->type);3112		return err;3113	}3114 3115	if (is_qp0(qp->type))3116		qp->ibqp.qp_num = 0;3117	else if (is_qp1(qp->type))3118		qp->ibqp.qp_num = 1;3119	else3120		qp->ibqp.qp_num = qp->trans_qp.base.mqp.qpn;3121 3122	mlx5_ib_dbg(dev,3123		"QP type %d, ib qpn 0x%X, mlx qpn 0x%x, rcqn 0x%x, scqn 0x%x, ece 0x%x\n",3124		qp->type, qp->ibqp.qp_num, qp->trans_qp.base.mqp.qpn,3125		params->attr->recv_cq ? to_mcq(params->attr->recv_cq)->mcq.cqn :3126					-1,3127		params->attr->send_cq ? to_mcq(params->attr->send_cq)->mcq.cqn :3128					-1,3129		params->resp.ece_options);3130 3131	return 0;3132}3133 3134static int check_qp_attr(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,3135			 struct ib_qp_init_attr *attr)3136{3137	int ret = 0;3138 3139	switch (qp->type) {3140	case MLX5_IB_QPT_DCT:3141		ret = (!attr->srq || !attr->recv_cq) ? -EINVAL : 0;3142		break;3143	case MLX5_IB_QPT_DCI:3144		ret = (attr->cap.max_recv_wr || attr->cap.max_recv_sge) ?3145			      -EINVAL :3146			      0;3147		break;3148	case IB_QPT_RAW_PACKET:3149		ret = (attr->rwq_ind_tbl && attr->send_cq) ? -EINVAL : 0;3150		break;3151	default:3152		break;3153	}3154 3155	if (ret)3156		mlx5_ib_dbg(dev, "QP type %d has wrong attributes\n", qp->type);3157 3158	return ret;3159}3160 3161static int get_qp_uidx(struct mlx5_ib_qp *qp,3162		       struct mlx5_create_qp_params *params)3163{3164	struct mlx5_ib_create_qp *ucmd = params->ucmd;3165	struct ib_udata *udata = params->udata;3166	struct mlx5_ib_ucontext *ucontext = rdma_udata_to_drv_context(3167		udata, struct mlx5_ib_ucontext, ibucontext);3168 3169	if (params->is_rss_raw)3170		return 0;3171 3172	return get_qp_user_index(ucontext, ucmd, sizeof(*ucmd), &params->uidx);3173}3174 3175static int mlx5_ib_destroy_dct(struct mlx5_ib_qp *mqp)3176{3177	struct mlx5_ib_dev *dev = to_mdev(mqp->ibqp.device);3178 3179	if (mqp->state == IB_QPS_RTR) {3180		int err;3181 3182		err = mlx5_core_destroy_dct(dev, &mqp->dct.mdct);3183		if (err) {3184			mlx5_ib_warn(dev, "failed to destroy DCT %d\n", err);3185			return err;3186		}3187	}3188 3189	kfree(mqp->dct.in);3190	return 0;3191}3192 3193static int check_ucmd_data(struct mlx5_ib_dev *dev,3194			   struct mlx5_create_qp_params *params)3195{3196	struct ib_udata *udata = params->udata;3197	size_t size, last;3198	int ret;3199 3200	if (params->is_rss_raw)3201		/*3202		 * These QPs don't have "reserved" field in their3203		 * create_qp input struct, so their data is always valid.3204		 */3205		last = sizeof(struct mlx5_ib_create_qp_rss);3206	else3207		last = offsetof(struct mlx5_ib_create_qp, reserved);3208 3209	if (udata->inlen <= last)3210		return 0;3211 3212	/*3213	 * User provides different create_qp structures based on the3214	 * flow and we need to know if he cleared memory after our3215	 * struct create_qp ends.3216	 */3217	size = udata->inlen - last;3218	ret = ib_is_udata_cleared(params->udata, last, size);3219	if (!ret)3220		mlx5_ib_dbg(3221			dev,3222			"udata is not cleared, inlen = %zu, ucmd = %zu, last = %zu, size = %zu\n",3223			udata->inlen, params->ucmd_size, last, size);3224	return ret ? 0 : -EINVAL;3225}3226 3227int mlx5_ib_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr,3228		      struct ib_udata *udata)3229{3230	struct mlx5_create_qp_params params = {};3231	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);3232	struct mlx5_ib_qp *qp = to_mqp(ibqp);3233	struct ib_pd *pd = ibqp->pd;3234	enum ib_qp_type type;3235	int err;3236 3237	err = mlx5_ib_dev_res_srq_init(dev);3238	if (err)3239		return err;3240 3241	err = check_qp_type(dev, attr, &type);3242	if (err)3243		return err;3244 3245	err = check_valid_flow(dev, pd, attr, udata);3246	if (err)3247		return err;3248 3249	params.udata = udata;3250	params.uidx = MLX5_IB_DEFAULT_UIDX;3251	params.attr = attr;3252	params.is_rss_raw = !!attr->rwq_ind_tbl;3253 3254	if (udata) {3255		err = process_udata_size(dev, &params);3256		if (err)3257			return err;3258 3259		err = check_ucmd_data(dev, &params);3260		if (err)3261			return err;3262 3263		params.ucmd = kzalloc(params.ucmd_size, GFP_KERNEL);3264		if (!params.ucmd)3265			return -ENOMEM;3266 3267		err = ib_copy_from_udata(params.ucmd, udata, params.inlen);3268		if (err)3269			goto free_ucmd;3270	}3271 3272	mutex_init(&qp->mutex);3273	qp->type = type;3274	if (udata) {3275		err = process_vendor_flags(dev, qp, params.ucmd, attr);3276		if (err)3277			goto free_ucmd;3278 3279		err = get_qp_uidx(qp, &params);3280		if (err)3281			goto free_ucmd;3282	}3283	err = process_create_flags(dev, qp, attr);3284	if (err)3285		goto free_ucmd;3286 3287	err = check_qp_attr(dev, qp, attr);3288	if (err)3289		goto free_ucmd;3290 3291	err = create_qp(dev, pd, qp, &params);3292	if (err)3293		goto free_ucmd;3294 3295	kfree(params.ucmd);3296	params.ucmd = NULL;3297 3298	if (udata)3299		/*3300		 * It is safe to copy response for all user create QP flows,3301		 * including MLX5_IB_QPT_DCT, which doesn't need it.3302		 * In that case, resp will be filled with zeros.3303		 */3304		err = ib_copy_to_udata(udata, &params.resp, params.outlen);3305	if (err)3306		goto destroy_qp;3307 3308	return 0;3309 3310destroy_qp:3311	switch (qp->type) {3312	case MLX5_IB_QPT_DCT:3313		mlx5_ib_destroy_dct(qp);3314		break;3315	case IB_QPT_GSI:3316		mlx5_ib_destroy_gsi(qp);3317		break;3318	default:3319		destroy_qp_common(dev, qp, udata);3320	}3321 3322free_ucmd:3323	kfree(params.ucmd);3324	return err;3325}3326 3327int mlx5_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata)3328{3329	struct mlx5_ib_dev *dev = to_mdev(qp->device);3330	struct mlx5_ib_qp *mqp = to_mqp(qp);3331 3332	if (mqp->type == IB_QPT_GSI)3333		return mlx5_ib_destroy_gsi(mqp);3334 3335	if (mqp->type == MLX5_IB_QPT_DCT)3336		return mlx5_ib_destroy_dct(mqp);3337 3338	destroy_qp_common(dev, mqp, udata);3339	return 0;3340}3341 3342static int set_qpc_atomic_flags(struct mlx5_ib_qp *qp,3343				const struct ib_qp_attr *attr, int attr_mask,3344				void *qpc)3345{3346	struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.device);3347	u8 dest_rd_atomic;3348	u32 access_flags;3349 3350	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)3351		dest_rd_atomic = attr->max_dest_rd_atomic;3352	else3353		dest_rd_atomic = qp->trans_qp.resp_depth;3354 3355	if (attr_mask & IB_QP_ACCESS_FLAGS)3356		access_flags = attr->qp_access_flags;3357	else3358		access_flags = qp->trans_qp.atomic_rd_en;3359 3360	if (!dest_rd_atomic)3361		access_flags &= IB_ACCESS_REMOTE_WRITE;3362 3363	MLX5_SET(qpc, qpc, rre, !!(access_flags & IB_ACCESS_REMOTE_READ));3364 3365	if (access_flags & IB_ACCESS_REMOTE_ATOMIC) {3366		int atomic_mode;3367 3368		atomic_mode = get_atomic_mode(dev, qp->type);3369		if (atomic_mode < 0)3370			return -EOPNOTSUPP;3371 3372		MLX5_SET(qpc, qpc, rae, 1);3373		MLX5_SET(qpc, qpc, atomic_mode, atomic_mode);3374	}3375 3376	MLX5_SET(qpc, qpc, rwe, !!(access_flags & IB_ACCESS_REMOTE_WRITE));3377	return 0;3378}3379 3380enum {3381	MLX5_PATH_FLAG_FL	= 1 << 0,3382	MLX5_PATH_FLAG_FREE_AR	= 1 << 1,3383	MLX5_PATH_FLAG_COUNTER	= 1 << 2,3384};3385 3386static int mlx5_to_ib_rate_map(u8 rate)3387{3388	static const int rates[] = { IB_RATE_PORT_CURRENT, IB_RATE_56_GBPS,3389				     IB_RATE_25_GBPS,	   IB_RATE_100_GBPS,3390				     IB_RATE_200_GBPS,	   IB_RATE_50_GBPS,3391				     IB_RATE_400_GBPS };3392 3393	if (rate < ARRAY_SIZE(rates))3394		return rates[rate];3395 3396	return rate - MLX5_STAT_RATE_OFFSET;3397}3398 3399static int ib_to_mlx5_rate_map(u8 rate)3400{3401	switch (rate) {3402	case IB_RATE_PORT_CURRENT:3403		return 0;3404	case IB_RATE_56_GBPS:3405		return 1;3406	case IB_RATE_25_GBPS:3407		return 2;3408	case IB_RATE_100_GBPS:3409		return 3;3410	case IB_RATE_200_GBPS:3411		return 4;3412	case IB_RATE_50_GBPS:3413		return 5;3414	case IB_RATE_400_GBPS:3415		return 6;3416	default:3417		return rate + MLX5_STAT_RATE_OFFSET;3418	}3419 3420	return 0;3421}3422 3423static int ib_rate_to_mlx5(struct mlx5_ib_dev *dev, u8 rate)3424{3425	u32 stat_rate_support;3426 3427	if (rate == IB_RATE_PORT_CURRENT)3428		return 0;3429 3430	if (rate < IB_RATE_2_5_GBPS || rate > IB_RATE_800_GBPS)3431		return -EINVAL;3432 3433	stat_rate_support = MLX5_CAP_GEN(dev->mdev, stat_rate_support);3434	while (rate != IB_RATE_PORT_CURRENT &&3435	       !(1 << ib_to_mlx5_rate_map(rate) & stat_rate_support))3436		--rate;3437 3438	return ib_to_mlx5_rate_map(rate);3439}3440 3441static int modify_raw_packet_eth_prio(struct mlx5_core_dev *dev,3442				      struct mlx5_ib_sq *sq, u8 sl,3443				      struct ib_pd *pd)3444{3445	void *in;3446	void *tisc;3447	int inlen;3448	int err;3449 3450	inlen = MLX5_ST_SZ_BYTES(modify_tis_in);3451	in = kvzalloc(inlen, GFP_KERNEL);3452	if (!in)3453		return -ENOMEM;3454 3455	MLX5_SET(modify_tis_in, in, bitmask.prio, 1);3456	MLX5_SET(modify_tis_in, in, uid, to_mpd(pd)->uid);3457 3458	tisc = MLX5_ADDR_OF(modify_tis_in, in, ctx);3459	MLX5_SET(tisc, tisc, prio, ((sl & 0x7) << 1));3460 3461	err = mlx5_core_modify_tis(dev, sq->tisn, in);3462 3463	kvfree(in);3464 3465	return err;3466}3467 3468static int modify_raw_packet_tx_affinity(struct mlx5_core_dev *dev,3469					 struct mlx5_ib_sq *sq, u8 tx_affinity,3470					 struct ib_pd *pd)3471{3472	void *in;3473	void *tisc;3474	int inlen;3475	int err;3476 3477	inlen = MLX5_ST_SZ_BYTES(modify_tis_in);3478	in = kvzalloc(inlen, GFP_KERNEL);3479	if (!in)3480		return -ENOMEM;3481 3482	MLX5_SET(modify_tis_in, in, bitmask.lag_tx_port_affinity, 1);3483	MLX5_SET(modify_tis_in, in, uid, to_mpd(pd)->uid);3484 3485	tisc = MLX5_ADDR_OF(modify_tis_in, in, ctx);3486	MLX5_SET(tisc, tisc, lag_tx_port_affinity, tx_affinity);3487 3488	err = mlx5_core_modify_tis(dev, sq->tisn, in);3489 3490	kvfree(in);3491 3492	return err;3493}3494 3495static void mlx5_set_path_udp_sport(void *path, const struct rdma_ah_attr *ah,3496				    u32 lqpn, u32 rqpn)3497 3498{3499	u32 fl = ah->grh.flow_label;3500 3501	if (!fl)3502		fl = rdma_calc_flow_label(lqpn, rqpn);3503 3504	MLX5_SET(ads, path, udp_sport, rdma_flow_label_to_udp_sport(fl));3505}3506 3507static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,3508			 const struct rdma_ah_attr *ah, void *path, u8 port,3509			 int attr_mask, u32 path_flags,3510			 const struct ib_qp_attr *attr, bool alt)3511{3512	const struct ib_global_route *grh = rdma_ah_read_grh(ah);3513	int err;3514	enum ib_gid_type gid_type;3515	u8 ah_flags = rdma_ah_get_ah_flags(ah);3516	u8 sl = rdma_ah_get_sl(ah);3517 3518	if (attr_mask & IB_QP_PKEY_INDEX)3519		MLX5_SET(ads, path, pkey_index,3520			 alt ? attr->alt_pkey_index : attr->pkey_index);3521 3522	if (ah_flags & IB_AH_GRH) {3523		const struct ib_port_immutable *immutable;3524 3525		immutable = ib_port_immutable_read(&dev->ib_dev, port);3526		if (grh->sgid_index >= immutable->gid_tbl_len) {3527			pr_err("sgid_index (%u) too large. max is %d\n",3528			       grh->sgid_index,3529			       immutable->gid_tbl_len);3530			return -EINVAL;3531		}3532	}3533 3534	if (ah->type == RDMA_AH_ATTR_TYPE_ROCE) {3535		if (!(ah_flags & IB_AH_GRH))3536			return -EINVAL;3537 3538		ether_addr_copy(MLX5_ADDR_OF(ads, path, rmac_47_32),3539				ah->roce.dmac);3540		if ((qp->type == IB_QPT_RC ||3541		     qp->type == IB_QPT_UC ||3542		     qp->type == IB_QPT_XRC_INI ||3543		     qp->type == IB_QPT_XRC_TGT) &&3544		    (grh->sgid_attr->gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) &&3545		    (attr_mask & IB_QP_DEST_QPN))3546			mlx5_set_path_udp_sport(path, ah,3547						qp->ibqp.qp_num,3548						attr->dest_qp_num);3549		MLX5_SET(ads, path, eth_prio, sl & 0x7);3550		gid_type = ah->grh.sgid_attr->gid_type;3551		if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)3552			MLX5_SET(ads, path, dscp, grh->traffic_class >> 2);3553	} else {3554		MLX5_SET(ads, path, fl, !!(path_flags & MLX5_PATH_FLAG_FL));3555		MLX5_SET(ads, path, free_ar,3556			 !!(path_flags & MLX5_PATH_FLAG_FREE_AR));3557		MLX5_SET(ads, path, rlid, rdma_ah_get_dlid(ah));3558		MLX5_SET(ads, path, mlid, rdma_ah_get_path_bits(ah));3559		MLX5_SET(ads, path, grh, !!(ah_flags & IB_AH_GRH));3560		MLX5_SET(ads, path, sl, sl);3561	}3562 3563	if (ah_flags & IB_AH_GRH) {3564		MLX5_SET(ads, path, src_addr_index, grh->sgid_index);3565		MLX5_SET(ads, path, hop_limit, grh->hop_limit);3566		MLX5_SET(ads, path, tclass, grh->traffic_class);3567		MLX5_SET(ads, path, flow_label, grh->flow_label);3568		memcpy(MLX5_ADDR_OF(ads, path, rgid_rip), grh->dgid.raw,3569		       sizeof(grh->dgid.raw));3570	}3571 3572	err = ib_rate_to_mlx5(dev, rdma_ah_get_static_rate(ah));3573	if (err < 0)3574		return err;3575	MLX5_SET(ads, path, stat_rate, err);3576	MLX5_SET(ads, path, vhca_port_num, port);3577 3578	if (attr_mask & IB_QP_TIMEOUT)3579		MLX5_SET(ads, path, ack_timeout,3580			 alt ? attr->alt_timeout : attr->timeout);3581 3582	if ((qp->type == IB_QPT_RAW_PACKET) && qp->sq.wqe_cnt)3583		return modify_raw_packet_eth_prio(dev->mdev,3584						  &qp->raw_packet_qp.sq,3585						  sl & 0xf, qp->ibqp.pd);3586 3587	return 0;3588}3589 3590static enum mlx5_qp_optpar opt_mask[MLX5_QP_NUM_STATE][MLX5_QP_NUM_STATE][MLX5_QP_ST_MAX] = {3591	[MLX5_QP_STATE_INIT] = {3592		[MLX5_QP_STATE_INIT] = {3593			[MLX5_QP_ST_RC] = MLX5_QP_OPTPAR_RRE		|3594					  MLX5_QP_OPTPAR_RAE		|3595					  MLX5_QP_OPTPAR_RWE		|3596					  MLX5_QP_OPTPAR_PKEY_INDEX	|3597					  MLX5_QP_OPTPAR_PRI_PORT	|3598					  MLX5_QP_OPTPAR_LAG_TX_AFF,3599			[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_RWE		|3600					  MLX5_QP_OPTPAR_PKEY_INDEX	|3601					  MLX5_QP_OPTPAR_PRI_PORT	|3602					  MLX5_QP_OPTPAR_LAG_TX_AFF,3603			[MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_PKEY_INDEX	|3604					  MLX5_QP_OPTPAR_Q_KEY		|3605					  MLX5_QP_OPTPAR_PRI_PORT,3606			[MLX5_QP_ST_XRC] = MLX5_QP_OPTPAR_RRE		|3607					  MLX5_QP_OPTPAR_RAE		|3608					  MLX5_QP_OPTPAR_RWE		|3609					  MLX5_QP_OPTPAR_PKEY_INDEX	|3610					  MLX5_QP_OPTPAR_PRI_PORT	|3611					  MLX5_QP_OPTPAR_LAG_TX_AFF,3612		},3613		[MLX5_QP_STATE_RTR] = {3614			[MLX5_QP_ST_RC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH  |3615					  MLX5_QP_OPTPAR_RRE            |3616					  MLX5_QP_OPTPAR_RAE            |3617					  MLX5_QP_OPTPAR_RWE            |3618					  MLX5_QP_OPTPAR_PKEY_INDEX	|3619					  MLX5_QP_OPTPAR_LAG_TX_AFF,3620			[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH  |3621					  MLX5_QP_OPTPAR_RWE            |3622					  MLX5_QP_OPTPAR_PKEY_INDEX	|3623					  MLX5_QP_OPTPAR_LAG_TX_AFF,3624			[MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_PKEY_INDEX     |3625					  MLX5_QP_OPTPAR_Q_KEY,3626			[MLX5_QP_ST_MLX] = MLX5_QP_OPTPAR_PKEY_INDEX	|3627					   MLX5_QP_OPTPAR_Q_KEY,3628			[MLX5_QP_ST_XRC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH |3629					  MLX5_QP_OPTPAR_RRE            |3630					  MLX5_QP_OPTPAR_RAE            |3631					  MLX5_QP_OPTPAR_RWE            |3632					  MLX5_QP_OPTPAR_PKEY_INDEX	|3633					  MLX5_QP_OPTPAR_LAG_TX_AFF,3634		},3635	},3636	[MLX5_QP_STATE_RTR] = {3637		[MLX5_QP_STATE_RTS] = {3638			[MLX5_QP_ST_RC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH	|3639					  MLX5_QP_OPTPAR_RRE		|3640					  MLX5_QP_OPTPAR_RAE		|3641					  MLX5_QP_OPTPAR_RWE		|3642					  MLX5_QP_OPTPAR_PM_STATE	|3643					  MLX5_QP_OPTPAR_RNR_TIMEOUT,3644			[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH	|3645					  MLX5_QP_OPTPAR_RWE		|3646					  MLX5_QP_OPTPAR_PM_STATE,3647			[MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_Q_KEY,3648			[MLX5_QP_ST_XRC] = MLX5_QP_OPTPAR_ALT_ADDR_PATH	|3649					  MLX5_QP_OPTPAR_RRE		|3650					  MLX5_QP_OPTPAR_RAE		|3651					  MLX5_QP_OPTPAR_RWE		|3652					  MLX5_QP_OPTPAR_PM_STATE	|3653					  MLX5_QP_OPTPAR_RNR_TIMEOUT,3654		},3655	},3656	[MLX5_QP_STATE_RTS] = {3657		[MLX5_QP_STATE_RTS] = {3658			[MLX5_QP_ST_RC] = MLX5_QP_OPTPAR_RRE		|3659					  MLX5_QP_OPTPAR_RAE		|3660					  MLX5_QP_OPTPAR_RWE		|3661					  MLX5_QP_OPTPAR_RNR_TIMEOUT	|3662					  MLX5_QP_OPTPAR_PM_STATE	|3663					  MLX5_QP_OPTPAR_ALT_ADDR_PATH,3664			[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_RWE		|3665					  MLX5_QP_OPTPAR_PM_STATE	|3666					  MLX5_QP_OPTPAR_ALT_ADDR_PATH,3667			[MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_Q_KEY		|3668					  MLX5_QP_OPTPAR_SRQN		|3669					  MLX5_QP_OPTPAR_CQN_RCV,3670			[MLX5_QP_ST_XRC] = MLX5_QP_OPTPAR_RRE		|3671					  MLX5_QP_OPTPAR_RAE		|3672					  MLX5_QP_OPTPAR_RWE		|3673					  MLX5_QP_OPTPAR_RNR_TIMEOUT	|3674					  MLX5_QP_OPTPAR_PM_STATE	|3675					  MLX5_QP_OPTPAR_ALT_ADDR_PATH,3676		},3677	},3678	[MLX5_QP_STATE_SQER] = {3679		[MLX5_QP_STATE_RTS] = {3680			[MLX5_QP_ST_UD]	 = MLX5_QP_OPTPAR_Q_KEY,3681			[MLX5_QP_ST_MLX] = MLX5_QP_OPTPAR_Q_KEY,3682			[MLX5_QP_ST_UC]	 = MLX5_QP_OPTPAR_RWE,3683			[MLX5_QP_ST_RC]	 = MLX5_QP_OPTPAR_RNR_TIMEOUT	|3684					   MLX5_QP_OPTPAR_RWE		|3685					   MLX5_QP_OPTPAR_RAE		|3686					   MLX5_QP_OPTPAR_RRE,3687			[MLX5_QP_ST_XRC]  = MLX5_QP_OPTPAR_RNR_TIMEOUT	|3688					   MLX5_QP_OPTPAR_RWE		|3689					   MLX5_QP_OPTPAR_RAE		|3690					   MLX5_QP_OPTPAR_RRE,3691		},3692	},3693	[MLX5_QP_STATE_SQD] = {3694		[MLX5_QP_STATE_RTS] = {3695			[MLX5_QP_ST_UD] = MLX5_QP_OPTPAR_Q_KEY,3696			[MLX5_QP_ST_MLX] = MLX5_QP_OPTPAR_Q_KEY,3697			[MLX5_QP_ST_UC] = MLX5_QP_OPTPAR_RWE,3698			[MLX5_QP_ST_RC] = MLX5_QP_OPTPAR_RNR_TIMEOUT	|3699					  MLX5_QP_OPTPAR_RWE		|3700					  MLX5_QP_OPTPAR_RAE		|3701					  MLX5_QP_OPTPAR_RRE,3702		},3703	},3704};3705 3706static int ib_nr_to_mlx5_nr(int ib_mask)3707{3708	switch (ib_mask) {3709	case IB_QP_STATE:3710		return 0;3711	case IB_QP_CUR_STATE:3712		return 0;3713	case IB_QP_EN_SQD_ASYNC_NOTIFY:3714		return 0;3715	case IB_QP_ACCESS_FLAGS:3716		return MLX5_QP_OPTPAR_RWE | MLX5_QP_OPTPAR_RRE |3717			MLX5_QP_OPTPAR_RAE;3718	case IB_QP_PKEY_INDEX:3719		return MLX5_QP_OPTPAR_PKEY_INDEX;3720	case IB_QP_PORT:3721		return MLX5_QP_OPTPAR_PRI_PORT;3722	case IB_QP_QKEY:3723		return MLX5_QP_OPTPAR_Q_KEY;3724	case IB_QP_AV:3725		return MLX5_QP_OPTPAR_PRIMARY_ADDR_PATH |3726			MLX5_QP_OPTPAR_PRI_PORT;3727	case IB_QP_PATH_MTU:3728		return 0;3729	case IB_QP_TIMEOUT:3730		return MLX5_QP_OPTPAR_ACK_TIMEOUT;3731	case IB_QP_RETRY_CNT:3732		return MLX5_QP_OPTPAR_RETRY_COUNT;3733	case IB_QP_RNR_RETRY:3734		return MLX5_QP_OPTPAR_RNR_RETRY;3735	case IB_QP_RQ_PSN:3736		return 0;3737	case IB_QP_MAX_QP_RD_ATOMIC:3738		return MLX5_QP_OPTPAR_SRA_MAX;3739	case IB_QP_ALT_PATH:3740		return MLX5_QP_OPTPAR_ALT_ADDR_PATH;3741	case IB_QP_MIN_RNR_TIMER:3742		return MLX5_QP_OPTPAR_RNR_TIMEOUT;3743	case IB_QP_SQ_PSN:3744		return 0;3745	case IB_QP_MAX_DEST_RD_ATOMIC:3746		return MLX5_QP_OPTPAR_RRA_MAX | MLX5_QP_OPTPAR_RWE |3747			MLX5_QP_OPTPAR_RRE | MLX5_QP_OPTPAR_RAE;3748	case IB_QP_PATH_MIG_STATE:3749		return MLX5_QP_OPTPAR_PM_STATE;3750	case IB_QP_CAP:3751		return 0;3752	case IB_QP_DEST_QPN:3753		return 0;3754	}3755	return 0;3756}3757 3758static int ib_mask_to_mlx5_opt(int ib_mask)3759{3760	int result = 0;3761	int i;3762 3763	for (i = 0; i < 8 * sizeof(int); i++) {3764		if ((1 << i) & ib_mask)3765			result |= ib_nr_to_mlx5_nr(1 << i);3766	}3767 3768	return result;3769}3770 3771static int modify_raw_packet_qp_rq(3772	struct mlx5_ib_dev *dev, struct mlx5_ib_rq *rq, int new_state,3773	const struct mlx5_modify_raw_qp_param *raw_qp_param, struct ib_pd *pd)3774{3775	void *in;3776	void *rqc;3777	int inlen;3778	int err;3779 3780	inlen = MLX5_ST_SZ_BYTES(modify_rq_in);3781	in = kvzalloc(inlen, GFP_KERNEL);3782	if (!in)3783		return -ENOMEM;3784 3785	MLX5_SET(modify_rq_in, in, rq_state, rq->state);3786	MLX5_SET(modify_rq_in, in, uid, to_mpd(pd)->uid);3787 3788	rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);3789	MLX5_SET(rqc, rqc, state, new_state);3790 3791	if (raw_qp_param->set_mask & MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID) {3792		if (MLX5_CAP_GEN(dev->mdev, modify_rq_counter_set_id)) {3793			MLX5_SET64(modify_rq_in, in, modify_bitmask,3794				   MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID);3795			MLX5_SET(rqc, rqc, counter_set_id, raw_qp_param->rq_q_ctr_id);3796		} else3797			dev_info_once(3798				&dev->ib_dev.dev,3799				"RAW PACKET QP counters are not supported on current FW\n");3800	}3801 3802	err = mlx5_core_modify_rq(dev->mdev, rq->base.mqp.qpn, in);3803	if (err)3804		goto out;3805 3806	rq->state = new_state;3807 3808out:3809	kvfree(in);3810	return err;3811}3812 3813static int modify_raw_packet_qp_sq(3814	struct mlx5_core_dev *dev, struct mlx5_ib_sq *sq, int new_state,3815	const struct mlx5_modify_raw_qp_param *raw_qp_param, struct ib_pd *pd)3816{3817	struct mlx5_ib_qp *ibqp = sq->base.container_mibqp;3818	struct mlx5_rate_limit old_rl = ibqp->rl;3819	struct mlx5_rate_limit new_rl = old_rl;3820	bool new_rate_added = false;3821	u16 rl_index = 0;3822	void *in;3823	void *sqc;3824	int inlen;3825	int err;3826 3827	inlen = MLX5_ST_SZ_BYTES(modify_sq_in);3828	in = kvzalloc(inlen, GFP_KERNEL);3829	if (!in)3830		return -ENOMEM;3831 3832	MLX5_SET(modify_sq_in, in, uid, to_mpd(pd)->uid);3833	MLX5_SET(modify_sq_in, in, sq_state, sq->state);3834 3835	sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);3836	MLX5_SET(sqc, sqc, state, new_state);3837 3838	if (raw_qp_param->set_mask & MLX5_RAW_QP_RATE_LIMIT) {3839		if (new_state != MLX5_SQC_STATE_RDY)3840			pr_warn("%s: Rate limit can only be changed when SQ is moving to RDY\n",3841				__func__);3842		else3843			new_rl = raw_qp_param->rl;3844	}3845 3846	if (!mlx5_rl_are_equal(&old_rl, &new_rl)) {3847		if (new_rl.rate) {3848			err = mlx5_rl_add_rate(dev, &rl_index, &new_rl);3849			if (err) {3850				pr_err("Failed configuring rate limit(err %d): \3851				       rate %u, max_burst_sz %u, typical_pkt_sz %u\n",3852				       err, new_rl.rate, new_rl.max_burst_sz,3853				       new_rl.typical_pkt_sz);3854 3855				goto out;3856			}3857			new_rate_added = true;3858		}3859 3860		MLX5_SET64(modify_sq_in, in, modify_bitmask, 1);3861		/* index 0 means no limit */3862		MLX5_SET(sqc, sqc, packet_pacing_rate_limit_index, rl_index);3863	}3864 3865	err = mlx5_core_modify_sq(dev, sq->base.mqp.qpn, in);3866	if (err) {3867		/* Remove new rate from table if failed */3868		if (new_rate_added)3869			mlx5_rl_remove_rate(dev, &new_rl);3870		goto out;3871	}3872 3873	/* Only remove the old rate after new rate was set */3874	if ((old_rl.rate && !mlx5_rl_are_equal(&old_rl, &new_rl)) ||3875	    (new_state != MLX5_SQC_STATE_RDY)) {3876		mlx5_rl_remove_rate(dev, &old_rl);3877		if (new_state != MLX5_SQC_STATE_RDY)3878			memset(&new_rl, 0, sizeof(new_rl));3879	}3880 3881	ibqp->rl = new_rl;3882	sq->state = new_state;3883 3884out:3885	kvfree(in);3886	return err;3887}3888 3889static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,3890				const struct mlx5_modify_raw_qp_param *raw_qp_param,3891				u8 tx_affinity)3892{3893	struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;3894	struct mlx5_ib_rq *rq = &raw_packet_qp->rq;3895	struct mlx5_ib_sq *sq = &raw_packet_qp->sq;3896	int modify_rq = !!qp->rq.wqe_cnt;3897	int modify_sq = !!qp->sq.wqe_cnt;3898	int rq_state;3899	int sq_state;3900	int err;3901 3902	switch (raw_qp_param->operation) {3903	case MLX5_CMD_OP_RST2INIT_QP:3904		rq_state = MLX5_RQC_STATE_RDY;3905		sq_state = MLX5_SQC_STATE_RST;3906		break;3907	case MLX5_CMD_OP_2ERR_QP:3908		rq_state = MLX5_RQC_STATE_ERR;3909		sq_state = MLX5_SQC_STATE_ERR;3910		break;3911	case MLX5_CMD_OP_2RST_QP:3912		rq_state = MLX5_RQC_STATE_RST;3913		sq_state = MLX5_SQC_STATE_RST;3914		break;3915	case MLX5_CMD_OP_RTR2RTS_QP:3916	case MLX5_CMD_OP_RTS2RTS_QP:3917		if (raw_qp_param->set_mask & ~MLX5_RAW_QP_RATE_LIMIT)3918			return -EINVAL;3919 3920		modify_rq = 0;3921		sq_state = MLX5_SQC_STATE_RDY;3922		break;3923	case MLX5_CMD_OP_INIT2INIT_QP:3924	case MLX5_CMD_OP_INIT2RTR_QP:3925		if (raw_qp_param->set_mask)3926			return -EINVAL;3927		else3928			return 0;3929	default:3930		WARN_ON(1);3931		return -EINVAL;3932	}3933 3934	if (modify_rq) {3935		err =  modify_raw_packet_qp_rq(dev, rq, rq_state, raw_qp_param,3936					       qp->ibqp.pd);3937		if (err)3938			return err;3939	}3940 3941	if (modify_sq) {3942		struct mlx5_flow_handle *flow_rule;3943 3944		if (tx_affinity) {3945			err = modify_raw_packet_tx_affinity(dev->mdev, sq,3946							    tx_affinity,3947							    qp->ibqp.pd);3948			if (err)3949				return err;3950		}3951 3952		flow_rule = create_flow_rule_vport_sq(dev, sq,3953						      raw_qp_param->port);3954		if (IS_ERR(flow_rule))3955			return PTR_ERR(flow_rule);3956 3957		err = modify_raw_packet_qp_sq(dev->mdev, sq, sq_state,3958					      raw_qp_param, qp->ibqp.pd);3959		if (err) {3960			if (flow_rule)3961				mlx5_del_flow_rules(flow_rule);3962			return err;3963		}3964 3965		if (flow_rule) {3966			destroy_flow_rule_vport_sq(sq);3967			sq->flow_rule = flow_rule;3968		}3969 3970		return err;3971	}3972 3973	return 0;3974}3975 3976static unsigned int get_tx_affinity_rr(struct mlx5_ib_dev *dev,3977				       struct ib_udata *udata)3978{3979	struct mlx5_ib_ucontext *ucontext = rdma_udata_to_drv_context(3980		udata, struct mlx5_ib_ucontext, ibucontext);3981	u8 port_num = mlx5_core_native_port_num(dev->mdev) - 1;3982	atomic_t *tx_port_affinity;3983 3984	if (ucontext)3985		tx_port_affinity = &ucontext->tx_port_affinity;3986	else3987		tx_port_affinity = &dev->port[port_num].roce.tx_port_affinity;3988 3989	return (unsigned int)atomic_add_return(1, tx_port_affinity) %3990		(dev->lag_active ? dev->lag_ports : MLX5_CAP_GEN(dev->mdev, num_lag_ports)) + 1;3991}3992 3993static bool qp_supports_affinity(struct mlx5_ib_qp *qp)3994{3995	if ((qp->type == IB_QPT_RC) || (qp->type == IB_QPT_UD) ||3996	    (qp->type == IB_QPT_UC) || (qp->type == IB_QPT_RAW_PACKET) ||3997	    (qp->type == IB_QPT_XRC_INI) || (qp->type == IB_QPT_XRC_TGT) ||3998	    (qp->type == MLX5_IB_QPT_DCI))3999		return true;4000	return false;4001}4002 4003static unsigned int get_tx_affinity(struct ib_qp *qp,4004				    const struct ib_qp_attr *attr,4005				    int attr_mask, u8 init,4006				    struct ib_udata *udata)4007{4008	struct mlx5_ib_ucontext *ucontext = rdma_udata_to_drv_context(4009		udata, struct mlx5_ib_ucontext, ibucontext);4010	struct mlx5_ib_dev *dev = to_mdev(qp->device);4011	struct mlx5_ib_qp *mqp = to_mqp(qp);4012	struct mlx5_ib_qp_base *qp_base;4013	unsigned int tx_affinity;4014 4015	if (!(mlx5_ib_lag_should_assign_affinity(dev) &&4016	      qp_supports_affinity(mqp)))4017		return 0;4018 4019	if (mqp->flags & MLX5_IB_QP_CREATE_SQPN_QP1)4020		tx_affinity = mqp->gsi_lag_port;4021	else if (init)4022		tx_affinity = get_tx_affinity_rr(dev, udata);4023	else if ((attr_mask & IB_QP_AV) && attr->xmit_slave)4024		tx_affinity =4025			mlx5_lag_get_slave_port(dev->mdev, attr->xmit_slave);4026	else4027		return 0;4028 4029	qp_base = &mqp->trans_qp.base;4030	if (ucontext)4031		mlx5_ib_dbg(dev, "Set tx affinity 0x%x to qpn 0x%x ucontext %p\n",4032			    tx_affinity, qp_base->mqp.qpn, ucontext);4033	else4034		mlx5_ib_dbg(dev, "Set tx affinity 0x%x to qpn 0x%x\n",4035			    tx_affinity, qp_base->mqp.qpn);4036	return tx_affinity;4037}4038 4039static int __mlx5_ib_qp_set_raw_qp_counter(struct mlx5_ib_qp *qp, u32 set_id,4040					   struct mlx5_core_dev *mdev)4041{4042	struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;4043	struct mlx5_ib_rq *rq = &raw_packet_qp->rq;4044	u32 in[MLX5_ST_SZ_DW(modify_rq_in)] = {};4045	void *rqc;4046 4047	if (!qp->rq.wqe_cnt)4048		return 0;4049 4050	MLX5_SET(modify_rq_in, in, rq_state, rq->state);4051	MLX5_SET(modify_rq_in, in, uid, to_mpd(qp->ibqp.pd)->uid);4052 4053	rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);4054	MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RDY);4055 4056	MLX5_SET64(modify_rq_in, in, modify_bitmask,4057		   MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID);4058	MLX5_SET(rqc, rqc, counter_set_id, set_id);4059 4060	return mlx5_core_modify_rq(mdev, rq->base.mqp.qpn, in);4061}4062 4063static int __mlx5_ib_qp_set_counter(struct ib_qp *qp,4064				    struct rdma_counter *counter)4065{4066	struct mlx5_ib_dev *dev = to_mdev(qp->device);4067	u32 in[MLX5_ST_SZ_DW(rts2rts_qp_in)] = {};4068	struct mlx5_ib_qp *mqp = to_mqp(qp);4069	struct mlx5_ib_qp_base *base;4070	u32 set_id;4071	u32 *qpc;4072 4073	if (counter)4074		set_id = counter->id;4075	else4076		set_id = mlx5_ib_get_counters_id(dev, mqp->port - 1);4077 4078	if (mqp->type == IB_QPT_RAW_PACKET)4079		return __mlx5_ib_qp_set_raw_qp_counter(mqp, set_id, dev->mdev);4080 4081	base = &mqp->trans_qp.base;4082	MLX5_SET(rts2rts_qp_in, in, opcode, MLX5_CMD_OP_RTS2RTS_QP);4083	MLX5_SET(rts2rts_qp_in, in, qpn, base->mqp.qpn);4084	MLX5_SET(rts2rts_qp_in, in, uid, base->mqp.uid);4085	MLX5_SET(rts2rts_qp_in, in, opt_param_mask,4086		 MLX5_QP_OPTPAR_COUNTER_SET_ID);4087 4088	qpc = MLX5_ADDR_OF(rts2rts_qp_in, in, qpc);4089	MLX5_SET(qpc, qpc, counter_set_id, set_id);4090	return mlx5_cmd_exec_in(dev->mdev, rts2rts_qp, in);4091}4092 4093static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,4094			       const struct ib_qp_attr *attr, int attr_mask,4095			       enum ib_qp_state cur_state,4096			       enum ib_qp_state new_state,4097			       const struct mlx5_ib_modify_qp *ucmd,4098			       struct mlx5_ib_modify_qp_resp *resp,4099			       struct ib_udata *udata)4100{4101	static const u16 optab[MLX5_QP_NUM_STATE][MLX5_QP_NUM_STATE] = {4102		[MLX5_QP_STATE_RST] = {4103			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,4104			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,4105			[MLX5_QP_STATE_INIT]	= MLX5_CMD_OP_RST2INIT_QP,4106		},4107		[MLX5_QP_STATE_INIT]  = {4108			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,4109			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,4110			[MLX5_QP_STATE_INIT]	= MLX5_CMD_OP_INIT2INIT_QP,4111			[MLX5_QP_STATE_RTR]	= MLX5_CMD_OP_INIT2RTR_QP,4112		},4113		[MLX5_QP_STATE_RTR]   = {4114			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,4115			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,4116			[MLX5_QP_STATE_RTS]	= MLX5_CMD_OP_RTR2RTS_QP,4117		},4118		[MLX5_QP_STATE_RTS]   = {4119			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,4120			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,4121			[MLX5_QP_STATE_RTS]	= MLX5_CMD_OP_RTS2RTS_QP,4122		},4123		[MLX5_QP_STATE_SQD] = {4124			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,4125			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,4126			[MLX5_QP_STATE_RTS]	= MLX5_CMD_OP_SQD_RTS_QP,4127		},4128		[MLX5_QP_STATE_SQER] = {4129			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,4130			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,4131			[MLX5_QP_STATE_RTS]	= MLX5_CMD_OP_SQERR2RTS_QP,4132		},4133		[MLX5_QP_STATE_ERR] = {4134			[MLX5_QP_STATE_RST]	= MLX5_CMD_OP_2RST_QP,4135			[MLX5_QP_STATE_ERR]	= MLX5_CMD_OP_2ERR_QP,4136		}4137	};4138 4139	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);4140	struct mlx5_ib_qp *qp = to_mqp(ibqp);4141	struct mlx5_ib_qp_base *base = &qp->trans_qp.base;4142	struct mlx5_ib_cq *send_cq, *recv_cq;4143	struct mlx5_ib_pd *pd;4144	enum mlx5_qp_state mlx5_cur, mlx5_new;4145	void *qpc, *pri_path, *alt_path;4146	enum mlx5_qp_optpar optpar = 0;4147	u32 set_id = 0;4148	int mlx5_st;4149	int err;4150	u16 op;4151	u8 tx_affinity = 0;4152 4153	mlx5_st = to_mlx5_st(qp->type);4154	if (mlx5_st < 0)4155		return -EINVAL;4156 4157	qpc = kzalloc(MLX5_ST_SZ_BYTES(qpc), GFP_KERNEL);4158	if (!qpc)4159		return -ENOMEM;4160 4161	pd = to_mpd(qp->ibqp.pd);4162	MLX5_SET(qpc, qpc, st, mlx5_st);4163 4164	if (!(attr_mask & IB_QP_PATH_MIG_STATE)) {4165		MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);4166	} else {4167		switch (attr->path_mig_state) {4168		case IB_MIG_MIGRATED:4169			MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);4170			break;4171		case IB_MIG_REARM:4172			MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_REARM);4173			break;4174		case IB_MIG_ARMED:4175			MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_ARMED);4176			break;4177		}4178	}4179 4180	tx_affinity = get_tx_affinity(ibqp, attr, attr_mask,4181				      cur_state == IB_QPS_RESET &&4182				      new_state == IB_QPS_INIT, udata);4183 4184	MLX5_SET(qpc, qpc, lag_tx_port_affinity, tx_affinity);4185	if (tx_affinity && new_state == IB_QPS_RTR &&4186	    MLX5_CAP_GEN(dev->mdev, init2_lag_tx_port_affinity))4187		optpar |= MLX5_QP_OPTPAR_LAG_TX_AFF;4188 4189	if (is_sqp(qp->type)) {4190		MLX5_SET(qpc, qpc, mtu, IB_MTU_256);4191		MLX5_SET(qpc, qpc, log_msg_max, 8);4192	} else if ((qp->type == IB_QPT_UD &&4193		    !(qp->flags & IB_QP_CREATE_SOURCE_QPN)) ||4194		   qp->type == MLX5_IB_QPT_REG_UMR) {4195		MLX5_SET(qpc, qpc, mtu, IB_MTU_4096);4196		MLX5_SET(qpc, qpc, log_msg_max, 12);4197	} else if (attr_mask & IB_QP_PATH_MTU) {4198		if (attr->path_mtu < IB_MTU_256 ||4199		    attr->path_mtu > IB_MTU_4096) {4200			mlx5_ib_warn(dev, "invalid mtu %d\n", attr->path_mtu);4201			err = -EINVAL;4202			goto out;4203		}4204		MLX5_SET(qpc, qpc, mtu, attr->path_mtu);4205		MLX5_SET(qpc, qpc, log_msg_max,4206			 MLX5_CAP_GEN(dev->mdev, log_max_msg));4207	}4208 4209	if (attr_mask & IB_QP_DEST_QPN)4210		MLX5_SET(qpc, qpc, remote_qpn, attr->dest_qp_num);4211 4212	pri_path = MLX5_ADDR_OF(qpc, qpc, primary_address_path);4213	alt_path = MLX5_ADDR_OF(qpc, qpc, secondary_address_path);4214 4215	if (attr_mask & IB_QP_PKEY_INDEX)4216		MLX5_SET(ads, pri_path, pkey_index, attr->pkey_index);4217 4218	/* todo implement counter_index functionality */4219 4220	if (dev->ib_dev.type == RDMA_DEVICE_TYPE_SMI && is_qp0(qp->type)) {4221		MLX5_SET(ads, pri_path, vhca_port_num,4222			 smi_to_native_portnum(dev, qp->port));4223		if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR)4224			MLX5_SET(ads, pri_path, plane_index, qp->port);4225	} else if (is_sqp(qp->type))4226		MLX5_SET(ads, pri_path, vhca_port_num, qp->port);4227 4228	if (attr_mask & IB_QP_PORT)4229		MLX5_SET(ads, pri_path, vhca_port_num, attr->port_num);4230 4231	if (attr_mask & IB_QP_AV) {4232		err = mlx5_set_path(dev, qp, &attr->ah_attr, pri_path,4233				    attr_mask & IB_QP_PORT ? attr->port_num :4234							     qp->port,4235				    attr_mask, 0, attr, false);4236		if (err)4237			goto out;4238	}4239 4240	if (attr_mask & IB_QP_TIMEOUT)4241		MLX5_SET(ads, pri_path, ack_timeout, attr->timeout);4242 4243	if (attr_mask & IB_QP_ALT_PATH) {4244		err = mlx5_set_path(dev, qp, &attr->alt_ah_attr, alt_path,4245				    attr->alt_port_num,4246				    attr_mask | IB_QP_PKEY_INDEX |4247					    IB_QP_TIMEOUT,4248				    0, attr, true);4249		if (err)4250			goto out;4251	}4252 4253	get_cqs(qp->type, qp->ibqp.send_cq, qp->ibqp.recv_cq,4254		&send_cq, &recv_cq);4255 4256	MLX5_SET(qpc, qpc, pd, pd ? pd->pdn : to_mpd(dev->devr.p0)->pdn);4257	if (send_cq)4258		MLX5_SET(qpc, qpc, cqn_snd, send_cq->mcq.cqn);4259	if (recv_cq)4260		MLX5_SET(qpc, qpc, cqn_rcv, recv_cq->mcq.cqn);4261 4262	MLX5_SET(qpc, qpc, log_ack_req_freq, MLX5_IB_ACK_REQ_FREQ);4263 4264	if (attr_mask & IB_QP_RNR_RETRY)4265		MLX5_SET(qpc, qpc, rnr_retry, attr->rnr_retry);4266 4267	if (attr_mask & IB_QP_RETRY_CNT)4268		MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt);4269 4270	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && attr->max_rd_atomic)4271		MLX5_SET(qpc, qpc, log_sra_max, fls(attr->max_rd_atomic - 1));4272 4273	if (attr_mask & IB_QP_SQ_PSN)4274		MLX5_SET(qpc, qpc, next_send_psn, attr->sq_psn);4275 4276	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && attr->max_dest_rd_atomic)4277		MLX5_SET(qpc, qpc, log_rra_max,4278			 fls(attr->max_dest_rd_atomic - 1));4279 4280	if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) {4281		err = set_qpc_atomic_flags(qp, attr, attr_mask, qpc);4282		if (err)4283			goto out;4284	}4285 4286	if (attr_mask & IB_QP_MIN_RNR_TIMER)4287		MLX5_SET(qpc, qpc, min_rnr_nak, attr->min_rnr_timer);4288 4289	if (attr_mask & IB_QP_RQ_PSN)4290		MLX5_SET(qpc, qpc, next_rcv_psn, attr->rq_psn);4291 4292	if (attr_mask & IB_QP_QKEY)4293		MLX5_SET(qpc, qpc, q_key, attr->qkey);4294 4295	if (qp->rq.wqe_cnt && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)4296		MLX5_SET64(qpc, qpc, dbr_addr, qp->db.dma);4297 4298	if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {4299		u8 port_num = (attr_mask & IB_QP_PORT ? attr->port_num :4300			       qp->port) - 1;4301 4302		/* Underlay port should be used - index 0 function per port */4303		if (qp->flags & IB_QP_CREATE_SOURCE_QPN)4304			port_num = 0;4305 4306		if (ibqp->counter)4307			set_id = ibqp->counter->id;4308		else4309			set_id = mlx5_ib_get_counters_id(dev, port_num);4310		MLX5_SET(qpc, qpc, counter_set_id, set_id);4311	}4312 4313	if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)4314		MLX5_SET(qpc, qpc, rlky, 1);4315 4316	if (qp->flags & MLX5_IB_QP_CREATE_SQPN_QP1)4317		MLX5_SET(qpc, qpc, deth_sqpn, 1);4318 4319	mlx5_cur = to_mlx5_state(cur_state);4320	mlx5_new = to_mlx5_state(new_state);4321 4322	if (mlx5_cur >= MLX5_QP_NUM_STATE || mlx5_new >= MLX5_QP_NUM_STATE ||4323	    !optab[mlx5_cur][mlx5_new]) {4324		err = -EINVAL;4325		goto out;4326	}4327 4328	op = optab[mlx5_cur][mlx5_new];4329	optpar |= ib_mask_to_mlx5_opt(attr_mask);4330	optpar &= opt_mask[mlx5_cur][mlx5_new][mlx5_st];4331 4332	if (qp->type == IB_QPT_RAW_PACKET ||4333	    qp->flags & IB_QP_CREATE_SOURCE_QPN) {4334		struct mlx5_modify_raw_qp_param raw_qp_param = {};4335 4336		raw_qp_param.operation = op;4337		if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {4338			raw_qp_param.rq_q_ctr_id = set_id;4339			raw_qp_param.set_mask |= MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID;4340		}4341 4342		if (attr_mask & IB_QP_PORT)4343			raw_qp_param.port = attr->port_num;4344 4345		if (attr_mask & IB_QP_RATE_LIMIT) {4346			raw_qp_param.rl.rate = attr->rate_limit;4347 4348			if (ucmd->burst_info.max_burst_sz) {4349				if (attr->rate_limit &&4350				    MLX5_CAP_QOS(dev->mdev, packet_pacing_burst_bound)) {4351					raw_qp_param.rl.max_burst_sz =4352						ucmd->burst_info.max_burst_sz;4353				} else {4354					err = -EINVAL;4355					goto out;4356				}4357			}4358 4359			if (ucmd->burst_info.typical_pkt_sz) {4360				if (attr->rate_limit &&4361				    MLX5_CAP_QOS(dev->mdev, packet_pacing_typical_size)) {4362					raw_qp_param.rl.typical_pkt_sz =4363						ucmd->burst_info.typical_pkt_sz;4364				} else {4365					err = -EINVAL;4366					goto out;4367				}4368			}4369 4370			raw_qp_param.set_mask |= MLX5_RAW_QP_RATE_LIMIT;4371		}4372 4373		err = modify_raw_packet_qp(dev, qp, &raw_qp_param, tx_affinity);4374	} else {4375		if (udata) {4376			/* For the kernel flows, the resp will stay zero */4377			resp->ece_options =4378				MLX5_CAP_GEN(dev->mdev, ece_support) ?4379					ucmd->ece_options : 0;4380			resp->response_length = sizeof(*resp);4381		}4382		err = mlx5_core_qp_modify(dev, op, optpar, qpc, &base->mqp,4383					  &resp->ece_options);4384	}4385 4386	if (err)4387		goto out;4388 4389	qp->state = new_state;4390 4391	if (attr_mask & IB_QP_ACCESS_FLAGS)4392		qp->trans_qp.atomic_rd_en = attr->qp_access_flags;4393	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)4394		qp->trans_qp.resp_depth = attr->max_dest_rd_atomic;4395	if (attr_mask & IB_QP_PORT)4396		qp->port = attr->port_num;4397	if (attr_mask & IB_QP_ALT_PATH)4398		qp->trans_qp.alt_port = attr->alt_port_num;4399 4400	/*4401	 * If we moved a kernel QP to RESET, clean up all old CQ4402	 * entries and reinitialize the QP.4403	 */4404	if (new_state == IB_QPS_RESET &&4405	    !ibqp->uobject && qp->type != IB_QPT_XRC_TGT) {4406		mlx5_ib_cq_clean(recv_cq, base->mqp.qpn,4407				 ibqp->srq ? to_msrq(ibqp->srq) : NULL);4408		if (send_cq != recv_cq)4409			mlx5_ib_cq_clean(send_cq, base->mqp.qpn, NULL);4410 4411		qp->rq.head = 0;4412		qp->rq.tail = 0;4413		qp->sq.head = 0;4414		qp->sq.tail = 0;4415		qp->sq.cur_post = 0;4416		if (qp->sq.wqe_cnt)4417			qp->sq.cur_edge = get_sq_edge(&qp->sq, 0);4418		qp->sq.last_poll = 0;4419		qp->db.db[MLX5_RCV_DBR] = 0;4420		qp->db.db[MLX5_SND_DBR] = 0;4421	}4422 4423	if ((new_state == IB_QPS_RTS) && qp->counter_pending) {4424		err = __mlx5_ib_qp_set_counter(ibqp, ibqp->counter);4425		if (!err)4426			qp->counter_pending = 0;4427	}4428 4429out:4430	kfree(qpc);4431	return err;4432}4433 4434static inline bool is_valid_mask(int mask, int req, int opt)4435{4436	if ((mask & req) != req)4437		return false;4438 4439	if (mask & ~(req | opt))4440		return false;4441 4442	return true;4443}4444 4445/* check valid transition for driver QP types4446 * for now the only QP type that this function supports is DCI4447 */4448static bool modify_dci_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state new_state,4449				enum ib_qp_attr_mask attr_mask)4450{4451	int req = IB_QP_STATE;4452	int opt = 0;4453 4454	if (new_state == IB_QPS_RESET) {4455		return is_valid_mask(attr_mask, req, opt);4456	} else if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {4457		req |= IB_QP_PKEY_INDEX | IB_QP_PORT;4458		return is_valid_mask(attr_mask, req, opt);4459	} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {4460		opt = IB_QP_PKEY_INDEX | IB_QP_PORT;4461		return is_valid_mask(attr_mask, req, opt);4462	} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {4463		req |= IB_QP_PATH_MTU;4464		opt = IB_QP_PKEY_INDEX | IB_QP_AV;4465		return is_valid_mask(attr_mask, req, opt);4466	} else if (cur_state == IB_QPS_RTR && new_state == IB_QPS_RTS) {4467		req |= IB_QP_TIMEOUT | IB_QP_RETRY_CNT | IB_QP_RNR_RETRY |4468		       IB_QP_MAX_QP_RD_ATOMIC | IB_QP_SQ_PSN;4469		opt = IB_QP_MIN_RNR_TIMER;4470		return is_valid_mask(attr_mask, req, opt);4471	} else if (cur_state == IB_QPS_RTS && new_state == IB_QPS_RTS) {4472		opt = IB_QP_MIN_RNR_TIMER;4473		return is_valid_mask(attr_mask, req, opt);4474	} else if (cur_state != IB_QPS_RESET && new_state == IB_QPS_ERR) {4475		return is_valid_mask(attr_mask, req, opt);4476	}4477	return false;4478}4479 4480/* mlx5_ib_modify_dct: modify a DCT QP4481 * valid transitions are:4482 * RESET to INIT: must set access_flags, pkey_index and port4483 * INIT  to RTR : must set min_rnr_timer, tclass, flow_label,4484 *			   mtu, gid_index and hop_limit4485 * Other transitions and attributes are illegal4486 */4487static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr,4488			      int attr_mask, struct mlx5_ib_modify_qp *ucmd,4489			      struct ib_udata *udata)4490{4491	struct mlx5_ib_qp *qp = to_mqp(ibqp);4492	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);4493	enum ib_qp_state cur_state, new_state;4494	int required = IB_QP_STATE;4495	void *dctc;4496	int err;4497 4498	if (!(attr_mask & IB_QP_STATE))4499		return -EINVAL;4500 4501	cur_state = qp->state;4502	new_state = attr->qp_state;4503 4504	dctc = MLX5_ADDR_OF(create_dct_in, qp->dct.in, dct_context_entry);4505	if (MLX5_CAP_GEN(dev->mdev, ece_support) && ucmd->ece_options)4506		/*4507		 * DCT doesn't initialize QP till modify command is executed,4508		 * so we need to overwrite previously set ECE field if user4509		 * provided any value except zero, which means not set/not4510		 * valid.4511		 */4512		MLX5_SET(dctc, dctc, ece, ucmd->ece_options);4513 4514	if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {4515		u16 set_id;4516 4517		required |= IB_QP_ACCESS_FLAGS | IB_QP_PKEY_INDEX | IB_QP_PORT;4518		if (!is_valid_mask(attr_mask, required, 0))4519			return -EINVAL;4520 4521		if (attr->port_num == 0 ||4522		    attr->port_num > dev->num_ports) {4523			mlx5_ib_dbg(dev, "invalid port number %d. number of ports is %d\n",4524				    attr->port_num, dev->num_ports);4525			return -EINVAL;4526		}4527		if (attr->qp_access_flags & IB_ACCESS_REMOTE_READ)4528			MLX5_SET(dctc, dctc, rre, 1);4529		if (attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE)4530			MLX5_SET(dctc, dctc, rwe, 1);4531		if (attr->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC) {4532			int atomic_mode;4533 4534			atomic_mode = get_atomic_mode(dev, MLX5_IB_QPT_DCT);4535			if (atomic_mode < 0)4536				return -EOPNOTSUPP;4537 4538			MLX5_SET(dctc, dctc, atomic_mode, atomic_mode);4539			MLX5_SET(dctc, dctc, rae, 1);4540		}4541		MLX5_SET(dctc, dctc, pkey_index, attr->pkey_index);4542		if (mlx5_lag_is_active(dev->mdev))4543			MLX5_SET(dctc, dctc, port,4544				 get_tx_affinity_rr(dev, udata));4545		else4546			MLX5_SET(dctc, dctc, port, attr->port_num);4547 4548		set_id = mlx5_ib_get_counters_id(dev, attr->port_num - 1);4549		MLX5_SET(dctc, dctc, counter_set_id, set_id);4550	} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {4551		struct mlx5_ib_modify_qp_resp resp = {};4552		u32 out[MLX5_ST_SZ_DW(create_dct_out)] = {};4553		u32 min_resp_len = offsetofend(typeof(resp), dctn);4554 4555		if (udata->outlen < min_resp_len)4556			return -EINVAL;4557		/*4558		 * If we don't have enough space for the ECE options,4559		 * simply indicate it with resp.response_length.4560		 */4561		resp.response_length = (udata->outlen < sizeof(resp)) ?4562					       min_resp_len :4563					       sizeof(resp);4564 4565		required |= IB_QP_MIN_RNR_TIMER | IB_QP_AV | IB_QP_PATH_MTU;4566		if (!is_valid_mask(attr_mask, required, 0))4567			return -EINVAL;4568		MLX5_SET(dctc, dctc, min_rnr_nak, attr->min_rnr_timer);4569		MLX5_SET(dctc, dctc, tclass, attr->ah_attr.grh.traffic_class);4570		MLX5_SET(dctc, dctc, flow_label, attr->ah_attr.grh.flow_label);4571		MLX5_SET(dctc, dctc, mtu, attr->path_mtu);4572		MLX5_SET(dctc, dctc, my_addr_index, attr->ah_attr.grh.sgid_index);4573		MLX5_SET(dctc, dctc, hop_limit, attr->ah_attr.grh.hop_limit);4574		if (attr->ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE)4575			MLX5_SET(dctc, dctc, eth_prio, attr->ah_attr.sl & 0x7);4576 4577		err = mlx5_core_create_dct(dev, &qp->dct.mdct, qp->dct.in,4578					   MLX5_ST_SZ_BYTES(create_dct_in), out,4579					   sizeof(out));4580		err = mlx5_cmd_check(dev->mdev, err, qp->dct.in, out);4581		if (err)4582			return err;4583		resp.dctn = qp->dct.mdct.mqp.qpn;4584		if (MLX5_CAP_GEN(dev->mdev, ece_support))4585			resp.ece_options = MLX5_GET(create_dct_out, out, ece);4586		err = ib_copy_to_udata(udata, &resp, resp.response_length);4587		if (err) {4588			mlx5_core_destroy_dct(dev, &qp->dct.mdct);4589			return err;4590		}4591	} else {4592		mlx5_ib_warn(dev, "Modify DCT: Invalid transition from %d to %d\n", cur_state, new_state);4593		return -EINVAL;4594	}4595 4596	qp->state = new_state;4597	return 0;4598}4599 4600static bool mlx5_ib_modify_qp_allowed(struct mlx5_ib_dev *dev,4601				      struct mlx5_ib_qp *qp)4602{4603	if (dev->profile != &raw_eth_profile)4604		return true;4605 4606	if (qp->type == IB_QPT_RAW_PACKET || qp->type == MLX5_IB_QPT_REG_UMR)4607		return true;4608 4609	return false;4610}4611 4612static int validate_rd_atomic(struct mlx5_ib_dev *dev, struct ib_qp_attr *attr,4613			      int attr_mask, enum ib_qp_type qp_type)4614{4615	int log_max_ra_res;4616	int log_max_ra_req;4617 4618	if (qp_type == MLX5_IB_QPT_DCI) {4619		log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev,4620						   log_max_ra_res_dc);4621		log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev,4622						   log_max_ra_req_dc);4623	} else {4624		log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev,4625						   log_max_ra_res_qp);4626		log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev,4627						   log_max_ra_req_qp);4628	}4629 4630	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC &&4631	    attr->max_rd_atomic > log_max_ra_res) {4632		mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n",4633			    attr->max_rd_atomic);4634		return false;4635	}4636 4637	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC &&4638	    attr->max_dest_rd_atomic > log_max_ra_req) {4639		mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n",4640			    attr->max_dest_rd_atomic);4641		return false;4642	}4643	return true;4644}4645 4646int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,4647		      int attr_mask, struct ib_udata *udata)4648{4649	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);4650	struct mlx5_ib_modify_qp_resp resp = {};4651	struct mlx5_ib_qp *qp = to_mqp(ibqp);4652	struct mlx5_ib_modify_qp ucmd = {};4653	enum ib_qp_type qp_type;4654	enum ib_qp_state cur_state, new_state;4655	int err = -EINVAL;4656 4657	if (!mlx5_ib_modify_qp_allowed(dev, qp))4658		return -EOPNOTSUPP;4659 4660	if (attr_mask & ~(IB_QP_ATTR_STANDARD_BITS | IB_QP_RATE_LIMIT))4661		return -EOPNOTSUPP;4662 4663	if (ibqp->rwq_ind_tbl)4664		return -ENOSYS;4665 4666	if (udata && udata->inlen) {4667		if (udata->inlen < offsetofend(typeof(ucmd), ece_options))4668			return -EINVAL;4669 4670		if (udata->inlen > sizeof(ucmd) &&4671		    !ib_is_udata_cleared(udata, sizeof(ucmd),4672					 udata->inlen - sizeof(ucmd)))4673			return -EOPNOTSUPP;4674 4675		if (ib_copy_from_udata(&ucmd, udata,4676				       min(udata->inlen, sizeof(ucmd))))4677			return -EFAULT;4678 4679		if (ucmd.comp_mask ||4680		    memchr_inv(&ucmd.burst_info.reserved, 0,4681			       sizeof(ucmd.burst_info.reserved)))4682			return -EOPNOTSUPP;4683 4684	}4685 4686	if (qp->type == IB_QPT_GSI)4687		return mlx5_ib_gsi_modify_qp(ibqp, attr, attr_mask);4688 4689	qp_type = (qp->type == MLX5_IB_QPT_HW_GSI) ? IB_QPT_GSI : qp->type;4690 4691	if (qp_type == MLX5_IB_QPT_DCT)4692		return mlx5_ib_modify_dct(ibqp, attr, attr_mask, &ucmd, udata);4693 4694	mutex_lock(&qp->mutex);4695 4696	cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;4697	new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state;4698 4699	if (qp->flags & IB_QP_CREATE_SOURCE_QPN) {4700		if (attr_mask & ~(IB_QP_STATE | IB_QP_CUR_STATE)) {4701			mlx5_ib_dbg(dev, "invalid attr_mask 0x%x when underlay QP is used\n",4702				    attr_mask);4703			goto out;4704		}4705	} else if (qp_type != MLX5_IB_QPT_REG_UMR &&4706		   qp_type != MLX5_IB_QPT_DCI &&4707		   !ib_modify_qp_is_ok(cur_state, new_state, qp_type,4708				       attr_mask)) {4709		mlx5_ib_dbg(dev, "invalid QP state transition from %d to %d, qp_type %d, attr_mask 0x%x\n",4710			    cur_state, new_state, qp->type, attr_mask);4711		goto out;4712	} else if (qp_type == MLX5_IB_QPT_DCI &&4713		   !modify_dci_qp_is_ok(cur_state, new_state, attr_mask)) {4714		mlx5_ib_dbg(dev, "invalid QP state transition from %d to %d, qp_type %d, attr_mask 0x%x\n",4715			    cur_state, new_state, qp_type, attr_mask);4716		goto out;4717	}4718 4719	if ((attr_mask & IB_QP_PORT) &&4720	    (attr->port_num == 0 ||4721	     attr->port_num > dev->num_ports)) {4722		mlx5_ib_dbg(dev, "invalid port number %d. number of ports is %d\n",4723			    attr->port_num, dev->num_ports);4724		goto out;4725	}4726 4727	if ((attr_mask & IB_QP_PKEY_INDEX) &&4728	    attr->pkey_index >= dev->pkey_table_len) {4729		mlx5_ib_dbg(dev, "invalid pkey index %d\n", attr->pkey_index);4730		goto out;4731	}4732 4733	if (!validate_rd_atomic(dev, attr, attr_mask, qp_type))4734		goto out;4735 4736	if (cur_state == new_state && cur_state == IB_QPS_RESET) {4737		err = 0;4738		goto out;4739	}4740 4741	err = __mlx5_ib_modify_qp(ibqp, attr, attr_mask, cur_state,4742				  new_state, &ucmd, &resp, udata);4743 4744	/* resp.response_length is set in ECE supported flows only */4745	if (!err && resp.response_length &&4746	    udata->outlen >= resp.response_length)4747		/* Return -EFAULT to the user and expect him to destroy QP. */4748		err = ib_copy_to_udata(udata, &resp, resp.response_length);4749 4750out:4751	mutex_unlock(&qp->mutex);4752	return err;4753}4754 4755static inline enum ib_qp_state to_ib_qp_state(enum mlx5_qp_state mlx5_state)4756{4757	switch (mlx5_state) {4758	case MLX5_QP_STATE_RST:      return IB_QPS_RESET;4759	case MLX5_QP_STATE_INIT:     return IB_QPS_INIT;4760	case MLX5_QP_STATE_RTR:      return IB_QPS_RTR;4761	case MLX5_QP_STATE_RTS:      return IB_QPS_RTS;4762	case MLX5_QP_STATE_SQ_DRAINING:4763	case MLX5_QP_STATE_SQD:      return IB_QPS_SQD;4764	case MLX5_QP_STATE_SQER:     return IB_QPS_SQE;4765	case MLX5_QP_STATE_ERR:      return IB_QPS_ERR;4766	default:		     return -1;4767	}4768}4769 4770static inline enum ib_mig_state to_ib_mig_state(int mlx5_mig_state)4771{4772	switch (mlx5_mig_state) {4773	case MLX5_QP_PM_ARMED:		return IB_MIG_ARMED;4774	case MLX5_QP_PM_REARM:		return IB_MIG_REARM;4775	case MLX5_QP_PM_MIGRATED:	return IB_MIG_MIGRATED;4776	default: return -1;4777	}4778}4779 4780static void to_rdma_ah_attr(struct mlx5_ib_dev *ibdev,4781			    struct rdma_ah_attr *ah_attr, void *path)4782{4783	int port = MLX5_GET(ads, path, vhca_port_num);4784	int static_rate;4785 4786	memset(ah_attr, 0, sizeof(*ah_attr));4787 4788	if (!port || port > ibdev->num_ports)4789		return;4790 4791	ah_attr->type = rdma_ah_find_type(&ibdev->ib_dev, port);4792 4793	rdma_ah_set_port_num(ah_attr, port);4794	rdma_ah_set_sl(ah_attr, MLX5_GET(ads, path, sl));4795 4796	rdma_ah_set_dlid(ah_attr, MLX5_GET(ads, path, rlid));4797	rdma_ah_set_path_bits(ah_attr, MLX5_GET(ads, path, mlid));4798 4799	static_rate = MLX5_GET(ads, path, stat_rate);4800	rdma_ah_set_static_rate(ah_attr, mlx5_to_ib_rate_map(static_rate));4801	if (MLX5_GET(ads, path, grh) ||4802	    ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) {4803		rdma_ah_set_grh(ah_attr, NULL, MLX5_GET(ads, path, flow_label),4804				MLX5_GET(ads, path, src_addr_index),4805				MLX5_GET(ads, path, hop_limit),4806				MLX5_GET(ads, path, tclass));4807		rdma_ah_set_dgid_raw(ah_attr, MLX5_ADDR_OF(ads, path, rgid_rip));4808	}4809}4810 4811static int query_raw_packet_qp_sq_state(struct mlx5_ib_dev *dev,4812					struct mlx5_ib_sq *sq,4813					u8 *sq_state)4814{4815	int err;4816 4817	err = mlx5_core_query_sq_state(dev->mdev, sq->base.mqp.qpn, sq_state);4818	if (err)4819		goto out;4820	sq->state = *sq_state;4821 4822out:4823	return err;4824}4825 4826static int query_raw_packet_qp_rq_state(struct mlx5_ib_dev *dev,4827					struct mlx5_ib_rq *rq,4828					u8 *rq_state)4829{4830	void *out;4831	void *rqc;4832	int inlen;4833	int err;4834 4835	inlen = MLX5_ST_SZ_BYTES(query_rq_out);4836	out = kvzalloc(inlen, GFP_KERNEL);4837	if (!out)4838		return -ENOMEM;4839 4840	err = mlx5_core_query_rq(dev->mdev, rq->base.mqp.qpn, out);4841	if (err)4842		goto out;4843 4844	rqc = MLX5_ADDR_OF(query_rq_out, out, rq_context);4845	*rq_state = MLX5_GET(rqc, rqc, state);4846	rq->state = *rq_state;4847 4848out:4849	kvfree(out);4850	return err;4851}4852 4853static int sqrq_state_to_qp_state(u8 sq_state, u8 rq_state,4854				  struct mlx5_ib_qp *qp, u8 *qp_state)4855{4856	static const u8 sqrq_trans[MLX5_RQ_NUM_STATE][MLX5_SQ_NUM_STATE] = {4857		[MLX5_RQC_STATE_RST] = {4858			[MLX5_SQC_STATE_RST]	= IB_QPS_RESET,4859			[MLX5_SQC_STATE_RDY]	= MLX5_QP_STATE_BAD,4860			[MLX5_SQC_STATE_ERR]	= MLX5_QP_STATE_BAD,4861			[MLX5_SQ_STATE_NA]	= IB_QPS_RESET,4862		},4863		[MLX5_RQC_STATE_RDY] = {4864			[MLX5_SQC_STATE_RST]	= MLX5_QP_STATE,4865			[MLX5_SQC_STATE_RDY]	= MLX5_QP_STATE,4866			[MLX5_SQC_STATE_ERR]	= IB_QPS_SQE,4867			[MLX5_SQ_STATE_NA]	= MLX5_QP_STATE,4868		},4869		[MLX5_RQC_STATE_ERR] = {4870			[MLX5_SQC_STATE_RST]    = MLX5_QP_STATE_BAD,4871			[MLX5_SQC_STATE_RDY]	= MLX5_QP_STATE_BAD,4872			[MLX5_SQC_STATE_ERR]	= IB_QPS_ERR,4873			[MLX5_SQ_STATE_NA]	= IB_QPS_ERR,4874		},4875		[MLX5_RQ_STATE_NA] = {4876			[MLX5_SQC_STATE_RST]    = MLX5_QP_STATE,4877			[MLX5_SQC_STATE_RDY]	= MLX5_QP_STATE,4878			[MLX5_SQC_STATE_ERR]	= MLX5_QP_STATE,4879			[MLX5_SQ_STATE_NA]	= MLX5_QP_STATE_BAD,4880		},4881	};4882 4883	*qp_state = sqrq_trans[rq_state][sq_state];4884 4885	if (*qp_state == MLX5_QP_STATE_BAD) {4886		WARN(1, "Buggy Raw Packet QP state, SQ 0x%x state: 0x%x, RQ 0x%x state: 0x%x",4887		     qp->raw_packet_qp.sq.base.mqp.qpn, sq_state,4888		     qp->raw_packet_qp.rq.base.mqp.qpn, rq_state);4889		return -EINVAL;4890	}4891 4892	if (*qp_state == MLX5_QP_STATE)4893		*qp_state = qp->state;4894 4895	return 0;4896}4897 4898static int query_raw_packet_qp_state(struct mlx5_ib_dev *dev,4899				     struct mlx5_ib_qp *qp,4900				     u8 *raw_packet_qp_state)4901{4902	struct mlx5_ib_raw_packet_qp *raw_packet_qp = &qp->raw_packet_qp;4903	struct mlx5_ib_sq *sq = &raw_packet_qp->sq;4904	struct mlx5_ib_rq *rq = &raw_packet_qp->rq;4905	int err;4906	u8 sq_state = MLX5_SQ_STATE_NA;4907	u8 rq_state = MLX5_RQ_STATE_NA;4908 4909	if (qp->sq.wqe_cnt) {4910		err = query_raw_packet_qp_sq_state(dev, sq, &sq_state);4911		if (err)4912			return err;4913	}4914 4915	if (qp->rq.wqe_cnt) {4916		err = query_raw_packet_qp_rq_state(dev, rq, &rq_state);4917		if (err)4918			return err;4919	}4920 4921	return sqrq_state_to_qp_state(sq_state, rq_state, qp,4922				      raw_packet_qp_state);4923}4924 4925static int query_qp_attr(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,4926			 struct ib_qp_attr *qp_attr)4927{4928	int outlen = MLX5_ST_SZ_BYTES(query_qp_out);4929	void *qpc, *pri_path, *alt_path;4930	u32 *outb;4931	int err;4932 4933	outb = kzalloc(outlen, GFP_KERNEL);4934	if (!outb)4935		return -ENOMEM;4936 4937	err = mlx5_core_qp_query(dev, &qp->trans_qp.base.mqp, outb, outlen,4938				 false);4939	if (err)4940		goto out;4941 4942	qpc = MLX5_ADDR_OF(query_qp_out, outb, qpc);4943 4944	qp->state = to_ib_qp_state(MLX5_GET(qpc, qpc, state));4945	if (MLX5_GET(qpc, qpc, state) == MLX5_QP_STATE_SQ_DRAINING)4946		qp_attr->sq_draining = 1;4947 4948	qp_attr->path_mtu = MLX5_GET(qpc, qpc, mtu);4949	qp_attr->path_mig_state = to_ib_mig_state(MLX5_GET(qpc, qpc, pm_state));4950	qp_attr->qkey = MLX5_GET(qpc, qpc, q_key);4951	qp_attr->rq_psn = MLX5_GET(qpc, qpc, next_rcv_psn);4952	qp_attr->sq_psn = MLX5_GET(qpc, qpc, next_send_psn);4953	qp_attr->dest_qp_num = MLX5_GET(qpc, qpc, remote_qpn);4954 4955	if (MLX5_GET(qpc, qpc, rre))4956		qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_READ;4957	if (MLX5_GET(qpc, qpc, rwe))4958		qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_WRITE;4959	if (MLX5_GET(qpc, qpc, rae))4960		qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_ATOMIC;4961 4962	qp_attr->max_rd_atomic = 1 << MLX5_GET(qpc, qpc, log_sra_max);4963	qp_attr->max_dest_rd_atomic = 1 << MLX5_GET(qpc, qpc, log_rra_max);4964	qp_attr->min_rnr_timer = MLX5_GET(qpc, qpc, min_rnr_nak);4965	qp_attr->retry_cnt = MLX5_GET(qpc, qpc, retry_count);4966	qp_attr->rnr_retry = MLX5_GET(qpc, qpc, rnr_retry);4967 4968	pri_path = MLX5_ADDR_OF(qpc, qpc, primary_address_path);4969	alt_path = MLX5_ADDR_OF(qpc, qpc, secondary_address_path);4970 4971	if (qp->type == IB_QPT_RC || qp->type == IB_QPT_UC ||4972	    qp->type == IB_QPT_XRC_INI || qp->type == IB_QPT_XRC_TGT) {4973		to_rdma_ah_attr(dev, &qp_attr->ah_attr, pri_path);4974		to_rdma_ah_attr(dev, &qp_attr->alt_ah_attr, alt_path);4975		qp_attr->alt_pkey_index = MLX5_GET(ads, alt_path, pkey_index);4976		qp_attr->alt_port_num = MLX5_GET(ads, alt_path, vhca_port_num);4977	}4978 4979	qp_attr->pkey_index = MLX5_GET(ads, pri_path, pkey_index);4980	qp_attr->port_num = MLX5_GET(ads, pri_path, vhca_port_num);4981	qp_attr->timeout = MLX5_GET(ads, pri_path, ack_timeout);4982	qp_attr->alt_timeout = MLX5_GET(ads, alt_path, ack_timeout);4983 4984out:4985	kfree(outb);4986	return err;4987}4988 4989static int mlx5_ib_dct_query_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *mqp,4990				struct ib_qp_attr *qp_attr, int qp_attr_mask,4991				struct ib_qp_init_attr *qp_init_attr)4992{4993	struct mlx5_core_dct	*dct = &mqp->dct.mdct;4994	u32 *out;4995	u32 access_flags = 0;4996	int outlen = MLX5_ST_SZ_BYTES(query_dct_out);4997	void *dctc;4998	int err;4999	int supported_mask = IB_QP_STATE |5000			     IB_QP_ACCESS_FLAGS |5001			     IB_QP_PORT |5002			     IB_QP_MIN_RNR_TIMER |5003			     IB_QP_AV |5004			     IB_QP_PATH_MTU |5005			     IB_QP_PKEY_INDEX;5006 5007	if (qp_attr_mask & ~supported_mask)5008		return -EINVAL;5009	if (mqp->state != IB_QPS_RTR)5010		return -EINVAL;5011 5012	out = kzalloc(outlen, GFP_KERNEL);5013	if (!out)5014		return -ENOMEM;5015 5016	err = mlx5_core_dct_query(dev, dct, out, outlen);5017	if (err)5018		goto out;5019 5020	dctc = MLX5_ADDR_OF(query_dct_out, out, dct_context_entry);5021 5022	if (qp_attr_mask & IB_QP_STATE)5023		qp_attr->qp_state = IB_QPS_RTR;5024 5025	if (qp_attr_mask & IB_QP_ACCESS_FLAGS) {5026		if (MLX5_GET(dctc, dctc, rre))5027			access_flags |= IB_ACCESS_REMOTE_READ;5028		if (MLX5_GET(dctc, dctc, rwe))5029			access_flags |= IB_ACCESS_REMOTE_WRITE;5030		if (MLX5_GET(dctc, dctc, rae))5031			access_flags |= IB_ACCESS_REMOTE_ATOMIC;5032		qp_attr->qp_access_flags = access_flags;5033	}5034 5035	if (qp_attr_mask & IB_QP_PORT)5036		qp_attr->port_num = MLX5_GET(dctc, dctc, port);5037	if (qp_attr_mask & IB_QP_MIN_RNR_TIMER)5038		qp_attr->min_rnr_timer = MLX5_GET(dctc, dctc, min_rnr_nak);5039	if (qp_attr_mask & IB_QP_AV) {5040		qp_attr->ah_attr.grh.traffic_class = MLX5_GET(dctc, dctc, tclass);5041		qp_attr->ah_attr.grh.flow_label = MLX5_GET(dctc, dctc, flow_label);5042		qp_attr->ah_attr.grh.sgid_index = MLX5_GET(dctc, dctc, my_addr_index);5043		qp_attr->ah_attr.grh.hop_limit = MLX5_GET(dctc, dctc, hop_limit);5044	}5045	if (qp_attr_mask & IB_QP_PATH_MTU)5046		qp_attr->path_mtu = MLX5_GET(dctc, dctc, mtu);5047	if (qp_attr_mask & IB_QP_PKEY_INDEX)5048		qp_attr->pkey_index = MLX5_GET(dctc, dctc, pkey_index);5049out:5050	kfree(out);5051	return err;5052}5053 5054int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,5055		     int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr)5056{5057	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);5058	struct mlx5_ib_qp *qp = to_mqp(ibqp);5059	int err = 0;5060	u8 raw_packet_qp_state;5061 5062	if (ibqp->rwq_ind_tbl)5063		return -ENOSYS;5064 5065	if (qp->type == IB_QPT_GSI)5066		return mlx5_ib_gsi_query_qp(ibqp, qp_attr, qp_attr_mask,5067					    qp_init_attr);5068 5069	/* Not all of output fields are applicable, make sure to zero them */5070	memset(qp_init_attr, 0, sizeof(*qp_init_attr));5071	memset(qp_attr, 0, sizeof(*qp_attr));5072 5073	if (unlikely(qp->type == MLX5_IB_QPT_DCT))5074		return mlx5_ib_dct_query_qp(dev, qp, qp_attr,5075					    qp_attr_mask, qp_init_attr);5076 5077	mutex_lock(&qp->mutex);5078 5079	if (qp->type == IB_QPT_RAW_PACKET ||5080	    qp->flags & IB_QP_CREATE_SOURCE_QPN) {5081		err = query_raw_packet_qp_state(dev, qp, &raw_packet_qp_state);5082		if (err)5083			goto out;5084		qp->state = raw_packet_qp_state;5085		qp_attr->port_num = 1;5086	} else {5087		err = query_qp_attr(dev, qp, qp_attr);5088		if (err)5089			goto out;5090	}5091 5092	qp_attr->qp_state	     = qp->state;5093	qp_attr->cur_qp_state	     = qp_attr->qp_state;5094	qp_attr->cap.max_recv_wr     = qp->rq.wqe_cnt;5095	qp_attr->cap.max_recv_sge    = qp->rq.max_gs;5096 5097	if (!ibqp->uobject) {5098		qp_attr->cap.max_send_wr  = qp->sq.max_post;5099		qp_attr->cap.max_send_sge = qp->sq.max_gs;5100		qp_init_attr->qp_context = ibqp->qp_context;5101	} else {5102		qp_attr->cap.max_send_wr  = 0;5103		qp_attr->cap.max_send_sge = 0;5104	}5105 5106	qp_init_attr->qp_type = qp->type;5107	qp_init_attr->recv_cq = ibqp->recv_cq;5108	qp_init_attr->send_cq = ibqp->send_cq;5109	qp_init_attr->srq = ibqp->srq;5110	qp_attr->cap.max_inline_data = qp->max_inline_data;5111 5112	qp_init_attr->cap	     = qp_attr->cap;5113 5114	qp_init_attr->create_flags = qp->flags;5115 5116	qp_init_attr->sq_sig_type = qp->sq_signal_bits & MLX5_WQE_CTRL_CQ_UPDATE ?5117		IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;5118 5119out:5120	mutex_unlock(&qp->mutex);5121	return err;5122}5123 5124int mlx5_ib_alloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata)5125{5126	struct mlx5_ib_dev *dev = to_mdev(ibxrcd->device);5127	struct mlx5_ib_xrcd *xrcd = to_mxrcd(ibxrcd);5128 5129	if (!MLX5_CAP_GEN(dev->mdev, xrc))5130		return -EOPNOTSUPP;5131 5132	return mlx5_cmd_xrcd_alloc(dev->mdev, &xrcd->xrcdn, 0);5133}5134 5135int mlx5_ib_dealloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata)5136{5137	struct mlx5_ib_dev *dev = to_mdev(xrcd->device);5138	u32 xrcdn = to_mxrcd(xrcd)->xrcdn;5139 5140	return mlx5_cmd_xrcd_dealloc(dev->mdev, xrcdn, 0);5141}5142 5143static void mlx5_ib_wq_event(struct mlx5_core_qp *core_qp, int type)5144{5145	struct mlx5_ib_rwq *rwq = to_mibrwq(core_qp);5146	struct mlx5_ib_dev *dev = to_mdev(rwq->ibwq.device);5147	struct ib_event event;5148 5149	if (rwq->ibwq.event_handler) {5150		event.device     = rwq->ibwq.device;5151		event.element.wq = &rwq->ibwq;5152		switch (type) {5153		case MLX5_EVENT_TYPE_WQ_CATAS_ERROR:5154			event.event = IB_EVENT_WQ_FATAL;5155			break;5156		default:5157			mlx5_ib_warn(dev, "Unexpected event type %d on WQ %06x\n", type, core_qp->qpn);5158			return;5159		}5160 5161		rwq->ibwq.event_handler(&event, rwq->ibwq.wq_context);5162	}5163}5164 5165static int set_delay_drop(struct mlx5_ib_dev *dev)5166{5167	int err = 0;5168 5169	mutex_lock(&dev->delay_drop.lock);5170	if (dev->delay_drop.activate)5171		goto out;5172 5173	err = mlx5_core_set_delay_drop(dev, dev->delay_drop.timeout);5174	if (err)5175		goto out;5176 5177	dev->delay_drop.activate = true;5178out:5179	mutex_unlock(&dev->delay_drop.lock);5180 5181	if (!err)5182		atomic_inc(&dev->delay_drop.rqs_cnt);5183	return err;5184}5185 5186static int  create_rq(struct mlx5_ib_rwq *rwq, struct ib_pd *pd,5187		      struct ib_wq_init_attr *init_attr)5188{5189	struct mlx5_ib_dev *dev;5190	int has_net_offloads;5191	__be64 *rq_pas0;5192	int ts_format;5193	void *in;5194	void *rqc;5195	void *wq;5196	int inlen;5197	int err;5198 5199	dev = to_mdev(pd->device);5200 5201	ts_format = get_rq_ts_format(dev, to_mcq(init_attr->cq));5202	if (ts_format < 0)5203		return ts_format;5204 5205	inlen = MLX5_ST_SZ_BYTES(create_rq_in) + sizeof(u64) * rwq->rq_num_pas;5206	in = kvzalloc(inlen, GFP_KERNEL);5207	if (!in)5208		return -ENOMEM;5209 5210	MLX5_SET(create_rq_in, in, uid, to_mpd(pd)->uid);5211	rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);5212	MLX5_SET(rqc,  rqc, mem_rq_type,5213		 MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE);5214	MLX5_SET(rqc, rqc, ts_format, ts_format);5215	MLX5_SET(rqc, rqc, user_index, rwq->user_index);5216	MLX5_SET(rqc,  rqc, cqn, to_mcq(init_attr->cq)->mcq.cqn);5217	MLX5_SET(rqc,  rqc, state, MLX5_RQC_STATE_RST);5218	MLX5_SET(rqc,  rqc, flush_in_error_en, 1);5219	wq = MLX5_ADDR_OF(rqc, rqc, wq);5220	MLX5_SET(wq, wq, wq_type,5221		 rwq->create_flags & MLX5_IB_WQ_FLAGS_STRIDING_RQ ?5222		 MLX5_WQ_TYPE_CYCLIC_STRIDING_RQ : MLX5_WQ_TYPE_CYCLIC);5223	if (init_attr->create_flags & IB_WQ_FLAGS_PCI_WRITE_END_PADDING) {5224		if (!MLX5_CAP_GEN(dev->mdev, end_pad)) {5225			mlx5_ib_dbg(dev, "Scatter end padding is not supported\n");5226			err = -EOPNOTSUPP;5227			goto out;5228		} else {5229			MLX5_SET(wq, wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN);5230		}5231	}5232	MLX5_SET(wq, wq, log_wq_stride, rwq->log_rq_stride);5233	if (rwq->create_flags & MLX5_IB_WQ_FLAGS_STRIDING_RQ) {5234		/*5235		 * In Firmware number of strides in each WQE is:5236		 *   "512 * 2^single_wqe_log_num_of_strides"5237		 * Values 3 to 8 are accepted as 10 to 15, 9 to 18 are5238		 * accepted as 0 to 95239		 */5240		static const u8 fw_map[] = { 10, 11, 12, 13, 14, 15, 0, 1,5241					     2,  3,  4,  5,  6,  7,  8, 9 };5242		MLX5_SET(wq, wq, two_byte_shift_en, rwq->two_byte_shift_en);5243		MLX5_SET(wq, wq, log_wqe_stride_size,5244			 rwq->single_stride_log_num_of_bytes -5245			 MLX5_MIN_SINGLE_STRIDE_LOG_NUM_BYTES);5246		MLX5_SET(wq, wq, log_wqe_num_of_strides,5247			 fw_map[rwq->log_num_strides -5248				MLX5_EXT_MIN_SINGLE_WQE_LOG_NUM_STRIDES]);5249	}5250	MLX5_SET(wq, wq, log_wq_sz, rwq->log_rq_size);5251	MLX5_SET(wq, wq, pd, to_mpd(pd)->pdn);5252	MLX5_SET(wq, wq, page_offset, rwq->rq_page_offset);5253	MLX5_SET(wq, wq, log_wq_pg_sz, rwq->log_page_size);5254	MLX5_SET(wq, wq, wq_signature, rwq->wq_sig);5255	MLX5_SET64(wq, wq, dbr_addr, rwq->db.dma);5256	has_net_offloads = MLX5_CAP_GEN(dev->mdev, eth_net_offloads);5257	if (init_attr->create_flags & IB_WQ_FLAGS_CVLAN_STRIPPING) {5258		if (!(has_net_offloads && MLX5_CAP_ETH(dev->mdev, vlan_cap))) {5259			mlx5_ib_dbg(dev, "VLAN offloads are not supported\n");5260			err = -EOPNOTSUPP;5261			goto out;5262		}5263	} else {5264		MLX5_SET(rqc, rqc, vsd, 1);5265	}5266	if (init_attr->create_flags & IB_WQ_FLAGS_SCATTER_FCS) {5267		if (!(has_net_offloads && MLX5_CAP_ETH(dev->mdev, scatter_fcs))) {5268			mlx5_ib_dbg(dev, "Scatter FCS is not supported\n");5269			err = -EOPNOTSUPP;5270			goto out;5271		}5272		MLX5_SET(rqc, rqc, scatter_fcs, 1);5273	}5274	if (init_attr->create_flags & IB_WQ_FLAGS_DELAY_DROP) {5275		if (!(dev->ib_dev.attrs.raw_packet_caps &5276		      IB_RAW_PACKET_CAP_DELAY_DROP)) {5277			mlx5_ib_dbg(dev, "Delay drop is not supported\n");5278			err = -EOPNOTSUPP;5279			goto out;5280		}5281		MLX5_SET(rqc, rqc, delay_drop_en, 1);5282	}5283	rq_pas0 = (__be64 *)MLX5_ADDR_OF(wq, wq, pas);5284	mlx5_ib_populate_pas(rwq->umem, 1UL << rwq->page_shift, rq_pas0, 0);5285	err = mlx5_core_create_rq_tracked(dev, in, inlen, &rwq->core_qp);5286	if (!err && init_attr->create_flags & IB_WQ_FLAGS_DELAY_DROP) {5287		err = set_delay_drop(dev);5288		if (err) {5289			mlx5_ib_warn(dev, "Failed to enable delay drop err=%d\n",5290				     err);5291			mlx5_core_destroy_rq_tracked(dev, &rwq->core_qp);5292		} else {5293			rwq->create_flags |= MLX5_IB_WQ_FLAGS_DELAY_DROP;5294		}5295	}5296out:5297	kvfree(in);5298	return err;5299}5300 5301static int set_user_rq_size(struct mlx5_ib_dev *dev,5302			    struct ib_wq_init_attr *wq_init_attr,5303			    struct mlx5_ib_create_wq *ucmd,5304			    struct mlx5_ib_rwq *rwq)5305{5306	/* Sanity check RQ size before proceeding */5307	if (wq_init_attr->max_wr > (1 << MLX5_CAP_GEN(dev->mdev, log_max_wq_sz)))5308		return -EINVAL;5309 5310	if (!ucmd->rq_wqe_count)5311		return -EINVAL;5312 5313	rwq->wqe_count = ucmd->rq_wqe_count;5314	rwq->wqe_shift = ucmd->rq_wqe_shift;5315	if (check_shl_overflow(rwq->wqe_count, rwq->wqe_shift, &rwq->buf_size))5316		return -EINVAL;5317 5318	rwq->log_rq_stride = rwq->wqe_shift;5319	rwq->log_rq_size = ilog2(rwq->wqe_count);5320	return 0;5321}5322 5323static bool log_of_strides_valid(struct mlx5_ib_dev *dev, u32 log_num_strides)5324{5325	if ((log_num_strides > MLX5_MAX_SINGLE_WQE_LOG_NUM_STRIDES) ||5326	    (log_num_strides < MLX5_EXT_MIN_SINGLE_WQE_LOG_NUM_STRIDES))5327		return false;5328 5329	if (!MLX5_CAP_GEN(dev->mdev, ext_stride_num_range) &&5330	    (log_num_strides < MLX5_MIN_SINGLE_WQE_LOG_NUM_STRIDES))5331		return false;5332 5333	return true;5334}5335 5336static int prepare_user_rq(struct ib_pd *pd,5337			   struct ib_wq_init_attr *init_attr,5338			   struct ib_udata *udata,5339			   struct mlx5_ib_rwq *rwq)5340{5341	struct mlx5_ib_dev *dev = to_mdev(pd->device);5342	struct mlx5_ib_create_wq ucmd = {};5343	int err;5344	size_t required_cmd_sz;5345 5346	required_cmd_sz = offsetofend(struct mlx5_ib_create_wq,5347				      single_stride_log_num_of_bytes);5348	if (udata->inlen < required_cmd_sz) {5349		mlx5_ib_dbg(dev, "invalid inlen\n");5350		return -EINVAL;5351	}5352 5353	if (udata->inlen > sizeof(ucmd) &&5354	    !ib_is_udata_cleared(udata, sizeof(ucmd),5355				 udata->inlen - sizeof(ucmd))) {5356		mlx5_ib_dbg(dev, "inlen is not supported\n");5357		return -EOPNOTSUPP;5358	}5359 5360	if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen))) {5361		mlx5_ib_dbg(dev, "copy failed\n");5362		return -EFAULT;5363	}5364 5365	if (ucmd.comp_mask & (~MLX5_IB_CREATE_WQ_STRIDING_RQ)) {5366		mlx5_ib_dbg(dev, "invalid comp mask\n");5367		return -EOPNOTSUPP;5368	} else if (ucmd.comp_mask & MLX5_IB_CREATE_WQ_STRIDING_RQ) {5369		if (!MLX5_CAP_GEN(dev->mdev, striding_rq)) {5370			mlx5_ib_dbg(dev, "Striding RQ is not supported\n");5371			return -EOPNOTSUPP;5372		}5373		if ((ucmd.single_stride_log_num_of_bytes <5374		    MLX5_MIN_SINGLE_STRIDE_LOG_NUM_BYTES) ||5375		    (ucmd.single_stride_log_num_of_bytes >5376		     MLX5_MAX_SINGLE_STRIDE_LOG_NUM_BYTES)) {5377			mlx5_ib_dbg(dev, "Invalid log stride size (%u. Range is %u - %u)\n",5378				    ucmd.single_stride_log_num_of_bytes,5379				    MLX5_MIN_SINGLE_STRIDE_LOG_NUM_BYTES,5380				    MLX5_MAX_SINGLE_STRIDE_LOG_NUM_BYTES);5381			return -EINVAL;5382		}5383		if (!log_of_strides_valid(dev,5384					  ucmd.single_wqe_log_num_of_strides)) {5385			mlx5_ib_dbg(5386				dev,5387				"Invalid log num strides (%u. Range is %u - %u)\n",5388				ucmd.single_wqe_log_num_of_strides,5389				MLX5_CAP_GEN(dev->mdev, ext_stride_num_range) ?5390					MLX5_EXT_MIN_SINGLE_WQE_LOG_NUM_STRIDES :5391					MLX5_MIN_SINGLE_WQE_LOG_NUM_STRIDES,5392				MLX5_MAX_SINGLE_WQE_LOG_NUM_STRIDES);5393			return -EINVAL;5394		}5395		rwq->single_stride_log_num_of_bytes =5396			ucmd.single_stride_log_num_of_bytes;5397		rwq->log_num_strides = ucmd.single_wqe_log_num_of_strides;5398		rwq->two_byte_shift_en = !!ucmd.two_byte_shift_en;5399		rwq->create_flags |= MLX5_IB_WQ_FLAGS_STRIDING_RQ;5400	}5401 5402	err = set_user_rq_size(dev, init_attr, &ucmd, rwq);5403	if (err) {5404		mlx5_ib_dbg(dev, "err %d\n", err);5405		return err;5406	}5407 5408	err = create_user_rq(dev, pd, udata, rwq, &ucmd);5409	if (err) {5410		mlx5_ib_dbg(dev, "err %d\n", err);5411		return err;5412	}5413 5414	rwq->user_index = ucmd.user_index;5415	return 0;5416}5417 5418struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd,5419				struct ib_wq_init_attr *init_attr,5420				struct ib_udata *udata)5421{5422	struct mlx5_ib_dev *dev;5423	struct mlx5_ib_rwq *rwq;5424	struct mlx5_ib_create_wq_resp resp = {};5425	size_t min_resp_len;5426	int err;5427 5428	if (!udata)5429		return ERR_PTR(-ENOSYS);5430 5431	min_resp_len = offsetofend(struct mlx5_ib_create_wq_resp, reserved);5432	if (udata->outlen && udata->outlen < min_resp_len)5433		return ERR_PTR(-EINVAL);5434 5435	if (!capable(CAP_SYS_RAWIO) &&5436	    init_attr->create_flags & IB_WQ_FLAGS_DELAY_DROP)5437		return ERR_PTR(-EPERM);5438 5439	dev = to_mdev(pd->device);5440	switch (init_attr->wq_type) {5441	case IB_WQT_RQ:5442		rwq = kzalloc(sizeof(*rwq), GFP_KERNEL);5443		if (!rwq)5444			return ERR_PTR(-ENOMEM);5445		err = prepare_user_rq(pd, init_attr, udata, rwq);5446		if (err)5447			goto err;5448		err = create_rq(rwq, pd, init_attr);5449		if (err)5450			goto err_user_rq;5451		break;5452	default:5453		mlx5_ib_dbg(dev, "unsupported wq type %d\n",5454			    init_attr->wq_type);5455		return ERR_PTR(-EINVAL);5456	}5457 5458	rwq->ibwq.wq_num = rwq->core_qp.qpn;5459	rwq->ibwq.state = IB_WQS_RESET;5460	if (udata->outlen) {5461		resp.response_length = offsetofend(5462			struct mlx5_ib_create_wq_resp, response_length);5463		err = ib_copy_to_udata(udata, &resp, resp.response_length);5464		if (err)5465			goto err_copy;5466	}5467 5468	rwq->core_qp.event = mlx5_ib_wq_event;5469	rwq->ibwq.event_handler = init_attr->event_handler;5470	return &rwq->ibwq;5471 5472err_copy:5473	mlx5_core_destroy_rq_tracked(dev, &rwq->core_qp);5474err_user_rq:5475	destroy_user_rq(dev, pd, rwq, udata);5476err:5477	kfree(rwq);5478	return ERR_PTR(err);5479}5480 5481int mlx5_ib_destroy_wq(struct ib_wq *wq, struct ib_udata *udata)5482{5483	struct mlx5_ib_dev *dev = to_mdev(wq->device);5484	struct mlx5_ib_rwq *rwq = to_mrwq(wq);5485	int ret;5486 5487	ret = mlx5_core_destroy_rq_tracked(dev, &rwq->core_qp);5488	if (ret)5489		return ret;5490	destroy_user_rq(dev, wq->pd, rwq, udata);5491	kfree(rwq);5492	return 0;5493}5494 5495int mlx5_ib_create_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_table,5496				 struct ib_rwq_ind_table_init_attr *init_attr,5497				 struct ib_udata *udata)5498{5499	struct mlx5_ib_rwq_ind_table *rwq_ind_tbl =5500		to_mrwq_ind_table(ib_rwq_ind_table);5501	struct mlx5_ib_dev *dev = to_mdev(ib_rwq_ind_table->device);5502	int sz = 1 << init_attr->log_ind_tbl_size;5503	struct mlx5_ib_create_rwq_ind_tbl_resp resp = {};5504	size_t min_resp_len;5505	int inlen;5506	int err;5507	int i;5508	u32 *in;5509	void *rqtc;5510 5511	if (udata->inlen > 0 &&5512	    !ib_is_udata_cleared(udata, 0,5513				 udata->inlen))5514		return -EOPNOTSUPP;5515 5516	if (init_attr->log_ind_tbl_size >5517	    MLX5_CAP_GEN(dev->mdev, log_max_rqt_size)) {5518		mlx5_ib_dbg(dev, "log_ind_tbl_size = %d is bigger than supported = %d\n",5519			    init_attr->log_ind_tbl_size,5520			    MLX5_CAP_GEN(dev->mdev, log_max_rqt_size));5521		return -EINVAL;5522	}5523 5524	min_resp_len =5525		offsetofend(struct mlx5_ib_create_rwq_ind_tbl_resp, reserved);5526	if (udata->outlen && udata->outlen < min_resp_len)5527		return -EINVAL;5528 5529	inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + sizeof(u32) * sz;5530	in = kvzalloc(inlen, GFP_KERNEL);5531	if (!in)5532		return -ENOMEM;5533 5534	rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);5535 5536	MLX5_SET(rqtc, rqtc, rqt_actual_size, sz);5537	MLX5_SET(rqtc, rqtc, rqt_max_size, sz);5538 5539	for (i = 0; i < sz; i++)5540		MLX5_SET(rqtc, rqtc, rq_num[i], init_attr->ind_tbl[i]->wq_num);5541 5542	rwq_ind_tbl->uid = to_mpd(init_attr->ind_tbl[0]->pd)->uid;5543	MLX5_SET(create_rqt_in, in, uid, rwq_ind_tbl->uid);5544 5545	err = mlx5_core_create_rqt(dev->mdev, in, inlen, &rwq_ind_tbl->rqtn);5546	kvfree(in);5547	if (err)5548		return err;5549 5550	rwq_ind_tbl->ib_rwq_ind_tbl.ind_tbl_num = rwq_ind_tbl->rqtn;5551	if (udata->outlen) {5552		resp.response_length =5553			offsetofend(struct mlx5_ib_create_rwq_ind_tbl_resp,5554				    response_length);5555		err = ib_copy_to_udata(udata, &resp, resp.response_length);5556		if (err)5557			goto err_copy;5558	}5559 5560	return 0;5561 5562err_copy:5563	mlx5_cmd_destroy_rqt(dev->mdev, rwq_ind_tbl->rqtn, rwq_ind_tbl->uid);5564	return err;5565}5566 5567int mlx5_ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *ib_rwq_ind_tbl)5568{5569	struct mlx5_ib_rwq_ind_table *rwq_ind_tbl = to_mrwq_ind_table(ib_rwq_ind_tbl);5570	struct mlx5_ib_dev *dev = to_mdev(ib_rwq_ind_tbl->device);5571 5572	return mlx5_cmd_destroy_rqt(dev->mdev, rwq_ind_tbl->rqtn, rwq_ind_tbl->uid);5573}5574 5575int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,5576		      u32 wq_attr_mask, struct ib_udata *udata)5577{5578	struct mlx5_ib_dev *dev = to_mdev(wq->device);5579	struct mlx5_ib_rwq *rwq = to_mrwq(wq);5580	struct mlx5_ib_modify_wq ucmd = {};5581	size_t required_cmd_sz;5582	int curr_wq_state;5583	int wq_state;5584	int inlen;5585	int err;5586	void *rqc;5587	void *in;5588 5589	required_cmd_sz = offsetofend(struct mlx5_ib_modify_wq, reserved);5590	if (udata->inlen < required_cmd_sz)5591		return -EINVAL;5592 5593	if (udata->inlen > sizeof(ucmd) &&5594	    !ib_is_udata_cleared(udata, sizeof(ucmd),5595				 udata->inlen - sizeof(ucmd)))5596		return -EOPNOTSUPP;5597 5598	if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)))5599		return -EFAULT;5600 5601	if (ucmd.comp_mask || ucmd.reserved)5602		return -EOPNOTSUPP;5603 5604	inlen = MLX5_ST_SZ_BYTES(modify_rq_in);5605	in = kvzalloc(inlen, GFP_KERNEL);5606	if (!in)5607		return -ENOMEM;5608 5609	rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);5610 5611	curr_wq_state = wq_attr->curr_wq_state;5612	wq_state = wq_attr->wq_state;5613	if (curr_wq_state == IB_WQS_ERR)5614		curr_wq_state = MLX5_RQC_STATE_ERR;5615	if (wq_state == IB_WQS_ERR)5616		wq_state = MLX5_RQC_STATE_ERR;5617	MLX5_SET(modify_rq_in, in, rq_state, curr_wq_state);5618	MLX5_SET(modify_rq_in, in, uid, to_mpd(wq->pd)->uid);5619	MLX5_SET(rqc, rqc, state, wq_state);5620 5621	if (wq_attr_mask & IB_WQ_FLAGS) {5622		if (wq_attr->flags_mask & IB_WQ_FLAGS_CVLAN_STRIPPING) {5623			if (!(MLX5_CAP_GEN(dev->mdev, eth_net_offloads) &&5624			      MLX5_CAP_ETH(dev->mdev, vlan_cap))) {5625				mlx5_ib_dbg(dev, "VLAN offloads are not supported\n");5626				err = -EOPNOTSUPP;5627				goto out;5628			}5629			MLX5_SET64(modify_rq_in, in, modify_bitmask,5630				   MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_VSD);5631			MLX5_SET(rqc, rqc, vsd,5632				 (wq_attr->flags & IB_WQ_FLAGS_CVLAN_STRIPPING) ? 0 : 1);5633		}5634 5635		if (wq_attr->flags_mask & IB_WQ_FLAGS_PCI_WRITE_END_PADDING) {5636			mlx5_ib_dbg(dev, "Modifying scatter end padding is not supported\n");5637			err = -EOPNOTSUPP;5638			goto out;5639		}5640	}5641 5642	if (curr_wq_state == IB_WQS_RESET && wq_state == IB_WQS_RDY) {5643		u16 set_id;5644 5645		set_id = mlx5_ib_get_counters_id(dev, 0);5646		if (MLX5_CAP_GEN(dev->mdev, modify_rq_counter_set_id)) {5647			MLX5_SET64(modify_rq_in, in, modify_bitmask,5648				   MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID);5649			MLX5_SET(rqc, rqc, counter_set_id, set_id);5650		} else5651			dev_info_once(5652				&dev->ib_dev.dev,5653				"Receive WQ counters are not supported on current FW\n");5654	}5655 5656	err = mlx5_core_modify_rq(dev->mdev, rwq->core_qp.qpn, in);5657	if (!err)5658		rwq->ibwq.state = (wq_state == MLX5_RQC_STATE_ERR) ? IB_WQS_ERR : wq_state;5659 5660out:5661	kvfree(in);5662	return err;5663}5664 5665struct mlx5_ib_drain_cqe {5666	struct ib_cqe cqe;5667	struct completion done;5668};5669 5670static void mlx5_ib_drain_qp_done(struct ib_cq *cq, struct ib_wc *wc)5671{5672	struct mlx5_ib_drain_cqe *cqe = container_of(wc->wr_cqe,5673						     struct mlx5_ib_drain_cqe,5674						     cqe);5675 5676	complete(&cqe->done);5677}5678 5679/* This function returns only once the drained WR was completed */5680static void handle_drain_completion(struct ib_cq *cq,5681				    struct mlx5_ib_drain_cqe *sdrain,5682				    struct mlx5_ib_dev *dev)5683{5684	struct mlx5_core_dev *mdev = dev->mdev;5685 5686	if (cq->poll_ctx == IB_POLL_DIRECT) {5687		while (wait_for_completion_timeout(&sdrain->done, HZ / 10) <= 0)5688			ib_process_cq_direct(cq, -1);5689		return;5690	}5691 5692	if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {5693		struct mlx5_ib_cq *mcq = to_mcq(cq);5694		bool triggered = false;5695		unsigned long flags;5696 5697		spin_lock_irqsave(&dev->reset_flow_resource_lock, flags);5698		/* Make sure that the CQ handler won't run if wasn't run yet */5699		if (!mcq->mcq.reset_notify_added)5700			mcq->mcq.reset_notify_added = 1;5701		else5702			triggered = true;5703		spin_unlock_irqrestore(&dev->reset_flow_resource_lock, flags);5704 5705		if (triggered) {5706			/* Wait for any scheduled/running task to be ended */5707			switch (cq->poll_ctx) {5708			case IB_POLL_SOFTIRQ:5709				irq_poll_disable(&cq->iop);5710				irq_poll_enable(&cq->iop);5711				break;5712			case IB_POLL_WORKQUEUE:5713				cancel_work_sync(&cq->work);5714				break;5715			default:5716				WARN_ON_ONCE(1);5717			}5718		}5719 5720		/* Run the CQ handler - this makes sure that the drain WR will5721		 * be processed if wasn't processed yet.5722		 */5723		mcq->mcq.comp(&mcq->mcq, NULL);5724	}5725 5726	wait_for_completion(&sdrain->done);5727}5728 5729void mlx5_ib_drain_sq(struct ib_qp *qp)5730{5731	struct ib_cq *cq = qp->send_cq;5732	struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR };5733	struct mlx5_ib_drain_cqe sdrain;5734	const struct ib_send_wr *bad_swr;5735	struct ib_rdma_wr swr = {5736		.wr = {5737			.next = NULL,5738			{ .wr_cqe	= &sdrain.cqe, },5739			.opcode	= IB_WR_RDMA_WRITE,5740		},5741	};5742	int ret;5743	struct mlx5_ib_dev *dev = to_mdev(qp->device);5744	struct mlx5_core_dev *mdev = dev->mdev;5745 5746	ret = ib_modify_qp(qp, &attr, IB_QP_STATE);5747	if (ret && mdev->state != MLX5_DEVICE_STATE_INTERNAL_ERROR) {5748		WARN_ONCE(ret, "failed to drain send queue: %d\n", ret);5749		return;5750	}5751 5752	sdrain.cqe.done = mlx5_ib_drain_qp_done;5753	init_completion(&sdrain.done);5754 5755	ret = mlx5_ib_post_send_drain(qp, &swr.wr, &bad_swr);5756	if (ret) {5757		WARN_ONCE(ret, "failed to drain send queue: %d\n", ret);5758		return;5759	}5760 5761	handle_drain_completion(cq, &sdrain, dev);5762}5763 5764void mlx5_ib_drain_rq(struct ib_qp *qp)5765{5766	struct ib_cq *cq = qp->recv_cq;5767	struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR };5768	struct mlx5_ib_drain_cqe rdrain;5769	struct ib_recv_wr rwr = {};5770	const struct ib_recv_wr *bad_rwr;5771	int ret;5772	struct mlx5_ib_dev *dev = to_mdev(qp->device);5773	struct mlx5_core_dev *mdev = dev->mdev;5774 5775	ret = ib_modify_qp(qp, &attr, IB_QP_STATE);5776	if (ret && mdev->state != MLX5_DEVICE_STATE_INTERNAL_ERROR) {5777		WARN_ONCE(ret, "failed to drain recv queue: %d\n", ret);5778		return;5779	}5780 5781	rwr.wr_cqe = &rdrain.cqe;5782	rdrain.cqe.done = mlx5_ib_drain_qp_done;5783	init_completion(&rdrain.done);5784 5785	ret = mlx5_ib_post_recv_drain(qp, &rwr, &bad_rwr);5786	if (ret) {5787		WARN_ONCE(ret, "failed to drain recv queue: %d\n", ret);5788		return;5789	}5790 5791	handle_drain_completion(cq, &rdrain, dev);5792}5793 5794/*5795 * Bind a qp to a counter. If @counter is NULL then bind the qp to5796 * the default counter5797 */5798int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter)5799{5800	struct mlx5_ib_dev *dev = to_mdev(qp->device);5801	struct mlx5_ib_qp *mqp = to_mqp(qp);5802	int err = 0;5803 5804	mutex_lock(&mqp->mutex);5805	if (mqp->state == IB_QPS_RESET) {5806		qp->counter = counter;5807		goto out;5808	}5809 5810	if (!MLX5_CAP_GEN(dev->mdev, rts2rts_qp_counters_set_id)) {5811		err = -EOPNOTSUPP;5812		goto out;5813	}5814 5815	if (mqp->state == IB_QPS_RTS) {5816		err = __mlx5_ib_qp_set_counter(qp, counter);5817		if (!err)5818			qp->counter = counter;5819 5820		goto out;5821	}5822 5823	mqp->counter_pending = 1;5824	qp->counter = counter;5825 5826out:5827	mutex_unlock(&mqp->mutex);5828	return err;5829}5830 5831int mlx5_ib_qp_event_init(void)5832{5833	mlx5_ib_qp_event_wq = alloc_ordered_workqueue("mlx5_ib_qp_event_wq", 0);5834	if (!mlx5_ib_qp_event_wq)5835		return -ENOMEM;5836 5837	return 0;5838}5839 5840void mlx5_ib_qp_event_cleanup(void)5841{5842	destroy_workqueue(mlx5_ib_qp_event_wq);5843}5844