1Added support for XRC receive-only QPs (version 2).
2
3Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
4---
5V2:
61. xrc_ops changed to more_ops
7
8diff --git a/src/mlx4.c b/src/mlx4.c
9index 27ca75d..e5ded78 100644
10--- a/src/mlx4.c
11+++ b/src/mlx4.c
12@@ -74,6 +74,11 @@ static struct ibv_more_ops mlx4_more_ops = {
13 	.create_xrc_srq   = mlx4_create_xrc_srq,
14 	.open_xrc_domain  = mlx4_open_xrc_domain,
15 	.close_xrc_domain = mlx4_close_xrc_domain,
16+	.create_xrc_rcv_qp = mlx4_create_xrc_rcv_qp,
17+	.modify_xrc_rcv_qp = mlx4_modify_xrc_rcv_qp,
18+	.query_xrc_rcv_qp = mlx4_query_xrc_rcv_qp,
19+	.reg_xrc_rcv_qp   = mlx4_reg_xrc_rcv_qp,
20+	.unreg_xrc_rcv_qp = mlx4_unreg_xrc_rcv_qp,
21 #endif
22 };
23 #endif
24diff --git a/src/mlx4.h b/src/mlx4.h
25index 3eadb98..6307a2d 100644
26--- a/src/mlx4.h
27+++ b/src/mlx4.h
28@@ -429,6 +429,21 @@ struct ibv_xrc_domain *mlx4_open_xrc_domain(struct ibv_context *context,
29 					    int fd, int oflag);
30 
31 int mlx4_close_xrc_domain(struct ibv_xrc_domain *d);
32+int mlx4_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
33+			   uint32_t *xrc_qp_num);
34+int mlx4_modify_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
35+			   uint32_t xrc_qp_num,
36+			   struct ibv_qp_attr *attr,
37+			   int attr_mask);
38+int mlx4_query_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
39+			  uint32_t xrc_qp_num,
40+			  struct ibv_qp_attr *attr,
41+			  int attr_mask,
42+			  struct ibv_qp_init_attr *init_attr);
43+int mlx4_reg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
44+			uint32_t xrc_qp_num);
45+int mlx4_unreg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
46+			uint32_t xrc_qp_num);
47 #endif
48 
49 
50diff --git a/src/verbs.c b/src/verbs.c
51index b7c9c8e..8261eae 100644
52--- a/src/verbs.c
53+++ b/src/verbs.c
54@@ -778,4 +778,59 @@ int mlx4_close_xrc_domain(struct ibv_xrc_domain *d)
55 	free(d);
56 	return 0;
57 }
58+
59+int mlx4_create_xrc_rcv_qp(struct ibv_qp_init_attr *init_attr,
60+			   uint32_t *xrc_qp_num)
61+{
62+
63+	return ibv_cmd_create_xrc_rcv_qp(init_attr, xrc_qp_num);
64+}
65+
66+int mlx4_modify_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
67+			   uint32_t xrc_qp_num,
68+			   struct ibv_qp_attr *attr,
69+			   int attr_mask)
70+{
71+	return ibv_cmd_modify_xrc_rcv_qp(xrc_domain, xrc_qp_num,
72+					 attr, attr_mask);
73+}
74+
75+int mlx4_query_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
76+			  uint32_t xrc_qp_num,
77+			  struct ibv_qp_attr *attr,
78+			  int attr_mask,
79+			  struct ibv_qp_init_attr *init_attr)
80+{
81+	int ret;
82+
83+	ret = ibv_cmd_query_xrc_rcv_qp(xrc_domain, xrc_qp_num,
84+				       attr, attr_mask, init_attr);
85+	if (ret)
86+		return ret;
87+
88+	init_attr->cap.max_send_wr = init_attr->cap.max_send_sge = 1;
89+	init_attr->cap.max_recv_sge = init_attr->cap.max_recv_wr = 0;
90+	init_attr->cap.max_inline_data = 0;
91+	init_attr->recv_cq = init_attr->send_cq = NULL;
92+	init_attr->srq = NULL;
93+	init_attr->xrc_domain = xrc_domain;
94+	init_attr->qp_type = IBV_QPT_XRC;
95+	init_attr->qp_context = NULL;
96+	attr->cap = init_attr->cap;
97+
98+	return 0;
99+}
100+
101+int mlx4_reg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
102+			uint32_t xrc_qp_num)
103+{
104+	return ibv_cmd_reg_xrc_rcv_qp(xrc_domain, xrc_qp_num);
105+}
106+
107+int mlx4_unreg_xrc_rcv_qp(struct ibv_xrc_domain *xrc_domain,
108+			  uint32_t xrc_qp_num)
109+{
110+	return ibv_cmd_unreg_xrc_rcv_qp(xrc_domain, xrc_qp_num);
111+}
112+
113 #endif
114