1 // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause 2 /* 3 * Copyright 2018-2026 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_1); 483 if (err) { 484 ibdev_err_ratelimited(edev->efa_dev, 485 "Failed to get queue attributes1 %d\n", 486 err); 487 return err; 488 } 489 490 result->max_qp = resp.u.queue_attr_1.max_qp; 491 result->max_sq_depth = resp.u.queue_attr_1.max_sq_depth; 492 result->max_rq_depth = resp.u.queue_attr_1.max_rq_depth; 493 result->max_cq = resp.u.queue_attr_1.max_cq; 494 result->max_cq_depth = resp.u.queue_attr_1.max_cq_depth; 495 result->inline_buf_size = resp.u.queue_attr_1.inline_buf_size; 496 result->max_sq_sge = resp.u.queue_attr_1.max_wr_send_sges; 497 result->max_rq_sge = resp.u.queue_attr_1.max_wr_recv_sges; 498 result->max_mr = resp.u.queue_attr_1.max_mr; 499 result->max_mr_pages = resp.u.queue_attr_1.max_mr_pages; 500 result->max_pd = resp.u.queue_attr_1.max_pd; 501 result->max_ah = resp.u.queue_attr_1.max_ah; 502 result->max_llq_size = resp.u.queue_attr_1.max_llq_size; 503 result->sub_cqs_per_cq = resp.u.queue_attr_1.sub_cqs_per_cq; 504 result->max_wr_rdma_sge = resp.u.queue_attr_1.max_wr_rdma_sges; 505 result->max_tx_batch = resp.u.queue_attr_1.max_tx_batch; 506 result->min_sq_depth = resp.u.queue_attr_1.min_sq_depth; 507 508 if (efa_com_check_supported_feature_id(edev, EFA_ADMIN_QUEUE_ATTR_2)) { 509 err = efa_com_get_feature(edev, &resp, 510 EFA_ADMIN_QUEUE_ATTR_2); 511 if (err) { 512 ibdev_err_ratelimited( 513 edev->efa_dev, 514 "Failed to get queue attributes2 %d\n", err); 515 return err; 516 } 517 518 result->inline_buf_size_ex = resp.u.queue_attr_2.inline_buf_size_ex; 519 } else { 520 result->inline_buf_size_ex = result->inline_buf_size; 521 } 522 523 err = efa_com_get_feature(edev, &resp, EFA_ADMIN_NETWORK_ATTR); 524 if (err) { 525 ibdev_err_ratelimited(edev->efa_dev, 526 "Failed to get network attributes %d\n", 527 err); 528 return err; 529 } 530 531 memcpy(result->addr, resp.u.network_attr.addr, 532 sizeof(resp.u.network_attr.addr)); 533 result->mtu = resp.u.network_attr.mtu; 534 535 if (efa_com_check_supported_feature_id(edev, 536 EFA_ADMIN_EVENT_QUEUE_ATTR)) { 537 err = efa_com_get_feature(edev, &resp, 538 EFA_ADMIN_EVENT_QUEUE_ATTR); 539 if (err) { 540 ibdev_err_ratelimited( 541 edev->efa_dev, 542 "Failed to get event queue attributes %d\n", 543 err); 544 return err; 545 } 546 547 result->max_eq = resp.u.event_queue_attr.max_eq; 548 result->max_eq_depth = resp.u.event_queue_attr.max_eq_depth; 549 result->event_bitmask = resp.u.event_queue_attr.event_bitmask; 550 } 551 552 return 0; 553 } 554 555 int efa_com_get_hw_hints(struct efa_com_dev *edev, 556 struct efa_com_get_hw_hints_result *result) 557 { 558 struct efa_admin_get_feature_resp resp; 559 int err; 560 561 err = efa_com_get_feature(edev, &resp, EFA_ADMIN_HW_HINTS); 562 if (err) { 563 ibdev_err_ratelimited(edev->efa_dev, 564 "Failed to get hw hints %d\n", err); 565 return err; 566 } 567 568 result->admin_completion_timeout = resp.u.hw_hints.admin_completion_timeout; 569 result->driver_watchdog_timeout = resp.u.hw_hints.driver_watchdog_timeout; 570 result->mmio_read_timeout = resp.u.hw_hints.mmio_read_timeout; 571 result->poll_interval = resp.u.hw_hints.poll_interval; 572 573 return 0; 574 } 575 576 int efa_com_set_feature_ex(struct efa_com_dev *edev, 577 struct efa_admin_set_feature_resp *set_resp, 578 struct efa_admin_set_feature_cmd *set_cmd, 579 enum efa_admin_aq_feature_id feature_id, 580 dma_addr_t control_buf_dma_addr, 581 u32 control_buff_size) 582 { 583 struct efa_com_admin_queue *aq; 584 int err; 585 586 if (!efa_com_check_supported_feature_id(edev, feature_id)) { 587 ibdev_err_ratelimited(edev->efa_dev, 588 "Feature %d isn't supported\n", 589 feature_id); 590 return -EOPNOTSUPP; 591 } 592 593 aq = &edev->aq; 594 595 set_cmd->aq_common_descriptor.opcode = EFA_ADMIN_SET_FEATURE; 596 if (control_buff_size) { 597 set_cmd->aq_common_descriptor.flags = 0; 598 EFA_SET(&set_cmd->aq_common_descriptor.flags, 599 EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1); 600 efa_com_set_dma_addr(control_buf_dma_addr, 601 &set_cmd->control_buffer.address.mem_addr_high, 602 &set_cmd->control_buffer.address.mem_addr_low); 603 } 604 605 set_cmd->control_buffer.length = control_buff_size; 606 set_cmd->feature_common.feature_id = feature_id; 607 err = efa_com_cmd_exec(aq, 608 (struct efa_admin_aq_entry *)set_cmd, 609 sizeof(*set_cmd), 610 (struct efa_admin_acq_entry *)set_resp, 611 sizeof(*set_resp)); 612 613 if (err) { 614 ibdev_err_ratelimited( 615 edev->efa_dev, 616 "Failed to submit set_feature command %d error: %d\n", 617 feature_id, err); 618 return err; 619 } 620 621 return 0; 622 } 623 624 static int efa_com_set_feature(struct efa_com_dev *edev, 625 struct efa_admin_set_feature_resp *set_resp, 626 struct efa_admin_set_feature_cmd *set_cmd, 627 enum efa_admin_aq_feature_id feature_id) 628 { 629 return efa_com_set_feature_ex(edev, set_resp, set_cmd, feature_id, 630 0, 0); 631 } 632 633 int efa_com_set_aenq_config(struct efa_com_dev *edev, u32 groups) 634 { 635 struct efa_admin_get_feature_resp get_resp; 636 struct efa_admin_set_feature_resp set_resp; 637 struct efa_admin_set_feature_cmd cmd = {}; 638 int err; 639 640 ibdev_dbg(edev->efa_dev, "Configuring aenq with groups[%#x]\n", groups); 641 642 err = efa_com_get_feature(edev, &get_resp, EFA_ADMIN_AENQ_CONFIG); 643 if (err) { 644 ibdev_err_ratelimited(edev->efa_dev, 645 "Failed to get aenq attributes: %d\n", 646 err); 647 return err; 648 } 649 650 ibdev_dbg(edev->efa_dev, 651 "Get aenq groups: supported[%#x] enabled[%#x]\n", 652 get_resp.u.aenq.supported_groups, 653 get_resp.u.aenq.enabled_groups); 654 655 if ((get_resp.u.aenq.supported_groups & groups) != groups) { 656 ibdev_err_ratelimited( 657 edev->efa_dev, 658 "Trying to set unsupported aenq groups[%#x] supported[%#x]\n", 659 groups, get_resp.u.aenq.supported_groups); 660 return -EOPNOTSUPP; 661 } 662 663 cmd.u.aenq.enabled_groups = groups; 664 err = efa_com_set_feature(edev, &set_resp, &cmd, 665 EFA_ADMIN_AENQ_CONFIG); 666 if (err) { 667 ibdev_err_ratelimited(edev->efa_dev, 668 "Failed to set aenq attributes: %d\n", 669 err); 670 return err; 671 } 672 673 return 0; 674 } 675 676 int efa_com_alloc_pd(struct efa_com_dev *edev, 677 struct efa_com_alloc_pd_result *result) 678 { 679 struct efa_com_admin_queue *aq = &edev->aq; 680 struct efa_admin_alloc_pd_cmd cmd = {}; 681 struct efa_admin_alloc_pd_resp resp; 682 int err; 683 684 cmd.aq_common_descriptor.opcode = EFA_ADMIN_ALLOC_PD; 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 pd[%d]\n", err); 694 return err; 695 } 696 697 result->pdn = resp.pd; 698 699 return 0; 700 } 701 702 int efa_com_dealloc_pd(struct efa_com_dev *edev, 703 struct efa_com_dealloc_pd_params *params) 704 { 705 struct efa_com_admin_queue *aq = &edev->aq; 706 struct efa_admin_dealloc_pd_cmd cmd = {}; 707 struct efa_admin_dealloc_pd_resp resp; 708 int err; 709 710 cmd.aq_common_descriptor.opcode = EFA_ADMIN_DEALLOC_PD; 711 cmd.pd = params->pdn; 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 pd-%u [%d]\n", 721 cmd.pd, err); 722 return err; 723 } 724 725 return 0; 726 } 727 728 int efa_com_alloc_uar(struct efa_com_dev *edev, 729 struct efa_com_alloc_uar_result *result) 730 { 731 struct efa_com_admin_queue *aq = &edev->aq; 732 struct efa_admin_alloc_uar_cmd cmd = {}; 733 struct efa_admin_alloc_uar_resp resp; 734 int err; 735 736 cmd.aq_common_descriptor.opcode = EFA_ADMIN_ALLOC_UAR; 737 738 err = efa_com_cmd_exec(aq, 739 (struct efa_admin_aq_entry *)&cmd, 740 sizeof(cmd), 741 (struct efa_admin_acq_entry *)&resp, 742 sizeof(resp)); 743 if (err) { 744 ibdev_err_ratelimited(edev->efa_dev, 745 "Failed to allocate uar[%d]\n", err); 746 return err; 747 } 748 749 result->uarn = resp.uar; 750 751 return 0; 752 } 753 754 int efa_com_dealloc_uar(struct efa_com_dev *edev, 755 struct efa_com_dealloc_uar_params *params) 756 { 757 struct efa_com_admin_queue *aq = &edev->aq; 758 struct efa_admin_dealloc_uar_cmd cmd = {}; 759 struct efa_admin_dealloc_uar_resp resp; 760 int err; 761 762 cmd.aq_common_descriptor.opcode = EFA_ADMIN_DEALLOC_UAR; 763 cmd.uar = params->uarn; 764 765 err = efa_com_cmd_exec(aq, 766 (struct efa_admin_aq_entry *)&cmd, 767 sizeof(cmd), 768 (struct efa_admin_acq_entry *)&resp, 769 sizeof(resp)); 770 if (err) { 771 ibdev_err_ratelimited(edev->efa_dev, 772 "Failed to deallocate uar-%u [%d]\n", 773 cmd.uar, err); 774 return err; 775 } 776 777 return 0; 778 } 779 780 int efa_com_get_stats(struct efa_com_dev *edev, 781 struct efa_com_get_stats_params *params, 782 union efa_com_get_stats_result *result) 783 { 784 struct efa_com_admin_queue *aq = &edev->aq; 785 struct efa_admin_aq_get_stats_cmd cmd = {}; 786 struct efa_admin_acq_get_stats_resp resp; 787 struct efa_admin_rdma_write_stats *rws; 788 struct efa_admin_rdma_read_stats *rrs; 789 struct efa_admin_messages_stats *ms; 790 struct efa_admin_network_stats *ns; 791 struct efa_admin_basic_stats *bs; 792 int err; 793 794 cmd.aq_common_descriptor.opcode = EFA_ADMIN_GET_STATS; 795 cmd.type = params->type; 796 cmd.scope = params->scope; 797 cmd.scope_modifier = params->scope_modifier; 798 799 err = efa_com_cmd_exec(aq, 800 (struct efa_admin_aq_entry *)&cmd, 801 sizeof(cmd), 802 (struct efa_admin_acq_entry *)&resp, 803 sizeof(resp)); 804 if (err) { 805 ibdev_err_ratelimited( 806 edev->efa_dev, 807 "Failed to get stats type-%u scope-%u.%u [%d]\n", 808 cmd.type, cmd.scope, cmd.scope_modifier, err); 809 return err; 810 } 811 812 switch (cmd.type) { 813 case EFA_ADMIN_GET_STATS_TYPE_BASIC: 814 bs = &resp.u.basic_stats; 815 result->basic_stats.tx_bytes = bs->tx_bytes; 816 result->basic_stats.tx_pkts = bs->tx_pkts; 817 result->basic_stats.rx_bytes = bs->rx_bytes; 818 result->basic_stats.rx_pkts = bs->rx_pkts; 819 result->basic_stats.rx_drops = bs->rx_drops; 820 break; 821 case EFA_ADMIN_GET_STATS_TYPE_MESSAGES: 822 ms = &resp.u.messages_stats; 823 result->messages_stats.send_bytes = ms->send_bytes; 824 result->messages_stats.send_wrs = ms->send_wrs; 825 result->messages_stats.recv_bytes = ms->recv_bytes; 826 result->messages_stats.recv_wrs = ms->recv_wrs; 827 break; 828 case EFA_ADMIN_GET_STATS_TYPE_RDMA_READ: 829 rrs = &resp.u.rdma_read_stats; 830 result->rdma_read_stats.read_wrs = rrs->read_wrs; 831 result->rdma_read_stats.read_bytes = rrs->read_bytes; 832 result->rdma_read_stats.read_wr_err = rrs->read_wr_err; 833 result->rdma_read_stats.read_resp_bytes = rrs->read_resp_bytes; 834 break; 835 case EFA_ADMIN_GET_STATS_TYPE_RDMA_WRITE: 836 rws = &resp.u.rdma_write_stats; 837 result->rdma_write_stats.write_wrs = rws->write_wrs; 838 result->rdma_write_stats.write_bytes = rws->write_bytes; 839 result->rdma_write_stats.write_wr_err = rws->write_wr_err; 840 result->rdma_write_stats.write_recv_bytes = rws->write_recv_bytes; 841 break; 842 case EFA_ADMIN_GET_STATS_TYPE_NETWORK: 843 ns = &resp.u.network_stats; 844 result->network_stats.retrans_bytes = ns->retrans_bytes; 845 result->network_stats.retrans_pkts = ns->retrans_pkts; 846 result->network_stats.retrans_timeout_events = ns->retrans_timeout_events; 847 result->network_stats.unresponsive_remote_events = ns->unresponsive_remote_events; 848 result->network_stats.impaired_remote_conn_events = ns->impaired_remote_conn_events; 849 break; 850 } 851 852 return 0; 853 } 854