Add a new API to expose GENEVE option FW information to DR layer. Signed-off-by: Michael Baum <michae...@nvidia.com> --- drivers/net/mlx5/mlx5_flow.h | 28 +++++++++ drivers/net/mlx5/mlx5_flow_geneve.c | 94 +++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+)
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 4bfc218175..dca3cacb65 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -1766,6 +1766,34 @@ flow_hw_get_reg_id_from_ctx(void *dr_ctx, return REG_NON; } +/** + * Get GENEVE TLV option FW information according type and class. + * + * @param[in] dr_ctx + * Pointer to HW steering DR context. + * @param[in] type + * GENEVE TLV option type. + * @param[in] class + * GENEVE TLV option class. + * @param[out] hl_ok_bit + * Pointer to header layout structure describing OK bit FW information. + * @param[out] num_of_dws + * Pointer to fill inside the size of 'hl_dws' array. + * @param[out] hl_dws + * Pointer to header layout array describing data DWs FW information. + * @param[out] ok_bit_on_class + * Pointer to an indicator whether OK bit includes class along with type. + * + * @return + * 0 on success, negative errno otherwise and rte_errno is set. + */ +int +mlx5_get_geneve_hl_data(const void *dr_ctx, uint8_t type, uint16_t class, + struct mlx5_hl_data ** const hl_ok_bit, + uint8_t *num_of_dws, + struct mlx5_hl_data ** const hl_dws, + bool *ok_bit_on_class); + void * mlx5_geneve_tlv_parser_create(uint16_t port_id, const struct rte_pmd_mlx5_geneve_tlv tlv_list[], diff --git a/drivers/net/mlx5/mlx5_flow_geneve.c b/drivers/net/mlx5/mlx5_flow_geneve.c index f23fb31aa0..2d593b70ba 100644 --- a/drivers/net/mlx5/mlx5_flow_geneve.c +++ b/drivers/net/mlx5/mlx5_flow_geneve.c @@ -58,6 +58,100 @@ struct mlx5_geneve_tlv_options { RTE_ATOMIC(uint32_t) refcnt; }; +/** + * Check if type and class is matching to given GENEVE TLV option. + * + * @param type + * GENEVE option type. + * @param class + * GENEVE option class. + * @param option + * Pointer to GENEVE TLV option structure. + * + * @return + * True if this type and class match to this option, false otherwise. + */ +static inline bool +option_match_type_and_class(uint8_t type, uint16_t class, + struct mlx5_geneve_tlv_option *option) +{ + if (type != option->type) + return false; + if (option->class_mode == 1 && option->class != class) + return false; + return true; +} + +/** + * Get GENEVE TLV option matching to given type and class. + * + * @param priv + * Pointer to port's private data. + * @param type + * GENEVE option type. + * @param class + * GENEVE option class. + * + * @return + * Pointer to option structure if exist, NULL otherwise and rte_errno is set. + */ +static struct mlx5_geneve_tlv_option * +mlx5_geneve_tlv_option_get(const struct mlx5_priv *priv, uint8_t type, + uint16_t class) +{ + struct mlx5_geneve_tlv_options *options; + uint8_t i; + + if (priv->tlv_options == NULL) { + DRV_LOG(ERR, + "Port %u doesn't have configured GENEVE TLV options.", + priv->dev_data->port_id); + rte_errno = EINVAL; + return NULL; + } + options = priv->tlv_options; + MLX5_ASSERT(options != NULL); + for (i = 0; i < options->nb_options; ++i) { + struct mlx5_geneve_tlv_option *option = &options->options[i]; + + if (option_match_type_and_class(type, class, option)) + return option; + } + DRV_LOG(ERR, "TLV option type %u class %u doesn't exist.", type, class); + rte_errno = ENOENT; + return NULL; +} + +int +mlx5_get_geneve_hl_data(const void *dr_ctx, uint8_t type, uint16_t class, + struct mlx5_hl_data ** const hl_ok_bit, + uint8_t *num_of_dws, + struct mlx5_hl_data ** const hl_dws, + bool *ok_bit_on_class) +{ + uint16_t port_id; + + MLX5_ETH_FOREACH_DEV(port_id, NULL) { + struct mlx5_priv *priv; + struct mlx5_geneve_tlv_option *option; + + priv = rte_eth_devices[port_id].data->dev_private; + if (priv->dr_ctx != dr_ctx) + continue; + /* Find specific option inside list. */ + option = mlx5_geneve_tlv_option_get(priv, type, class); + if (option == NULL) + return -rte_errno; + *hl_ok_bit = &option->hl_ok_bit; + *hl_dws = option->match_data; + *num_of_dws = option->match_data_size; + *ok_bit_on_class = !!(option->class_mode == 1); + return 0; + } + DRV_LOG(ERR, "DR CTX %p doesn't belong to any DPDK port.", dr_ctx); + return -EINVAL; +} + /** * Create single GENEVE TLV option sample. * -- 2.25.1