Commit f18e26af authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Jason Gunthorpe
Browse files

RDMA/mlx5: Convert modify QP to use MLX5_SET macros

Instead of hand crafted mlx5_qp_context and mlx5_qp_path use common
MLX5_SET() macros.

Link: https://lore.kernel.org/r/20200526115440.205922-7-leon@kernel.org


Reviewed-by: default avatarMaor Gottlieb <maorg@mellanox.com>
Reviewed-by: default avatarMark Zhang <markz@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 70bd7fb8
Loading
Loading
Loading
Loading
+97 −106
Original line number Diff line number Diff line
@@ -3028,14 +3028,13 @@ int mlx5_ib_destroy_qp(struct ib_qp *qp, struct ib_udata *udata)
	return 0;
}

static int to_mlx5_access_flags(struct mlx5_ib_qp *qp,
				const struct ib_qp_attr *attr,
				int attr_mask, __be32 *hw_access_flags_be)
static int set_qpc_atomic_flags(struct mlx5_ib_qp *qp,
				const struct ib_qp_attr *attr, int attr_mask,
				void *qpc)
{
	u8 dest_rd_atomic;
	u32 access_flags, hw_access_flags = 0;

	struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.device);
	u8 dest_rd_atomic;
	u32 access_flags;

	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
		dest_rd_atomic = attr->max_dest_rd_atomic;
