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