X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fmlx5%2Fmlx5_devx_cmds.c;h=9893287ba855fdb693e5194d8a864663687d20a7;hb=71da60b8380a35639342551536c4168f100c426a;hp=5faa2a0974f8fb5942fe0d0b92b83a1cf19b953a;hpb=c3aea272eed8a4a59b8d3dd1132140f8993d5743;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_devx_cmds.c b/drivers/net/mlx5/mlx5_devx_cmds.c index 5faa2a0974..9893287ba8 100644 --- a/drivers/net/mlx5/mlx5_devx_cmds.c +++ b/drivers/net/mlx5/mlx5_devx_cmds.c @@ -40,7 +40,7 @@ mlx5_devx_cmd_flow_counter_alloc(struct ibv_context *ctx, uint32_t bulk_n_128) dcs->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); if (!dcs->obj) { - DRV_LOG(ERR, "Can't allocate counters - error %d\n", errno); + DRV_LOG(ERR, "Can't allocate counters - error %d", errno); rte_errno = errno; rte_free(dcs); return NULL; @@ -111,7 +111,7 @@ mlx5_devx_cmd_flow_counter_query(struct mlx5_devx_obj *dcs, out_len, async_id, cmd_comp); if (rc) { - DRV_LOG(ERR, "Failed to query devx counters with rc %d\n ", rc); + DRV_LOG(ERR, "Failed to query devx counters with rc %d", rc); rte_errno = rc; return -rc; } @@ -171,7 +171,7 @@ mlx5_devx_cmd_mkey_create(struct ibv_context *ctx, mkey->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, sizeof(out)); if (!mkey->obj) { - DRV_LOG(ERR, "Can't create mkey - error %d\n", errno); + DRV_LOG(ERR, "Can't create mkey - error %d", errno); rte_errno = errno; rte_free(mkey); return NULL; @@ -202,7 +202,7 @@ mlx5_devx_get_out_command_status(void *out) if (status) { int syndrome = MLX5_GET(query_flow_counter_out, out, syndrome); - DRV_LOG(ERR, "Bad devX status %x, syndrome = %x\n", status, + DRV_LOG(ERR, "Bad devX status %x, syndrome = %x", status, syndrome); } return status; @@ -327,9 +327,42 @@ mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, attr->flow_counters_dump = MLX5_GET(cmd_hca_cap, hcattr, flow_counters_dump); attr->eswitch_manager = MLX5_GET(cmd_hca_cap, hcattr, eswitch_manager); + attr->hairpin = MLX5_GET(cmd_hca_cap, hcattr, hairpin); + attr->log_max_hairpin_queues = MLX5_GET(cmd_hca_cap, hcattr, + log_max_hairpin_queues); + attr->log_max_hairpin_wq_data_sz = MLX5_GET(cmd_hca_cap, hcattr, + log_max_hairpin_wq_data_sz); + attr->log_max_hairpin_num_packets = MLX5_GET + (cmd_hca_cap, hcattr, log_min_hairpin_wq_data_sz); + attr->vhca_id = MLX5_GET(cmd_hca_cap, hcattr, vhca_id); attr->eth_net_offloads = MLX5_GET(cmd_hca_cap, hcattr, eth_net_offloads); attr->eth_virt = MLX5_GET(cmd_hca_cap, hcattr, eth_virt); + attr->flex_parser_protocols = MLX5_GET(cmd_hca_cap, hcattr, + flex_parser_protocols); + attr->qos.sup = MLX5_GET(cmd_hca_cap, hcattr, qos); + if (attr->qos.sup) { + MLX5_SET(query_hca_cap_in, in, op_mod, + MLX5_GET_HCA_CAP_OP_MOD_QOS_CAP | + MLX5_HCA_CAP_OPMOD_GET_CUR); + rc = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), + out, sizeof(out)); + if (rc) + goto error; + if (status) { + DRV_LOG(DEBUG, "Failed to query devx QOS capabilities," + " status %x, syndrome = %x", + status, syndrome); + return -1; + } + hcattr = MLX5_ADDR_OF(query_hca_cap_out, out, capability); + attr->qos.srtcm_sup = + MLX5_GET(qos_cap, hcattr, flow_meter_srtcm); + attr->qos.log_max_flow_meter = + MLX5_GET(qos_cap, hcattr, log_max_flow_meter); + attr->qos.flow_meter_reg_c_ids = + MLX5_GET(qos_cap, hcattr, flow_meter_reg_id); + } if (!attr->eth_net_offloads) return 0; @@ -374,6 +407,12 @@ mlx5_devx_cmd_query_hca_attr(struct ibv_context *ctx, MLX5_GET(per_protocol_networking_offload_caps, hcattr, lro_timer_supported_periods[i]); } + attr->tunnel_stateless_geneve_rx = + MLX5_GET(per_protocol_networking_offload_caps, + hcattr, tunnel_stateless_geneve_rx); + attr->geneve_max_opt_len = + MLX5_GET(per_protocol_networking_offload_caps, + hcattr, max_geneve_opt_len); attr->wqe_inline_mode = MLX5_GET(per_protocol_networking_offload_caps, hcattr, wqe_inline_mode); if (attr->wqe_inline_mode != MLX5_CAP_INLINE_MODE_VPORT_CONTEXT) @@ -648,3 +687,243 @@ mlx5_devx_cmd_create_tir(struct ibv_context *ctx, 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; +} + +/** + * Create SQ using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] sq_attr + * Pointer to SQ 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_sq(struct ibv_context *ctx, + struct mlx5_devx_create_sq_attr *sq_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_sq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_sq_out)] = {0}; + void *sq_ctx; + void *wq_ctx; + struct mlx5_devx_wq_attr *wq_attr; + struct mlx5_devx_obj *sq = NULL; + + sq = rte_calloc(__func__, 1, sizeof(*sq), 0); + if (!sq) { + DRV_LOG(ERR, "Failed to allocate SQ data"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_sq_in, in, opcode, MLX5_CMD_OP_CREATE_SQ); + sq_ctx = MLX5_ADDR_OF(create_sq_in, in, ctx); + MLX5_SET(sqc, sq_ctx, rlky, sq_attr->rlky); + MLX5_SET(sqc, sq_ctx, cd_master, sq_attr->cd_master); + MLX5_SET(sqc, sq_ctx, fre, sq_attr->fre); + MLX5_SET(sqc, sq_ctx, flush_in_error_en, sq_attr->flush_in_error_en); + MLX5_SET(sqc, sq_ctx, allow_multi_pkt_send_wqe, + sq_attr->flush_in_error_en); + MLX5_SET(sqc, sq_ctx, min_wqe_inline_mode, + sq_attr->min_wqe_inline_mode); + MLX5_SET(sqc, sq_ctx, state, sq_attr->state); + MLX5_SET(sqc, sq_ctx, reg_umr, sq_attr->reg_umr); + MLX5_SET(sqc, sq_ctx, allow_swp, sq_attr->allow_swp); + MLX5_SET(sqc, sq_ctx, hairpin, sq_attr->hairpin); + MLX5_SET(sqc, sq_ctx, user_index, sq_attr->user_index); + MLX5_SET(sqc, sq_ctx, cqn, sq_attr->cqn); + MLX5_SET(sqc, sq_ctx, packet_pacing_rate_limit_index, + sq_attr->packet_pacing_rate_limit_index); + MLX5_SET(sqc, sq_ctx, tis_lst_sz, sq_attr->tis_lst_sz); + MLX5_SET(sqc, sq_ctx, tis_num_0, sq_attr->tis_num); + wq_ctx = MLX5_ADDR_OF(sqc, sq_ctx, wq); + wq_attr = &sq_attr->wq_attr; + devx_cmd_fill_wq_data(wq_ctx, wq_attr); + sq->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), + out, sizeof(out)); + if (!sq->obj) { + DRV_LOG(ERR, "Failed to create SQ using DevX"); + rte_errno = errno; + rte_free(sq); + return NULL; + } + sq->id = MLX5_GET(create_sq_out, out, sqn); + return sq; +} + +/** + * Modify SQ using DevX API. + * + * @param[in] sq + * Pointer to SQ object structure. + * @param [in] sq_attr + * Pointer to SQ attributes structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_devx_cmd_modify_sq(struct mlx5_devx_obj *sq, + struct mlx5_devx_modify_sq_attr *sq_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(modify_sq_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(modify_sq_out)] = {0}; + void *sq_ctx; + int ret; + + MLX5_SET(modify_sq_in, in, opcode, MLX5_CMD_OP_MODIFY_SQ); + MLX5_SET(modify_sq_in, in, sq_state, sq_attr->sq_state); + MLX5_SET(modify_sq_in, in, sqn, sq->id); + sq_ctx = MLX5_ADDR_OF(modify_sq_in, in, ctx); + MLX5_SET(sqc, sq_ctx, state, sq_attr->state); + MLX5_SET(sqc, sq_ctx, hairpin_peer_rq, sq_attr->hairpin_peer_rq); + MLX5_SET(sqc, sq_ctx, hairpin_peer_vhca, sq_attr->hairpin_peer_vhca); + ret = mlx5_glue->devx_obj_modify(sq->obj, in, sizeof(in), + out, sizeof(out)); + if (ret) { + DRV_LOG(ERR, "Failed to modify SQ using DevX"); + rte_errno = errno; + return -errno; + } + return ret; +} + +/** + * Create TIS using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * @param [in] tis_attr + * Pointer to TIS attributes structure. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_tis(struct ibv_context *ctx, + struct mlx5_devx_tis_attr *tis_attr) +{ + uint32_t in[MLX5_ST_SZ_DW(create_tis_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(create_tis_out)] = {0}; + struct mlx5_devx_obj *tis = NULL; + void *tis_ctx; + + tis = rte_calloc(__func__, 1, sizeof(*tis), 0); + if (!tis) { + DRV_LOG(ERR, "Failed to allocate TIS object"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(create_tis_in, in, opcode, MLX5_CMD_OP_CREATE_TIS); + tis_ctx = MLX5_ADDR_OF(create_tis_in, in, ctx); + MLX5_SET(tisc, tis_ctx, strict_lag_tx_port_affinity, + tis_attr->strict_lag_tx_port_affinity); + MLX5_SET(tisc, tis_ctx, strict_lag_tx_port_affinity, + tis_attr->strict_lag_tx_port_affinity); + MLX5_SET(tisc, tis_ctx, prio, tis_attr->prio); + MLX5_SET(tisc, tis_ctx, transport_domain, + tis_attr->transport_domain); + tis->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), + out, sizeof(out)); + if (!tis->obj) { + DRV_LOG(ERR, "Failed to create TIS using DevX"); + rte_errno = errno; + rte_free(tis); + return NULL; + } + tis->id = MLX5_GET(create_tis_out, out, tisn); + return tis; +} + +/** + * Create transport domain using DevX API. + * + * @param[in] ctx + * ibv_context returned from mlx5dv_open_device. + * + * @return + * The DevX object created, NULL otherwise and rte_errno is set. + */ +struct mlx5_devx_obj * +mlx5_devx_cmd_create_td(struct ibv_context *ctx) +{ + uint32_t in[MLX5_ST_SZ_DW(alloc_transport_domain_in)] = {0}; + uint32_t out[MLX5_ST_SZ_DW(alloc_transport_domain_out)] = {0}; + struct mlx5_devx_obj *td = NULL; + + td = rte_calloc(__func__, 1, sizeof(*td), 0); + if (!td) { + DRV_LOG(ERR, "Failed to allocate TD object"); + rte_errno = ENOMEM; + return NULL; + } + MLX5_SET(alloc_transport_domain_in, in, opcode, + MLX5_CMD_OP_ALLOC_TRANSPORT_DOMAIN); + td->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), + out, sizeof(out)); + if (!td->obj) { + DRV_LOG(ERR, "Failed to create TIS using DevX"); + rte_errno = errno; + rte_free(td); + return NULL; + } + td->id = MLX5_GET(alloc_transport_domain_out, out, + transport_domain); + return td; +}