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