xref: /OK3568_Linux_fs/kernel/drivers/infiniband/hw/efa/efa_com_cmd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All rights reserved.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include "efa_com.h"
7*4882a593Smuzhiyun #include "efa_com_cmd.h"
8*4882a593Smuzhiyun 
efa_com_set_dma_addr(dma_addr_t addr,u32 * addr_high,u32 * addr_low)9*4882a593Smuzhiyun void efa_com_set_dma_addr(dma_addr_t addr, u32 *addr_high, u32 *addr_low)
10*4882a593Smuzhiyun {
11*4882a593Smuzhiyun 	*addr_low = lower_32_bits(addr);
12*4882a593Smuzhiyun 	*addr_high = upper_32_bits(addr);
13*4882a593Smuzhiyun }
14*4882a593Smuzhiyun 
efa_com_create_qp(struct efa_com_dev * edev,struct efa_com_create_qp_params * params,struct efa_com_create_qp_result * res)15*4882a593Smuzhiyun int efa_com_create_qp(struct efa_com_dev *edev,
16*4882a593Smuzhiyun 		      struct efa_com_create_qp_params *params,
17*4882a593Smuzhiyun 		      struct efa_com_create_qp_result *res)
18*4882a593Smuzhiyun {
19*4882a593Smuzhiyun 	struct efa_admin_create_qp_cmd create_qp_cmd = {};
20*4882a593Smuzhiyun 	struct efa_admin_create_qp_resp cmd_completion;
21*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
22*4882a593Smuzhiyun 	int err;
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun 	create_qp_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_QP;
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun 	create_qp_cmd.pd = params->pd;
27*4882a593Smuzhiyun 	create_qp_cmd.qp_type = params->qp_type;
28*4882a593Smuzhiyun 	create_qp_cmd.rq_base_addr = params->rq_base_addr;
29*4882a593Smuzhiyun 	create_qp_cmd.send_cq_idx = params->send_cq_idx;
30*4882a593Smuzhiyun 	create_qp_cmd.recv_cq_idx = params->recv_cq_idx;
31*4882a593Smuzhiyun 	create_qp_cmd.qp_alloc_size.send_queue_ring_size =
32*4882a593Smuzhiyun 		params->sq_ring_size_in_bytes;
33*4882a593Smuzhiyun 	create_qp_cmd.qp_alloc_size.send_queue_depth =
34*4882a593Smuzhiyun 			params->sq_depth;
35*4882a593Smuzhiyun 	create_qp_cmd.qp_alloc_size.recv_queue_ring_size =
36*4882a593Smuzhiyun 			params->rq_ring_size_in_bytes;
37*4882a593Smuzhiyun 	create_qp_cmd.qp_alloc_size.recv_queue_depth =
38*4882a593Smuzhiyun 			params->rq_depth;
39*4882a593Smuzhiyun 	create_qp_cmd.uar = params->uarn;
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
42*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&create_qp_cmd,
43*4882a593Smuzhiyun 			       sizeof(create_qp_cmd),
44*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&cmd_completion,
45*4882a593Smuzhiyun 			       sizeof(cmd_completion));
46*4882a593Smuzhiyun 	if (err) {
47*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
48*4882a593Smuzhiyun 				      "Failed to create qp [%d]\n", err);
49*4882a593Smuzhiyun 		return err;
50*4882a593Smuzhiyun 	}
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	res->qp_handle = cmd_completion.qp_handle;
53*4882a593Smuzhiyun 	res->qp_num = cmd_completion.qp_num;
54*4882a593Smuzhiyun 	res->sq_db_offset = cmd_completion.sq_db_offset;
55*4882a593Smuzhiyun 	res->rq_db_offset = cmd_completion.rq_db_offset;
56*4882a593Smuzhiyun 	res->llq_descriptors_offset = cmd_completion.llq_descriptors_offset;
57*4882a593Smuzhiyun 	res->send_sub_cq_idx = cmd_completion.send_sub_cq_idx;
58*4882a593Smuzhiyun 	res->recv_sub_cq_idx = cmd_completion.recv_sub_cq_idx;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	return 0;
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun 
efa_com_modify_qp(struct efa_com_dev * edev,struct efa_com_modify_qp_params * params)63*4882a593Smuzhiyun int efa_com_modify_qp(struct efa_com_dev *edev,
64*4882a593Smuzhiyun 		      struct efa_com_modify_qp_params *params)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
67*4882a593Smuzhiyun 	struct efa_admin_modify_qp_cmd cmd = {};
68*4882a593Smuzhiyun 	struct efa_admin_modify_qp_resp resp;
69*4882a593Smuzhiyun 	int err;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	cmd.aq_common_desc.opcode = EFA_ADMIN_MODIFY_QP;
72*4882a593Smuzhiyun 	cmd.modify_mask = params->modify_mask;
73*4882a593Smuzhiyun 	cmd.qp_handle = params->qp_handle;
74*4882a593Smuzhiyun 	cmd.qp_state = params->qp_state;
75*4882a593Smuzhiyun 	cmd.cur_qp_state = params->cur_qp_state;
76*4882a593Smuzhiyun 	cmd.qkey = params->qkey;
77*4882a593Smuzhiyun 	cmd.sq_psn = params->sq_psn;
78*4882a593Smuzhiyun 	cmd.sq_drained_async_notify = params->sq_drained_async_notify;
79*4882a593Smuzhiyun 	cmd.rnr_retry = params->rnr_retry;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
82*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&cmd,
83*4882a593Smuzhiyun 			       sizeof(cmd),
84*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&resp,
85*4882a593Smuzhiyun 			       sizeof(resp));
86*4882a593Smuzhiyun 	if (err) {
87*4882a593Smuzhiyun 		ibdev_err_ratelimited(
88*4882a593Smuzhiyun 			edev->efa_dev,
89*4882a593Smuzhiyun 			"Failed to modify qp-%u modify_mask[%#x] [%d]\n",
90*4882a593Smuzhiyun 			cmd.qp_handle, cmd.modify_mask, err);
91*4882a593Smuzhiyun 		return err;
92*4882a593Smuzhiyun 	}
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	return 0;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun 
efa_com_query_qp(struct efa_com_dev * edev,struct efa_com_query_qp_params * params,struct efa_com_query_qp_result * result)97*4882a593Smuzhiyun int efa_com_query_qp(struct efa_com_dev *edev,
98*4882a593Smuzhiyun 		     struct efa_com_query_qp_params *params,
99*4882a593Smuzhiyun 		     struct efa_com_query_qp_result *result)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
102*4882a593Smuzhiyun 	struct efa_admin_query_qp_cmd cmd = {};
103*4882a593Smuzhiyun 	struct efa_admin_query_qp_resp resp;
104*4882a593Smuzhiyun 	int err;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	cmd.aq_common_desc.opcode = EFA_ADMIN_QUERY_QP;
107*4882a593Smuzhiyun 	cmd.qp_handle = params->qp_handle;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
110*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&cmd,
111*4882a593Smuzhiyun 			       sizeof(cmd),
112*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&resp,
113*4882a593Smuzhiyun 			       sizeof(resp));
114*4882a593Smuzhiyun 	if (err) {
115*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
116*4882a593Smuzhiyun 				      "Failed to query qp-%u [%d]\n",
117*4882a593Smuzhiyun 				      cmd.qp_handle, err);
118*4882a593Smuzhiyun 		return err;
119*4882a593Smuzhiyun 	}
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	result->qp_state = resp.qp_state;
122*4882a593Smuzhiyun 	result->qkey = resp.qkey;
123*4882a593Smuzhiyun 	result->sq_draining = resp.sq_draining;
124*4882a593Smuzhiyun 	result->sq_psn = resp.sq_psn;
125*4882a593Smuzhiyun 	result->rnr_retry = resp.rnr_retry;
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	return 0;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
efa_com_destroy_qp(struct efa_com_dev * edev,struct efa_com_destroy_qp_params * params)130*4882a593Smuzhiyun int efa_com_destroy_qp(struct efa_com_dev *edev,
131*4882a593Smuzhiyun 		       struct efa_com_destroy_qp_params *params)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	struct efa_admin_destroy_qp_resp cmd_completion;
134*4882a593Smuzhiyun 	struct efa_admin_destroy_qp_cmd qp_cmd = {};
135*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
136*4882a593Smuzhiyun 	int err;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	qp_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_QP;
139*4882a593Smuzhiyun 	qp_cmd.qp_handle = params->qp_handle;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
142*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&qp_cmd,
143*4882a593Smuzhiyun 			       sizeof(qp_cmd),
144*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&cmd_completion,
145*4882a593Smuzhiyun 			       sizeof(cmd_completion));
146*4882a593Smuzhiyun 	if (err) {
147*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
148*4882a593Smuzhiyun 				      "Failed to destroy qp-%u [%d]\n",
149*4882a593Smuzhiyun 				      qp_cmd.qp_handle, err);
150*4882a593Smuzhiyun 		return err;
151*4882a593Smuzhiyun 	}
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	return 0;
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
efa_com_create_cq(struct efa_com_dev * edev,struct efa_com_create_cq_params * params,struct efa_com_create_cq_result * result)156*4882a593Smuzhiyun int efa_com_create_cq(struct efa_com_dev *edev,
157*4882a593Smuzhiyun 		      struct efa_com_create_cq_params *params,
158*4882a593Smuzhiyun 		      struct efa_com_create_cq_result *result)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun 	struct efa_admin_create_cq_resp cmd_completion;
161*4882a593Smuzhiyun 	struct efa_admin_create_cq_cmd create_cmd = {};
162*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
163*4882a593Smuzhiyun 	int err;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	create_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_CQ;
166*4882a593Smuzhiyun 	EFA_SET(&create_cmd.cq_caps_2,
167*4882a593Smuzhiyun 		EFA_ADMIN_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS,
168*4882a593Smuzhiyun 		params->entry_size_in_bytes / 4);
169*4882a593Smuzhiyun 	create_cmd.cq_depth = params->cq_depth;
170*4882a593Smuzhiyun 	create_cmd.num_sub_cqs = params->num_sub_cqs;
171*4882a593Smuzhiyun 	create_cmd.uar = params->uarn;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	efa_com_set_dma_addr(params->dma_addr,
174*4882a593Smuzhiyun 			     &create_cmd.cq_ba.mem_addr_high,
175*4882a593Smuzhiyun 			     &create_cmd.cq_ba.mem_addr_low);
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
178*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&create_cmd,
179*4882a593Smuzhiyun 			       sizeof(create_cmd),
180*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&cmd_completion,
181*4882a593Smuzhiyun 			       sizeof(cmd_completion));
182*4882a593Smuzhiyun 	if (err) {
183*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
184*4882a593Smuzhiyun 				      "Failed to create cq[%d]\n", err);
185*4882a593Smuzhiyun 		return err;
186*4882a593Smuzhiyun 	}
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	result->cq_idx = cmd_completion.cq_idx;
189*4882a593Smuzhiyun 	result->actual_depth = params->cq_depth;
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	return 0;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun 
efa_com_destroy_cq(struct efa_com_dev * edev,struct efa_com_destroy_cq_params * params)194*4882a593Smuzhiyun int efa_com_destroy_cq(struct efa_com_dev *edev,
195*4882a593Smuzhiyun 		       struct efa_com_destroy_cq_params *params)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun 	struct efa_admin_destroy_cq_cmd destroy_cmd = {};
198*4882a593Smuzhiyun 	struct efa_admin_destroy_cq_resp destroy_resp;
199*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
200*4882a593Smuzhiyun 	int err;
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	destroy_cmd.cq_idx = params->cq_idx;
203*4882a593Smuzhiyun 	destroy_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_CQ;
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
206*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&destroy_cmd,
207*4882a593Smuzhiyun 			       sizeof(destroy_cmd),
208*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&destroy_resp,
209*4882a593Smuzhiyun 			       sizeof(destroy_resp));
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	if (err) {
212*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
213*4882a593Smuzhiyun 				      "Failed to destroy CQ-%u [%d]\n",
214*4882a593Smuzhiyun 				      params->cq_idx, err);
215*4882a593Smuzhiyun 		return err;
216*4882a593Smuzhiyun 	}
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun 	return 0;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
efa_com_register_mr(struct efa_com_dev * edev,struct efa_com_reg_mr_params * params,struct efa_com_reg_mr_result * result)221*4882a593Smuzhiyun int efa_com_register_mr(struct efa_com_dev *edev,
222*4882a593Smuzhiyun 			struct efa_com_reg_mr_params *params,
223*4882a593Smuzhiyun 			struct efa_com_reg_mr_result *result)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun 	struct efa_admin_reg_mr_resp cmd_completion;
226*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
227*4882a593Smuzhiyun 	struct efa_admin_reg_mr_cmd mr_cmd = {};
228*4882a593Smuzhiyun 	int err;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	mr_cmd.aq_common_desc.opcode = EFA_ADMIN_REG_MR;
231*4882a593Smuzhiyun 	mr_cmd.pd = params->pd;
232*4882a593Smuzhiyun 	mr_cmd.mr_length = params->mr_length_in_bytes;
233*4882a593Smuzhiyun 	EFA_SET(&mr_cmd.flags, EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT,
234*4882a593Smuzhiyun 		params->page_shift);
235*4882a593Smuzhiyun 	mr_cmd.iova = params->iova;
236*4882a593Smuzhiyun 	mr_cmd.permissions = params->permissions;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	if (params->inline_pbl) {
239*4882a593Smuzhiyun 		memcpy(mr_cmd.pbl.inline_pbl_array,
240*4882a593Smuzhiyun 		       params->pbl.inline_pbl_array,
241*4882a593Smuzhiyun 		       sizeof(mr_cmd.pbl.inline_pbl_array));
242*4882a593Smuzhiyun 	} else {
243*4882a593Smuzhiyun 		mr_cmd.pbl.pbl.length = params->pbl.pbl.length;
244*4882a593Smuzhiyun 		mr_cmd.pbl.pbl.address.mem_addr_low =
245*4882a593Smuzhiyun 			params->pbl.pbl.address.mem_addr_low;
246*4882a593Smuzhiyun 		mr_cmd.pbl.pbl.address.mem_addr_high =
247*4882a593Smuzhiyun 			params->pbl.pbl.address.mem_addr_high;
248*4882a593Smuzhiyun 		EFA_SET(&mr_cmd.aq_common_desc.flags,
249*4882a593Smuzhiyun 			EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
250*4882a593Smuzhiyun 		if (params->indirect)
251*4882a593Smuzhiyun 			EFA_SET(&mr_cmd.aq_common_desc.flags,
252*4882a593Smuzhiyun 				EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT, 1);
253*4882a593Smuzhiyun 	}
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
256*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&mr_cmd,
257*4882a593Smuzhiyun 			       sizeof(mr_cmd),
258*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&cmd_completion,
259*4882a593Smuzhiyun 			       sizeof(cmd_completion));
260*4882a593Smuzhiyun 	if (err) {
261*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
262*4882a593Smuzhiyun 				      "Failed to register mr [%d]\n", err);
263*4882a593Smuzhiyun 		return err;
264*4882a593Smuzhiyun 	}
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	result->l_key = cmd_completion.l_key;
267*4882a593Smuzhiyun 	result->r_key = cmd_completion.r_key;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	return 0;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun 
efa_com_dereg_mr(struct efa_com_dev * edev,struct efa_com_dereg_mr_params * params)272*4882a593Smuzhiyun int efa_com_dereg_mr(struct efa_com_dev *edev,
273*4882a593Smuzhiyun 		     struct efa_com_dereg_mr_params *params)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun 	struct efa_admin_dereg_mr_resp cmd_completion;
276*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
277*4882a593Smuzhiyun 	struct efa_admin_dereg_mr_cmd mr_cmd = {};
278*4882a593Smuzhiyun 	int err;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	mr_cmd.aq_common_desc.opcode = EFA_ADMIN_DEREG_MR;
281*4882a593Smuzhiyun 	mr_cmd.l_key = params->l_key;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
284*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&mr_cmd,
285*4882a593Smuzhiyun 			       sizeof(mr_cmd),
286*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&cmd_completion,
287*4882a593Smuzhiyun 			       sizeof(cmd_completion));
288*4882a593Smuzhiyun 	if (err) {
289*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
290*4882a593Smuzhiyun 				      "Failed to de-register mr(lkey-%u) [%d]\n",
291*4882a593Smuzhiyun 				      mr_cmd.l_key, err);
292*4882a593Smuzhiyun 		return err;
293*4882a593Smuzhiyun 	}
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	return 0;
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun 
efa_com_create_ah(struct efa_com_dev * edev,struct efa_com_create_ah_params * params,struct efa_com_create_ah_result * result)298*4882a593Smuzhiyun int efa_com_create_ah(struct efa_com_dev *edev,
299*4882a593Smuzhiyun 		      struct efa_com_create_ah_params *params,
300*4882a593Smuzhiyun 		      struct efa_com_create_ah_result *result)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun 	struct efa_admin_create_ah_resp cmd_completion;
303*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
304*4882a593Smuzhiyun 	struct efa_admin_create_ah_cmd ah_cmd = {};
305*4882a593Smuzhiyun 	int err;
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	ah_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_AH;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	memcpy(ah_cmd.dest_addr, params->dest_addr, sizeof(ah_cmd.dest_addr));
310*4882a593Smuzhiyun 	ah_cmd.pd = params->pdn;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
313*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&ah_cmd,
314*4882a593Smuzhiyun 			       sizeof(ah_cmd),
315*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&cmd_completion,
316*4882a593Smuzhiyun 			       sizeof(cmd_completion));
317*4882a593Smuzhiyun 	if (err) {
318*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
319*4882a593Smuzhiyun 				      "Failed to create ah for %pI6 [%d]\n",
320*4882a593Smuzhiyun 				      ah_cmd.dest_addr, err);
321*4882a593Smuzhiyun 		return err;
322*4882a593Smuzhiyun 	}
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	result->ah = cmd_completion.ah;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	return 0;
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun 
efa_com_destroy_ah(struct efa_com_dev * edev,struct efa_com_destroy_ah_params * params)329*4882a593Smuzhiyun int efa_com_destroy_ah(struct efa_com_dev *edev,
330*4882a593Smuzhiyun 		       struct efa_com_destroy_ah_params *params)
331*4882a593Smuzhiyun {
332*4882a593Smuzhiyun 	struct efa_admin_destroy_ah_resp cmd_completion;
333*4882a593Smuzhiyun 	struct efa_admin_destroy_ah_cmd ah_cmd = {};
334*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
335*4882a593Smuzhiyun 	int err;
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	ah_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_AH;
338*4882a593Smuzhiyun 	ah_cmd.ah = params->ah;
339*4882a593Smuzhiyun 	ah_cmd.pd = params->pdn;
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
342*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&ah_cmd,
343*4882a593Smuzhiyun 			       sizeof(ah_cmd),
344*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&cmd_completion,
345*4882a593Smuzhiyun 			       sizeof(cmd_completion));
346*4882a593Smuzhiyun 	if (err) {
347*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
348*4882a593Smuzhiyun 				      "Failed to destroy ah-%d pd-%d [%d]\n",
349*4882a593Smuzhiyun 				      ah_cmd.ah, ah_cmd.pd, err);
350*4882a593Smuzhiyun 		return err;
351*4882a593Smuzhiyun 	}
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	return 0;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun bool
efa_com_check_supported_feature_id(struct efa_com_dev * edev,enum efa_admin_aq_feature_id feature_id)357*4882a593Smuzhiyun efa_com_check_supported_feature_id(struct efa_com_dev *edev,
358*4882a593Smuzhiyun 				   enum efa_admin_aq_feature_id feature_id)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun 	u32 feature_mask = 1 << feature_id;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	/* Device attributes is always supported */
363*4882a593Smuzhiyun 	if (feature_id != EFA_ADMIN_DEVICE_ATTR &&
364*4882a593Smuzhiyun 	    !(edev->supported_features & feature_mask))
365*4882a593Smuzhiyun 		return false;
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	return true;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun 
efa_com_get_feature_ex(struct efa_com_dev * edev,struct efa_admin_get_feature_resp * get_resp,enum efa_admin_aq_feature_id feature_id,dma_addr_t control_buf_dma_addr,u32 control_buff_size)370*4882a593Smuzhiyun static int efa_com_get_feature_ex(struct efa_com_dev *edev,
371*4882a593Smuzhiyun 				  struct efa_admin_get_feature_resp *get_resp,
372*4882a593Smuzhiyun 				  enum efa_admin_aq_feature_id feature_id,
373*4882a593Smuzhiyun 				  dma_addr_t control_buf_dma_addr,
374*4882a593Smuzhiyun 				  u32 control_buff_size)
375*4882a593Smuzhiyun {
376*4882a593Smuzhiyun 	struct efa_admin_get_feature_cmd get_cmd = {};
377*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq;
378*4882a593Smuzhiyun 	int err;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	if (!efa_com_check_supported_feature_id(edev, feature_id)) {
381*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
382*4882a593Smuzhiyun 				      "Feature %d isn't supported\n",
383*4882a593Smuzhiyun 				      feature_id);
384*4882a593Smuzhiyun 		return -EOPNOTSUPP;
385*4882a593Smuzhiyun 	}
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	aq = &edev->aq;
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	get_cmd.aq_common_descriptor.opcode = EFA_ADMIN_GET_FEATURE;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	if (control_buff_size)
392*4882a593Smuzhiyun 		EFA_SET(&get_cmd.aq_common_descriptor.flags,
393*4882a593Smuzhiyun 			EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	efa_com_set_dma_addr(control_buf_dma_addr,
396*4882a593Smuzhiyun 			     &get_cmd.control_buffer.address.mem_addr_high,
397*4882a593Smuzhiyun 			     &get_cmd.control_buffer.address.mem_addr_low);
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 	get_cmd.control_buffer.length = control_buff_size;
400*4882a593Smuzhiyun 	get_cmd.feature_common.feature_id = feature_id;
401*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
402*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)
403*4882a593Smuzhiyun 			       &get_cmd,
404*4882a593Smuzhiyun 			       sizeof(get_cmd),
405*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)
406*4882a593Smuzhiyun 			       get_resp,
407*4882a593Smuzhiyun 			       sizeof(*get_resp));
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	if (err) {
410*4882a593Smuzhiyun 		ibdev_err_ratelimited(
411*4882a593Smuzhiyun 			edev->efa_dev,
412*4882a593Smuzhiyun 			"Failed to submit get_feature command %d [%d]\n",
413*4882a593Smuzhiyun 			feature_id, err);
414*4882a593Smuzhiyun 		return err;
415*4882a593Smuzhiyun 	}
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	return 0;
418*4882a593Smuzhiyun }
419*4882a593Smuzhiyun 
efa_com_get_feature(struct efa_com_dev * edev,struct efa_admin_get_feature_resp * get_resp,enum efa_admin_aq_feature_id feature_id)420*4882a593Smuzhiyun static int efa_com_get_feature(struct efa_com_dev *edev,
421*4882a593Smuzhiyun 			       struct efa_admin_get_feature_resp *get_resp,
422*4882a593Smuzhiyun 			       enum efa_admin_aq_feature_id feature_id)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun 	return efa_com_get_feature_ex(edev, get_resp, feature_id, 0, 0);
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun 
efa_com_get_device_attr(struct efa_com_dev * edev,struct efa_com_get_device_attr_result * result)427*4882a593Smuzhiyun int efa_com_get_device_attr(struct efa_com_dev *edev,
428*4882a593Smuzhiyun 			    struct efa_com_get_device_attr_result *result)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun 	struct efa_admin_get_feature_resp resp;
431*4882a593Smuzhiyun 	int err;
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	err = efa_com_get_feature(edev, &resp, EFA_ADMIN_DEVICE_ATTR);
434*4882a593Smuzhiyun 	if (err) {
435*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
436*4882a593Smuzhiyun 				      "Failed to get device attributes %d\n",
437*4882a593Smuzhiyun 				      err);
438*4882a593Smuzhiyun 		return err;
439*4882a593Smuzhiyun 	}
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 	result->page_size_cap = resp.u.device_attr.page_size_cap;
442*4882a593Smuzhiyun 	result->fw_version = resp.u.device_attr.fw_version;
443*4882a593Smuzhiyun 	result->admin_api_version = resp.u.device_attr.admin_api_version;
444*4882a593Smuzhiyun 	result->device_version = resp.u.device_attr.device_version;
445*4882a593Smuzhiyun 	result->supported_features = resp.u.device_attr.supported_features;
446*4882a593Smuzhiyun 	result->phys_addr_width = resp.u.device_attr.phys_addr_width;
447*4882a593Smuzhiyun 	result->virt_addr_width = resp.u.device_attr.virt_addr_width;
448*4882a593Smuzhiyun 	result->db_bar = resp.u.device_attr.db_bar;
449*4882a593Smuzhiyun 	result->max_rdma_size = resp.u.device_attr.max_rdma_size;
450*4882a593Smuzhiyun 	result->device_caps = resp.u.device_attr.device_caps;
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 	if (result->admin_api_version < 1) {
453*4882a593Smuzhiyun 		ibdev_err_ratelimited(
454*4882a593Smuzhiyun 			edev->efa_dev,
455*4882a593Smuzhiyun 			"Failed to get device attr api version [%u < 1]\n",
456*4882a593Smuzhiyun 			result->admin_api_version);
457*4882a593Smuzhiyun 		return -EINVAL;
458*4882a593Smuzhiyun 	}
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	edev->supported_features = resp.u.device_attr.supported_features;
461*4882a593Smuzhiyun 	err = efa_com_get_feature(edev, &resp,
462*4882a593Smuzhiyun 				  EFA_ADMIN_QUEUE_ATTR);
463*4882a593Smuzhiyun 	if (err) {
464*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
465*4882a593Smuzhiyun 				      "Failed to get queue attributes %d\n",
466*4882a593Smuzhiyun 				      err);
467*4882a593Smuzhiyun 		return err;
468*4882a593Smuzhiyun 	}
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	result->max_qp = resp.u.queue_attr.max_qp;
471*4882a593Smuzhiyun 	result->max_sq_depth = resp.u.queue_attr.max_sq_depth;
472*4882a593Smuzhiyun 	result->max_rq_depth = resp.u.queue_attr.max_rq_depth;
473*4882a593Smuzhiyun 	result->max_cq = resp.u.queue_attr.max_cq;
474*4882a593Smuzhiyun 	result->max_cq_depth = resp.u.queue_attr.max_cq_depth;
475*4882a593Smuzhiyun 	result->inline_buf_size = resp.u.queue_attr.inline_buf_size;
476*4882a593Smuzhiyun 	result->max_sq_sge = resp.u.queue_attr.max_wr_send_sges;
477*4882a593Smuzhiyun 	result->max_rq_sge = resp.u.queue_attr.max_wr_recv_sges;
478*4882a593Smuzhiyun 	result->max_mr = resp.u.queue_attr.max_mr;
479*4882a593Smuzhiyun 	result->max_mr_pages = resp.u.queue_attr.max_mr_pages;
480*4882a593Smuzhiyun 	result->max_pd = resp.u.queue_attr.max_pd;
481*4882a593Smuzhiyun 	result->max_ah = resp.u.queue_attr.max_ah;
482*4882a593Smuzhiyun 	result->max_llq_size = resp.u.queue_attr.max_llq_size;
483*4882a593Smuzhiyun 	result->sub_cqs_per_cq = resp.u.queue_attr.sub_cqs_per_cq;
484*4882a593Smuzhiyun 	result->max_wr_rdma_sge = resp.u.queue_attr.max_wr_rdma_sges;
485*4882a593Smuzhiyun 	result->max_tx_batch = resp.u.queue_attr.max_tx_batch;
486*4882a593Smuzhiyun 	result->min_sq_depth = resp.u.queue_attr.min_sq_depth;
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	err = efa_com_get_feature(edev, &resp, EFA_ADMIN_NETWORK_ATTR);
489*4882a593Smuzhiyun 	if (err) {
490*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
491*4882a593Smuzhiyun 				      "Failed to get network attributes %d\n",
492*4882a593Smuzhiyun 				      err);
493*4882a593Smuzhiyun 		return err;
494*4882a593Smuzhiyun 	}
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 	memcpy(result->addr, resp.u.network_attr.addr,
497*4882a593Smuzhiyun 	       sizeof(resp.u.network_attr.addr));
498*4882a593Smuzhiyun 	result->mtu = resp.u.network_attr.mtu;
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	return 0;
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun 
efa_com_get_hw_hints(struct efa_com_dev * edev,struct efa_com_get_hw_hints_result * result)503*4882a593Smuzhiyun int efa_com_get_hw_hints(struct efa_com_dev *edev,
504*4882a593Smuzhiyun 			 struct efa_com_get_hw_hints_result *result)
505*4882a593Smuzhiyun {
506*4882a593Smuzhiyun 	struct efa_admin_get_feature_resp resp;
507*4882a593Smuzhiyun 	int err;
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	err = efa_com_get_feature(edev, &resp, EFA_ADMIN_HW_HINTS);
510*4882a593Smuzhiyun 	if (err) {
511*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
512*4882a593Smuzhiyun 				      "Failed to get hw hints %d\n", err);
513*4882a593Smuzhiyun 		return err;
514*4882a593Smuzhiyun 	}
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	result->admin_completion_timeout = resp.u.hw_hints.admin_completion_timeout;
517*4882a593Smuzhiyun 	result->driver_watchdog_timeout = resp.u.hw_hints.driver_watchdog_timeout;
518*4882a593Smuzhiyun 	result->mmio_read_timeout = resp.u.hw_hints.mmio_read_timeout;
519*4882a593Smuzhiyun 	result->poll_interval = resp.u.hw_hints.poll_interval;
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	return 0;
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun 
efa_com_set_feature_ex(struct efa_com_dev * edev,struct efa_admin_set_feature_resp * set_resp,struct efa_admin_set_feature_cmd * set_cmd,enum efa_admin_aq_feature_id feature_id,dma_addr_t control_buf_dma_addr,u32 control_buff_size)524*4882a593Smuzhiyun int efa_com_set_feature_ex(struct efa_com_dev *edev,
525*4882a593Smuzhiyun 			   struct efa_admin_set_feature_resp *set_resp,
526*4882a593Smuzhiyun 			   struct efa_admin_set_feature_cmd *set_cmd,
527*4882a593Smuzhiyun 			   enum efa_admin_aq_feature_id feature_id,
528*4882a593Smuzhiyun 			   dma_addr_t control_buf_dma_addr,
529*4882a593Smuzhiyun 			   u32 control_buff_size)
530*4882a593Smuzhiyun {
531*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq;
532*4882a593Smuzhiyun 	int err;
533*4882a593Smuzhiyun 
534*4882a593Smuzhiyun 	if (!efa_com_check_supported_feature_id(edev, feature_id)) {
535*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
536*4882a593Smuzhiyun 				      "Feature %d isn't supported\n",
537*4882a593Smuzhiyun 				      feature_id);
538*4882a593Smuzhiyun 		return -EOPNOTSUPP;
539*4882a593Smuzhiyun 	}
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun 	aq = &edev->aq;
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 	set_cmd->aq_common_descriptor.opcode = EFA_ADMIN_SET_FEATURE;
544*4882a593Smuzhiyun 	if (control_buff_size) {
545*4882a593Smuzhiyun 		set_cmd->aq_common_descriptor.flags = 0;
546*4882a593Smuzhiyun 		EFA_SET(&set_cmd->aq_common_descriptor.flags,
547*4882a593Smuzhiyun 			EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
548*4882a593Smuzhiyun 		efa_com_set_dma_addr(control_buf_dma_addr,
549*4882a593Smuzhiyun 				     &set_cmd->control_buffer.address.mem_addr_high,
550*4882a593Smuzhiyun 				     &set_cmd->control_buffer.address.mem_addr_low);
551*4882a593Smuzhiyun 	}
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	set_cmd->control_buffer.length = control_buff_size;
554*4882a593Smuzhiyun 	set_cmd->feature_common.feature_id = feature_id;
555*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
556*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)set_cmd,
557*4882a593Smuzhiyun 			       sizeof(*set_cmd),
558*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)set_resp,
559*4882a593Smuzhiyun 			       sizeof(*set_resp));
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	if (err) {
562*4882a593Smuzhiyun 		ibdev_err_ratelimited(
563*4882a593Smuzhiyun 			edev->efa_dev,
564*4882a593Smuzhiyun 			"Failed to submit set_feature command %d error: %d\n",
565*4882a593Smuzhiyun 			feature_id, err);
566*4882a593Smuzhiyun 		return err;
567*4882a593Smuzhiyun 	}
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	return 0;
570*4882a593Smuzhiyun }
571*4882a593Smuzhiyun 
efa_com_set_feature(struct efa_com_dev * edev,struct efa_admin_set_feature_resp * set_resp,struct efa_admin_set_feature_cmd * set_cmd,enum efa_admin_aq_feature_id feature_id)572*4882a593Smuzhiyun static int efa_com_set_feature(struct efa_com_dev *edev,
573*4882a593Smuzhiyun 			       struct efa_admin_set_feature_resp *set_resp,
574*4882a593Smuzhiyun 			       struct efa_admin_set_feature_cmd *set_cmd,
575*4882a593Smuzhiyun 			       enum efa_admin_aq_feature_id feature_id)
576*4882a593Smuzhiyun {
577*4882a593Smuzhiyun 	return efa_com_set_feature_ex(edev, set_resp, set_cmd, feature_id,
578*4882a593Smuzhiyun 				      0, 0);
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun 
efa_com_set_aenq_config(struct efa_com_dev * edev,u32 groups)581*4882a593Smuzhiyun int efa_com_set_aenq_config(struct efa_com_dev *edev, u32 groups)
582*4882a593Smuzhiyun {
583*4882a593Smuzhiyun 	struct efa_admin_get_feature_resp get_resp;
584*4882a593Smuzhiyun 	struct efa_admin_set_feature_resp set_resp;
585*4882a593Smuzhiyun 	struct efa_admin_set_feature_cmd cmd = {};
586*4882a593Smuzhiyun 	int err;
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 	ibdev_dbg(edev->efa_dev, "Configuring aenq with groups[%#x]\n", groups);
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	err = efa_com_get_feature(edev, &get_resp, EFA_ADMIN_AENQ_CONFIG);
591*4882a593Smuzhiyun 	if (err) {
592*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
593*4882a593Smuzhiyun 				      "Failed to get aenq attributes: %d\n",
594*4882a593Smuzhiyun 				      err);
595*4882a593Smuzhiyun 		return err;
596*4882a593Smuzhiyun 	}
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun 	ibdev_dbg(edev->efa_dev,
599*4882a593Smuzhiyun 		  "Get aenq groups: supported[%#x] enabled[%#x]\n",
600*4882a593Smuzhiyun 		  get_resp.u.aenq.supported_groups,
601*4882a593Smuzhiyun 		  get_resp.u.aenq.enabled_groups);
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 	if ((get_resp.u.aenq.supported_groups & groups) != groups) {
604*4882a593Smuzhiyun 		ibdev_err_ratelimited(
605*4882a593Smuzhiyun 			edev->efa_dev,
606*4882a593Smuzhiyun 			"Trying to set unsupported aenq groups[%#x] supported[%#x]\n",
607*4882a593Smuzhiyun 			groups, get_resp.u.aenq.supported_groups);
608*4882a593Smuzhiyun 		return -EOPNOTSUPP;
609*4882a593Smuzhiyun 	}
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun 	cmd.u.aenq.enabled_groups = groups;
612*4882a593Smuzhiyun 	err = efa_com_set_feature(edev, &set_resp, &cmd,
613*4882a593Smuzhiyun 				  EFA_ADMIN_AENQ_CONFIG);
614*4882a593Smuzhiyun 	if (err) {
615*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
616*4882a593Smuzhiyun 				      "Failed to set aenq attributes: %d\n",
617*4882a593Smuzhiyun 				      err);
618*4882a593Smuzhiyun 		return err;
619*4882a593Smuzhiyun 	}
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 	return 0;
622*4882a593Smuzhiyun }
623*4882a593Smuzhiyun 
efa_com_alloc_pd(struct efa_com_dev * edev,struct efa_com_alloc_pd_result * result)624*4882a593Smuzhiyun int efa_com_alloc_pd(struct efa_com_dev *edev,
625*4882a593Smuzhiyun 		     struct efa_com_alloc_pd_result *result)
626*4882a593Smuzhiyun {
627*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
628*4882a593Smuzhiyun 	struct efa_admin_alloc_pd_cmd cmd = {};
629*4882a593Smuzhiyun 	struct efa_admin_alloc_pd_resp resp;
630*4882a593Smuzhiyun 	int err;
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	cmd.aq_common_descriptor.opcode = EFA_ADMIN_ALLOC_PD;
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
635*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&cmd,
636*4882a593Smuzhiyun 			       sizeof(cmd),
637*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&resp,
638*4882a593Smuzhiyun 			       sizeof(resp));
639*4882a593Smuzhiyun 	if (err) {
640*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
641*4882a593Smuzhiyun 				      "Failed to allocate pd[%d]\n", err);
642*4882a593Smuzhiyun 		return err;
643*4882a593Smuzhiyun 	}
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun 	result->pdn = resp.pd;
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 	return 0;
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun 
efa_com_dealloc_pd(struct efa_com_dev * edev,struct efa_com_dealloc_pd_params * params)650*4882a593Smuzhiyun int efa_com_dealloc_pd(struct efa_com_dev *edev,
651*4882a593Smuzhiyun 		       struct efa_com_dealloc_pd_params *params)
652*4882a593Smuzhiyun {
653*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
654*4882a593Smuzhiyun 	struct efa_admin_dealloc_pd_cmd cmd = {};
655*4882a593Smuzhiyun 	struct efa_admin_dealloc_pd_resp resp;
656*4882a593Smuzhiyun 	int err;
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun 	cmd.aq_common_descriptor.opcode = EFA_ADMIN_DEALLOC_PD;
659*4882a593Smuzhiyun 	cmd.pd = params->pdn;
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
662*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&cmd,
663*4882a593Smuzhiyun 			       sizeof(cmd),
664*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&resp,
665*4882a593Smuzhiyun 			       sizeof(resp));
666*4882a593Smuzhiyun 	if (err) {
667*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
668*4882a593Smuzhiyun 				      "Failed to deallocate pd-%u [%d]\n",
669*4882a593Smuzhiyun 				      cmd.pd, err);
670*4882a593Smuzhiyun 		return err;
671*4882a593Smuzhiyun 	}
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun 	return 0;
674*4882a593Smuzhiyun }
675*4882a593Smuzhiyun 
efa_com_alloc_uar(struct efa_com_dev * edev,struct efa_com_alloc_uar_result * result)676*4882a593Smuzhiyun int efa_com_alloc_uar(struct efa_com_dev *edev,
677*4882a593Smuzhiyun 		      struct efa_com_alloc_uar_result *result)
678*4882a593Smuzhiyun {
679*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
680*4882a593Smuzhiyun 	struct efa_admin_alloc_uar_cmd cmd = {};
681*4882a593Smuzhiyun 	struct efa_admin_alloc_uar_resp resp;
682*4882a593Smuzhiyun 	int err;
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	cmd.aq_common_descriptor.opcode = EFA_ADMIN_ALLOC_UAR;
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
687*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&cmd,
688*4882a593Smuzhiyun 			       sizeof(cmd),
689*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&resp,
690*4882a593Smuzhiyun 			       sizeof(resp));
691*4882a593Smuzhiyun 	if (err) {
692*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
693*4882a593Smuzhiyun 				      "Failed to allocate uar[%d]\n", err);
694*4882a593Smuzhiyun 		return err;
695*4882a593Smuzhiyun 	}
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	result->uarn = resp.uar;
698*4882a593Smuzhiyun 
699*4882a593Smuzhiyun 	return 0;
700*4882a593Smuzhiyun }
701*4882a593Smuzhiyun 
efa_com_dealloc_uar(struct efa_com_dev * edev,struct efa_com_dealloc_uar_params * params)702*4882a593Smuzhiyun int efa_com_dealloc_uar(struct efa_com_dev *edev,
703*4882a593Smuzhiyun 			struct efa_com_dealloc_uar_params *params)
704*4882a593Smuzhiyun {
705*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
706*4882a593Smuzhiyun 	struct efa_admin_dealloc_uar_cmd cmd = {};
707*4882a593Smuzhiyun 	struct efa_admin_dealloc_uar_resp resp;
708*4882a593Smuzhiyun 	int err;
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	cmd.aq_common_descriptor.opcode = EFA_ADMIN_DEALLOC_UAR;
711*4882a593Smuzhiyun 	cmd.uar = params->uarn;
712*4882a593Smuzhiyun 
713*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
714*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&cmd,
715*4882a593Smuzhiyun 			       sizeof(cmd),
716*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&resp,
717*4882a593Smuzhiyun 			       sizeof(resp));
718*4882a593Smuzhiyun 	if (err) {
719*4882a593Smuzhiyun 		ibdev_err_ratelimited(edev->efa_dev,
720*4882a593Smuzhiyun 				      "Failed to deallocate uar-%u [%d]\n",
721*4882a593Smuzhiyun 				      cmd.uar, err);
722*4882a593Smuzhiyun 		return err;
723*4882a593Smuzhiyun 	}
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun 	return 0;
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun 
efa_com_get_stats(struct efa_com_dev * edev,struct efa_com_get_stats_params * params,union efa_com_get_stats_result * result)728*4882a593Smuzhiyun int efa_com_get_stats(struct efa_com_dev *edev,
729*4882a593Smuzhiyun 		      struct efa_com_get_stats_params *params,
730*4882a593Smuzhiyun 		      union efa_com_get_stats_result *result)
731*4882a593Smuzhiyun {
732*4882a593Smuzhiyun 	struct efa_com_admin_queue *aq = &edev->aq;
733*4882a593Smuzhiyun 	struct efa_admin_aq_get_stats_cmd cmd = {};
734*4882a593Smuzhiyun 	struct efa_admin_acq_get_stats_resp resp;
735*4882a593Smuzhiyun 	int err;
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun 	cmd.aq_common_descriptor.opcode = EFA_ADMIN_GET_STATS;
738*4882a593Smuzhiyun 	cmd.type = params->type;
739*4882a593Smuzhiyun 	cmd.scope = params->scope;
740*4882a593Smuzhiyun 	cmd.scope_modifier = params->scope_modifier;
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	err = efa_com_cmd_exec(aq,
743*4882a593Smuzhiyun 			       (struct efa_admin_aq_entry *)&cmd,
744*4882a593Smuzhiyun 			       sizeof(cmd),
745*4882a593Smuzhiyun 			       (struct efa_admin_acq_entry *)&resp,
746*4882a593Smuzhiyun 			       sizeof(resp));
747*4882a593Smuzhiyun 	if (err) {
748*4882a593Smuzhiyun 		ibdev_err_ratelimited(
749*4882a593Smuzhiyun 			edev->efa_dev,
750*4882a593Smuzhiyun 			"Failed to get stats type-%u scope-%u.%u [%d]\n",
751*4882a593Smuzhiyun 			cmd.type, cmd.scope, cmd.scope_modifier, err);
752*4882a593Smuzhiyun 		return err;
753*4882a593Smuzhiyun 	}
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun 	switch (cmd.type) {
756*4882a593Smuzhiyun 	case EFA_ADMIN_GET_STATS_TYPE_BASIC:
757*4882a593Smuzhiyun 		result->basic_stats.tx_bytes = resp.u.basic_stats.tx_bytes;
758*4882a593Smuzhiyun 		result->basic_stats.tx_pkts = resp.u.basic_stats.tx_pkts;
759*4882a593Smuzhiyun 		result->basic_stats.rx_bytes = resp.u.basic_stats.rx_bytes;
760*4882a593Smuzhiyun 		result->basic_stats.rx_pkts = resp.u.basic_stats.rx_pkts;
761*4882a593Smuzhiyun 		result->basic_stats.rx_drops = resp.u.basic_stats.rx_drops;
762*4882a593Smuzhiyun 		break;
763*4882a593Smuzhiyun 	case EFA_ADMIN_GET_STATS_TYPE_MESSAGES:
764*4882a593Smuzhiyun 		result->messages_stats.send_bytes = resp.u.messages_stats.send_bytes;
765*4882a593Smuzhiyun 		result->messages_stats.send_wrs = resp.u.messages_stats.send_wrs;
766*4882a593Smuzhiyun 		result->messages_stats.recv_bytes = resp.u.messages_stats.recv_bytes;
767*4882a593Smuzhiyun 		result->messages_stats.recv_wrs = resp.u.messages_stats.recv_wrs;
768*4882a593Smuzhiyun 		break;
769*4882a593Smuzhiyun 	case EFA_ADMIN_GET_STATS_TYPE_RDMA_READ:
770*4882a593Smuzhiyun 		result->rdma_read_stats.read_wrs = resp.u.rdma_read_stats.read_wrs;
771*4882a593Smuzhiyun 		result->rdma_read_stats.read_bytes = resp.u.rdma_read_stats.read_bytes;
772*4882a593Smuzhiyun 		result->rdma_read_stats.read_wr_err = resp.u.rdma_read_stats.read_wr_err;
773*4882a593Smuzhiyun 		result->rdma_read_stats.read_resp_bytes = resp.u.rdma_read_stats.read_resp_bytes;
774*4882a593Smuzhiyun 		break;
775*4882a593Smuzhiyun 	}
776*4882a593Smuzhiyun 
777*4882a593Smuzhiyun 	return 0;
778*4882a593Smuzhiyun }
779