xref: /openbmc/linux/drivers/infiniband/hw/mlx5/umr.c (revision 04876c12c19e94bbbc94bb0446c7bc7cd75163de)
1*04876c12SAharon Landau // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2*04876c12SAharon Landau /* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. */
3*04876c12SAharon Landau 
4*04876c12SAharon Landau #include "mlx5_ib.h"
5*04876c12SAharon Landau #include "umr.h"
6*04876c12SAharon Landau 
7*04876c12SAharon Landau enum {
8*04876c12SAharon Landau 	MAX_UMR_WR = 128,
9*04876c12SAharon Landau };
10*04876c12SAharon Landau 
11*04876c12SAharon Landau static int mlx5r_umr_qp_rst2rts(struct mlx5_ib_dev *dev, struct ib_qp *qp)
12*04876c12SAharon Landau {
13*04876c12SAharon Landau 	struct ib_qp_attr attr = {};
14*04876c12SAharon Landau 	int ret;
15*04876c12SAharon Landau 
16*04876c12SAharon Landau 	attr.qp_state = IB_QPS_INIT;
17*04876c12SAharon Landau 	attr.port_num = 1;
18*04876c12SAharon Landau 	ret = ib_modify_qp(qp, &attr,
19*04876c12SAharon Landau 			   IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT);
20*04876c12SAharon Landau 	if (ret) {
21*04876c12SAharon Landau 		mlx5_ib_dbg(dev, "Couldn't modify UMR QP\n");
22*04876c12SAharon Landau 		return ret;
23*04876c12SAharon Landau 	}
24*04876c12SAharon Landau 
25*04876c12SAharon Landau 	memset(&attr, 0, sizeof(attr));
26*04876c12SAharon Landau 	attr.qp_state = IB_QPS_RTR;
27*04876c12SAharon Landau 
28*04876c12SAharon Landau 	ret = ib_modify_qp(qp, &attr, IB_QP_STATE);
29*04876c12SAharon Landau 	if (ret) {
30*04876c12SAharon Landau 		mlx5_ib_dbg(dev, "Couldn't modify umr QP to rtr\n");
31*04876c12SAharon Landau 		return ret;
32*04876c12SAharon Landau 	}
33*04876c12SAharon Landau 
34*04876c12SAharon Landau 	memset(&attr, 0, sizeof(attr));
35*04876c12SAharon Landau 	attr.qp_state = IB_QPS_RTS;
36*04876c12SAharon Landau 	ret = ib_modify_qp(qp, &attr, IB_QP_STATE);
37*04876c12SAharon Landau 	if (ret) {
38*04876c12SAharon Landau 		mlx5_ib_dbg(dev, "Couldn't modify umr QP to rts\n");
39*04876c12SAharon Landau 		return ret;
40*04876c12SAharon Landau 	}
41*04876c12SAharon Landau 
42*04876c12SAharon Landau 	return 0;
43*04876c12SAharon Landau }
44*04876c12SAharon Landau 
45*04876c12SAharon Landau int mlx5r_umr_resource_init(struct mlx5_ib_dev *dev)
46*04876c12SAharon Landau {
47*04876c12SAharon Landau 	struct ib_qp_init_attr init_attr = {};
48*04876c12SAharon Landau 	struct ib_pd *pd;
49*04876c12SAharon Landau 	struct ib_cq *cq;
50*04876c12SAharon Landau 	struct ib_qp *qp;
51*04876c12SAharon Landau 	int ret;
52*04876c12SAharon Landau 
53*04876c12SAharon Landau 	pd = ib_alloc_pd(&dev->ib_dev, 0);
54*04876c12SAharon Landau 	if (IS_ERR(pd)) {
55*04876c12SAharon Landau 		mlx5_ib_dbg(dev, "Couldn't create PD for sync UMR QP\n");
56*04876c12SAharon Landau 		return PTR_ERR(pd);
57*04876c12SAharon Landau 	}
58*04876c12SAharon Landau 
59*04876c12SAharon Landau 	cq = ib_alloc_cq(&dev->ib_dev, NULL, 128, 0, IB_POLL_SOFTIRQ);
60*04876c12SAharon Landau 	if (IS_ERR(cq)) {
61*04876c12SAharon Landau 		mlx5_ib_dbg(dev, "Couldn't create CQ for sync UMR QP\n");
62*04876c12SAharon Landau 		ret = PTR_ERR(cq);
63*04876c12SAharon Landau 		goto destroy_pd;
64*04876c12SAharon Landau 	}
65*04876c12SAharon Landau 
66*04876c12SAharon Landau 	init_attr.send_cq = cq;
67*04876c12SAharon Landau 	init_attr.recv_cq = cq;
68*04876c12SAharon Landau 	init_attr.sq_sig_type = IB_SIGNAL_ALL_WR;
69*04876c12SAharon Landau 	init_attr.cap.max_send_wr = MAX_UMR_WR;
70*04876c12SAharon Landau 	init_attr.cap.max_send_sge = 1;
71*04876c12SAharon Landau 	init_attr.qp_type = MLX5_IB_QPT_REG_UMR;
72*04876c12SAharon Landau 	init_attr.port_num = 1;
73*04876c12SAharon Landau 	qp = ib_create_qp(pd, &init_attr);
74*04876c12SAharon Landau 	if (IS_ERR(qp)) {
75*04876c12SAharon Landau 		mlx5_ib_dbg(dev, "Couldn't create sync UMR QP\n");
76*04876c12SAharon Landau 		ret = PTR_ERR(qp);
77*04876c12SAharon Landau 		goto destroy_cq;
78*04876c12SAharon Landau 	}
79*04876c12SAharon Landau 
80*04876c12SAharon Landau 	ret = mlx5r_umr_qp_rst2rts(dev, qp);
81*04876c12SAharon Landau 	if (ret)
82*04876c12SAharon Landau 		goto destroy_qp;
83*04876c12SAharon Landau 
84*04876c12SAharon Landau 	dev->umrc.qp = qp;
85*04876c12SAharon Landau 	dev->umrc.cq = cq;
86*04876c12SAharon Landau 	dev->umrc.pd = pd;
87*04876c12SAharon Landau 
88*04876c12SAharon Landau 	sema_init(&dev->umrc.sem, MAX_UMR_WR);
89*04876c12SAharon Landau 
90*04876c12SAharon Landau 	return 0;
91*04876c12SAharon Landau 
92*04876c12SAharon Landau destroy_qp:
93*04876c12SAharon Landau 	ib_destroy_qp(qp);
94*04876c12SAharon Landau destroy_cq:
95*04876c12SAharon Landau 	ib_free_cq(cq);
96*04876c12SAharon Landau destroy_pd:
97*04876c12SAharon Landau 	ib_dealloc_pd(pd);
98*04876c12SAharon Landau 	return ret;
99*04876c12SAharon Landau }
100*04876c12SAharon Landau 
101*04876c12SAharon Landau void mlx5r_umr_resource_cleanup(struct mlx5_ib_dev *dev)
102*04876c12SAharon Landau {
103*04876c12SAharon Landau 	ib_destroy_qp(dev->umrc.qp);
104*04876c12SAharon Landau 	ib_free_cq(dev->umrc.cq);
105*04876c12SAharon Landau 	ib_dealloc_pd(dev->umrc.pd);
106*04876c12SAharon Landau }
107