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 #define EFA_DEFAULT_LINK_SPEED_GBPS 100 10 11 int efa_com_create_qp(struct efa_com_dev *edev, 12 struct efa_com_create_qp_params *params, 13 struct efa_com_create_qp_result *res) 14 { 15 struct efa_admin_create_qp_cmd create_qp_cmd = {}; 16 struct efa_admin_create_qp_resp cmd_completion; 17 struct efa_com_admin_queue *aq = &edev->aq; 18 int err; 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 if (params->sq_64_bit_req_id) 40 EFA_SET(&create_qp_cmd.flags, EFA_ADMIN_CREATE_QP_CMD_SQ_64_BIT_REQ_ID, 1); 41 42 err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_QP, 0, 43 &create_qp_cmd, 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.modify_mask = params->modify_mask; 72 cmd.qp_handle = params->qp_handle; 73 cmd.qp_state = params->qp_state; 74 cmd.cur_qp_state = params->cur_qp_state; 75 cmd.qkey = params->qkey; 76 cmd.sq_psn = params->sq_psn; 77 cmd.sq_drained_async_notify = params->sq_drained_async_notify; 78 cmd.rnr_retry = params->rnr_retry; 79 80 err = efa_com_cmd_exec(aq, EFA_ADMIN_MODIFY_QP, 0, 81 &cmd, sizeof(cmd), 82 (struct efa_admin_acq_entry *)&resp, sizeof(resp)); 83 if (err) { 84 ibdev_err_ratelimited( 85 edev->efa_dev, 86 "Failed to modify qp-%u modify_mask[%#x] [%d]\n", 87 cmd.qp_handle, cmd.modify_mask, err); 88 return err; 89 } 90 91 return 0; 92 } 93 94 int efa_com_query_qp(struct efa_com_dev *edev, 95 struct efa_com_query_qp_params *params, 96 struct efa_com_query_qp_result *result) 97 { 98 struct efa_com_admin_queue *aq = &edev->aq; 99 struct efa_admin_query_qp_cmd cmd = {}; 100 struct efa_admin_query_qp_resp resp; 101 int err; 102 103 cmd.qp_handle = params->qp_handle; 104 105 err = efa_com_cmd_exec(aq, EFA_ADMIN_QUERY_QP, 0, 106 &cmd, sizeof(cmd), 107 (struct efa_admin_acq_entry *)&resp, 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.qp_handle = params->qp_handle; 133 134 err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_QP, 0, 135 &qp_cmd, sizeof(qp_cmd), 136 (struct efa_admin_acq_entry *)&cmd_completion, 137 sizeof(cmd_completion)); 138 if (err) { 139 ibdev_err_ratelimited(edev->efa_dev, 140 "Failed to destroy qp-%u [%d]\n", 141 qp_cmd.qp_handle, err); 142 return err; 143 } 144 145 return 0; 146 } 147 148 int efa_com_create_cq(struct efa_com_dev *edev, 149 struct efa_com_create_cq_params *params, 150 struct efa_com_create_cq_result *result) 151 { 152 struct efa_admin_create_cq_resp cmd_completion = {}; 153 struct efa_admin_create_cq_cmd create_cmd = {}; 154 struct efa_com_admin_queue *aq = &edev->aq; 155 int err; 156 157 EFA_SET(&create_cmd.cq_caps_2, 158 EFA_ADMIN_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS, 159 params->entry_size_in_bytes / 4); 160 create_cmd.sub_cq_depth = params->sub_cq_depth; 161 create_cmd.num_sub_cqs = params->num_sub_cqs; 162 create_cmd.uar = params->uarn; 163 if (params->interrupt_mode_enabled) { 164 EFA_SET(&create_cmd.cq_caps_1, 165 EFA_ADMIN_CREATE_CQ_CMD_INTERRUPT_MODE_ENABLED, 1); 166 create_cmd.eqn = params->eqn; 167 } 168 if (params->set_src_addr) { 169 EFA_SET(&create_cmd.cq_caps_2, 170 EFA_ADMIN_CREATE_CQ_CMD_SET_SRC_ADDR, 1); 171 } 172 if (params->sq_comp_64_bit_req_id) { 173 EFA_SET(&create_cmd.cq_caps_2, 174 EFA_ADMIN_CREATE_CQ_CMD_SQ_COMP_64_BIT_REQ_ID, 1); 175 } 176 177 efa_com_set_dma_addr(params->dma_addr, 178 &create_cmd.cq_ba.mem_addr_high, 179 &create_cmd.cq_ba.mem_addr_low); 180 181 err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_CQ, 0, 182 &create_cmd, sizeof(create_cmd), 183 (struct efa_admin_acq_entry *)&cmd_completion, 184 sizeof(cmd_completion)); 185 if (err) { 186 ibdev_err_ratelimited(edev->efa_dev, 187 "Failed to create cq[%d]\n", err); 188 return err; 189 } 190 191 result->cq_idx = cmd_completion.cq_idx; 192 result->actual_depth = params->sub_cq_depth; 193 result->db_off = cmd_completion.db_offset; 194 result->db_valid = EFA_GET(&cmd_completion.flags, 195 EFA_ADMIN_CREATE_CQ_RESP_DB_VALID); 196 197 return 0; 198 } 199 200 int efa_com_destroy_cq(struct efa_com_dev *edev, 201 struct efa_com_destroy_cq_params *params) 202 { 203 struct efa_admin_destroy_cq_cmd destroy_cmd = {}; 204 struct efa_admin_destroy_cq_resp destroy_resp; 205 struct efa_com_admin_queue *aq = &edev->aq; 206 int err; 207 208 destroy_cmd.cq_idx = params->cq_idx; 209 210 err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_CQ, 0, 211 &destroy_cmd, sizeof(destroy_cmd), 212 (struct efa_admin_acq_entry *)&destroy_resp, 213 sizeof(destroy_resp)); 214 215 if (err) { 216 ibdev_err_ratelimited(edev->efa_dev, 217 "Failed to destroy CQ-%u [%d]\n", 218 params->cq_idx, err); 219 return err; 220 } 221 222 return 0; 223 } 224 225 int efa_com_register_mr(struct efa_com_dev *edev, 226 struct efa_com_reg_mr_params *params, 227 struct efa_com_reg_mr_result *result) 228 { 229 struct efa_admin_reg_mr_resp cmd_completion; 230 struct efa_com_admin_queue *aq = &edev->aq; 231 struct efa_admin_reg_mr_cmd mr_cmd = {}; 232 u8 flags = 0; 233 int err; 234 235 mr_cmd.pd = params->pd; 236 mr_cmd.mr_length = params->mr_length_in_bytes; 237 EFA_SET(&mr_cmd.flags, EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT, 238 params->page_shift); 239 mr_cmd.iova = params->iova; 240 mr_cmd.permissions = params->permissions; 241 242 if (params->inline_pbl) { 243 memcpy(mr_cmd.pbl.inline_pbl_array, 244 params->pbl.inline_pbl_array, 245 sizeof(mr_cmd.pbl.inline_pbl_array)); 246 } else { 247 mr_cmd.pbl.pbl.length = params->pbl.pbl.length; 248 mr_cmd.pbl.pbl.address.mem_addr_low = 249 params->pbl.pbl.address.mem_addr_low; 250 mr_cmd.pbl.pbl.address.mem_addr_high = 251 params->pbl.pbl.address.mem_addr_high; 252 EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1); 253 if (params->indirect) 254 EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT, 1); 255 } 256 257 err = efa_com_cmd_exec(aq, EFA_ADMIN_REG_MR, flags, 258 &mr_cmd, sizeof(mr_cmd), 259 (struct efa_admin_acq_entry *)&cmd_completion, 260 sizeof(cmd_completion)); 261 if (err) { 262 ibdev_err_ratelimited(edev->efa_dev, 263 "Failed to register mr [%d]\n", err); 264 return err; 265 } 266 267 result->l_key = cmd_completion.l_key; 268 result->r_key = cmd_completion.r_key; 269 result->ic_info.recv_ic_id = cmd_completion.recv_ic_id; 270 result->ic_info.rdma_read_ic_id = cmd_completion.rdma_read_ic_id; 271 result->ic_info.rdma_recv_ic_id = cmd_completion.rdma_recv_ic_id; 272 result->ic_info.recv_ic_id_valid = EFA_GET(&cmd_completion.validity, 273 EFA_ADMIN_REG_MR_RESP_RECV_IC_ID); 274 result->ic_info.rdma_read_ic_id_valid = EFA_GET(&cmd_completion.validity, 275 EFA_ADMIN_REG_MR_RESP_RDMA_READ_IC_ID); 276 result->ic_info.rdma_recv_ic_id_valid = EFA_GET(&cmd_completion.validity, 277 EFA_ADMIN_REG_MR_RESP_RDMA_RECV_IC_ID); 278 279 return 0; 280 } 281 282 int efa_com_dereg_mr(struct efa_com_dev *edev, 283 struct efa_com_dereg_mr_params *params) 284 { 285 struct efa_admin_dereg_mr_resp cmd_completion; 286 struct efa_com_admin_queue *aq = &edev->aq; 287 struct efa_admin_dereg_mr_cmd mr_cmd = {}; 288 int err; 289 290 mr_cmd.l_key = params->l_key; 291 292 err = efa_com_cmd_exec(aq, EFA_ADMIN_DEREG_MR, 0, 293 &mr_cmd, sizeof(mr_cmd), 294 (struct efa_admin_acq_entry *)&cmd_completion, 295 sizeof(cmd_completion)); 296 if (err) { 297 ibdev_err_ratelimited(edev->efa_dev, 298 "Failed to de-register mr(lkey-%u) [%d]\n", 299 mr_cmd.l_key, err); 300 return err; 301 } 302 303 return 0; 304 } 305 306 int efa_com_create_ah(struct efa_com_dev *edev, 307 struct efa_com_create_ah_params *params, 308 struct efa_com_create_ah_result *result) 309 { 310 struct efa_admin_create_ah_resp cmd_completion; 311 struct efa_com_admin_queue *aq = &edev->aq; 312 struct efa_admin_create_ah_cmd ah_cmd = {}; 313 struct efa_ah_cache_entry *entry; 314 int err; 315 316 entry = efa_ah_cache_get(&edev->ah_cache, params->pdn, params->dest_addr); 317 if (IS_ERR(entry)) 318 return PTR_ERR(entry); 319 320 mutex_lock(&entry->lock); 321 if (entry->usecnt) { 322 result->ah = entry->ah; 323 entry->usecnt++; 324 mutex_unlock(&entry->lock); 325 return 0; 326 } 327 328 memcpy(ah_cmd.dest_addr, params->dest_addr, sizeof(ah_cmd.dest_addr)); 329 ah_cmd.pd = params->pdn; 330 331 err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_AH, 0, 332 &ah_cmd, sizeof(ah_cmd), 333 (struct efa_admin_acq_entry *)&cmd_completion, 334 sizeof(cmd_completion)); 335 if (err) { 336 mutex_unlock(&entry->lock); 337 efa_ah_cache_put(&edev->ah_cache, entry); 338 ibdev_err_ratelimited(edev->efa_dev, 339 "Failed to create ah for %pI6 [%d]\n", 340 ah_cmd.dest_addr, err); 341 return err; 342 } 343 344 entry->ah = cmd_completion.ah; 345 result->ah = cmd_completion.ah; 346 entry->usecnt++; 347 mutex_unlock(&entry->lock); 348 349 return 0; 350 } 351 352 int efa_com_destroy_ah(struct efa_com_dev *edev, 353 struct efa_com_destroy_ah_params *params) 354 { 355 struct efa_admin_destroy_ah_resp cmd_completion; 356 struct efa_admin_destroy_ah_cmd ah_cmd = {}; 357 struct efa_com_admin_queue *aq = &edev->aq; 358 struct efa_ah_cache_entry *entry; 359 int err = 0; 360 361 entry = efa_ah_cache_lookup(&edev->ah_cache, params->pdn, params->gid); 362 if (!entry) 363 return -EINVAL; 364 365 mutex_lock(&entry->lock); 366 if (entry->usecnt > 1) 367 goto out_put; 368 369 ah_cmd.ah = entry->ah; 370 ah_cmd.pd = entry->key.pd; 371 372 err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_AH, 0, 373 &ah_cmd, sizeof(ah_cmd), 374 (struct efa_admin_acq_entry *)&cmd_completion, 375 sizeof(cmd_completion)); 376 if (err) { 377 mutex_unlock(&entry->lock); 378 ibdev_err_ratelimited(edev->efa_dev, 379 "Failed to destroy ah-%d pd-%d [%d]\n", 380 ah_cmd.ah, ah_cmd.pd, err); 381 return err; 382 } 383 384 out_put: 385 entry->usecnt--; 386 mutex_unlock(&entry->lock); 387 efa_ah_cache_put(&edev->ah_cache, entry); 388 389 return err; 390 } 391 392 bool 393 efa_com_check_supported_feature_id(struct efa_com_dev *edev, 394 enum efa_admin_aq_feature_id feature_id) 395 { 396 u32 feature_mask = 1 << feature_id; 397 398 /* Device attributes is always supported */ 399 if (feature_id != EFA_ADMIN_DEVICE_ATTR && 400 !(edev->supported_features & feature_mask)) 401 return false; 402 403 return true; 404 } 405 406 static int efa_com_get_feature_ex(struct efa_com_dev *edev, 407 struct efa_admin_get_feature_resp *get_resp, 408 enum efa_admin_aq_feature_id feature_id, 409 dma_addr_t control_buf_dma_addr, 410 u32 control_buff_size) 411 { 412 struct efa_admin_get_feature_cmd get_cmd = {}; 413 struct efa_com_admin_queue *aq; 414 u8 flags = 0; 415 int err; 416 417 if (!efa_com_check_supported_feature_id(edev, feature_id)) { 418 ibdev_err_ratelimited(edev->efa_dev, 419 "Feature %d isn't supported\n", 420 feature_id); 421 return -EOPNOTSUPP; 422 } 423 424 aq = &edev->aq; 425 426 if (control_buff_size) 427 EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1); 428 429 efa_com_set_dma_addr(control_buf_dma_addr, 430 &get_cmd.control_buffer.address.mem_addr_high, 431 &get_cmd.control_buffer.address.mem_addr_low); 432 433 get_cmd.control_buffer.length = control_buff_size; 434 get_cmd.feature_common.feature_id = feature_id; 435 err = efa_com_cmd_exec(aq, EFA_ADMIN_GET_FEATURE, flags, 436 &get_cmd, sizeof(get_cmd), 437 (struct efa_admin_acq_entry *)get_resp, 438 sizeof(*get_resp)); 439 440 if (err) { 441 ibdev_err_ratelimited( 442 edev->efa_dev, 443 "Failed to submit get_feature command %d [%d]\n", 444 feature_id, err); 445 return err; 446 } 447 448 return 0; 449 } 450 451 static int efa_com_get_feature(struct efa_com_dev *edev, 452 struct efa_admin_get_feature_resp *get_resp, 453 enum efa_admin_aq_feature_id feature_id) 454 { 455 return efa_com_get_feature_ex(edev, get_resp, feature_id, 0, 0); 456 } 457 458 int efa_com_get_device_attr(struct efa_com_dev *edev, 459 struct efa_com_get_device_attr_result *result) 460 { 461 struct efa_admin_get_feature_resp resp; 462 int err; 463 464 err = efa_com_get_feature(edev, &resp, EFA_ADMIN_DEVICE_ATTR); 465 if (err) { 466 ibdev_err_ratelimited(edev->efa_dev, 467 "Failed to get device attributes %d\n", 468 err); 469 return err; 470 } 471 472 result->page_size_cap = resp.u.device_attr.page_size_cap; 473 result->fw_version = resp.u.device_attr.fw_version; 474 result->admin_api_version = resp.u.device_attr.admin_api_version; 475 result->device_version = resp.u.device_attr.device_version; 476 result->supported_features = resp.u.device_attr.supported_features; 477 result->phys_addr_width = resp.u.device_attr.phys_addr_width; 478 result->virt_addr_width = resp.u.device_attr.virt_addr_width; 479 result->db_bar = resp.u.device_attr.db_bar; 480 result->max_rdma_size = resp.u.device_attr.max_rdma_size; 481 result->device_caps = resp.u.device_attr.device_caps; 482 result->guid = resp.u.device_attr.guid; 483 result->max_link_speed_gbps = resp.u.device_attr.max_link_speed_gbps; 484 if (!result->max_link_speed_gbps) 485 result->max_link_speed_gbps = EFA_DEFAULT_LINK_SPEED_GBPS; 486 487 if (result->admin_api_version < 1) { 488 ibdev_err_ratelimited( 489 edev->efa_dev, 490 "Failed to get device attr api version [%u < 1]\n", 491 result->admin_api_version); 492 return -EINVAL; 493 } 494 495 edev->supported_features = resp.u.device_attr.supported_features; 496 err = efa_com_get_feature(edev, &resp, 497 EFA_ADMIN_QUEUE_ATTR_1); 498 if (err) { 499 ibdev_err_ratelimited(edev->efa_dev, 500 "Failed to get queue attributes1 %d\n", 501 err); 502 return err; 503 } 504 505 result->max_qp = resp.u.queue_attr_1.max_qp; 506 result->max_sq_depth = resp.u.queue_attr_1.max_sq_depth; 507 result->max_rq_depth = resp.u.queue_attr_1.max_rq_depth; 508 result->max_cq = resp.u.queue_attr_1.max_cq; 509 result->max_cq_depth = resp.u.queue_attr_1.max_cq_depth; 510 result->inline_buf_size = resp.u.queue_attr_1.inline_buf_size; 511 result->max_sq_sge = resp.u.queue_attr_1.max_wr_send_sges; 512 result->max_rq_sge = resp.u.queue_attr_1.max_wr_recv_sges; 513 result->max_mr = resp.u.queue_attr_1.max_mr; 514 result->max_mr_pages = resp.u.queue_attr_1.max_mr_pages; 515 result->max_pd = resp.u.queue_attr_1.max_pd; 516 result->max_ah = resp.u.queue_attr_1.max_ah; 517 result->max_llq_size = resp.u.queue_attr_1.max_llq_size; 518 result->sub_cqs_per_cq = resp.u.queue_attr_1.sub_cqs_per_cq; 519 result->max_wr_rdma_sge = resp.u.queue_attr_1.max_wr_rdma_sges; 520 result->max_tx_batch = resp.u.queue_attr_1.max_tx_batch; 521 result->min_sq_depth = resp.u.queue_attr_1.min_sq_depth; 522 523 if (efa_com_check_supported_feature_id(edev, EFA_ADMIN_QUEUE_ATTR_2)) { 524 err = efa_com_get_feature(edev, &resp, 525 EFA_ADMIN_QUEUE_ATTR_2); 526 if (err) { 527 ibdev_err_ratelimited( 528 edev->efa_dev, 529 "Failed to get queue attributes2 %d\n", err); 530 return err; 531 } 532 533 result->inline_buf_size_ex = resp.u.queue_attr_2.inline_buf_size_ex; 534 result->max_event_counters = resp.u.queue_attr_2.max_event_counters; 535 result->event_counter_max_val = resp.u.queue_attr_2.event_counter_max_val; 536 result->supported_event_counter_qp_events = 537 resp.u.queue_attr_2.supported_event_counter_qp_events; 538 } else { 539 result->inline_buf_size_ex = result->inline_buf_size; 540 } 541 542 err = efa_com_get_feature(edev, &resp, EFA_ADMIN_NETWORK_ATTR); 543 if (err) { 544 ibdev_err_ratelimited(edev->efa_dev, 545 "Failed to get network attributes %d\n", 546 err); 547 return err; 548 } 549 550 memcpy(result->addr, resp.u.network_attr.addr, 551 sizeof(resp.u.network_attr.addr)); 552 result->mtu = resp.u.network_attr.mtu; 553 554 if (efa_com_check_supported_feature_id(edev, 555 EFA_ADMIN_EVENT_QUEUE_ATTR)) { 556 err = efa_com_get_feature(edev, &resp, 557 EFA_ADMIN_EVENT_QUEUE_ATTR); 558 if (err) { 559 ibdev_err_ratelimited( 560 edev->efa_dev, 561 "Failed to get event queue attributes %d\n", 562 err); 563 return err; 564 } 565 566 result->max_eq = resp.u.event_queue_attr.max_eq; 567 result->max_eq_depth = resp.u.event_queue_attr.max_eq_depth; 568 result->event_bitmask = resp.u.event_queue_attr.event_bitmask; 569 } 570 571 return 0; 572 } 573 574 int efa_com_get_hw_hints(struct efa_com_dev *edev, 575 struct efa_com_get_hw_hints_result *result) 576 { 577 struct efa_admin_get_feature_resp resp; 578 int err; 579 580 err = efa_com_get_feature(edev, &resp, EFA_ADMIN_HW_HINTS); 581 if (err) { 582 ibdev_err_ratelimited(edev->efa_dev, 583 "Failed to get hw hints %d\n", err); 584 return err; 585 } 586 587 result->admin_completion_timeout = resp.u.hw_hints.admin_completion_timeout; 588 result->driver_watchdog_timeout = resp.u.hw_hints.driver_watchdog_timeout; 589 result->mmio_read_timeout = resp.u.hw_hints.mmio_read_timeout; 590 result->poll_interval = resp.u.hw_hints.poll_interval; 591 592 return 0; 593 } 594 595 int efa_com_set_feature_ex(struct efa_com_dev *edev, 596 struct efa_admin_set_feature_resp *set_resp, 597 struct efa_admin_set_feature_cmd *set_cmd, 598 enum efa_admin_aq_feature_id feature_id, 599 dma_addr_t control_buf_dma_addr, 600 u32 control_buff_size) 601 { 602 struct efa_com_admin_queue *aq; 603 u8 flags = 0; 604 int err; 605 606 if (!efa_com_check_supported_feature_id(edev, feature_id)) { 607 ibdev_err_ratelimited(edev->efa_dev, 608 "Feature %d isn't supported\n", 609 feature_id); 610 return -EOPNOTSUPP; 611 } 612 613 aq = &edev->aq; 614 615 if (control_buff_size) { 616 EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1); 617 efa_com_set_dma_addr(control_buf_dma_addr, 618 &set_cmd->control_buffer.address.mem_addr_high, 619 &set_cmd->control_buffer.address.mem_addr_low); 620 } 621 622 set_cmd->control_buffer.length = control_buff_size; 623 set_cmd->feature_common.feature_id = feature_id; 624 err = efa_com_cmd_exec(aq, EFA_ADMIN_SET_FEATURE, flags, 625 set_cmd, sizeof(*set_cmd), 626 (struct efa_admin_acq_entry *)set_resp, 627 sizeof(*set_resp)); 628 629 if (err) { 630 ibdev_err_ratelimited( 631 edev->efa_dev, 632 "Failed to submit set_feature command %d error: %d\n", 633 feature_id, err); 634 return err; 635 } 636 637 return 0; 638 } 639 640 static int efa_com_set_feature(struct efa_com_dev *edev, 641 struct efa_admin_set_feature_resp *set_resp, 642 struct efa_admin_set_feature_cmd *set_cmd, 643 enum efa_admin_aq_feature_id feature_id) 644 { 645 return efa_com_set_feature_ex(edev, set_resp, set_cmd, feature_id, 646 0, 0); 647 } 648 649 int efa_com_set_aenq_config(struct efa_com_dev *edev, u32 groups) 650 { 651 struct efa_admin_get_feature_resp get_resp; 652 struct efa_admin_set_feature_resp set_resp; 653 struct efa_admin_set_feature_cmd cmd = {}; 654 int err; 655 656 ibdev_dbg(edev->efa_dev, "Configuring aenq with groups[%#x]\n", groups); 657 658 err = efa_com_get_feature(edev, &get_resp, EFA_ADMIN_AENQ_CONFIG); 659 if (err) { 660 ibdev_err_ratelimited(edev->efa_dev, 661 "Failed to get aenq attributes: %d\n", 662 err); 663 return err; 664 } 665 666 ibdev_dbg(edev->efa_dev, 667 "Get aenq groups: supported[%#x] enabled[%#x]\n", 668 get_resp.u.aenq.supported_groups, 669 get_resp.u.aenq.enabled_groups); 670 671 if ((get_resp.u.aenq.supported_groups & groups) != groups) { 672 ibdev_err_ratelimited( 673 edev->efa_dev, 674 "Trying to set unsupported aenq groups[%#x] supported[%#x]\n", 675 groups, get_resp.u.aenq.supported_groups); 676 return -EOPNOTSUPP; 677 } 678 679 cmd.u.aenq.enabled_groups = groups; 680 err = efa_com_set_feature(edev, &set_resp, &cmd, 681 EFA_ADMIN_AENQ_CONFIG); 682 if (err) { 683 ibdev_err_ratelimited(edev->efa_dev, 684 "Failed to set aenq attributes: %d\n", 685 err); 686 return err; 687 } 688 689 return 0; 690 } 691 692 int efa_com_alloc_pd(struct efa_com_dev *edev, 693 struct efa_com_alloc_pd_result *result) 694 { 695 struct efa_com_admin_queue *aq = &edev->aq; 696 struct efa_admin_alloc_pd_resp resp; 697 int err; 698 699 err = efa_com_cmd_exec(aq, EFA_ADMIN_ALLOC_PD, 0, 700 NULL, 0, 701 (struct efa_admin_acq_entry *)&resp, sizeof(resp)); 702 if (err) { 703 ibdev_err_ratelimited(edev->efa_dev, 704 "Failed to allocate pd[%d]\n", err); 705 return err; 706 } 707 708 result->pdn = resp.pd; 709 710 return 0; 711 } 712 713 int efa_com_dealloc_pd(struct efa_com_dev *edev, 714 struct efa_com_dealloc_pd_params *params) 715 { 716 struct efa_com_admin_queue *aq = &edev->aq; 717 struct efa_admin_dealloc_pd_cmd cmd = {}; 718 struct efa_admin_dealloc_pd_resp resp; 719 int err; 720 721 cmd.pd = params->pdn; 722 723 err = efa_com_cmd_exec(aq, EFA_ADMIN_DEALLOC_PD, 0, 724 &cmd, sizeof(cmd), 725 (struct efa_admin_acq_entry *)&resp, sizeof(resp)); 726 if (err) { 727 ibdev_err_ratelimited(edev->efa_dev, 728 "Failed to deallocate pd-%u [%d]\n", 729 cmd.pd, err); 730 return err; 731 } 732 733 return 0; 734 } 735 736 int efa_com_alloc_uar(struct efa_com_dev *edev, 737 struct efa_com_alloc_uar_result *result) 738 { 739 struct efa_com_admin_queue *aq = &edev->aq; 740 struct efa_admin_alloc_uar_resp resp; 741 int err; 742 743 err = efa_com_cmd_exec(aq, EFA_ADMIN_ALLOC_UAR, 0, 744 NULL, 0, 745 (struct efa_admin_acq_entry *)&resp, sizeof(resp)); 746 if (err) { 747 ibdev_err_ratelimited(edev->efa_dev, 748 "Failed to allocate uar[%d]\n", err); 749 return err; 750 } 751 752 result->uarn = resp.uar; 753 754 return 0; 755 } 756 757 int efa_com_dealloc_uar(struct efa_com_dev *edev, 758 struct efa_com_dealloc_uar_params *params) 759 { 760 struct efa_com_admin_queue *aq = &edev->aq; 761 struct efa_admin_dealloc_uar_cmd cmd = {}; 762 struct efa_admin_dealloc_uar_resp resp; 763 int err; 764 765 cmd.uar = params->uarn; 766 767 err = efa_com_cmd_exec(aq, EFA_ADMIN_DEALLOC_UAR, 0, 768 &cmd, sizeof(cmd), 769 (struct efa_admin_acq_entry *)&resp, 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.type = params->type; 795 cmd.scope = params->scope; 796 cmd.scope_modifier = params->scope_modifier; 797 798 err = efa_com_cmd_exec(aq, EFA_ADMIN_GET_STATS, 0, 799 &cmd, sizeof(cmd), 800 (struct efa_admin_acq_entry *)&resp, sizeof(resp)); 801 if (err) { 802 ibdev_err_ratelimited( 803 edev->efa_dev, 804 "Failed to get stats type-%u scope-%u.%u [%d]\n", 805 cmd.type, cmd.scope, cmd.scope_modifier, err); 806 return err; 807 } 808 809 switch (cmd.type) { 810 case EFA_ADMIN_GET_STATS_TYPE_BASIC: 811 bs = &resp.u.basic_stats; 812 result->basic_stats.tx_bytes = bs->tx_bytes; 813 result->basic_stats.tx_pkts = bs->tx_pkts; 814 result->basic_stats.rx_bytes = bs->rx_bytes; 815 result->basic_stats.rx_pkts = bs->rx_pkts; 816 result->basic_stats.rx_drops = bs->rx_drops; 817 break; 818 case EFA_ADMIN_GET_STATS_TYPE_MESSAGES: 819 ms = &resp.u.messages_stats; 820 result->messages_stats.send_bytes = ms->send_bytes; 821 result->messages_stats.send_wrs = ms->send_wrs; 822 result->messages_stats.recv_bytes = ms->recv_bytes; 823 result->messages_stats.recv_wrs = ms->recv_wrs; 824 break; 825 case EFA_ADMIN_GET_STATS_TYPE_RDMA_READ: 826 rrs = &resp.u.rdma_read_stats; 827 result->rdma_read_stats.read_wrs = rrs->read_wrs; 828 result->rdma_read_stats.read_bytes = rrs->read_bytes; 829 result->rdma_read_stats.read_wr_err = rrs->read_wr_err; 830 result->rdma_read_stats.read_resp_bytes = rrs->read_resp_bytes; 831 break; 832 case EFA_ADMIN_GET_STATS_TYPE_RDMA_WRITE: 833 rws = &resp.u.rdma_write_stats; 834 result->rdma_write_stats.write_wrs = rws->write_wrs; 835 result->rdma_write_stats.write_bytes = rws->write_bytes; 836 result->rdma_write_stats.write_wr_err = rws->write_wr_err; 837 result->rdma_write_stats.write_recv_bytes = rws->write_recv_bytes; 838 break; 839 case EFA_ADMIN_GET_STATS_TYPE_NETWORK: 840 ns = &resp.u.network_stats; 841 result->network_stats.retrans_bytes = ns->retrans_bytes; 842 result->network_stats.retrans_pkts = ns->retrans_pkts; 843 result->network_stats.retrans_timeout_events = ns->retrans_timeout_events; 844 result->network_stats.unresponsive_remote_events = ns->unresponsive_remote_events; 845 result->network_stats.impaired_remote_conn_events = ns->impaired_remote_conn_events; 846 break; 847 } 848 849 return 0; 850 } 851 852 int efa_com_create_event_counter(struct efa_com_dev *edev, 853 struct efa_com_create_event_counter_params *params, 854 struct efa_com_create_event_counter_result *result) 855 { 856 struct efa_admin_create_event_counter_cmd cmd = {}; 857 struct efa_admin_create_event_counter_resp resp; 858 struct efa_com_admin_queue *aq = &edev->aq; 859 int err; 860 861 cmd.uar = params->uarn; 862 cmd.paddr = params->dma_addr; 863 864 err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_EVENT_COUNTER, 0, 865 &cmd, sizeof(cmd), 866 (struct efa_admin_acq_entry *)&resp, 867 sizeof(resp)); 868 if (err) { 869 ibdev_err_ratelimited(edev->efa_dev, 870 "Failed to create event counter [%d]\n", 871 err); 872 return err; 873 } 874 875 result->cntr_handle = resp.cntr_handle; 876 return 0; 877 } 878 879 int efa_com_destroy_event_counter(struct efa_com_dev *edev, 880 struct efa_com_destroy_event_counter_params *params) 881 { 882 struct efa_admin_destroy_event_counter_cmd cmd = {}; 883 struct efa_admin_destroy_event_counter_resp resp; 884 struct efa_com_admin_queue *aq = &edev->aq; 885 int err; 886 887 cmd.cntr_handle = params->cntr_handle; 888 889 err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_EVENT_COUNTER, 0, 890 &cmd, sizeof(cmd), 891 (struct efa_admin_acq_entry *)&resp, 892 sizeof(resp)); 893 if (err) { 894 ibdev_err_ratelimited(edev->efa_dev, 895 "Failed to destroy event counter [%d]\n", 896 err); 897 return err; 898 } 899 900 return 0; 901 } 902 903 static int efa_com_attach_detach_event_counter(struct efa_com_dev *edev, u8 opcode, 904 u32 cntr_handle, u32 qp_handle, 905 u32 events) 906 { 907 struct efa_admin_attach_detach_event_counter_cmd cmd = {}; 908 struct efa_admin_attach_detach_event_counter_resp resp; 909 struct efa_com_admin_queue *aq = &edev->aq; 910 int err; 911 912 cmd.cntr_handle = cntr_handle; 913 cmd.attach_type = EFA_ADMIN_EVENT_COUNTER_ATTACH_QP_EVENTS; 914 cmd.u.qp_events.qp_handle = qp_handle; 915 cmd.u.qp_events.events = events; 916 917 err = efa_com_cmd_exec(aq, opcode, 0, 918 &cmd, sizeof(cmd), 919 (struct efa_admin_acq_entry *)&resp, 920 sizeof(resp)); 921 if (err) { 922 ibdev_err_ratelimited(edev->efa_dev, 923 "Failed to %s event counter [%d]\n", 924 opcode == EFA_ADMIN_ATTACH_EVENT_COUNTER 925 ? "attach" 926 : "detach", 927 err); 928 return err; 929 } 930 931 return 0; 932 } 933 934 int efa_com_attach_event_counter(struct efa_com_dev *edev, 935 struct efa_com_attach_event_counter_params *params) 936 { 937 return efa_com_attach_detach_event_counter(edev, 938 EFA_ADMIN_ATTACH_EVENT_COUNTER, 939 params->cntr_handle, 940 params->qp_handle, 941 params->events); 942 } 943 944 int efa_com_detach_event_counter(struct efa_com_dev *edev, 945 struct efa_com_detach_event_counter_params *params) 946 { 947 return efa_com_attach_detach_event_counter(edev, 948 EFA_ADMIN_DETACH_EVENT_COUNTER, 949 params->cntr_handle, 950 params->qp_handle, 951 params->events); 952 } 953 954 int efa_com_modify_event_counter(struct efa_com_dev *edev, 955 struct efa_com_modify_event_counter_params *params) 956 { 957 struct efa_admin_modify_event_counter_cmd cmd = {}; 958 struct efa_admin_modify_event_counter_resp resp; 959 struct efa_com_admin_queue *aq = &edev->aq; 960 int err; 961 962 cmd.cntr_handle = params->cntr_handle; 963 cmd.operation = params->operation; 964 cmd.value = params->value; 965 966 err = efa_com_cmd_exec(aq, EFA_ADMIN_MODIFY_EVENT_COUNTER, 0, 967 &cmd, sizeof(cmd), 968 (struct efa_admin_acq_entry *)&resp, 969 sizeof(resp)); 970 if (err) { 971 ibdev_err_ratelimited(edev->efa_dev, 972 "Failed to modify event counter [%d]\n", 973 err); 974 return err; 975 } 976 977 return 0; 978 } 979