Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
0002 /*
0003  * Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved.
0004  */
0005 
0006 #include "efa_com.h"
0007 #include "efa_com_cmd.h"
0008 
0009 int efa_com_create_qp(struct efa_com_dev *edev,
0010               struct efa_com_create_qp_params *params,
0011               struct efa_com_create_qp_result *res)
0012 {
0013     struct efa_admin_create_qp_cmd create_qp_cmd = {};
0014     struct efa_admin_create_qp_resp cmd_completion;
0015     struct efa_com_admin_queue *aq = &edev->aq;
0016     int err;
0017 
0018     create_qp_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_QP;
0019 
0020     create_qp_cmd.pd = params->pd;
0021     create_qp_cmd.qp_type = params->qp_type;
0022     create_qp_cmd.rq_base_addr = params->rq_base_addr;
0023     create_qp_cmd.send_cq_idx = params->send_cq_idx;
0024     create_qp_cmd.recv_cq_idx = params->recv_cq_idx;
0025     create_qp_cmd.qp_alloc_size.send_queue_ring_size =
0026         params->sq_ring_size_in_bytes;
0027     create_qp_cmd.qp_alloc_size.send_queue_depth =
0028             params->sq_depth;
0029     create_qp_cmd.qp_alloc_size.recv_queue_ring_size =
0030             params->rq_ring_size_in_bytes;
0031     create_qp_cmd.qp_alloc_size.recv_queue_depth =
0032             params->rq_depth;
0033     create_qp_cmd.uar = params->uarn;
0034 
0035     err = efa_com_cmd_exec(aq,
0036                    (struct efa_admin_aq_entry *)&create_qp_cmd,
0037                    sizeof(create_qp_cmd),
0038                    (struct efa_admin_acq_entry *)&cmd_completion,
0039                    sizeof(cmd_completion));
0040     if (err) {
0041         ibdev_err_ratelimited(edev->efa_dev,
0042                       "Failed to create qp [%d]\n", err);
0043         return err;
0044     }
0045 
0046     res->qp_handle = cmd_completion.qp_handle;
0047     res->qp_num = cmd_completion.qp_num;
0048     res->sq_db_offset = cmd_completion.sq_db_offset;
0049     res->rq_db_offset = cmd_completion.rq_db_offset;
0050     res->llq_descriptors_offset = cmd_completion.llq_descriptors_offset;
0051     res->send_sub_cq_idx = cmd_completion.send_sub_cq_idx;
0052     res->recv_sub_cq_idx = cmd_completion.recv_sub_cq_idx;
0053 
0054     return 0;
0055 }
0056 
0057 int efa_com_modify_qp(struct efa_com_dev *edev,
0058               struct efa_com_modify_qp_params *params)
0059 {
0060     struct efa_com_admin_queue *aq = &edev->aq;
0061     struct efa_admin_modify_qp_cmd cmd = {};
0062     struct efa_admin_modify_qp_resp resp;
0063     int err;
0064 
0065     cmd.aq_common_desc.opcode = EFA_ADMIN_MODIFY_QP;
0066     cmd.modify_mask = params->modify_mask;
0067     cmd.qp_handle = params->qp_handle;
0068     cmd.qp_state = params->qp_state;
0069     cmd.cur_qp_state = params->cur_qp_state;
0070     cmd.qkey = params->qkey;
0071     cmd.sq_psn = params->sq_psn;
0072     cmd.sq_drained_async_notify = params->sq_drained_async_notify;
0073     cmd.rnr_retry = params->rnr_retry;
0074 
0075     err = efa_com_cmd_exec(aq,
0076                    (struct efa_admin_aq_entry *)&cmd,
0077                    sizeof(cmd),
0078                    (struct efa_admin_acq_entry *)&resp,
0079                    sizeof(resp));
0080     if (err) {
0081         ibdev_err_ratelimited(
0082             edev->efa_dev,
0083             "Failed to modify qp-%u modify_mask[%#x] [%d]\n",
0084             cmd.qp_handle, cmd.modify_mask, err);
0085         return err;
0086     }
0087 
0088     return 0;
0089 }
0090 
0091 int efa_com_query_qp(struct efa_com_dev *edev,
0092              struct efa_com_query_qp_params *params,
0093              struct efa_com_query_qp_result *result)
0094 {
0095     struct efa_com_admin_queue *aq = &edev->aq;
0096     struct efa_admin_query_qp_cmd cmd = {};
0097     struct efa_admin_query_qp_resp resp;
0098     int err;
0099 
0100     cmd.aq_common_desc.opcode = EFA_ADMIN_QUERY_QP;
0101     cmd.qp_handle = params->qp_handle;
0102 
0103     err = efa_com_cmd_exec(aq,
0104                    (struct efa_admin_aq_entry *)&cmd,
0105                    sizeof(cmd),
0106                    (struct efa_admin_acq_entry *)&resp,
0107                    sizeof(resp));
0108     if (err) {
0109         ibdev_err_ratelimited(edev->efa_dev,
0110                       "Failed to query qp-%u [%d]\n",
0111                       cmd.qp_handle, err);
0112         return err;
0113     }
0114 
0115     result->qp_state = resp.qp_state;
0116     result->qkey = resp.qkey;
0117     result->sq_draining = resp.sq_draining;
0118     result->sq_psn = resp.sq_psn;
0119     result->rnr_retry = resp.rnr_retry;
0120 
0121     return 0;
0122 }
0123 
0124 int efa_com_destroy_qp(struct efa_com_dev *edev,
0125                struct efa_com_destroy_qp_params *params)
0126 {
0127     struct efa_admin_destroy_qp_resp cmd_completion;
0128     struct efa_admin_destroy_qp_cmd qp_cmd = {};
0129     struct efa_com_admin_queue *aq = &edev->aq;
0130     int err;
0131 
0132     qp_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_QP;
0133     qp_cmd.qp_handle = params->qp_handle;
0134 
0135     err = efa_com_cmd_exec(aq,
0136                    (struct efa_admin_aq_entry *)&qp_cmd,
0137                    sizeof(qp_cmd),
0138                    (struct efa_admin_acq_entry *)&cmd_completion,
0139                    sizeof(cmd_completion));
0140     if (err) {
0141         ibdev_err_ratelimited(edev->efa_dev,
0142                       "Failed to destroy qp-%u [%d]\n",
0143                       qp_cmd.qp_handle, err);
0144         return err;
0145     }
0146 
0147     return 0;
0148 }
0149 
0150 int efa_com_create_cq(struct efa_com_dev *edev,
0151               struct efa_com_create_cq_params *params,
0152               struct efa_com_create_cq_result *result)
0153 {
0154     struct efa_admin_create_cq_resp cmd_completion = {};
0155     struct efa_admin_create_cq_cmd create_cmd = {};
0156     struct efa_com_admin_queue *aq = &edev->aq;
0157     int err;
0158 
0159     create_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_CQ;
0160     EFA_SET(&create_cmd.cq_caps_2,
0161         EFA_ADMIN_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS,
0162         params->entry_size_in_bytes / 4);
0163     create_cmd.cq_depth = params->cq_depth;
0164     create_cmd.num_sub_cqs = params->num_sub_cqs;
0165     create_cmd.uar = params->uarn;
0166     if (params->interrupt_mode_enabled) {
0167         EFA_SET(&create_cmd.cq_caps_1,
0168             EFA_ADMIN_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED, 1);
0169         create_cmd.eqn = params->eqn;
0170     }
0171 
0172     efa_com_set_dma_addr(params->dma_addr,
0173                  &create_cmd.cq_ba.mem_addr_high,
0174                  &create_cmd.cq_ba.mem_addr_low);
0175 
0176     err = efa_com_cmd_exec(aq,
0177                    (struct efa_admin_aq_entry *)&create_cmd,
0178                    sizeof(create_cmd),
0179                    (struct efa_admin_acq_entry *)&cmd_completion,
0180                    sizeof(cmd_completion));
0181     if (err) {
0182         ibdev_err_ratelimited(edev->efa_dev,
0183                       "Failed to create cq[%d]\n", err);
0184         return err;
0185     }
0186 
0187     result->cq_idx = cmd_completion.cq_idx;
0188     result->actual_depth = params->cq_depth;
0189     result->db_off = cmd_completion.db_offset;
0190     result->db_valid = EFA_GET(&cmd_completion.flags,
0191                    EFA_ADMIN_CREATE_CQ_RESP_DB_VALID);
0192 
0193     return 0;
0194 }
0195 
0196 int efa_com_destroy_cq(struct efa_com_dev *edev,
0197                struct efa_com_destroy_cq_params *params)
0198 {
0199     struct efa_admin_destroy_cq_cmd destroy_cmd = {};
0200     struct efa_admin_destroy_cq_resp destroy_resp;
0201     struct efa_com_admin_queue *aq = &edev->aq;
0202     int err;
0203 
0204     destroy_cmd.cq_idx = params->cq_idx;
0205     destroy_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_CQ;
0206 
0207     err = efa_com_cmd_exec(aq,
0208                    (struct efa_admin_aq_entry *)&destroy_cmd,
0209                    sizeof(destroy_cmd),
0210                    (struct efa_admin_acq_entry *)&destroy_resp,
0211                    sizeof(destroy_resp));
0212 
0213     if (err) {
0214         ibdev_err_ratelimited(edev->efa_dev,
0215                       "Failed to destroy CQ-%u [%d]\n",
0216                       params->cq_idx, err);
0217         return err;
0218     }
0219 
0220     return 0;
0221 }
0222 
0223 int efa_com_register_mr(struct efa_com_dev *edev,
0224             struct efa_com_reg_mr_params *params,
0225             struct efa_com_reg_mr_result *result)
0226 {
0227     struct efa_admin_reg_mr_resp cmd_completion;
0228     struct efa_com_admin_queue *aq = &edev->aq;
0229     struct efa_admin_reg_mr_cmd mr_cmd = {};
0230     int err;
0231 
0232     mr_cmd.aq_common_desc.opcode = EFA_ADMIN_REG_MR;
0233     mr_cmd.pd = params->pd;
0234     mr_cmd.mr_length = params->mr_length_in_bytes;
0235     EFA_SET(&mr_cmd.flags, EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT,
0236         params->page_shift);
0237     mr_cmd.iova = params->iova;
0238     mr_cmd.permissions = params->permissions;
0239 
0240     if (params->inline_pbl) {
0241         memcpy(mr_cmd.pbl.inline_pbl_array,
0242                params->pbl.inline_pbl_array,
0243                sizeof(mr_cmd.pbl.inline_pbl_array));
0244     } else {
0245         mr_cmd.pbl.pbl.length = params->pbl.pbl.length;
0246         mr_cmd.pbl.pbl.address.mem_addr_low =
0247             params->pbl.pbl.address.mem_addr_low;
0248         mr_cmd.pbl.pbl.address.mem_addr_high =
0249             params->pbl.pbl.address.mem_addr_high;
0250         EFA_SET(&mr_cmd.aq_common_desc.flags,
0251             EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
0252         if (params->indirect)
0253             EFA_SET(&mr_cmd.aq_common_desc.flags,
0254                 EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT, 1);
0255     }
0256 
0257     err = efa_com_cmd_exec(aq,
0258                    (struct efa_admin_aq_entry *)&mr_cmd,
0259                    sizeof(mr_cmd),
0260                    (struct efa_admin_acq_entry *)&cmd_completion,
0261                    sizeof(cmd_completion));
0262     if (err) {
0263         ibdev_err_ratelimited(edev->efa_dev,
0264                       "Failed to register mr [%d]\n", err);
0265         return err;
0266     }
0267 
0268     result->l_key = cmd_completion.l_key;
0269     result->r_key = cmd_completion.r_key;
0270 
0271     return 0;
0272 }
0273 
0274 int efa_com_dereg_mr(struct efa_com_dev *edev,
0275              struct efa_com_dereg_mr_params *params)
0276 {
0277     struct efa_admin_dereg_mr_resp cmd_completion;
0278     struct efa_com_admin_queue *aq = &edev->aq;
0279     struct efa_admin_dereg_mr_cmd mr_cmd = {};
0280     int err;
0281 
0282     mr_cmd.aq_common_desc.opcode = EFA_ADMIN_DEREG_MR;
0283     mr_cmd.l_key = params->l_key;
0284 
0285     err = efa_com_cmd_exec(aq,
0286                    (struct efa_admin_aq_entry *)&mr_cmd,
0287                    sizeof(mr_cmd),
0288                    (struct efa_admin_acq_entry *)&cmd_completion,
0289                    sizeof(cmd_completion));
0290     if (err) {
0291         ibdev_err_ratelimited(edev->efa_dev,
0292                       "Failed to de-register mr(lkey-%u) [%d]\n",
0293                       mr_cmd.l_key, err);
0294         return err;
0295     }
0296 
0297     return 0;
0298 }
0299 
0300 int efa_com_create_ah(struct efa_com_dev *edev,
0301               struct efa_com_create_ah_params *params,
0302               struct efa_com_create_ah_result *result)
0303 {
0304     struct efa_admin_create_ah_resp cmd_completion;
0305     struct efa_com_admin_queue *aq = &edev->aq;
0306     struct efa_admin_create_ah_cmd ah_cmd = {};
0307     int err;
0308 
0309     ah_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_AH;
0310 
0311     memcpy(ah_cmd.dest_addr, params->dest_addr, sizeof(ah_cmd.dest_addr));
0312     ah_cmd.pd = params->pdn;
0313 
0314     err = efa_com_cmd_exec(aq,
0315                    (struct efa_admin_aq_entry *)&ah_cmd,
0316                    sizeof(ah_cmd),
0317                    (struct efa_admin_acq_entry *)&cmd_completion,
0318                    sizeof(cmd_completion));
0319     if (err) {
0320         ibdev_err_ratelimited(edev->efa_dev,
0321                       "Failed to create ah for %pI6 [%d]\n",
0322                       ah_cmd.dest_addr, err);
0323         return err;
0324     }
0325 
0326     result->ah = cmd_completion.ah;
0327 
0328     return 0;
0329 }
0330 
0331 int efa_com_destroy_ah(struct efa_com_dev *edev,
0332                struct efa_com_destroy_ah_params *params)
0333 {
0334     struct efa_admin_destroy_ah_resp cmd_completion;
0335     struct efa_admin_destroy_ah_cmd ah_cmd = {};
0336     struct efa_com_admin_queue *aq = &edev->aq;
0337     int err;
0338 
0339     ah_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_AH;
0340     ah_cmd.ah = params->ah;
0341     ah_cmd.pd = params->pdn;
0342 
0343     err = efa_com_cmd_exec(aq,
0344                    (struct efa_admin_aq_entry *)&ah_cmd,
0345                    sizeof(ah_cmd),
0346                    (struct efa_admin_acq_entry *)&cmd_completion,
0347                    sizeof(cmd_completion));
0348     if (err) {
0349         ibdev_err_ratelimited(edev->efa_dev,
0350                       "Failed to destroy ah-%d pd-%d [%d]\n",
0351                       ah_cmd.ah, ah_cmd.pd, err);
0352         return err;
0353     }
0354 
0355     return 0;
0356 }
0357 
0358 bool
0359 efa_com_check_supported_feature_id(struct efa_com_dev *edev,
0360                    enum efa_admin_aq_feature_id feature_id)
0361 {
0362     u32 feature_mask = 1 << feature_id;
0363 
0364     /* Device attributes is always supported */
0365     if (feature_id != EFA_ADMIN_DEVICE_ATTR &&
0366         !(edev->supported_features & feature_mask))
0367         return false;
0368 
0369     return true;
0370 }
0371 
0372 static int efa_com_get_feature_ex(struct efa_com_dev *edev,
0373                   struct efa_admin_get_feature_resp *get_resp,
0374                   enum efa_admin_aq_feature_id feature_id,
0375                   dma_addr_t control_buf_dma_addr,
0376                   u32 control_buff_size)
0377 {
0378     struct efa_admin_get_feature_cmd get_cmd = {};
0379     struct efa_com_admin_queue *aq;
0380     int err;
0381 
0382     if (!efa_com_check_supported_feature_id(edev, feature_id)) {
0383         ibdev_err_ratelimited(edev->efa_dev,
0384                       "Feature %d isn't supported\n",
0385                       feature_id);
0386         return -EOPNOTSUPP;
0387     }
0388 
0389     aq = &edev->aq;
0390 
0391     get_cmd.aq_common_descriptor.opcode = EFA_ADMIN_GET_FEATURE;
0392 
0393     if (control_buff_size)
0394         EFA_SET(&get_cmd.aq_common_descriptor.flags,
0395             EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
0396 
0397     efa_com_set_dma_addr(control_buf_dma_addr,
0398                  &get_cmd.control_buffer.address.mem_addr_high,
0399                  &get_cmd.control_buffer.address.mem_addr_low);
0400 
0401     get_cmd.control_buffer.length = control_buff_size;
0402     get_cmd.feature_common.feature_id = feature_id;
0403     err = efa_com_cmd_exec(aq,
0404                    (struct efa_admin_aq_entry *)
0405                    &get_cmd,
0406                    sizeof(get_cmd),
0407                    (struct efa_admin_acq_entry *)
0408                    get_resp,
0409                    sizeof(*get_resp));
0410 
0411     if (err) {
0412         ibdev_err_ratelimited(
0413             edev->efa_dev,
0414             "Failed to submit get_feature command %d [%d]\n",
0415             feature_id, err);
0416         return err;
0417     }
0418 
0419     return 0;
0420 }
0421 
0422 static int efa_com_get_feature(struct efa_com_dev *edev,
0423                    struct efa_admin_get_feature_resp *get_resp,
0424                    enum efa_admin_aq_feature_id feature_id)
0425 {
0426     return efa_com_get_feature_ex(edev, get_resp, feature_id, 0, 0);
0427 }
0428 
0429 int efa_com_get_device_attr(struct efa_com_dev *edev,
0430                 struct efa_com_get_device_attr_result *result)
0431 {
0432     struct efa_admin_get_feature_resp resp;
0433     int err;
0434 
0435     err = efa_com_get_feature(edev, &resp, EFA_ADMIN_DEVICE_ATTR);
0436     if (err) {
0437         ibdev_err_ratelimited(edev->efa_dev,
0438                       "Failed to get device attributes %d\n",
0439                       err);
0440         return err;
0441     }
0442 
0443     result->page_size_cap = resp.u.device_attr.page_size_cap;
0444     result->fw_version = resp.u.device_attr.fw_version;
0445     result->admin_api_version = resp.u.device_attr.admin_api_version;
0446     result->device_version = resp.u.device_attr.device_version;
0447     result->supported_features = resp.u.device_attr.supported_features;
0448     result->phys_addr_width = resp.u.device_attr.phys_addr_width;
0449     result->virt_addr_width = resp.u.device_attr.virt_addr_width;
0450     result->db_bar = resp.u.device_attr.db_bar;
0451     result->max_rdma_size = resp.u.device_attr.max_rdma_size;
0452     result->device_caps = resp.u.device_attr.device_caps;
0453 
0454     if (result->admin_api_version < 1) {
0455         ibdev_err_ratelimited(
0456             edev->efa_dev,
0457             "Failed to get device attr api version [%u < 1]\n",
0458             result->admin_api_version);
0459         return -EINVAL;
0460     }
0461 
0462     edev->supported_features = resp.u.device_attr.supported_features;
0463     err = efa_com_get_feature(edev, &resp,
0464                   EFA_ADMIN_QUEUE_ATTR);
0465     if (err) {
0466         ibdev_err_ratelimited(edev->efa_dev,
0467                       "Failed to get queue attributes %d\n",
0468                       err);
0469         return err;
0470     }
0471 
0472     result->max_qp = resp.u.queue_attr.max_qp;
0473     result->max_sq_depth = resp.u.queue_attr.max_sq_depth;
0474     result->max_rq_depth = resp.u.queue_attr.max_rq_depth;
0475     result->max_cq = resp.u.queue_attr.max_cq;
0476     result->max_cq_depth = resp.u.queue_attr.max_cq_depth;
0477     result->inline_buf_size = resp.u.queue_attr.inline_buf_size;
0478     result->max_sq_sge = resp.u.queue_attr.max_wr_send_sges;
0479     result->max_rq_sge = resp.u.queue_attr.max_wr_recv_sges;
0480     result->max_mr = resp.u.queue_attr.max_mr;
0481     result->max_mr_pages = resp.u.queue_attr.max_mr_pages;
0482     result->max_pd = resp.u.queue_attr.max_pd;
0483     result->max_ah = resp.u.queue_attr.max_ah;
0484     result->max_llq_size = resp.u.queue_attr.max_llq_size;
0485     result->sub_cqs_per_cq = resp.u.queue_attr.sub_cqs_per_cq;
0486     result->max_wr_rdma_sge = resp.u.queue_attr.max_wr_rdma_sges;
0487     result->max_tx_batch = resp.u.queue_attr.max_tx_batch;
0488     result->min_sq_depth = resp.u.queue_attr.min_sq_depth;
0489 
0490     err = efa_com_get_feature(edev, &resp, EFA_ADMIN_NETWORK_ATTR);
0491     if (err) {
0492         ibdev_err_ratelimited(edev->efa_dev,
0493                       "Failed to get network attributes %d\n",
0494                       err);
0495         return err;
0496     }
0497 
0498     memcpy(result->addr, resp.u.network_attr.addr,
0499            sizeof(resp.u.network_attr.addr));
0500     result->mtu = resp.u.network_attr.mtu;
0501 
0502     if (efa_com_check_supported_feature_id(edev,
0503                            EFA_ADMIN_EVENT_QUEUE_ATTR)) {
0504         err = efa_com_get_feature(edev, &resp,
0505                       EFA_ADMIN_EVENT_QUEUE_ATTR);
0506         if (err) {
0507             ibdev_err_ratelimited(
0508                 edev->efa_dev,
0509                 "Failed to get event queue attributes %d\n",
0510                 err);
0511             return err;
0512         }
0513 
0514         result->max_eq = resp.u.event_queue_attr.max_eq;
0515         result->max_eq_depth = resp.u.event_queue_attr.max_eq_depth;
0516         result->event_bitmask = resp.u.event_queue_attr.event_bitmask;
0517     }
0518 
0519     return 0;
0520 }
0521 
0522 int efa_com_get_hw_hints(struct efa_com_dev *edev,
0523              struct efa_com_get_hw_hints_result *result)
0524 {
0525     struct efa_admin_get_feature_resp resp;
0526     int err;
0527 
0528     err = efa_com_get_feature(edev, &resp, EFA_ADMIN_HW_HINTS);
0529     if (err) {
0530         ibdev_err_ratelimited(edev->efa_dev,
0531                       "Failed to get hw hints %d\n", err);
0532         return err;
0533     }
0534 
0535     result->admin_completion_timeout = resp.u.hw_hints.admin_completion_timeout;
0536     result->driver_watchdog_timeout = resp.u.hw_hints.driver_watchdog_timeout;
0537     result->mmio_read_timeout = resp.u.hw_hints.mmio_read_timeout;
0538     result->poll_interval = resp.u.hw_hints.poll_interval;
0539 
0540     return 0;
0541 }
0542 
0543 int efa_com_set_feature_ex(struct efa_com_dev *edev,
0544                struct efa_admin_set_feature_resp *set_resp,
0545                struct efa_admin_set_feature_cmd *set_cmd,
0546                enum efa_admin_aq_feature_id feature_id,
0547                dma_addr_t control_buf_dma_addr,
0548                u32 control_buff_size)
0549 {
0550     struct efa_com_admin_queue *aq;
0551     int err;
0552 
0553     if (!efa_com_check_supported_feature_id(edev, feature_id)) {
0554         ibdev_err_ratelimited(edev->efa_dev,
0555                       "Feature %d isn't supported\n",
0556                       feature_id);
0557         return -EOPNOTSUPP;
0558     }
0559 
0560     aq = &edev->aq;
0561 
0562     set_cmd->aq_common_descriptor.opcode = EFA_ADMIN_SET_FEATURE;
0563     if (control_buff_size) {
0564         set_cmd->aq_common_descriptor.flags = 0;
0565         EFA_SET(&set_cmd->aq_common_descriptor.flags,
0566             EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
0567         efa_com_set_dma_addr(control_buf_dma_addr,
0568                      &set_cmd->control_buffer.address.mem_addr_high,
0569                      &set_cmd->control_buffer.address.mem_addr_low);
0570     }
0571 
0572     set_cmd->control_buffer.length = control_buff_size;
0573     set_cmd->feature_common.feature_id = feature_id;
0574     err = efa_com_cmd_exec(aq,
0575                    (struct efa_admin_aq_entry *)set_cmd,
0576                    sizeof(*set_cmd),
0577                    (struct efa_admin_acq_entry *)set_resp,
0578                    sizeof(*set_resp));
0579 
0580     if (err) {
0581         ibdev_err_ratelimited(
0582             edev->efa_dev,
0583             "Failed to submit set_feature command %d error: %d\n",
0584             feature_id, err);
0585         return err;
0586     }
0587 
0588     return 0;
0589 }
0590 
0591 static int efa_com_set_feature(struct efa_com_dev *edev,
0592                    struct efa_admin_set_feature_resp *set_resp,
0593                    struct efa_admin_set_feature_cmd *set_cmd,
0594                    enum efa_admin_aq_feature_id feature_id)
0595 {
0596     return efa_com_set_feature_ex(edev, set_resp, set_cmd, feature_id,
0597                       0, 0);
0598 }
0599 
0600 int efa_com_set_aenq_config(struct efa_com_dev *edev, u32 groups)
0601 {
0602     struct efa_admin_get_feature_resp get_resp;
0603     struct efa_admin_set_feature_resp set_resp;
0604     struct efa_admin_set_feature_cmd cmd = {};
0605     int err;
0606 
0607     ibdev_dbg(edev->efa_dev, "Configuring aenq with groups[%#x]\n", groups);
0608 
0609     err = efa_com_get_feature(edev, &get_resp, EFA_ADMIN_AENQ_CONFIG);
0610     if (err) {
0611         ibdev_err_ratelimited(edev->efa_dev,
0612                       "Failed to get aenq attributes: %d\n",
0613                       err);
0614         return err;
0615     }
0616 
0617     ibdev_dbg(edev->efa_dev,
0618           "Get aenq groups: supported[%#x] enabled[%#x]\n",
0619           get_resp.u.aenq.supported_groups,
0620           get_resp.u.aenq.enabled_groups);
0621 
0622     if ((get_resp.u.aenq.supported_groups & groups) != groups) {
0623         ibdev_err_ratelimited(
0624             edev->efa_dev,
0625             "Trying to set unsupported aenq groups[%#x] supported[%#x]\n",
0626             groups, get_resp.u.aenq.supported_groups);
0627         return -EOPNOTSUPP;
0628     }
0629 
0630     cmd.u.aenq.enabled_groups = groups;
0631     err = efa_com_set_feature(edev, &set_resp, &cmd,
0632                   EFA_ADMIN_AENQ_CONFIG);
0633     if (err) {
0634         ibdev_err_ratelimited(edev->efa_dev,
0635                       "Failed to set aenq attributes: %d\n",
0636                       err);
0637         return err;
0638     }
0639 
0640     return 0;
0641 }
0642 
0643 int efa_com_alloc_pd(struct efa_com_dev *edev,
0644              struct efa_com_alloc_pd_result *result)
0645 {
0646     struct efa_com_admin_queue *aq = &edev->aq;
0647     struct efa_admin_alloc_pd_cmd cmd = {};
0648     struct efa_admin_alloc_pd_resp resp;
0649     int err;
0650 
0651     cmd.aq_common_descriptor.opcode = EFA_ADMIN_ALLOC_PD;
0652 
0653     err = efa_com_cmd_exec(aq,
0654                    (struct efa_admin_aq_entry *)&cmd,
0655                    sizeof(cmd),
0656                    (struct efa_admin_acq_entry *)&resp,
0657                    sizeof(resp));
0658     if (err) {
0659         ibdev_err_ratelimited(edev->efa_dev,
0660                       "Failed to allocate pd[%d]\n", err);
0661         return err;
0662     }
0663 
0664     result->pdn = resp.pd;
0665 
0666     return 0;
0667 }
0668 
0669 int efa_com_dealloc_pd(struct efa_com_dev *edev,
0670                struct efa_com_dealloc_pd_params *params)
0671 {
0672     struct efa_com_admin_queue *aq = &edev->aq;
0673     struct efa_admin_dealloc_pd_cmd cmd = {};
0674     struct efa_admin_dealloc_pd_resp resp;
0675     int err;
0676 
0677     cmd.aq_common_descriptor.opcode = EFA_ADMIN_DEALLOC_PD;
0678     cmd.pd = params->pdn;
0679 
0680     err = efa_com_cmd_exec(aq,
0681                    (struct efa_admin_aq_entry *)&cmd,
0682                    sizeof(cmd),
0683                    (struct efa_admin_acq_entry *)&resp,
0684                    sizeof(resp));
0685     if (err) {
0686         ibdev_err_ratelimited(edev->efa_dev,
0687                       "Failed to deallocate pd-%u [%d]\n",
0688                       cmd.pd, err);
0689         return err;
0690     }
0691 
0692     return 0;
0693 }
0694 
0695 int efa_com_alloc_uar(struct efa_com_dev *edev,
0696               struct efa_com_alloc_uar_result *result)
0697 {
0698     struct efa_com_admin_queue *aq = &edev->aq;
0699     struct efa_admin_alloc_uar_cmd cmd = {};
0700     struct efa_admin_alloc_uar_resp resp;
0701     int err;
0702 
0703     cmd.aq_common_descriptor.opcode = EFA_ADMIN_ALLOC_UAR;
0704 
0705     err = efa_com_cmd_exec(aq,
0706                    (struct efa_admin_aq_entry *)&cmd,
0707                    sizeof(cmd),
0708                    (struct efa_admin_acq_entry *)&resp,
0709                    sizeof(resp));
0710     if (err) {
0711         ibdev_err_ratelimited(edev->efa_dev,
0712                       "Failed to allocate uar[%d]\n", err);
0713         return err;
0714     }
0715 
0716     result->uarn = resp.uar;
0717 
0718     return 0;
0719 }
0720 
0721 int efa_com_dealloc_uar(struct efa_com_dev *edev,
0722             struct efa_com_dealloc_uar_params *params)
0723 {
0724     struct efa_com_admin_queue *aq = &edev->aq;
0725     struct efa_admin_dealloc_uar_cmd cmd = {};
0726     struct efa_admin_dealloc_uar_resp resp;
0727     int err;
0728 
0729     cmd.aq_common_descriptor.opcode = EFA_ADMIN_DEALLOC_UAR;
0730     cmd.uar = params->uarn;
0731 
0732     err = efa_com_cmd_exec(aq,
0733                    (struct efa_admin_aq_entry *)&cmd,
0734                    sizeof(cmd),
0735                    (struct efa_admin_acq_entry *)&resp,
0736                    sizeof(resp));
0737     if (err) {
0738         ibdev_err_ratelimited(edev->efa_dev,
0739                       "Failed to deallocate uar-%u [%d]\n",
0740                       cmd.uar, err);
0741         return err;
0742     }
0743 
0744     return 0;
0745 }
0746 
0747 int efa_com_get_stats(struct efa_com_dev *edev,
0748               struct efa_com_get_stats_params *params,
0749               union efa_com_get_stats_result *result)
0750 {
0751     struct efa_com_admin_queue *aq = &edev->aq;
0752     struct efa_admin_aq_get_stats_cmd cmd = {};
0753     struct efa_admin_acq_get_stats_resp resp;
0754     int err;
0755 
0756     cmd.aq_common_descriptor.opcode = EFA_ADMIN_GET_STATS;
0757     cmd.type = params->type;
0758     cmd.scope = params->scope;
0759     cmd.scope_modifier = params->scope_modifier;
0760 
0761     err = efa_com_cmd_exec(aq,
0762                    (struct efa_admin_aq_entry *)&cmd,
0763                    sizeof(cmd),
0764                    (struct efa_admin_acq_entry *)&resp,
0765                    sizeof(resp));
0766     if (err) {
0767         ibdev_err_ratelimited(
0768             edev->efa_dev,
0769             "Failed to get stats type-%u scope-%u.%u [%d]\n",
0770             cmd.type, cmd.scope, cmd.scope_modifier, err);
0771         return err;
0772     }
0773 
0774     switch (cmd.type) {
0775     case EFA_ADMIN_GET_STATS_TYPE_BASIC:
0776         result->basic_stats.tx_bytes = resp.u.basic_stats.tx_bytes;
0777         result->basic_stats.tx_pkts = resp.u.basic_stats.tx_pkts;
0778         result->basic_stats.rx_bytes = resp.u.basic_stats.rx_bytes;
0779         result->basic_stats.rx_pkts = resp.u.basic_stats.rx_pkts;
0780         result->basic_stats.rx_drops = resp.u.basic_stats.rx_drops;
0781         break;
0782     case EFA_ADMIN_GET_STATS_TYPE_MESSAGES:
0783         result->messages_stats.send_bytes = resp.u.messages_stats.send_bytes;
0784         result->messages_stats.send_wrs = resp.u.messages_stats.send_wrs;
0785         result->messages_stats.recv_bytes = resp.u.messages_stats.recv_bytes;
0786         result->messages_stats.recv_wrs = resp.u.messages_stats.recv_wrs;
0787         break;
0788     case EFA_ADMIN_GET_STATS_TYPE_RDMA_READ:
0789         result->rdma_read_stats.read_wrs = resp.u.rdma_read_stats.read_wrs;
0790         result->rdma_read_stats.read_bytes = resp.u.rdma_read_stats.read_bytes;
0791         result->rdma_read_stats.read_wr_err = resp.u.rdma_read_stats.read_wr_err;
0792         result->rdma_read_stats.read_resp_bytes = resp.u.rdma_read_stats.read_resp_bytes;
0793         break;
0794     }
0795 
0796     return 0;
0797 }