@@ -3050,8 +3049,8 @@ static int to_mlx5_access_flags(struct mlx5_ib_qp *qp,
	if (!dest_rd_atomic)
		access_flags &= IB_ACCESS_REMOTE_WRITE;

	if (access_flags & IB_ACCESS_REMOTE_READ)
		hw_access_flags |= MLX5_QP_BIT_RRE;
	MLX5_SET(qpc, qpc, rre, !!(access_flags & IB_ACCESS_REMOTE_READ));

	if (access_flags & IB_ACCESS_REMOTE_ATOMIC) {
		int atomic_mode;

@@ -3059,15 +3058,11 @@ static int to_mlx5_access_flags(struct mlx5_ib_qp *qp,
		if (atomic_mode < 0)
			return -EOPNOTSUPP;

		hw_access_flags |= MLX5_QP_BIT_RAE;
		hw_access_flags |= atomic_mode << MLX5_ATOMIC_MODE_OFFSET;
		MLX5_SET(qpc, qpc, rae, 1);
		MLX5_SET(qpc, qpc, atomic_mode, atomic_mode);
	}

	if (access_flags & IB_ACCESS_REMOTE_WRITE)
		hw_access_flags |= MLX5_QP_BIT_RWE;

	*hw_access_flags_be = cpu_to_be32(hw_access_flags);

	MLX5_SET(qpc, qpc, rwe, !!(access_flags & IB_ACCESS_REMOTE_WRITE));
	return 0;
}

@@ -3147,26 +3142,22 @@ static int modify_raw_packet_tx_affinity(struct mlx5_core_dev *dev,
	return err;
}

static void mlx5_set_path_udp_sport(struct mlx5_qp_path *path,
				    const struct rdma_ah_attr *ah,
static void mlx5_set_path_udp_sport(void *path, const struct rdma_ah_attr *ah,
				    u32 lqpn, u32 rqpn)

{
	u32 fl = ah->grh.flow_label;
	u16 sport;

	if (!fl)
		fl = rdma_calc_flow_label(lqpn, rqpn);

	sport = rdma_flow_label_to_udp_sport(fl);
	path->udp_sport = cpu_to_be16(sport);
	MLX5_SET(ads, path, udp_sport, rdma_flow_label_to_udp_sport(fl));
}

static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
			 const struct rdma_ah_attr *ah,
			 struct mlx5_qp_path *path, u8 port, int attr_mask,
			 u32 path_flags, const struct ib_qp_attr *attr,
			 bool alt)
			 const struct rdma_ah_attr *ah, void *path, u8 port,
			 int attr_mask, u32 path_flags,
			 const struct ib_qp_attr *attr, bool alt)
{
	const struct ib_global_route *grh = rdma_ah_read_grh(ah);
	int err;
@@ -3175,8 +3166,8 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
	u8 sl = rdma_ah_get_sl(ah);

	if (attr_mask & IB_QP_PKEY_INDEX)
		path->pkey_index = cpu_to_be16(alt ? attr->alt_pkey_index :
						     attr->pkey_index);
		MLX5_SET(ads, path, pkey_index,
			 alt ? attr->alt_pkey_index : attr->pkey_index);

	if (ah_flags & IB_AH_GRH) {
		if (grh->sgid_index >=
@@ -3192,7 +3183,8 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
		if (!(ah_flags & IB_AH_GRH))
			return -EINVAL;

		memcpy(path->rmac, ah->roce.dmac, sizeof(ah->roce.dmac));
		ether_addr_copy(MLX5_ADDR_OF(ads, path, rmac_47_32),
				ah->roce.dmac);
		if ((qp->ibqp.qp_type == IB_QPT_RC ||
		     qp->ibqp.qp_type == IB_QPT_UC ||
		     qp->ibqp.qp_type == IB_QPT_XRC_INI ||
@@ -3202,38 +3194,38 @@ static int mlx5_set_path(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
			mlx5_set_path_udp_sport(path, ah,
						qp->ibqp.qp_num,
						attr->dest_qp_num);
		path->dci_cfi_prio_sl = (sl & 0x7) << 4;
		MLX5_SET(ads, path, eth_prio, sl & 0x7);
		gid_type = ah->grh.sgid_attr->gid_type;
		if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP)
			path->ecn_dscp = (grh->traffic_class >> 2) & 0x3f;
			MLX5_SET(ads, path, dscp, grh->traffic_class >> 2);
	} else {
		path->fl_free_ar = (path_flags & MLX5_PATH_FLAG_FL) ? 0x80 : 0;
		path->fl_free_ar |=
			(path_flags & MLX5_PATH_FLAG_FREE_AR) ? 0x40 : 0;
		path->rlid = cpu_to_be16(rdma_ah_get_dlid(ah));
		path->grh_mlid = rdma_ah_get_path_bits(ah) & 0x7f;
		if (ah_flags & IB_AH_GRH)
			path->grh_mlid	|= 1 << 7;
		path->dci_cfi_prio_sl = sl & 0xf;
		MLX5_SET(ads, path, fl, !!(path_flags & MLX5_PATH_FLAG_FL));
		MLX5_SET(ads, path, free_ar,
			 !!(path_flags & MLX5_PATH_FLAG_FREE_AR));
		MLX5_SET(ads, path, rlid, rdma_ah_get_dlid(ah));
		MLX5_SET(ads, path, mlid, rdma_ah_get_path_bits(ah));
		MLX5_SET(ads, path, grh, !!(ah_flags & IB_AH_GRH));
		MLX5_SET(ads, path, sl, sl);
	}

	if (ah_flags & IB_AH_GRH) {
		path->mgid_index = grh->sgid_index;
		path->hop_limit  = grh->hop_limit;
		path->tclass_flowlabel =
			cpu_to_be32((grh->traffic_class << 20) |
				    (grh->flow_label));
		memcpy(path->rgid, grh->dgid.raw, 16);
		MLX5_SET(ads, path, src_addr_index, grh->sgid_index);
		MLX5_SET(ads, path, hop_limit, grh->hop_limit);
		MLX5_SET(ads, path, tclass, grh->traffic_class);
		MLX5_SET(ads, path, flow_label, grh->flow_label);
		memcpy(MLX5_ADDR_OF(ads, path, rgid_rip), grh->dgid.raw,
		       sizeof(grh->dgid.raw));
	}

	err = ib_rate_to_mlx5(dev, rdma_ah_get_static_rate(ah));
	if (err < 0)
		return err;
	path->static_rate = err;
	path->port = port;
	MLX5_SET(ads, path, stat_rate, err);
	MLX5_SET(ads, path, vhca_port_num, port);

	if (attr_mask & IB_QP_TIMEOUT)
		path->ackto_lt = (alt ? attr->alt_timeout : attr->timeout) << 3;
		MLX5_SET(ads, path, ack_timeout,
			 alt ? attr->alt_timeout : attr->timeout);

	if ((qp->ibqp.qp_type == IB_QPT_RAW_PACKET) && qp->sq.wqe_cnt)
		return modify_raw_packet_eth_prio(dev->mdev,
@@ -3759,9 +3751,9 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
	struct mlx5_ib_qp *qp = to_mqp(ibqp);
	struct mlx5_ib_qp_base *base = &qp->trans_qp.base;
	struct mlx5_ib_cq *send_cq, *recv_cq;
	struct mlx5_qp_context *context;
	struct mlx5_ib_pd *pd;
	enum mlx5_qp_state mlx5_cur, mlx5_new;
	void *qpc, *pri_path, *alt_path;
	enum mlx5_qp_optpar optpar = 0;
	u32 set_id = 0;
	int mlx5_st;
@@ -3773,25 +3765,25 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
	if (mlx5_st < 0)
		return -EINVAL;

	context = kzalloc(sizeof(*context), GFP_KERNEL);
	if (!context)
	qpc = kzalloc(MLX5_ST_SZ_BYTES(qpc), GFP_KERNEL);
	if (!qpc)
		return -ENOMEM;

	pd = to_mpd(qp->ibqp.pd);
	context->flags = cpu_to_be32(mlx5_st << 16);
	MLX5_SET(qpc, qpc, st, mlx5_st);

	if (!(attr_mask & IB_QP_PATH_MIG_STATE)) {
		context->flags |= cpu_to_be32(MLX5_QP_PM_MIGRATED << 11);
		MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
	} else {
		switch (attr->path_mig_state) {
		case IB_MIG_MIGRATED:
			context->flags |= cpu_to_be32(MLX5_QP_PM_MIGRATED << 11);
			MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
			break;
		case IB_MIG_REARM:
			context->flags |= cpu_to_be32(MLX5_QP_PM_REARM << 11);
			MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_REARM);
			break;
		case IB_MIG_ARMED:
			context->flags |= cpu_to_be32(MLX5_QP_PM_ARMED << 11);
			MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_ARMED);
			break;
		}
	}
@@ -3799,19 +3791,20 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
	tx_affinity = get_tx_affinity(ibqp, attr, attr_mask,
				      cur_state == IB_QPS_RESET &&
				      new_state == IB_QPS_INIT, udata);
	if (tx_affinity) {
		context->flags |= cpu_to_be32(tx_affinity << 24);
		if (new_state == IB_QPS_RTR &&

	MLX5_SET(qpc, qpc, lag_tx_port_affinity, tx_affinity);
	if (tx_affinity && new_state == IB_QPS_RTR &&
	    MLX5_CAP_GEN(dev->mdev, init2_lag_tx_port_affinity))
		optpar |= MLX5_QP_OPTPAR_LAG_TX_AFF;
	}

	if (is_sqp(ibqp->qp_type)) {
		context->mtu_msgmax = (IB_MTU_256 << 5) | 8;
		MLX5_SET(qpc, qpc, mtu, IB_MTU_256);
		MLX5_SET(qpc, qpc, log_msg_max, 8);
	} else if ((ibqp->qp_type == IB_QPT_UD &&
		    !(qp->flags & IB_QP_CREATE_SOURCE_QPN)) ||
		   ibqp->qp_type == MLX5_IB_QPT_REG_UMR) {
		context->mtu_msgmax = (IB_MTU_4096 << 5) | 12;
		MLX5_SET(qpc, qpc, mtu, IB_MTU_4096);
		MLX5_SET(qpc, qpc, log_msg_max, 12);
	} else if (attr_mask & IB_QP_PATH_MTU) {
		if (attr->path_mtu < IB_MTU_256 ||
		    attr->path_mtu > IB_MTU_4096) {
@@ -3819,40 +3812,45 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
			err = -EINVAL;
			goto out;
		}
		context->mtu_msgmax = (attr->path_mtu << 5) |
				      (u8)MLX5_CAP_GEN(dev->mdev, log_max_msg);
		MLX5_SET(qpc, qpc, mtu, attr->path_mtu);
		MLX5_SET(qpc, qpc, log_msg_max,
			 MLX5_CAP_GEN(dev->mdev, log_max_msg));
	}

	if (attr_mask & IB_QP_DEST_QPN)
		context->log_pg_sz_remote_qpn = cpu_to_be32(attr->dest_qp_num);
		MLX5_SET(qpc, qpc, remote_qpn, attr->dest_qp_num);

	pri_path = MLX5_ADDR_OF(qpc, qpc, primary_address_path);
	alt_path = MLX5_ADDR_OF(qpc, qpc, secondary_address_path);

	if (attr_mask & IB_QP_PKEY_INDEX)
		context->pri_path.pkey_index = cpu_to_be16(attr->pkey_index);
		MLX5_SET(ads, pri_path, pkey_index, attr->pkey_index);

	/* todo implement counter_index functionality */

	if (is_sqp(ibqp->qp_type))
		context->pri_path.port = qp->port;
		MLX5_SET(ads, pri_path, vhca_port_num, qp->port);

	if (attr_mask & IB_QP_PORT)
		context->pri_path.port = attr->port_num;
		MLX5_SET(ads, pri_path, vhca_port_num, attr->port_num);

	if (attr_mask & IB_QP_AV) {
		err = mlx5_set_path(dev, qp, &attr->ah_attr, &context->pri_path,
				    attr_mask & IB_QP_PORT ? attr->port_num : qp->port,
		err = mlx5_set_path(dev, qp, &attr->ah_attr, pri_path,
				    attr_mask & IB_QP_PORT ? attr->port_num :
							     qp->port,
				    attr_mask, 0, attr, false);
		if (err)
			goto out;
	}

	if (attr_mask & IB_QP_TIMEOUT)
		context->pri_path.ackto_lt |= attr->timeout << 3;
		MLX5_SET(ads, pri_path, ack_timeout, attr->timeout);

	if (attr_mask & IB_QP_ALT_PATH) {
		err = mlx5_set_path(dev, qp, &attr->alt_ah_attr,
				    &context->alt_path,
		err = mlx5_set_path(dev, qp, &attr->alt_ah_attr, alt_path,
				    attr->alt_port_num,
				    attr_mask | IB_QP_PKEY_INDEX | IB_QP_TIMEOUT,
				    attr_mask | IB_QP_PKEY_INDEX |
					    IB_QP_TIMEOUT,
				    0, attr, true);
		if (err)
			goto out;
@@ -3861,53 +3859,47 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
	get_cqs(qp->ibqp.qp_type, qp->ibqp.send_cq, qp->ibqp.recv_cq,
		&send_cq, &recv_cq);

	context->flags_pd = cpu_to_be32(pd ? pd->pdn : to_mpd(dev->devr.p0)->pdn);
	context->cqn_send = send_cq ? cpu_to_be32(send_cq->mcq.cqn) : 0;
	context->cqn_recv = recv_cq ? cpu_to_be32(recv_cq->mcq.cqn) : 0;
	context->params1  = cpu_to_be32(MLX5_IB_ACK_REQ_FREQ << 28);
	MLX5_SET(qpc, qpc, pd, pd ? pd->pdn : to_mpd(dev->devr.p0)->pdn);
	if (send_cq)
		MLX5_SET(qpc, qpc, cqn_snd, send_cq->mcq.cqn);
	if (recv_cq)
		MLX5_SET(qpc, qpc, cqn_rcv, recv_cq->mcq.cqn);

	MLX5_SET(qpc, qpc, log_ack_req_freq, MLX5_IB_ACK_REQ_FREQ);

	if (attr_mask & IB_QP_RNR_RETRY)
		context->params1 |= cpu_to_be32(attr->rnr_retry << 13);
		MLX5_SET(qpc, qpc, rnr_retry, attr->rnr_retry);

	if (attr_mask & IB_QP_RETRY_CNT)
		context->params1 |= cpu_to_be32(attr->retry_cnt << 16);
		MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt);

	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {
		if (attr->max_rd_atomic)
			context->params1 |=
				cpu_to_be32(fls(attr->max_rd_atomic - 1) << 21);
	}
	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && attr->max_rd_atomic)
		MLX5_SET(qpc, qpc, log_sra_max, ilog2(attr->max_rd_atomic));

	if (attr_mask & IB_QP_SQ_PSN)
		context->next_send_psn = cpu_to_be32(attr->sq_psn);
		MLX5_SET(qpc, qpc, next_send_psn, attr->sq_psn);

	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) {
		if (attr->max_dest_rd_atomic)
			context->params2 |=
				cpu_to_be32(fls(attr->max_dest_rd_atomic - 1) << 21);
	}
	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && attr->max_dest_rd_atomic)
		MLX5_SET(qpc, qpc, log_rra_max,
			 ilog2(attr->max_dest_rd_atomic));

	if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) {
		__be32 access_flags;

		err = to_mlx5_access_flags(qp, attr, attr_mask, &access_flags);
		err = set_qpc_atomic_flags(qp, attr, attr_mask, qpc);
		if (err)
			goto out;

		context->params2 |= access_flags;
	}

	if (attr_mask & IB_QP_MIN_RNR_TIMER)
		context->rnr_nextrecvpsn |= cpu_to_be32(attr->min_rnr_timer << 24);
		MLX5_SET(qpc, qpc, min_rnr_nak, attr->min_rnr_timer);

	if (attr_mask & IB_QP_RQ_PSN)
		context->rnr_nextrecvpsn |= cpu_to_be32(attr->rq_psn);
		MLX5_SET(qpc, qpc, next_rcv_psn, attr->rq_psn);

	if (attr_mask & IB_QP_QKEY)
		context->qkey = cpu_to_be32(attr->qkey);
		MLX5_SET(qpc, qpc, q_key, attr->qkey);

	if (qp->rq.wqe_cnt && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
		context->db_rec_addr = cpu_to_be64(qp->db.dma);
		MLX5_SET64(qpc, qpc, dbr_addr, qp->db.dma);

	if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
		u8 port_num = (attr_mask & IB_QP_PORT ? attr->port_num :
@@ -3921,15 +3913,14 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
			set_id = ibqp->counter->id;
		else
			set_id = mlx5_ib_get_counters_id(dev, port_num);
		context->qp_counter_set_usr_page |=
			cpu_to_be32(set_id << 24);
		MLX5_SET(qpc, qpc, counter_set_id, set_id);
	}

	if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
		context->sq_crq_size |= cpu_to_be16(1 << 4);
		MLX5_SET(qpc, qpc, rlky, 1);

	if (qp->flags & MLX5_IB_QP_CREATE_SQPN_QP1)
		context->deth_sqpn = cpu_to_be32(1);
		MLX5_SET(qpc, qpc, deth_sqpn, 1);

	mlx5_cur = to_mlx5_state(cur_state);
	mlx5_new = to_mlx5_state(new_state);
@@ -3987,7 +3978,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,

		err = modify_raw_packet_qp(dev, qp, &raw_qp_param, tx_affinity);
	} else {
		err = mlx5_core_qp_modify(dev, op, optpar, context, &base->mqp);
		err = mlx5_core_qp_modify(dev, op, optpar, qpc, &base->mqp);
	}

	if (err)
@@ -4034,7 +4025,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
	}

out:
	kfree(context);
	kfree(qpc);
	return err;
}

