cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

efa_com_cmd.c (23174B)


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