xref: /linux/drivers/infiniband/hw/efa/efa_com_cmd.c (revision 2d7eaeb05ae265bd64270376e6a2c0d80244771f)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
2 /*
3  * Copyright 2018-2026 Amazon.com, Inc. or its affiliates. All rights reserved.
4  */
5 
6 #include "efa_com.h"
7 #include "efa_com_cmd.h"
8 
9 #define EFA_DEFAULT_LINK_SPEED_GBPS 100
10 
11 int efa_com_create_qp(struct efa_com_dev *edev,
12 		      struct efa_com_create_qp_params *params,
13 		      struct efa_com_create_qp_result *res)
14 {
15 	struct efa_admin_create_qp_cmd create_qp_cmd = {};
16 	struct efa_admin_create_qp_resp cmd_completion;
17 	struct efa_com_admin_queue *aq = &edev->aq;
18 	int err;
19 
20 	create_qp_cmd.pd = params->pd;
21 	create_qp_cmd.qp_type = params->qp_type;
22 	create_qp_cmd.rq_base_addr = params->rq_base_addr;
23 	create_qp_cmd.send_cq_idx = params->send_cq_idx;
24 	create_qp_cmd.recv_cq_idx = params->recv_cq_idx;
25 	create_qp_cmd.qp_alloc_size.send_queue_ring_size =
26 		params->sq_ring_size_in_bytes;
27 	create_qp_cmd.qp_alloc_size.send_queue_depth =
28 			params->sq_depth;
29 	create_qp_cmd.qp_alloc_size.recv_queue_ring_size =
30 			params->rq_ring_size_in_bytes;
31 	create_qp_cmd.qp_alloc_size.recv_queue_depth =
32 			params->rq_depth;
33 	create_qp_cmd.uar = params->uarn;
34 	create_qp_cmd.sl = params->sl;
35 
36 	if (params->unsolicited_write_recv)
37 		EFA_SET(&create_qp_cmd.flags, EFA_ADMIN_CREATE_QP_CMD_UNSOLICITED_WRITE_RECV, 1);
38 
39 	if (params->sq_64_bit_req_id)
40 		EFA_SET(&create_qp_cmd.flags, EFA_ADMIN_CREATE_QP_CMD_SQ_64_BIT_REQ_ID, 1);
41 
42 	err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_QP, 0,
43 			       &create_qp_cmd, sizeof(create_qp_cmd),
44 			       (struct efa_admin_acq_entry *)&cmd_completion,
45 			       sizeof(cmd_completion));
46 	if (err) {
47 		ibdev_err_ratelimited(edev->efa_dev,
48 				      "Failed to create qp [%d]\n", err);
49 		return err;
50 	}
51 
52 	res->qp_handle = cmd_completion.qp_handle;
53 	res->qp_num = cmd_completion.qp_num;
54 	res->sq_db_offset = cmd_completion.sq_db_offset;
55 	res->rq_db_offset = cmd_completion.rq_db_offset;
56 	res->llq_descriptors_offset = cmd_completion.llq_descriptors_offset;
57 	res->send_sub_cq_idx = cmd_completion.send_sub_cq_idx;
58 	res->recv_sub_cq_idx = cmd_completion.recv_sub_cq_idx;
59 
60 	return 0;
61 }
62 
63 int efa_com_modify_qp(struct efa_com_dev *edev,
64 		      struct efa_com_modify_qp_params *params)
65 {
66 	struct efa_com_admin_queue *aq = &edev->aq;
67 	struct efa_admin_modify_qp_cmd cmd = {};
68 	struct efa_admin_modify_qp_resp resp;
69 	int err;
70 
71 	cmd.modify_mask = params->modify_mask;
72 	cmd.qp_handle = params->qp_handle;
73 	cmd.qp_state = params->qp_state;
74 	cmd.cur_qp_state = params->cur_qp_state;
75 	cmd.qkey = params->qkey;
76 	cmd.sq_psn = params->sq_psn;
77 	cmd.sq_drained_async_notify = params->sq_drained_async_notify;
78 	cmd.rnr_retry = params->rnr_retry;
79 
80 	err = efa_com_cmd_exec(aq, EFA_ADMIN_MODIFY_QP, 0,
81 			       &cmd, sizeof(cmd),
82 			       (struct efa_admin_acq_entry *)&resp, sizeof(resp));
83 	if (err) {
84 		ibdev_err_ratelimited(
85 			edev->efa_dev,
86 			"Failed to modify qp-%u modify_mask[%#x] [%d]\n",
87 			cmd.qp_handle, cmd.modify_mask, err);
88 		return err;
89 	}
90 
91 	return 0;
92 }
93 
94 int efa_com_query_qp(struct efa_com_dev *edev,
95 		     struct efa_com_query_qp_params *params,
96 		     struct efa_com_query_qp_result *result)
97 {
98 	struct efa_com_admin_queue *aq = &edev->aq;
99 	struct efa_admin_query_qp_cmd cmd = {};
100 	struct efa_admin_query_qp_resp resp;
101 	int err;
102 
103 	cmd.qp_handle = params->qp_handle;
104 
105 	err = efa_com_cmd_exec(aq, EFA_ADMIN_QUERY_QP, 0,
106 			       &cmd, sizeof(cmd),
107 			       (struct efa_admin_acq_entry *)&resp, sizeof(resp));
108 	if (err) {
109 		ibdev_err_ratelimited(edev->efa_dev,
110 				      "Failed to query qp-%u [%d]\n",
111 				      cmd.qp_handle, err);
112 		return err;
113 	}
114 
115 	result->qp_state = resp.qp_state;
116 	result->qkey = resp.qkey;
117 	result->sq_draining = resp.sq_draining;
118 	result->sq_psn = resp.sq_psn;
119 	result->rnr_retry = resp.rnr_retry;
120 
121 	return 0;
122 }
123 
124 int efa_com_destroy_qp(struct efa_com_dev *edev,
125 		       struct efa_com_destroy_qp_params *params)
126 {
127 	struct efa_admin_destroy_qp_resp cmd_completion;
128 	struct efa_admin_destroy_qp_cmd qp_cmd = {};
129 	struct efa_com_admin_queue *aq = &edev->aq;
130 	int err;
131 
132 	qp_cmd.qp_handle = params->qp_handle;
133 
134 	err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_QP, 0,
135 			       &qp_cmd, sizeof(qp_cmd),
136 			       (struct efa_admin_acq_entry *)&cmd_completion,
137 			       sizeof(cmd_completion));
138 	if (err) {
139 		ibdev_err_ratelimited(edev->efa_dev,
140 				      "Failed to destroy qp-%u [%d]\n",
141 				      qp_cmd.qp_handle, err);
142 		return err;
143 	}
144 
145 	return 0;
146 }
147 
148 int efa_com_create_cq(struct efa_com_dev *edev,
149 		      struct efa_com_create_cq_params *params,
150 		      struct efa_com_create_cq_result *result)
151 {
152 	struct efa_admin_create_cq_resp cmd_completion = {};
153 	struct efa_admin_create_cq_cmd create_cmd = {};
154 	struct efa_com_admin_queue *aq = &edev->aq;
155 	int err;
156 
157 	EFA_SET(&create_cmd.cq_caps_2,
158 		EFA_ADMIN_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS,
159 		params->entry_size_in_bytes / 4);
160 	create_cmd.sub_cq_depth = params->sub_cq_depth;
161 	create_cmd.num_sub_cqs = params->num_sub_cqs;
162 	create_cmd.uar = params->uarn;
163 	if (params->interrupt_mode_enabled) {
164 		EFA_SET(&create_cmd.cq_caps_1,
165 			EFA_ADMIN_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED, 1);
166 		create_cmd.eqn = params->eqn;
167 	}
168 	if (params->set_src_addr) {
169 		EFA_SET(&create_cmd.cq_caps_2,
170 			EFA_ADMIN_CREATE_CQ_CMD_SET_SRC_ADDR, 1);
171 	}
172 	if (params->sq_comp_64_bit_req_id) {
173 		EFA_SET(&create_cmd.cq_caps_2,
174 			EFA_ADMIN_CREATE_CQ_CMD_SQ_COMP_64_BIT_REQ_ID, 1);
175 	}
176 
177 	efa_com_set_dma_addr(params->dma_addr,
178 			     &create_cmd.cq_ba.mem_addr_high,
179 			     &create_cmd.cq_ba.mem_addr_low);
180 
181 	err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_CQ, 0,
182 			       &create_cmd, sizeof(create_cmd),
183 			       (struct efa_admin_acq_entry *)&cmd_completion,
184 			       sizeof(cmd_completion));
185 	if (err) {
186 		ibdev_err_ratelimited(edev->efa_dev,
187 				      "Failed to create cq[%d]\n", err);
188 		return err;
189 	}
190 
191 	result->cq_idx = cmd_completion.cq_idx;
192 	result->actual_depth = params->sub_cq_depth;
193 	result->db_off = cmd_completion.db_offset;
194 	result->db_valid = EFA_GET(&cmd_completion.flags,
195 				   EFA_ADMIN_CREATE_CQ_RESP_DB_VALID);
196 
197 	return 0;
198 }
199 
200 int efa_com_destroy_cq(struct efa_com_dev *edev,
201 		       struct efa_com_destroy_cq_params *params)
202 {
203 	struct efa_admin_destroy_cq_cmd destroy_cmd = {};
204 	struct efa_admin_destroy_cq_resp destroy_resp;
205 	struct efa_com_admin_queue *aq = &edev->aq;
206 	int err;
207 
208 	destroy_cmd.cq_idx = params->cq_idx;
209 
210 	err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_CQ, 0,
211 			       &destroy_cmd, sizeof(destroy_cmd),
212 			       (struct efa_admin_acq_entry *)&destroy_resp,
213 			       sizeof(destroy_resp));
214 
215 	if (err) {
216 		ibdev_err_ratelimited(edev->efa_dev,
217 				      "Failed to destroy CQ-%u [%d]\n",
218 				      params->cq_idx, err);
219 		return err;
220 	}
221 
222 	return 0;
223 }
224 
225 int efa_com_register_mr(struct efa_com_dev *edev,
226 			struct efa_com_reg_mr_params *params,
227 			struct efa_com_reg_mr_result *result)
228 {
229 	struct efa_admin_reg_mr_resp cmd_completion;
230 	struct efa_com_admin_queue *aq = &edev->aq;
231 	struct efa_admin_reg_mr_cmd mr_cmd = {};
232 	u8 flags = 0;
233 	int err;
234 
235 	mr_cmd.pd = params->pd;
236 	mr_cmd.mr_length = params->mr_length_in_bytes;
237 	EFA_SET(&mr_cmd.flags, EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT,
238 		params->page_shift);
239 	if (params->relaxed_ordering)
240 		EFA_SET(&mr_cmd.flags, EFA_ADMIN_REG_MR_CMD_RELAXED_ORDERING_ENABLE, 1);
241 	mr_cmd.iova = params->iova;
242 	if (params->permissions.local_write)
243 		EFA_SET(&mr_cmd.permissions, EFA_ADMIN_REG_MR_CMD_LOCAL_WRITE_ENABLE, 1);
244 	if (params->permissions.remote_write)
245 		EFA_SET(&mr_cmd.permissions, EFA_ADMIN_REG_MR_CMD_REMOTE_WRITE_ENABLE, 1);
246 	if (params->permissions.remote_read)
247 		EFA_SET(&mr_cmd.permissions, EFA_ADMIN_REG_MR_CMD_REMOTE_READ_ENABLE, 1);
248 
249 	if (params->inline_pbl) {
250 		memcpy(mr_cmd.pbl.inline_pbl_array,
251 		       params->pbl.inline_pbl_array,
252 		       sizeof(mr_cmd.pbl.inline_pbl_array));
253 	} else {
254 		mr_cmd.pbl.pbl.length = params->pbl.pbl.length;
255 		mr_cmd.pbl.pbl.address.mem_addr_low =
256 			params->pbl.pbl.address.mem_addr_low;
257 		mr_cmd.pbl.pbl.address.mem_addr_high =
258 			params->pbl.pbl.address.mem_addr_high;
259 		EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
260 		if (params->indirect)
261 			EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT, 1);
262 	}
263 
264 	err = efa_com_cmd_exec(aq, EFA_ADMIN_REG_MR, flags,
265 			       &mr_cmd, sizeof(mr_cmd),
266 			       (struct efa_admin_acq_entry *)&cmd_completion,
267 			       sizeof(cmd_completion));
268 	if (err) {
269 		ibdev_err_ratelimited(edev->efa_dev,
270 				      "Failed to register mr [%d]\n", err);
271 		return err;
272 	}
273 
274 	result->l_key = cmd_completion.l_key;
275 	result->r_key = cmd_completion.r_key;
276 	result->ic_info.recv_ic_id = cmd_completion.recv_ic_id;
277 	result->ic_info.rdma_read_ic_id = cmd_completion.rdma_read_ic_id;
278 	result->ic_info.rdma_recv_ic_id = cmd_completion.rdma_recv_ic_id;
279 	result->ic_info.recv_ic_id_valid = EFA_GET(&cmd_completion.validity,
280 						   EFA_ADMIN_REG_MR_RESP_RECV_IC_ID);
281 	result->ic_info.rdma_read_ic_id_valid = EFA_GET(&cmd_completion.validity,
282 							EFA_ADMIN_REG_MR_RESP_RDMA_READ_IC_ID);
283 	result->ic_info.rdma_recv_ic_id_valid = EFA_GET(&cmd_completion.validity,
284 							EFA_ADMIN_REG_MR_RESP_RDMA_RECV_IC_ID);
285 
286 	return 0;
287 }
288 
289 int efa_com_dereg_mr(struct efa_com_dev *edev,
290 		     struct efa_com_dereg_mr_params *params)
291 {
292 	struct efa_admin_dereg_mr_resp cmd_completion;
293 	struct efa_com_admin_queue *aq = &edev->aq;
294 	struct efa_admin_dereg_mr_cmd mr_cmd = {};
295 	int err;
296 
297 	mr_cmd.l_key = params->l_key;
298 
299 	err = efa_com_cmd_exec(aq, EFA_ADMIN_DEREG_MR, 0,
300 			       &mr_cmd, sizeof(mr_cmd),
301 			       (struct efa_admin_acq_entry *)&cmd_completion,
302 			       sizeof(cmd_completion));
303 	if (err) {
304 		ibdev_err_ratelimited(edev->efa_dev,
305 				      "Failed to de-register mr(lkey-%u) [%d]\n",
306 				      mr_cmd.l_key, err);
307 		return err;
308 	}
309 
310 	return 0;
311 }
312 
313 int efa_com_create_ah(struct efa_com_dev *edev,
314 		      struct efa_com_create_ah_params *params,
315 		      struct efa_com_create_ah_result *result)
316 {
317 	struct efa_admin_create_ah_resp cmd_completion;
318 	struct efa_com_admin_queue *aq = &edev->aq;
319 	struct efa_admin_create_ah_cmd ah_cmd = {};
320 	struct efa_ah_cache_entry *entry;
321 	int err;
322 
323 	entry = efa_ah_cache_get(&edev->ah_cache, params->pdn, params->dest_addr);
324 	if (IS_ERR(entry))
325 		return PTR_ERR(entry);
326 
327 	mutex_lock(&entry->lock);
328 	if (entry->usecnt) {
329 		result->ah = entry->ah;
330 		entry->usecnt++;
331 		mutex_unlock(&entry->lock);
332 		return 0;
333 	}
334 
335 	memcpy(ah_cmd.dest_addr, params->dest_addr, sizeof(ah_cmd.dest_addr));
336 	ah_cmd.pd = params->pdn;
337 
338 	err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_AH, 0,
339 			       &ah_cmd, sizeof(ah_cmd),
340 			       (struct efa_admin_acq_entry *)&cmd_completion,
341 			       sizeof(cmd_completion));
342 	if (err) {
343 		mutex_unlock(&entry->lock);
344 		efa_ah_cache_put(&edev->ah_cache, entry);
345 		ibdev_err_ratelimited(edev->efa_dev,
346 				      "Failed to create ah for %pI6 [%d]\n",
347 				      ah_cmd.dest_addr, err);
348 		return err;
349 	}
350 
351 	entry->ah = cmd_completion.ah;
352 	result->ah = cmd_completion.ah;
353 	entry->usecnt++;
354 	mutex_unlock(&entry->lock);
355 
356 	return 0;
357 }
358 
359 int efa_com_destroy_ah(struct efa_com_dev *edev,
360 		       struct efa_com_destroy_ah_params *params)
361 {
362 	struct efa_admin_destroy_ah_resp cmd_completion;
363 	struct efa_admin_destroy_ah_cmd ah_cmd = {};
364 	struct efa_com_admin_queue *aq = &edev->aq;
365 	struct efa_ah_cache_entry *entry;
366 	int err = 0;
367 
368 	entry = efa_ah_cache_lookup(&edev->ah_cache, params->pdn, params->gid);
369 	if (!entry)
370 		return -EINVAL;
371 
372 	mutex_lock(&entry->lock);
373 	if (entry->usecnt > 1)
374 		goto out_put;
375 
376 	ah_cmd.ah = entry->ah;
377 	ah_cmd.pd = entry->key.pd;
378 
379 	err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_AH, 0,
380 			       &ah_cmd, sizeof(ah_cmd),
381 			       (struct efa_admin_acq_entry *)&cmd_completion,
382 			       sizeof(cmd_completion));
383 	if (err) {
384 		mutex_unlock(&entry->lock);
385 		ibdev_err_ratelimited(edev->efa_dev,
386 				      "Failed to destroy ah-%d pd-%d [%d]\n",
387 				      ah_cmd.ah, ah_cmd.pd, err);
388 		return err;
389 	}
390 
391 out_put:
392 	entry->usecnt--;
393 	mutex_unlock(&entry->lock);
394 	efa_ah_cache_put(&edev->ah_cache, entry);
395 
396 	return err;
397 }
398 
399 bool
400 efa_com_check_supported_feature_id(struct efa_com_dev *edev,
401 				   enum efa_admin_aq_feature_id feature_id)
402 {
403 	u32 feature_mask = 1 << feature_id;
404 
405 	/* Device attributes is always supported */
406 	if (feature_id != EFA_ADMIN_DEVICE_ATTR &&
407 	    !(edev->supported_features & feature_mask))
408 		return false;
409 
410 	return true;
411 }
412 
413 static int efa_com_get_feature_ex(struct efa_com_dev *edev,
414 				  struct efa_admin_get_feature_resp *get_resp,
415 				  enum efa_admin_aq_feature_id feature_id,
416 				  dma_addr_t control_buf_dma_addr,
417 				  u32 control_buff_size)
418 {
419 	struct efa_admin_get_feature_cmd get_cmd = {};
420 	struct efa_com_admin_queue *aq;
421 	u8 flags = 0;
422 	int err;
423 
424 	if (!efa_com_check_supported_feature_id(edev, feature_id)) {
425 		ibdev_err_ratelimited(edev->efa_dev,
426 				      "Feature %d isn't supported\n",
427 				      feature_id);
428 		return -EOPNOTSUPP;
429 	}
430 
431 	aq = &edev->aq;
432 
433 	if (control_buff_size)
434 		EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
435 
436 	efa_com_set_dma_addr(control_buf_dma_addr,
437 			     &get_cmd.control_buffer.address.mem_addr_high,
438 			     &get_cmd.control_buffer.address.mem_addr_low);
439 
440 	get_cmd.control_buffer.length = control_buff_size;
441 	get_cmd.feature_common.feature_id = feature_id;
442 	err = efa_com_cmd_exec(aq, EFA_ADMIN_GET_FEATURE, flags,
443 			       &get_cmd, sizeof(get_cmd),
444 			       (struct efa_admin_acq_entry *)get_resp,
445 			       sizeof(*get_resp));
446 
447 	if (err) {
448 		ibdev_err_ratelimited(
449 			edev->efa_dev,
450 			"Failed to submit get_feature command %d [%d]\n",
451 			feature_id, err);
452 		return err;
453 	}
454 
455 	return 0;
456 }
457 
458 static int efa_com_get_feature(struct efa_com_dev *edev,
459 			       struct efa_admin_get_feature_resp *get_resp,
460 			       enum efa_admin_aq_feature_id feature_id)
461 {
462 	return efa_com_get_feature_ex(edev, get_resp, feature_id, 0, 0);
463 }
464 
465 int efa_com_get_device_attr(struct efa_com_dev *edev,
466 			    struct efa_com_get_device_attr_result *result)
467 {
468 	struct efa_admin_get_feature_resp resp;
469 	int err;
470 
471 	err = efa_com_get_feature(edev, &resp, EFA_ADMIN_DEVICE_ATTR);
472 	if (err) {
473 		ibdev_err_ratelimited(edev->efa_dev,
474 				      "Failed to get device attributes %d\n",
475 				      err);
476 		return err;
477 	}
478 
479 	result->page_size_cap = resp.u.device_attr.page_size_cap;
480 	result->fw_version = resp.u.device_attr.fw_version;
481 	result->admin_api_version = resp.u.device_attr.admin_api_version;
482 	result->device_version = resp.u.device_attr.device_version;
483 	result->supported_features = resp.u.device_attr.supported_features;
484 	result->phys_addr_width = resp.u.device_attr.phys_addr_width;
485 	result->virt_addr_width = resp.u.device_attr.virt_addr_width;
486 	result->db_bar = resp.u.device_attr.db_bar;
487 	result->max_rdma_size = resp.u.device_attr.max_rdma_size;
488 	result->device_caps = resp.u.device_attr.device_caps;
489 	result->guid = resp.u.device_attr.guid;
490 	result->max_link_speed_gbps = resp.u.device_attr.max_link_speed_gbps;
491 	if (!result->max_link_speed_gbps)
492 		result->max_link_speed_gbps = EFA_DEFAULT_LINK_SPEED_GBPS;
493 
494 	if (result->admin_api_version < 1) {
495 		ibdev_err_ratelimited(
496 			edev->efa_dev,
497 			"Failed to get device attr api version [%u < 1]\n",
498 			result->admin_api_version);
499 		return -EINVAL;
500 	}
501 
502 	edev->supported_features = resp.u.device_attr.supported_features;
503 	err = efa_com_get_feature(edev, &resp,
504 				  EFA_ADMIN_QUEUE_ATTR_1);
505 	if (err) {
506 		ibdev_err_ratelimited(edev->efa_dev,
507 				      "Failed to get queue attributes1 %d\n",
508 				      err);
509 		return err;
510 	}
511 
512 	result->max_qp = resp.u.queue_attr_1.max_qp;
513 	result->max_sq_depth = resp.u.queue_attr_1.max_sq_depth;
514 	result->max_rq_depth = resp.u.queue_attr_1.max_rq_depth;
515 	result->max_cq = resp.u.queue_attr_1.max_cq;
516 	result->max_cq_depth = resp.u.queue_attr_1.max_cq_depth;
517 	result->inline_buf_size = resp.u.queue_attr_1.inline_buf_size;
518 	result->max_sq_sge = resp.u.queue_attr_1.max_wr_send_sges;
519 	result->max_rq_sge = resp.u.queue_attr_1.max_wr_recv_sges;
520 	result->max_mr = resp.u.queue_attr_1.max_mr;
521 	result->max_mr_pages = resp.u.queue_attr_1.max_mr_pages;
522 	result->max_pd = resp.u.queue_attr_1.max_pd;
523 	result->max_ah = resp.u.queue_attr_1.max_ah;
524 	result->max_llq_size = resp.u.queue_attr_1.max_llq_size;
525 	result->sub_cqs_per_cq = resp.u.queue_attr_1.sub_cqs_per_cq;
526 	result->max_wr_rdma_sge = resp.u.queue_attr_1.max_wr_rdma_sges;
527 	result->max_tx_batch = resp.u.queue_attr_1.max_tx_batch;
528 	result->min_sq_depth = resp.u.queue_attr_1.min_sq_depth;
529 
530 	if (efa_com_check_supported_feature_id(edev, EFA_ADMIN_QUEUE_ATTR_2)) {
531 		err = efa_com_get_feature(edev, &resp,
532 					  EFA_ADMIN_QUEUE_ATTR_2);
533 		if (err) {
534 			ibdev_err_ratelimited(
535 				edev->efa_dev,
536 				"Failed to get queue attributes2 %d\n", err);
537 			return err;
538 		}
539 
540 		result->inline_buf_size_ex = resp.u.queue_attr_2.inline_buf_size_ex;
541 		result->max_event_counters = resp.u.queue_attr_2.max_event_counters;
542 		result->event_counter_max_val = resp.u.queue_attr_2.event_counter_max_val;
543 		result->supported_event_counter_qp_events =
544 			resp.u.queue_attr_2.supported_event_counter_qp_events;
545 	} else {
546 		result->inline_buf_size_ex = result->inline_buf_size;
547 	}
548 
549 	err = efa_com_get_feature(edev, &resp, EFA_ADMIN_NETWORK_ATTR);
550 	if (err) {
551 		ibdev_err_ratelimited(edev->efa_dev,
552 				      "Failed to get network attributes %d\n",
553 				      err);
554 		return err;
555 	}
556 
557 	memcpy(result->addr, resp.u.network_attr.addr,
558 	       sizeof(resp.u.network_attr.addr));
559 	result->mtu = resp.u.network_attr.mtu;
560 
561 	if (efa_com_check_supported_feature_id(edev,
562 					       EFA_ADMIN_EVENT_QUEUE_ATTR)) {
563 		err = efa_com_get_feature(edev, &resp,
564 					  EFA_ADMIN_EVENT_QUEUE_ATTR);
565 		if (err) {
566 			ibdev_err_ratelimited(
567 				edev->efa_dev,
568 				"Failed to get event queue attributes %d\n",
569 				err);
570 			return err;
571 		}
572 
573 		result->max_eq = resp.u.event_queue_attr.max_eq;
574 		result->max_eq_depth = resp.u.event_queue_attr.max_eq_depth;
575 		result->event_bitmask = resp.u.event_queue_attr.event_bitmask;
576 	}
577 
578 	return 0;
579 }
580 
581 int efa_com_get_hw_hints(struct efa_com_dev *edev,
582 			 struct efa_com_get_hw_hints_result *result)
583 {
584 	struct efa_admin_get_feature_resp resp;
585 	int err;
586 
587 	err = efa_com_get_feature(edev, &resp, EFA_ADMIN_HW_HINTS);
588 	if (err) {
589 		ibdev_err_ratelimited(edev->efa_dev,
590 				      "Failed to get hw hints %d\n", err);
591 		return err;
592 	}
593 
594 	result->admin_completion_timeout = resp.u.hw_hints.admin_completion_timeout;
595 	result->driver_watchdog_timeout = resp.u.hw_hints.driver_watchdog_timeout;
596 	result->mmio_read_timeout = resp.u.hw_hints.mmio_read_timeout;
597 	result->poll_interval = resp.u.hw_hints.poll_interval;
598 
599 	return 0;
600 }
601 
602 int efa_com_set_feature_ex(struct efa_com_dev *edev,
603 			   struct efa_admin_set_feature_resp *set_resp,
604 			   struct efa_admin_set_feature_cmd *set_cmd,
605 			   enum efa_admin_aq_feature_id feature_id,
606 			   dma_addr_t control_buf_dma_addr,
607 			   u32 control_buff_size)
608 {
609 	struct efa_com_admin_queue *aq;
610 	u8 flags = 0;
611 	int err;
612 
613 	if (!efa_com_check_supported_feature_id(edev, feature_id)) {
614 		ibdev_err_ratelimited(edev->efa_dev,
615 				      "Feature %d isn't supported\n",
616 				      feature_id);
617 		return -EOPNOTSUPP;
618 	}
619 
620 	aq = &edev->aq;
621 
622 	if (control_buff_size) {
623 		EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
624 		efa_com_set_dma_addr(control_buf_dma_addr,
625 				     &set_cmd->control_buffer.address.mem_addr_high,
626 				     &set_cmd->control_buffer.address.mem_addr_low);
627 	}
628 
629 	set_cmd->control_buffer.length = control_buff_size;
630 	set_cmd->feature_common.feature_id = feature_id;
631 	err = efa_com_cmd_exec(aq, EFA_ADMIN_SET_FEATURE, flags,
632 			       set_cmd, sizeof(*set_cmd),
633 			       (struct efa_admin_acq_entry *)set_resp,
634 			       sizeof(*set_resp));
635 
636 	if (err) {
637 		ibdev_err_ratelimited(
638 			edev->efa_dev,
639 			"Failed to submit set_feature command %d error: %d\n",
640 			feature_id, err);
641 		return err;
642 	}
643 
644 	return 0;
645 }
646 
647 static int efa_com_set_feature(struct efa_com_dev *edev,
648 			       struct efa_admin_set_feature_resp *set_resp,
649 			       struct efa_admin_set_feature_cmd *set_cmd,
650 			       enum efa_admin_aq_feature_id feature_id)
651 {
652 	return efa_com_set_feature_ex(edev, set_resp, set_cmd, feature_id,
653 				      0, 0);
654 }
655 
656 int efa_com_set_aenq_config(struct efa_com_dev *edev, u32 groups)
657 {
658 	struct efa_admin_get_feature_resp get_resp;
659 	struct efa_admin_set_feature_resp set_resp;
660 	struct efa_admin_set_feature_cmd cmd = {};
661 	int err;
662 
663 	ibdev_dbg(edev->efa_dev, "Configuring aenq with groups[%#x]\n", groups);
664 
665 	err = efa_com_get_feature(edev, &get_resp, EFA_ADMIN_AENQ_CONFIG);
666 	if (err) {
667 		ibdev_err_ratelimited(edev->efa_dev,
668 				      "Failed to get aenq attributes: %d\n",
669 				      err);
670 		return err;
671 	}
672 
673 	ibdev_dbg(edev->efa_dev,
674 		  "Get aenq groups: supported[%#x] enabled[%#x]\n",
675 		  get_resp.u.aenq.supported_groups,
676 		  get_resp.u.aenq.enabled_groups);
677 
678 	if ((get_resp.u.aenq.supported_groups & groups) != groups) {
679 		ibdev_err_ratelimited(
680 			edev->efa_dev,
681 			"Trying to set unsupported aenq groups[%#x] supported[%#x]\n",
682 			groups, get_resp.u.aenq.supported_groups);
683 		return -EOPNOTSUPP;
684 	}
685 
686 	cmd.u.aenq.enabled_groups = groups;
687 	err = efa_com_set_feature(edev, &set_resp, &cmd,
688 				  EFA_ADMIN_AENQ_CONFIG);
689 	if (err) {
690 		ibdev_err_ratelimited(edev->efa_dev,
691 				      "Failed to set aenq attributes: %d\n",
692 				      err);
693 		return err;
694 	}
695 
696 	return 0;
697 }
698 
699 int efa_com_alloc_pd(struct efa_com_dev *edev,
700 		     struct efa_com_alloc_pd_result *result)
701 {
702 	struct efa_com_admin_queue *aq = &edev->aq;
703 	struct efa_admin_alloc_pd_resp resp;
704 	int err;
705 
706 	err = efa_com_cmd_exec(aq, EFA_ADMIN_ALLOC_PD, 0,
707 			       NULL, 0,
708 			       (struct efa_admin_acq_entry *)&resp, sizeof(resp));
709 	if (err) {
710 		ibdev_err_ratelimited(edev->efa_dev,
711 				      "Failed to allocate pd[%d]\n", err);
712 		return err;
713 	}
714 
715 	result->pdn = resp.pd;
716 
717 	return 0;
718 }
719 
720 int efa_com_dealloc_pd(struct efa_com_dev *edev,
721 		       struct efa_com_dealloc_pd_params *params)
722 {
723 	struct efa_com_admin_queue *aq = &edev->aq;
724 	struct efa_admin_dealloc_pd_cmd cmd = {};
725 	struct efa_admin_dealloc_pd_resp resp;
726 	int err;
727 
728 	cmd.pd = params->pdn;
729 
730 	err = efa_com_cmd_exec(aq, EFA_ADMIN_DEALLOC_PD, 0,
731 			       &cmd, sizeof(cmd),
732 			       (struct efa_admin_acq_entry *)&resp, sizeof(resp));
733 	if (err) {
734 		ibdev_err_ratelimited(edev->efa_dev,
735 				      "Failed to deallocate pd-%u [%d]\n",
736 				      cmd.pd, err);
737 		return err;
738 	}
739 
740 	return 0;
741 }
742 
743 int efa_com_alloc_uar(struct efa_com_dev *edev,
744 		      struct efa_com_alloc_uar_result *result)
745 {
746 	struct efa_com_admin_queue *aq = &edev->aq;
747 	struct efa_admin_alloc_uar_resp resp;
748 	int err;
749 
750 	err = efa_com_cmd_exec(aq, EFA_ADMIN_ALLOC_UAR, 0,
751 			       NULL, 0,
752 			       (struct efa_admin_acq_entry *)&resp, sizeof(resp));
753 	if (err) {
754 		ibdev_err_ratelimited(edev->efa_dev,
755 				      "Failed to allocate uar[%d]\n", err);
756 		return err;
757 	}
758 
759 	result->uarn = resp.uar;
760 
761 	return 0;
762 }
763 
764 int efa_com_dealloc_uar(struct efa_com_dev *edev,
765 			struct efa_com_dealloc_uar_params *params)
766 {
767 	struct efa_com_admin_queue *aq = &edev->aq;
768 	struct efa_admin_dealloc_uar_cmd cmd = {};
769 	struct efa_admin_dealloc_uar_resp resp;
770 	int err;
771 
772 	cmd.uar = params->uarn;
773 
774 	err = efa_com_cmd_exec(aq, EFA_ADMIN_DEALLOC_UAR, 0,
775 			       &cmd, sizeof(cmd),
776 			       (struct efa_admin_acq_entry *)&resp, sizeof(resp));
777 	if (err) {
778 		ibdev_err_ratelimited(edev->efa_dev,
779 				      "Failed to deallocate uar-%u [%d]\n",
780 				      cmd.uar, err);
781 		return err;
782 	}
783 
784 	return 0;
785 }
786 
787 int efa_com_get_stats(struct efa_com_dev *edev,
788 		      struct efa_com_get_stats_params *params,
789 		      union efa_com_get_stats_result *result)
790 {
791 	struct efa_com_admin_queue *aq = &edev->aq;
792 	struct efa_admin_aq_get_stats_cmd cmd = {};
793 	struct efa_admin_acq_get_stats_resp resp;
794 	struct efa_admin_rdma_write_stats *rws;
795 	struct efa_admin_rdma_read_stats *rrs;
796 	struct efa_admin_messages_stats *ms;
797 	struct efa_admin_network_stats *ns;
798 	struct efa_admin_basic_stats *bs;
799 	int err;
800 
801 	cmd.type = params->type;
802 	cmd.scope = params->scope;
803 	cmd.scope_modifier = params->scope_modifier;
804 
805 	err = efa_com_cmd_exec(aq, EFA_ADMIN_GET_STATS, 0,
806 			       &cmd, sizeof(cmd),
807 			       (struct efa_admin_acq_entry *)&resp, sizeof(resp));
808 	if (err) {
809 		ibdev_err_ratelimited(
810 			edev->efa_dev,
811 			"Failed to get stats type-%u scope-%u.%u [%d]\n",
812 			cmd.type, cmd.scope, cmd.scope_modifier, err);
813 		return err;
814 	}
815 
816 	switch (cmd.type) {
817 	case EFA_ADMIN_GET_STATS_TYPE_BASIC:
818 		bs = &resp.u.basic_stats;
819 		result->basic_stats.tx_bytes = bs->tx_bytes;
820 		result->basic_stats.tx_pkts = bs->tx_pkts;
821 		result->basic_stats.rx_bytes = bs->rx_bytes;
822 		result->basic_stats.rx_pkts = bs->rx_pkts;
823 		result->basic_stats.rx_drops = bs->rx_drops;
824 		break;
825 	case EFA_ADMIN_GET_STATS_TYPE_MESSAGES:
826 		ms = &resp.u.messages_stats;
827 		result->messages_stats.send_bytes = ms->send_bytes;
828 		result->messages_stats.send_wrs = ms->send_wrs;
829 		result->messages_stats.recv_bytes = ms->recv_bytes;
830 		result->messages_stats.recv_wrs = ms->recv_wrs;
831 		break;
832 	case EFA_ADMIN_GET_STATS_TYPE_RDMA_READ:
833 		rrs = &resp.u.rdma_read_stats;
834 		result->rdma_read_stats.read_wrs = rrs->read_wrs;
835 		result->rdma_read_stats.read_bytes = rrs->read_bytes;
836 		result->rdma_read_stats.read_wr_err = rrs->read_wr_err;
837 		result->rdma_read_stats.read_resp_bytes = rrs->read_resp_bytes;
838 		break;
839 	case EFA_ADMIN_GET_STATS_TYPE_RDMA_WRITE:
840 		rws = &resp.u.rdma_write_stats;
841 		result->rdma_write_stats.write_wrs = rws->write_wrs;
842 		result->rdma_write_stats.write_bytes = rws->write_bytes;
843 		result->rdma_write_stats.write_wr_err = rws->write_wr_err;
844 		result->rdma_write_stats.write_recv_bytes = rws->write_recv_bytes;
845 		break;
846 	case EFA_ADMIN_GET_STATS_TYPE_NETWORK:
847 		ns = &resp.u.network_stats;
848 		result->network_stats.retrans_bytes = ns->retrans_bytes;
849 		result->network_stats.retrans_pkts = ns->retrans_pkts;
850 		result->network_stats.retrans_timeout_events = ns->retrans_timeout_events;
851 		result->network_stats.unresponsive_remote_events = ns->unresponsive_remote_events;
852 		result->network_stats.impaired_remote_conn_events = ns->impaired_remote_conn_events;
853 		break;
854 	}
855 
856 	return 0;
857 }
858 
859 int efa_com_create_event_counter(struct efa_com_dev *edev,
860 				 struct efa_com_create_event_counter_params *params,
861 				 struct efa_com_create_event_counter_result *result)
862 {
863 	struct efa_admin_create_event_counter_cmd cmd = {};
864 	struct efa_admin_create_event_counter_resp resp;
865 	struct efa_com_admin_queue *aq = &edev->aq;
866 	int err;
867 
868 	cmd.uar = params->uarn;
869 	cmd.paddr = params->dma_addr;
870 
871 	err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_EVENT_COUNTER, 0,
872 			       &cmd, sizeof(cmd),
873 			       (struct efa_admin_acq_entry *)&resp,
874 			       sizeof(resp));
875 	if (err) {
876 		ibdev_err_ratelimited(edev->efa_dev,
877 				      "Failed to create event counter [%d]\n",
878 				      err);
879 		return err;
880 	}
881 
882 	result->cntr_handle = resp.cntr_handle;
883 	return 0;
884 }
885 
886 int efa_com_destroy_event_counter(struct efa_com_dev *edev,
887 				  struct efa_com_destroy_event_counter_params *params)
888 {
889 	struct efa_admin_destroy_event_counter_cmd cmd = {};
890 	struct efa_admin_destroy_event_counter_resp resp;
891 	struct efa_com_admin_queue *aq = &edev->aq;
892 	int err;
893 
894 	cmd.cntr_handle = params->cntr_handle;
895 
896 	err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_EVENT_COUNTER, 0,
897 			       &cmd, sizeof(cmd),
898 			       (struct efa_admin_acq_entry *)&resp,
899 			       sizeof(resp));
900 	if (err) {
901 		ibdev_err_ratelimited(edev->efa_dev,
902 				      "Failed to destroy event counter [%d]\n",
903 				      err);
904 		return err;
905 	}
906 
907 	return 0;
908 }
909 
910 static int efa_com_attach_detach_event_counter(struct efa_com_dev *edev, u8 opcode,
911 					       u32 cntr_handle, u32 qp_handle,
912 					       u32 events)
913 {
914 	struct efa_admin_attach_detach_event_counter_cmd cmd = {};
915 	struct efa_admin_attach_detach_event_counter_resp resp;
916 	struct efa_com_admin_queue *aq = &edev->aq;
917 	int err;
918 
919 	cmd.cntr_handle = cntr_handle;
920 	cmd.attach_type = EFA_ADMIN_EVENT_COUNTER_ATTACH_QP_EVENTS;
921 	cmd.u.qp_events.qp_handle = qp_handle;
922 	cmd.u.qp_events.events = events;
923 
924 	err = efa_com_cmd_exec(aq, opcode, 0,
925 			       &cmd, sizeof(cmd),
926 			       (struct efa_admin_acq_entry *)&resp,
927 			       sizeof(resp));
928 	if (err) {
929 		ibdev_err_ratelimited(edev->efa_dev,
930 				      "Failed to %s event counter [%d]\n",
931 				      opcode == EFA_ADMIN_ATTACH_EVENT_COUNTER
932 					      ? "attach"
933 					      : "detach",
934 				      err);
935 		return err;
936 	}
937 
938 	return 0;
939 }
940 
941 int efa_com_attach_event_counter(struct efa_com_dev *edev,
942 				 struct efa_com_attach_event_counter_params *params)
943 {
944 	return efa_com_attach_detach_event_counter(edev,
945 						   EFA_ADMIN_ATTACH_EVENT_COUNTER,
946 						   params->cntr_handle,
947 						   params->qp_handle,
948 						   params->events);
949 }
950 
951 int efa_com_detach_event_counter(struct efa_com_dev *edev,
952 				 struct efa_com_detach_event_counter_params *params)
953 {
954 	return efa_com_attach_detach_event_counter(edev,
955 						   EFA_ADMIN_DETACH_EVENT_COUNTER,
956 						   params->cntr_handle,
957 						   params->qp_handle,
958 						   params->events);
959 }
960 
961 int efa_com_modify_event_counter(struct efa_com_dev *edev,
962 				 struct efa_com_modify_event_counter_params *params)
963 {
964 	struct efa_admin_modify_event_counter_cmd cmd = {};
965 	struct efa_admin_modify_event_counter_resp resp;
966 	struct efa_com_admin_queue *aq = &edev->aq;
967 	int err;
968 
969 	cmd.cntr_handle = params->cntr_handle;
970 	cmd.operation = params->operation;
971 	cmd.value = params->value;
972 
973 	err = efa_com_cmd_exec(aq, EFA_ADMIN_MODIFY_EVENT_COUNTER, 0,
974 			       &cmd, sizeof(cmd),
975 			       (struct efa_admin_acq_entry *)&resp,
976 			       sizeof(resp));
977 	if (err) {
978 		ibdev_err_ratelimited(edev->efa_dev,
979 				      "Failed to modify event counter [%d]\n",
980 				      err);
981 		return err;
982 	}
983 
984 	return 0;
985 }
986