+0 −66
Original line number Diff line number Diff line
@@ -495,72 +495,6 @@ struct mlx5_core_dct {
	struct completion	drained;
};

struct mlx5_qp_path {
	u8			fl_free_ar;
	u8			rsvd3;
	__be16			pkey_index;
	u8			rsvd0;
	u8			grh_mlid;
	__be16			rlid;
	u8			ackto_lt;
	u8			mgid_index;
	u8			static_rate;
	u8			hop_limit;
	__be32			tclass_flowlabel;
	union {
		u8		rgid[16];
		u8		rip[16];
	};
	u8			f_dscp_ecn_prio;
	u8			ecn_dscp;
	__be16			udp_sport;
	u8			dci_cfi_prio_sl;
	u8			port;
	u8			rmac[6];
};

/* FIXME: use mlx5_ifc.h qpc */
struct mlx5_qp_context {
	__be32			flags;
	__be32			flags_pd;
	u8			mtu_msgmax;
	u8			rq_size_stride;
	__be16			sq_crq_size;
	__be32			qp_counter_set_usr_page;
	__be32			wire_qpn;
	__be32			log_pg_sz_remote_qpn;
	struct			mlx5_qp_path pri_path;
	struct			mlx5_qp_path alt_path;
	__be32			params1;
	u8			reserved2[4];
	__be32			next_send_psn;
	__be32			cqn_send;
	__be32			deth_sqpn;
	u8			reserved3[4];
	__be32			last_acked_psn;
	__be32			ssn;
	__be32			params2;
	__be32			rnr_nextrecvpsn;
	__be32			xrcd;
	__be32			cqn_recv;
	__be64			db_rec_addr;
	__be32			qkey;
	__be32			rq_type_srqn;
	__be32			rmsn;
	__be16			hw_sq_wqe_counter;
	__be16			sw_sq_wqe_counter;
	__be16			hw_rcyclic_byte_counter;
	__be16			hw_rq_counter;
	__be16			sw_rcyclic_byte_counter;
	__be16			sw_rq_counter;
	u8			rsvd0[5];
	u8			cgs;
	u8			cs_req;
	u8			cs_res;
	__be64			dc_access_key;
	u8			rsvd1[24];
};

int mlx5_debug_qp_add(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp);
void mlx5_debug_qp_remove(struct mlx5_core_dev *dev, struct mlx5_core_qp *qp);