0001
0002
0003
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
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 }