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