/* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2021 Intel Corporation */ #ifndef __INCLUDE_RTE_SWX_TABLE_SELECTOR_H__ #define __INCLUDE_RTE_SWX_TABLE_SELECTOR_H__ #ifdef __cplusplus extern "C" { #endif /** * @file * RTE SWX Selector Table * * Selector table interface. */ #include #include #include "rte_swx_table.h" /** Selector table creation parameters. */ struct rte_swx_table_selector_params { /** Group ID offset. */ uint32_t group_id_offset; /** Selector size in bytes. Must be non-zero. */ uint32_t selector_size; /** Offset of the first byte of the selector within the selector buffer. */ uint32_t selector_offset; /** Mask of *selector_size* bytes logically laid over the bytes at positions * selector_offset* .. (*selector_offset* + *selector_size* - 1) of the selector buffer in * order to specify which bits from the selector buffer are part of the selector and which * ones are not. A bit value of 1 in the *selector_mask* means the respective bit in the * selector buffer is part of the selector, while a bit value of 0 means the opposite. A * NULL value means that all the bits are part of the selector, i.e. the *selector_mask* * is an all-ones mask. */ uint8_t *selector_mask; /** Member ID offset. */ uint32_t member_id_offset; /** Maximum number of groups. Must be non-zero. */ uint32_t n_groups_max; /** Maximum number of members per group. Must be non-zero. */ uint32_t n_members_per_group_max; }; /** Group member parameters. */ struct rte_swx_table_selector_member { /** Linked list connectivity. */ RTE_TAILQ_ENTRY(rte_swx_table_selector_member) node; /** Member ID. */ uint32_t member_id; /** Member weight. */ uint32_t member_weight; }; /** List of group members. */ RTE_TAILQ_HEAD(rte_swx_table_selector_member_list, rte_swx_table_selector_member); /** Group parameters. */ struct rte_swx_table_selector_group { /** List of group members. */ struct rte_swx_table_selector_member_list members; }; /** * Selector table memory footprint get * * @param[in] n_groups_max * Maximum number of groups. Must be non-zero. * @param[in] n_members_per_group_max * Maximum number of members per group. Must be non-zero. * @return * Selector table memory footprint in bytes. */ __rte_experimental uint64_t rte_swx_table_selector_footprint_get(uint32_t n_groups_max, uint32_t n_members_per_group_max); /** * Selector table mailbox size get * * The mailbox is used to store the context of a select operation that is in * progress and it is passed as a parameter to the select operation. This allows * for multiple concurrent select operations into the same table. * * @return * Selector table mailbox footprint in bytes. */ __rte_experimental uint64_t rte_swx_table_selector_mailbox_size_get(void); /** * Selector table create * * @param[in] params * Selector table creation parameters. * @param[in] groups * Groups to be added to the table at creation time. When NULL, it signifies that all groups are * invalid, otherwise it points to a pre-allocated array of size *n_groups_max*, where a NULL * element indicates that the associated group is invalid. * @param[in] numa_node * Non-Uniform Memory Access (NUMA) node. * @return * Table handle, on success, or NULL, on error. */ __rte_experimental void * rte_swx_table_selector_create(struct rte_swx_table_selector_params *params, struct rte_swx_table_selector_group **groups, int numa_node); /** * Group set * * @param[in] table * Selector table handle. * @param[in] group_id * Group ID. * @param[in] group * Group parameters. * @return * 0 on success or the following error codes otherwise: * -EINVAL: Invalid argument(s); * -ENOSPC: Too many group members. */ __rte_experimental int rte_swx_table_selector_group_set(void *table, uint32_t group_id, struct rte_swx_table_selector_group *group); /** * Selector table select * * This operation selects a member from the given group based on a hasing scheme. * * Multiple invocations of this function may be required in order to complete a single select * operation for a given table and a given group ID. The completion of the operation is flagged by * a return value of 1; in case of a return value of 0, the function must be invoked again with * exactly the same arguments. * * The mailbox argument is used to store the context of each on-going operation. The mailbox * mechanism allows for multiple concurrent select operations into the same table. * * The typical reason an implementation may choose to split the operation into multiple steps is to * hide the latency of the inherent memory read operations: before a read operation with the * source data likely not in the CPU cache, the source data prefetch is issued and the operation is * postponed in favor of some other unrelated work, which the CPU executes in parallel with the * source data being fetched into the CPU cache; later on, the operation is resumed, this time with * the source data likely to be read from the CPU cache with no CPU pipeline stall, which * significantly improves the operation performance. * * @param[in] table * Selector table handle. * @param[in] mailbox * Mailbox for the current operation. * @param[in] group_id_buffer * Buffer where the input group ID is located at offset *group_id_offset*. * @param[in] selector_buffer * Buffer where the key to select a member within the identified group is located starting from * offset *selector_offset*. Its size must be equal to the table *selector_size*. * @param[in] member_id_buffer * Buffer where the output member ID is to be placed at offset *member_id_offset*. * @return * 0 when the operation is not yet completed, and 1 when the operation is complete. No other * return values are allowed. */ __rte_experimental int rte_swx_table_selector_select(void *table, void *mailbox, uint8_t **group_id_buffer, uint8_t **selector_buffer, uint8_t **member_id_buffer); /** * Selector table free * * @param[in] table * Selector table handle. */ __rte_experimental void rte_swx_table_selector_free(void *table); #ifdef __cplusplus } #endif #endif