X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5_devx_cmds.c;h=acfe1dea13909809478cd528eeffebe4a9c13f51;hb=c345c7d1acf43b4d30e1ecdd5a8cd3402234a6aa;hp=1cba00f2a91da44240f7771d4539c29476fedc95;hpb=d9102b331286e12ccdce0db51b2612be6faf8495;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_devx_cmds.c b/drivers/net/mlx5/mlx5_devx_cmds.c index 1cba00f2a9..acfe1dea13 100644 --- a/drivers/net/mlx5/mlx5_devx_cmds.c +++ b/drivers/net/mlx5/mlx5_devx_cmds.c @@ -390,3 +390,315 @@ error: rc = (rc > 0) ? -rc : rc; return rc; } + +/** + * Query TIS transport domain from QP verbs object using DevX API. + * + * @param[in] qp + * Pointer to verbs QP returned by ibv_create_qp . + * @param[in] tis_num + * TIS number of TIS to query. + * @param[out] tis_td + * Pointer to TIS transport domain variable, to be set by the routine. + * + * @return + * 0 on success, a negative value otherwise. + */ +int +mlx5_devx_cmd_qp_query_tis_td(struct ibv_qp *qp, uint32_t tis_num, + uint32_t *tis_td) +{ + uint32_t in[MLX5_ST_SZ_DW(query_tis_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(query_tis_out)] = {0}; + int rc; + void *tis_ctx; + + MLX5_SET(query_tis_in, in, opcode, MLX5_CMD_OP_QUERY_TIS); + MLX5_SET(query_tis_in, in, tisn, tis_num); + rc = mlx5_glue->devx_qp_query(qp, in, sizeof(in), out, sizeof(out)); + if (rc) { + DRV_LOG(ERR, "Failed to query QP using DevX"); + return -rc; + }; + tis_ctx = MLX5_ADDR_OF(query_tis_out, out, tis_context); + *tis_td = MLX5_GET(tisc, tis_ctx, transport_domain); + return 0; +} + +/** + * Fill WQ data for DevX API command. + * Utility function for use when creating DevX objects containing a WQ. + * + * @param[in] wq_ctx + * Pointer to WQ context to fill with data. + * @param [in] wq_attr + * Pointer to WQ attributes structure to fill in WQ context. + */ +static void +devx_cmd_fill_wq_data(void *wq_ctx, struct mlx5_devx_wq_attr *wq_attr) +{ + MLX5_SET(wq, wq_ctx, wq_type, wq_attr->wq_type); + MLX5_SET(wq, wq_ctx, wq_signature, wq_attr->wq_signature); + MLX5_SET(wq, wq_ctx, end_padding_mode, wq_attr->end_padding_mode); + MLX5_SET(wq, wq_ctx, cd_slave, wq_attr->cd_slave); + MLX5_SET(wq, wq_ctx, hds_skip_first_sge, wq_attr->hds_skip_first_sge); + MLX5_SET(wq, wq_ctx, log2_hds_buf_size, wq_attr->log2_hds_buf_size); + MLX5_SET(wq, wq_ctx, page_offset, wq_attr->page_offset); + MLX5_SET(wq, wq_ctx, lwm, wq_attr->lwm); + MLX5_SET(wq, wq_ctx, pd, wq_attr->pd); + MLX5_SET(wq, wq_ctx, uar_page, wq_attr->uar_page); + MLX5_SET64(wq, wq_ctx, dbr_addr, wq_attr->dbr_addr); + MLX5_SET(wq, wq_ctx, hw_counter, wq_attr->hw_counter); + MLX5_SET(wq, wq_ctx, sw_counter, wq_attr->sw_counter); + MLX5_SET(wq, wq_ctx, log_wq_stride, wq_attr->log_wq_stride); + MLX5_SET(wq, wq_ctx, log_wq_pg_sz, wq_attr->log_wq_pg_sz); + MLX5_SET(wq, wq_ctx, log_wq_sz, wq_attr->log_wq_sz); + MLX5_SET(wq, wq_ctx, dbr_umem_valid, wq_attr->dbr_umem_valid); + MLX5_SET(wq, wq_ctx, wq_umem_valid, wq_attr->wq_umem_valid); + MLX5_SET(wq, wq_ctx, log_hairpin_num_packets, + wq_attr->log_hairpin_num_packets); + MLX5_SET(wq, wq_ctx, log_hairpin_data_sz, wq_attr->log_hairpin_data_sz); + MLX5_SET(wq, wq_ctx, single_wqe_log_num_of_strides, + wq_attr->single_wqe_log_num_of_strides); + MLX5_SET(wq, wq_ctx, two_byte_shift_en, wq_attr->two_byte_shift_en); + MLX5_SET(wq, wq_ctx, single_stride_log_num_of_bytes, + wq_attr->single_stride_log_num_of_bytes); + MLX5_SET(wq, wq_ctx, dbr_umem_id, wq_attr->dbr_umem_id); + MLX5_SET(wq, wq_ctx, wq_umem_id, wq_attr->wq_umem_id); + MLX5_SET64(wq, wq_ctx, wq_umem_offset, wq_attr->wq_umem_offset); +} + +/** + * Create RQ using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] rq_attr + * Pointer to create RQ attributes structure. + * @param [in] socket + * CPU socket ID for allocations. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_rq(struct ibv_context *ctx, + struct mlx5_devx_create_rq_attr *rq_attr, + int socket) +{ + uint32_t in[MLX5_ST_SZ_DW(create_rq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_rq_out)] = {0}; + void *rq_ctx, *wq_ctx; + struct mlx5_devx_wq_attr *wq_attr; + struct mlx5_devx_obj *rq = NULL; + + rq = rte_calloc_socket(__func__, 1, sizeof(*rq), 0, socket); + if (!rq) { + DRV_LOG(ERR, "Failed to allocate RQ data"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_rq_in, in, opcode, MLX5_CMD_OP_CREATE_RQ); + rq_ctx = MLX5_ADDR_OF(create_rq_in, in, ctx); + MLX5_SET(rqc, rq_ctx, rlky, rq_attr->rlky); + MLX5_SET(rqc, rq_ctx, delay_drop_en, rq_attr->delay_drop_en); + MLX5_SET(rqc, rq_ctx, scatter_fcs, rq_attr->scatter_fcs); + MLX5_SET(rqc, rq_ctx, vsd, rq_attr->vsd); + MLX5_SET(rqc, rq_ctx, mem_rq_type, rq_attr->mem_rq_type); + MLX5_SET(rqc, rq_ctx, state, rq_attr->state); + MLX5_SET(rqc, rq_ctx, flush_in_error_en, rq_attr->flush_in_error_en); + MLX5_SET(rqc, rq_ctx, hairpin, rq_attr->hairpin); + MLX5_SET(rqc, rq_ctx, user_index, rq_attr->user_index); + MLX5_SET(rqc, rq_ctx, cqn, rq_attr->cqn); + MLX5_SET(rqc, rq_ctx, counter_set_id, rq_attr->counter_set_id); + MLX5_SET(rqc, rq_ctx, rmpn, rq_attr->rmpn); + wq_ctx = MLX5_ADDR_OF(rqc, rq_ctx, wq); + wq_attr = &rq_attr->wq_attr; + devx_cmd_fill_wq_data(wq_ctx, wq_attr); + rq->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), + out, sizeof(out)); + if (!rq->obj) { + DRV_LOG(ERR, "Failed to create RQ using DevX"); + rte_errno = errno; + rte_free(rq); + return NULL; + } + rq->id = MLX5_GET(create_rq_out, out, rqn); + return rq; +} + +/** + * Modify RQ using DevX API. + * + * @param[in] rq + * Pointer to RQ object structure. + * @param [in] rq_attr + * Pointer to modify RQ attributes structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_devx_cmd_modify_rq(struct mlx5_devx_obj *rq, + struct mlx5_devx_modify_rq_attr *rq_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(modify_rq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(modify_rq_out)] = {0}; + void *rq_ctx, *wq_ctx; + int ret; + + MLX5_SET(modify_rq_in, in, opcode, MLX5_CMD_OP_MODIFY_RQ); + MLX5_SET(modify_rq_in, in, rq_state, rq_attr->rq_state); + MLX5_SET(modify_rq_in, in, rqn, rq->id); + MLX5_SET64(modify_rq_in, in, modify_bitmask, rq_attr->modify_bitmask); + rq_ctx = MLX5_ADDR_OF(modify_rq_in, in, ctx); + MLX5_SET(rqc, rq_ctx, state, rq_attr->state); + if (rq_attr->modify_bitmask & + MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_SCATTER_FCS) + MLX5_SET(rqc, rq_ctx, scatter_fcs, rq_attr->scatter_fcs); + if (rq_attr->modify_bitmask & MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_VSD) + MLX5_SET(rqc, rq_ctx, vsd, rq_attr->vsd); + if (rq_attr->modify_bitmask & + MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_RQ_COUNTER_SET_ID) + MLX5_SET(rqc, rq_ctx, counter_set_id, rq_attr->counter_set_id); + MLX5_SET(rqc, rq_ctx, hairpin_peer_sq, rq_attr->hairpin_peer_sq); + MLX5_SET(rqc, rq_ctx, hairpin_peer_vhca, rq_attr->hairpin_peer_vhca); + if (rq_attr->modify_bitmask & MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_WQ_LWM) { + wq_ctx = MLX5_ADDR_OF(rqc, rq_ctx, wq); + MLX5_SET(wq, wq_ctx, lwm, rq_attr->lwm); + } + ret = mlx5_glue->devx_obj_modify(rq->obj, in, sizeof(in), + out, sizeof(out)); + if (ret) { + DRV_LOG(ERR, "Failed to modify RQ using DevX"); + rte_errno = errno; + return -errno; + } + return ret; +} + +/** + * Create TIR using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] tir_attr + * Pointer to TIR attributes structure. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_tir(struct ibv_context *ctx, + struct mlx5_devx_tir_attr *tir_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_tir_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_tir_out)] = {0}; + void *tir_ctx, *outer, *inner; + struct mlx5_devx_obj *tir = NULL; + int i; + + tir = rte_calloc(__func__, 1, sizeof(*tir), 0); + if (!tir) { + DRV_LOG(ERR, "Failed to allocate TIR data"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_tir_in, in, opcode, MLX5_CMD_OP_CREATE_TIR); + tir_ctx = MLX5_ADDR_OF(create_tir_in, in, ctx); + MLX5_SET(tirc, tir_ctx, disp_type, tir_attr->disp_type); + MLX5_SET(tirc, tir_ctx, lro_timeout_period_usecs, + tir_attr->lro_timeout_period_usecs); + MLX5_SET(tirc, tir_ctx, lro_enable_mask, tir_attr->lro_enable_mask); + MLX5_SET(tirc, tir_ctx, lro_max_msg_sz, tir_attr->lro_max_msg_sz); + MLX5_SET(tirc, tir_ctx, inline_rqn, tir_attr->inline_rqn); + MLX5_SET(tirc, tir_ctx, rx_hash_symmetric, tir_attr->rx_hash_symmetric); + MLX5_SET(tirc, tir_ctx, tunneled_offload_en, + tir_attr->tunneled_offload_en); + MLX5_SET(tirc, tir_ctx, indirect_table, tir_attr->indirect_table); + MLX5_SET(tirc, tir_ctx, rx_hash_fn, tir_attr->rx_hash_fn); + MLX5_SET(tirc, tir_ctx, self_lb_block, tir_attr->self_lb_block); + MLX5_SET(tirc, tir_ctx, transport_domain, tir_attr->transport_domain); + for (i = 0; i < 10; i++) { + MLX5_SET(tirc, tir_ctx, rx_hash_toeplitz_key[i], + tir_attr->rx_hash_toeplitz_key[i]); + } + outer = MLX5_ADDR_OF(tirc, tir_ctx, rx_hash_field_selector_outer); + MLX5_SET(rx_hash_field_select, outer, l3_prot_type, + tir_attr->rx_hash_field_selector_outer.l3_prot_type); + MLX5_SET(rx_hash_field_select, outer, l4_prot_type, + tir_attr->rx_hash_field_selector_outer.l4_prot_type); + MLX5_SET(rx_hash_field_select, outer, selected_fields, + tir_attr->rx_hash_field_selector_outer.selected_fields); + inner = MLX5_ADDR_OF(tirc, tir_ctx, rx_hash_field_selector_inner); + MLX5_SET(rx_hash_field_select, inner, l3_prot_type, + tir_attr->rx_hash_field_selector_inner.l3_prot_type); + MLX5_SET(rx_hash_field_select, inner, l4_prot_type, + tir_attr->rx_hash_field_selector_inner.l4_prot_type); + MLX5_SET(rx_hash_field_select, inner, selected_fields, + tir_attr->rx_hash_field_selector_inner.selected_fields); + tir->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), + out, sizeof(out)); + if (!tir->obj) { + DRV_LOG(ERR, "Failed to create TIR using DevX"); + rte_errno = errno; + rte_free(tir); + return NULL; + } + tir->id = MLX5_GET(create_tir_out, out, tirn); + return tir; +} + +/** + * Create RQT using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] rqt_attr + * Pointer to RQT attributes structure. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_rqt(struct ibv_context *ctx, + struct mlx5_devx_rqt_attr *rqt_attr) +{ + uint32_t *in = NULL; + uint32_t inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + + rqt_attr->rqt_actual_size * sizeof(uint32_t); + uint32_t out[MLX5_ST_SZ_DW(create_rqt_out)] = {0}; + void *rqt_ctx; + struct mlx5_devx_obj *rqt = NULL; + int i; + + in = rte_calloc(__func__, 1, inlen, 0); + if (!in) { + DRV_LOG(ERR, "Failed to allocate RQT IN data"); + rte_errno = ENOMEM; + return NULL; + } + rqt = rte_calloc(__func__, 1, sizeof(*rqt), 0); + if (!rqt) { + DRV_LOG(ERR, "Failed to allocate RQT data"); + rte_errno = ENOMEM; + rte_free(in); + return NULL; + } + MLX5_SET(create_rqt_in, in, opcode, MLX5_CMD_OP_CREATE_RQT); + rqt_ctx = MLX5_ADDR_OF(create_rqt_in, in, rqt_context); + MLX5_SET(rqtc, rqt_ctx, rqt_max_size, rqt_attr->rqt_max_size); + MLX5_SET(rqtc, rqt_ctx, rqt_actual_size, rqt_attr->rqt_actual_size); + for (i = 0; i < rqt_attr->rqt_actual_size; i++) + MLX5_SET(rqtc, rqt_ctx, rq_num[i], rqt_attr->rq_list[i]); + rqt->obj = mlx5_glue->devx_obj_create(ctx, in, inlen, out, sizeof(out)); + rte_free(in); + if (!rqt->obj) { + DRV_LOG(ERR, "Failed to create RQT using DevX"); + rte_errno = errno; + rte_free(rqt); + return NULL; + } + rqt->id = MLX5_GET(create_rqt_out, out, rqtn); + return rqt; +}