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