199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2015-2019 Vladimir Medvedkin <medvedkinv@gmail.com> 399a2dd95SBruce Richardson * Copyright(c) 2021 Intel Corporation 499a2dd95SBruce Richardson */ 599a2dd95SBruce Richardson 699a2dd95SBruce Richardson #ifndef _RTE_THASH_H 799a2dd95SBruce Richardson #define _RTE_THASH_H 899a2dd95SBruce Richardson 999a2dd95SBruce Richardson /** 1099a2dd95SBruce Richardson * @file 1199a2dd95SBruce Richardson * 1299a2dd95SBruce Richardson * Software implementation of the Toeplitz hash function used by RSS. 1399a2dd95SBruce Richardson * Can be used either for packet distribution on single queue NIC 1499a2dd95SBruce Richardson * or for simulating of RSS computation on specific NIC (for example 1599a2dd95SBruce Richardson * after GRE header decapsulating) 1699a2dd95SBruce Richardson */ 1799a2dd95SBruce Richardson 1899a2dd95SBruce Richardson #include <stdint.h> 19b9dd86dbSStephen Hemminger 2099a2dd95SBruce Richardson #include <rte_byteorder.h> 2199a2dd95SBruce Richardson #include <rte_ip.h> 2299a2dd95SBruce Richardson #include <rte_common.h> 234fd8c4cbSVladimir Medvedkin #include <rte_thash_gfni.h> 2499a2dd95SBruce Richardson 2599a2dd95SBruce Richardson #if defined(RTE_ARCH_X86) || defined(__ARM_NEON) 2699a2dd95SBruce Richardson #include <rte_vect.h> 2799a2dd95SBruce Richardson #endif 2899a2dd95SBruce Richardson 29719834a6SMattias Rönnblom #ifdef __cplusplus 30719834a6SMattias Rönnblom extern "C" { 31719834a6SMattias Rönnblom #endif 32719834a6SMattias Rönnblom 3399a2dd95SBruce Richardson #ifdef RTE_ARCH_X86 3499a2dd95SBruce Richardson /* Byte swap mask used for converting IPv6 address 3599a2dd95SBruce Richardson * 4-byte chunks to CPU byte order 3699a2dd95SBruce Richardson */ 3799a2dd95SBruce Richardson static const __m128i rte_thash_ipv6_bswap_mask = { 3899a2dd95SBruce Richardson 0x0405060700010203ULL, 0x0C0D0E0F08090A0BULL}; 3999a2dd95SBruce Richardson #endif 4099a2dd95SBruce Richardson 4199a2dd95SBruce Richardson /** 4299a2dd95SBruce Richardson * length in dwords of input tuple to 4399a2dd95SBruce Richardson * calculate hash of ipv4 header only 4499a2dd95SBruce Richardson */ 4599a2dd95SBruce Richardson #define RTE_THASH_V4_L3_LEN ((sizeof(struct rte_ipv4_tuple) - \ 4699a2dd95SBruce Richardson sizeof(((struct rte_ipv4_tuple *)0)->sctp_tag)) / 4) 4799a2dd95SBruce Richardson 4899a2dd95SBruce Richardson /** 4999a2dd95SBruce Richardson * length in dwords of input tuple to 5099a2dd95SBruce Richardson * calculate hash of ipv4 header + 5199a2dd95SBruce Richardson * transport header 5299a2dd95SBruce Richardson */ 5399a2dd95SBruce Richardson #define RTE_THASH_V4_L4_LEN ((sizeof(struct rte_ipv4_tuple)) / 4) 5499a2dd95SBruce Richardson 5599a2dd95SBruce Richardson /** 5699a2dd95SBruce Richardson * length in dwords of input tuple to 5799a2dd95SBruce Richardson * calculate hash of ipv6 header only 5899a2dd95SBruce Richardson */ 5999a2dd95SBruce Richardson #define RTE_THASH_V6_L3_LEN ((sizeof(struct rte_ipv6_tuple) - \ 6099a2dd95SBruce Richardson sizeof(((struct rte_ipv6_tuple *)0)->sctp_tag)) / 4) 6199a2dd95SBruce Richardson 6299a2dd95SBruce Richardson /** 6399a2dd95SBruce Richardson * length in dwords of input tuple to 6499a2dd95SBruce Richardson * calculate hash of ipv6 header + 6599a2dd95SBruce Richardson * transport header 6699a2dd95SBruce Richardson */ 6799a2dd95SBruce Richardson #define RTE_THASH_V6_L4_LEN ((sizeof(struct rte_ipv6_tuple)) / 4) 6899a2dd95SBruce Richardson 6999a2dd95SBruce Richardson /** 7099a2dd95SBruce Richardson * IPv4 tuple 7199a2dd95SBruce Richardson * addresses and ports/sctp_tag have to be CPU byte order 7299a2dd95SBruce Richardson */ 7399a2dd95SBruce Richardson struct rte_ipv4_tuple { 7499a2dd95SBruce Richardson uint32_t src_addr; 7599a2dd95SBruce Richardson uint32_t dst_addr; 7699a2dd95SBruce Richardson union { 7799a2dd95SBruce Richardson struct { 7899a2dd95SBruce Richardson uint16_t dport; 7999a2dd95SBruce Richardson uint16_t sport; 8099a2dd95SBruce Richardson }; 8199a2dd95SBruce Richardson uint32_t sctp_tag; 8299a2dd95SBruce Richardson }; 8399a2dd95SBruce Richardson }; 8499a2dd95SBruce Richardson 8599a2dd95SBruce Richardson /** 8699a2dd95SBruce Richardson * IPv6 tuple 8799a2dd95SBruce Richardson * Addresses have to be filled by rte_thash_load_v6_addr() 8899a2dd95SBruce Richardson * ports/sctp_tag have to be CPU byte order 8999a2dd95SBruce Richardson */ 9099a2dd95SBruce Richardson struct rte_ipv6_tuple { 91431e6b9aSRobin Jarry struct rte_ipv6_addr src_addr; 92431e6b9aSRobin Jarry struct rte_ipv6_addr dst_addr; 9399a2dd95SBruce Richardson union { 9499a2dd95SBruce Richardson struct { 9599a2dd95SBruce Richardson uint16_t dport; 9699a2dd95SBruce Richardson uint16_t sport; 9799a2dd95SBruce Richardson }; 9899a2dd95SBruce Richardson uint32_t sctp_tag; 9999a2dd95SBruce Richardson }; 10099a2dd95SBruce Richardson }; 10199a2dd95SBruce Richardson 102c6552d9aSTyler Retzlaff #ifdef RTE_ARCH_X86 103c6552d9aSTyler Retzlaff union __rte_aligned(XMM_SIZE) rte_thash_tuple { 104c6552d9aSTyler Retzlaff #else 10599a2dd95SBruce Richardson union rte_thash_tuple { 106c6552d9aSTyler Retzlaff #endif 10799a2dd95SBruce Richardson struct rte_ipv4_tuple v4; 10899a2dd95SBruce Richardson struct rte_ipv6_tuple v6; 10999a2dd95SBruce Richardson }; 11099a2dd95SBruce Richardson 111f9773e66SVladimir Medvedkin /** @internal 112f9773e66SVladimir Medvedkin * @brief Generates a random polynomial 113f9773e66SVladimir Medvedkin * 114f9773e66SVladimir Medvedkin * @param poly_degree 115f9773e66SVladimir Medvedkin * degree of the polynomial 116f9773e66SVladimir Medvedkin * 117f9773e66SVladimir Medvedkin * @return 118f9773e66SVladimir Medvedkin * random polynomial 119f9773e66SVladimir Medvedkin */ 120f9773e66SVladimir Medvedkin __rte_internal 121f9773e66SVladimir Medvedkin uint32_t 122f9773e66SVladimir Medvedkin thash_get_rand_poly(uint32_t poly_degree); 123f9773e66SVladimir Medvedkin 12499a2dd95SBruce Richardson /** 12599a2dd95SBruce Richardson * Prepare special converted key to use with rte_softrss_be() 12699a2dd95SBruce Richardson * @param orig 12799a2dd95SBruce Richardson * pointer to original RSS key 12899a2dd95SBruce Richardson * @param targ 12999a2dd95SBruce Richardson * pointer to target RSS key 13099a2dd95SBruce Richardson * @param len 13199a2dd95SBruce Richardson * RSS key length 13299a2dd95SBruce Richardson */ 13399a2dd95SBruce Richardson static inline void 13499a2dd95SBruce Richardson rte_convert_rss_key(const uint32_t *orig, uint32_t *targ, int len) 13599a2dd95SBruce Richardson { 13699a2dd95SBruce Richardson int i; 13799a2dd95SBruce Richardson 13899a2dd95SBruce Richardson for (i = 0; i < (len >> 2); i++) 13999a2dd95SBruce Richardson targ[i] = rte_be_to_cpu_32(orig[i]); 14099a2dd95SBruce Richardson } 14199a2dd95SBruce Richardson 14299a2dd95SBruce Richardson /** 14399a2dd95SBruce Richardson * Prepare and load IPv6 addresses (src and dst) 14499a2dd95SBruce Richardson * into target tuple 14599a2dd95SBruce Richardson * @param orig 14699a2dd95SBruce Richardson * Pointer to ipv6 header of the original packet 14799a2dd95SBruce Richardson * @param targ 14899a2dd95SBruce Richardson * Pointer to rte_ipv6_tuple structure 14999a2dd95SBruce Richardson */ 15099a2dd95SBruce Richardson static inline void 15199a2dd95SBruce Richardson rte_thash_load_v6_addrs(const struct rte_ipv6_hdr *orig, 15299a2dd95SBruce Richardson union rte_thash_tuple *targ) 15399a2dd95SBruce Richardson { 15499a2dd95SBruce Richardson #ifdef RTE_ARCH_X86 15589b5642dSRobin Jarry __m128i ipv6 = _mm_loadu_si128((const __m128i *)&orig->src_addr); 156431e6b9aSRobin Jarry *(__m128i *)&targ->v6.src_addr = 15799a2dd95SBruce Richardson _mm_shuffle_epi8(ipv6, rte_thash_ipv6_bswap_mask); 15889b5642dSRobin Jarry ipv6 = _mm_loadu_si128((const __m128i *)&orig->dst_addr); 159431e6b9aSRobin Jarry *(__m128i *)&targ->v6.dst_addr = 16099a2dd95SBruce Richardson _mm_shuffle_epi8(ipv6, rte_thash_ipv6_bswap_mask); 16199a2dd95SBruce Richardson #elif defined(__ARM_NEON) 162431e6b9aSRobin Jarry uint8x16_t ipv6 = vld1q_u8(orig->src_addr.a); 163431e6b9aSRobin Jarry vst1q_u8(targ->v6.src_addr.a, vrev32q_u8(ipv6)); 164431e6b9aSRobin Jarry ipv6 = vld1q_u8(orig->dst_addr.a); 165431e6b9aSRobin Jarry vst1q_u8(targ->v6.dst_addr.a, vrev32q_u8(ipv6)); 16699a2dd95SBruce Richardson #else 16799a2dd95SBruce Richardson int i; 16899a2dd95SBruce Richardson for (i = 0; i < 4; i++) { 169431e6b9aSRobin Jarry *((uint32_t *)&targ->v6.src_addr + i) = 17089b5642dSRobin Jarry rte_be_to_cpu_32(*((const uint32_t *)&orig->src_addr + i)); 171431e6b9aSRobin Jarry *((uint32_t *)&targ->v6.dst_addr + i) = 17289b5642dSRobin Jarry rte_be_to_cpu_32(*((const uint32_t *)&orig->dst_addr + i)); 17399a2dd95SBruce Richardson } 17499a2dd95SBruce Richardson #endif 17599a2dd95SBruce Richardson } 17699a2dd95SBruce Richardson 17799a2dd95SBruce Richardson /** 17899a2dd95SBruce Richardson * Generic implementation. Can be used with original rss_key 17999a2dd95SBruce Richardson * @param input_tuple 18099a2dd95SBruce Richardson * Pointer to input tuple 18199a2dd95SBruce Richardson * @param input_len 18299a2dd95SBruce Richardson * Length of input_tuple in 4-bytes chunks 18399a2dd95SBruce Richardson * @param rss_key 18499a2dd95SBruce Richardson * Pointer to RSS hash key. 18599a2dd95SBruce Richardson * @return 18699a2dd95SBruce Richardson * Calculated hash value. 18799a2dd95SBruce Richardson */ 18899a2dd95SBruce Richardson static inline uint32_t 18999a2dd95SBruce Richardson rte_softrss(uint32_t *input_tuple, uint32_t input_len, 19099a2dd95SBruce Richardson const uint8_t *rss_key) 19199a2dd95SBruce Richardson { 19299a2dd95SBruce Richardson uint32_t i, j, map, ret = 0; 19399a2dd95SBruce Richardson 19499a2dd95SBruce Richardson for (j = 0; j < input_len; j++) { 19599a2dd95SBruce Richardson for (map = input_tuple[j]; map; map &= (map - 1)) { 19699a2dd95SBruce Richardson i = rte_bsf32(map); 19799a2dd95SBruce Richardson ret ^= rte_cpu_to_be_32(((const uint32_t *)rss_key)[j]) << (31 - i) | 19899a2dd95SBruce Richardson (uint32_t)((uint64_t)(rte_cpu_to_be_32(((const uint32_t *)rss_key)[j + 1])) >> 19999a2dd95SBruce Richardson (i + 1)); 20099a2dd95SBruce Richardson } 20199a2dd95SBruce Richardson } 20299a2dd95SBruce Richardson return ret; 20399a2dd95SBruce Richardson } 20499a2dd95SBruce Richardson 20599a2dd95SBruce Richardson /** 20699a2dd95SBruce Richardson * Optimized implementation. 20799a2dd95SBruce Richardson * If you want the calculated hash value matches NIC RSS value 20899a2dd95SBruce Richardson * you have to use special converted key with rte_convert_rss_key() fn. 20999a2dd95SBruce Richardson * @param input_tuple 21099a2dd95SBruce Richardson * Pointer to input tuple 21199a2dd95SBruce Richardson * @param input_len 21299a2dd95SBruce Richardson * Length of input_tuple in 4-bytes chunks 21399a2dd95SBruce Richardson * @param *rss_key 21499a2dd95SBruce Richardson * Pointer to RSS hash key. 21599a2dd95SBruce Richardson * @return 21699a2dd95SBruce Richardson * Calculated hash value. 21799a2dd95SBruce Richardson */ 21899a2dd95SBruce Richardson static inline uint32_t 21999a2dd95SBruce Richardson rte_softrss_be(uint32_t *input_tuple, uint32_t input_len, 22099a2dd95SBruce Richardson const uint8_t *rss_key) 22199a2dd95SBruce Richardson { 22299a2dd95SBruce Richardson uint32_t i, j, map, ret = 0; 22399a2dd95SBruce Richardson 22499a2dd95SBruce Richardson for (j = 0; j < input_len; j++) { 22599a2dd95SBruce Richardson for (map = input_tuple[j]; map; map &= (map - 1)) { 22699a2dd95SBruce Richardson i = rte_bsf32(map); 22799a2dd95SBruce Richardson ret ^= ((const uint32_t *)rss_key)[j] << (31 - i) | 22899a2dd95SBruce Richardson (uint32_t)((uint64_t)(((const uint32_t *)rss_key)[j + 1]) >> (i + 1)); 22999a2dd95SBruce Richardson } 23099a2dd95SBruce Richardson } 23199a2dd95SBruce Richardson return ret; 23299a2dd95SBruce Richardson } 23399a2dd95SBruce Richardson 2344fd8c4cbSVladimir Medvedkin /** 2354fd8c4cbSVladimir Medvedkin * Indicates if GFNI implementations of the Toeplitz hash are supported. 2364fd8c4cbSVladimir Medvedkin * 2374fd8c4cbSVladimir Medvedkin * @return 2384fd8c4cbSVladimir Medvedkin * 1 if GFNI is supported 2394fd8c4cbSVladimir Medvedkin * 0 otherwise 2404fd8c4cbSVladimir Medvedkin */ 2414fd8c4cbSVladimir Medvedkin int 2424fd8c4cbSVladimir Medvedkin rte_thash_gfni_supported(void); 2434fd8c4cbSVladimir Medvedkin 2444fd8c4cbSVladimir Medvedkin /** 2454fd8c4cbSVladimir Medvedkin * Converts Toeplitz hash key (RSS key) into matrixes required 2464fd8c4cbSVladimir Medvedkin * for GFNI implementation 2474fd8c4cbSVladimir Medvedkin * 2484fd8c4cbSVladimir Medvedkin * @param matrixes 2494fd8c4cbSVladimir Medvedkin * pointer to the memory where matrices will be written. 2504fd8c4cbSVladimir Medvedkin * Note: the size of this memory must be equal to size * 8 2514fd8c4cbSVladimir Medvedkin * @param rss_key 2524fd8c4cbSVladimir Medvedkin * pointer to the Toeplitz hash key 2534fd8c4cbSVladimir Medvedkin * @param size 2544fd8c4cbSVladimir Medvedkin * Size of the rss_key in bytes. 2554fd8c4cbSVladimir Medvedkin */ 2564fd8c4cbSVladimir Medvedkin void 2574fd8c4cbSVladimir Medvedkin rte_thash_complete_matrix(uint64_t *matrixes, const uint8_t *rss_key, 2584fd8c4cbSVladimir Medvedkin int size); 2594fd8c4cbSVladimir Medvedkin 26099a2dd95SBruce Richardson /** @internal Logarithm of minimum size of the RSS ReTa */ 26199a2dd95SBruce Richardson #define RTE_THASH_RETA_SZ_MIN 2U 26299a2dd95SBruce Richardson /** @internal Logarithm of maximum size of the RSS ReTa */ 26399a2dd95SBruce Richardson #define RTE_THASH_RETA_SZ_MAX 16U 26499a2dd95SBruce Richardson 26599a2dd95SBruce Richardson /** 26699a2dd95SBruce Richardson * LFSR will ignore if generated m-sequence has more than 2^n -1 bits, 26799a2dd95SBruce Richardson * where n is the logarithm of the RSS ReTa size. 26899a2dd95SBruce Richardson */ 26999a2dd95SBruce Richardson #define RTE_THASH_IGNORE_PERIOD_OVERFLOW 0x1 27099a2dd95SBruce Richardson /** 27199a2dd95SBruce Richardson * Generate minimal required bit (equal to ReTa LSB) sequence into 27299a2dd95SBruce Richardson * the hash_key 27399a2dd95SBruce Richardson */ 27499a2dd95SBruce Richardson #define RTE_THASH_MINIMAL_SEQ 0x2 27599a2dd95SBruce Richardson 27699a2dd95SBruce Richardson /** @internal thash context structure. */ 27799a2dd95SBruce Richardson struct rte_thash_ctx; 27899a2dd95SBruce Richardson /** @internal thash helper structure. */ 27999a2dd95SBruce Richardson struct rte_thash_subtuple_helper; 28099a2dd95SBruce Richardson 28199a2dd95SBruce Richardson /** 28299a2dd95SBruce Richardson * Create a new thash context. 28399a2dd95SBruce Richardson * 28499a2dd95SBruce Richardson * @param name 28599a2dd95SBruce Richardson * Context name 28699a2dd95SBruce Richardson * @param key_len 28799a2dd95SBruce Richardson * Length of the toeplitz hash key 28899a2dd95SBruce Richardson * @param reta_sz 28999a2dd95SBruce Richardson * Logarithm of the NIC's Redirection Table (ReTa) size, 29099a2dd95SBruce Richardson * i.e. number of the LSBs if the hash used to determine 29199a2dd95SBruce Richardson * the reta entry. 29299a2dd95SBruce Richardson * @param key 29399a2dd95SBruce Richardson * Pointer to the key used to init an internal key state. 29499a2dd95SBruce Richardson * Could be NULL, in this case internal key will be inited with random. 29599a2dd95SBruce Richardson * @param flags 29699a2dd95SBruce Richardson * Supported flags are: 29799a2dd95SBruce Richardson * RTE_THASH_IGNORE_PERIOD_OVERFLOW 29899a2dd95SBruce Richardson * RTE_THASH_MINIMAL_SEQ 29999a2dd95SBruce Richardson * @return 30099a2dd95SBruce Richardson * A pointer to the created context on success 30199a2dd95SBruce Richardson * NULL otherwise 30299a2dd95SBruce Richardson */ 30399a2dd95SBruce Richardson struct rte_thash_ctx * 30499a2dd95SBruce Richardson rte_thash_init_ctx(const char *name, uint32_t key_len, uint32_t reta_sz, 30599a2dd95SBruce Richardson uint8_t *key, uint32_t flags); 30699a2dd95SBruce Richardson 30799a2dd95SBruce Richardson /** 30899a2dd95SBruce Richardson * Find an existing thash context and return a pointer to it. 30999a2dd95SBruce Richardson * 31099a2dd95SBruce Richardson * @param name 31199a2dd95SBruce Richardson * Name of the thash context 31299a2dd95SBruce Richardson * @return 31399a2dd95SBruce Richardson * Pointer to the thash context or NULL if it was not found with rte_errno 31499a2dd95SBruce Richardson * set appropriately. Possible rte_errno values include: 31599a2dd95SBruce Richardson * - ENOENT - required entry not available to return. 31699a2dd95SBruce Richardson */ 31799a2dd95SBruce Richardson struct rte_thash_ctx * 31899a2dd95SBruce Richardson rte_thash_find_existing(const char *name); 31999a2dd95SBruce Richardson 32099a2dd95SBruce Richardson /** 32199a2dd95SBruce Richardson * Free a thash context object 32299a2dd95SBruce Richardson * 32399a2dd95SBruce Richardson * @param ctx 32499a2dd95SBruce Richardson * Thash context 32599a2dd95SBruce Richardson */ 32699a2dd95SBruce Richardson void 32799a2dd95SBruce Richardson rte_thash_free_ctx(struct rte_thash_ctx *ctx); 32899a2dd95SBruce Richardson 32999a2dd95SBruce Richardson /** 33099a2dd95SBruce Richardson * Add a special properties to the toeplitz hash key inside a thash context. 33199a2dd95SBruce Richardson * Creates an internal helper struct which has a complementary table 33299a2dd95SBruce Richardson * to calculate toeplitz hash collisions. 33399a2dd95SBruce Richardson * This function is not multi-thread safe. 33499a2dd95SBruce Richardson * 33599a2dd95SBruce Richardson * @param ctx 33699a2dd95SBruce Richardson * Thash context 33799a2dd95SBruce Richardson * @param name 33899a2dd95SBruce Richardson * Name of the helper 33999a2dd95SBruce Richardson * @param len 34099a2dd95SBruce Richardson * Length in bits of the target subtuple 34199a2dd95SBruce Richardson * Must be no shorter than reta_sz passed on rte_thash_init_ctx(). 34299a2dd95SBruce Richardson * @param offset 34399a2dd95SBruce Richardson * Offset in bits of the subtuple 34499a2dd95SBruce Richardson * @return 34599a2dd95SBruce Richardson * 0 on success 34699a2dd95SBruce Richardson * negative on error 34799a2dd95SBruce Richardson */ 34899a2dd95SBruce Richardson int 34999a2dd95SBruce Richardson rte_thash_add_helper(struct rte_thash_ctx *ctx, const char *name, uint32_t len, 35099a2dd95SBruce Richardson uint32_t offset); 35199a2dd95SBruce Richardson 35299a2dd95SBruce Richardson /** 35399a2dd95SBruce Richardson * Find a helper in the context by the given name 35499a2dd95SBruce Richardson * 35599a2dd95SBruce Richardson * @param ctx 35699a2dd95SBruce Richardson * Thash context 35799a2dd95SBruce Richardson * @param name 35899a2dd95SBruce Richardson * Name of the helper 35999a2dd95SBruce Richardson * @return 36099a2dd95SBruce Richardson * Pointer to the thash helper or NULL if it was not found. 36199a2dd95SBruce Richardson */ 36299a2dd95SBruce Richardson struct rte_thash_subtuple_helper * 36399a2dd95SBruce Richardson rte_thash_get_helper(struct rte_thash_ctx *ctx, const char *name); 36499a2dd95SBruce Richardson 36599a2dd95SBruce Richardson /** 36699a2dd95SBruce Richardson * Get a complementary value for the subtuple to produce a 36799a2dd95SBruce Richardson * partial toeplitz hash collision. It must be XOR'ed with the 36899a2dd95SBruce Richardson * subtuple to produce the hash value with the desired hash LSB's 36999a2dd95SBruce Richardson * This function is multi-thread safe. 37099a2dd95SBruce Richardson * 37199a2dd95SBruce Richardson * @param h 37299a2dd95SBruce Richardson * Pointer to the helper struct 37399a2dd95SBruce Richardson * @param hash 37499a2dd95SBruce Richardson * Toeplitz hash value calculated for the given tuple 37599a2dd95SBruce Richardson * @param desired_hash 37699a2dd95SBruce Richardson * Desired hash value to find a collision for 37799a2dd95SBruce Richardson * @return 37899a2dd95SBruce Richardson * A complementary value which must be xored with the corresponding subtuple 37999a2dd95SBruce Richardson */ 38099a2dd95SBruce Richardson uint32_t 38199a2dd95SBruce Richardson rte_thash_get_complement(struct rte_thash_subtuple_helper *h, 38299a2dd95SBruce Richardson uint32_t hash, uint32_t desired_hash); 38399a2dd95SBruce Richardson 38499a2dd95SBruce Richardson /** 38599a2dd95SBruce Richardson * Get a pointer to the toeplitz hash contained in the context. 38699a2dd95SBruce Richardson * It changes after each addition of a helper. It should be installed to 38799a2dd95SBruce Richardson * the NIC. 38899a2dd95SBruce Richardson * 38999a2dd95SBruce Richardson * @param ctx 39099a2dd95SBruce Richardson * Thash context 39199a2dd95SBruce Richardson * @return 39299a2dd95SBruce Richardson * A pointer to the toeplitz hash key 39399a2dd95SBruce Richardson */ 39499a2dd95SBruce Richardson const uint8_t * 39599a2dd95SBruce Richardson rte_thash_get_key(struct rte_thash_ctx *ctx); 39699a2dd95SBruce Richardson 39799a2dd95SBruce Richardson /** 398d27e2b7eSVladimir Medvedkin * Get a pointer to the toeplitz hash matrices contained in the context. 399d27e2b7eSVladimir Medvedkin * These matrices could be used with fast toeplitz hash implementation if 400d27e2b7eSVladimir Medvedkin * CPU supports GFNI. 401d27e2b7eSVladimir Medvedkin * Matrices changes after each addition of a helper. 402d27e2b7eSVladimir Medvedkin * 403d27e2b7eSVladimir Medvedkin * @param ctx 404d27e2b7eSVladimir Medvedkin * Thash context 405d27e2b7eSVladimir Medvedkin * @return 406d27e2b7eSVladimir Medvedkin * A pointer to the toeplitz hash key matrices on success 407d27e2b7eSVladimir Medvedkin * NULL if GFNI is not supported. 408d27e2b7eSVladimir Medvedkin */ 409d27e2b7eSVladimir Medvedkin const uint64_t * 410d27e2b7eSVladimir Medvedkin rte_thash_get_gfni_matrices(struct rte_thash_ctx *ctx); 411d27e2b7eSVladimir Medvedkin 412d27e2b7eSVladimir Medvedkin /** 41399a2dd95SBruce Richardson * Function prototype for the rte_thash_adjust_tuple 41499a2dd95SBruce Richardson * to check if adjusted tuple could be used. 41599a2dd95SBruce Richardson * Generally it is some kind of lookup function to check 41699a2dd95SBruce Richardson * if adjusted tuple is already in use. 41799a2dd95SBruce Richardson * 41899a2dd95SBruce Richardson * @param userdata 41999a2dd95SBruce Richardson * Pointer to the userdata. It could be a pointer to the 42099a2dd95SBruce Richardson * table with used tuples to search. 42199a2dd95SBruce Richardson * @param tuple 42299a2dd95SBruce Richardson * Pointer to the tuple to check 42399a2dd95SBruce Richardson * 42499a2dd95SBruce Richardson * @return 42599a2dd95SBruce Richardson * 1 on success 42699a2dd95SBruce Richardson * 0 otherwise 42799a2dd95SBruce Richardson */ 42899a2dd95SBruce Richardson typedef int (*rte_thash_check_tuple_t)(void *userdata, uint8_t *tuple); 42999a2dd95SBruce Richardson 43099a2dd95SBruce Richardson /** 43199a2dd95SBruce Richardson * Adjusts tuple in the way to make Toeplitz hash has 43299a2dd95SBruce Richardson * desired least significant bits. 43399a2dd95SBruce Richardson * This function is multi-thread safe. 43499a2dd95SBruce Richardson * 43599a2dd95SBruce Richardson * @param ctx 43699a2dd95SBruce Richardson * Thash context 43799a2dd95SBruce Richardson * @param h 43899a2dd95SBruce Richardson * Pointer to the helper struct 43999a2dd95SBruce Richardson * @param tuple 44099a2dd95SBruce Richardson * Pointer to the tuple to be adjusted 44199a2dd95SBruce Richardson * @param tuple_len 44299a2dd95SBruce Richardson * Length of the tuple. Must be multiple of 4. 44399a2dd95SBruce Richardson * @param desired_value 44499a2dd95SBruce Richardson * Desired value of least significant bits of the hash 44599a2dd95SBruce Richardson * @param attempts 44699a2dd95SBruce Richardson * Number of attempts to adjust tuple with fn() calling 44799a2dd95SBruce Richardson * @param fn 44899a2dd95SBruce Richardson * Callback function to check adjusted tuple. Could be NULL 44999a2dd95SBruce Richardson * @param userdata 45099a2dd95SBruce Richardson * Pointer to the userdata to be passed to fn(). Could be NULL 45199a2dd95SBruce Richardson * 45299a2dd95SBruce Richardson * @return 45399a2dd95SBruce Richardson * 0 on success 45499a2dd95SBruce Richardson * negative otherwise 45599a2dd95SBruce Richardson */ 45699a2dd95SBruce Richardson int 45799a2dd95SBruce Richardson rte_thash_adjust_tuple(struct rte_thash_ctx *ctx, 45899a2dd95SBruce Richardson struct rte_thash_subtuple_helper *h, 45999a2dd95SBruce Richardson uint8_t *tuple, unsigned int tuple_len, 46099a2dd95SBruce Richardson uint32_t desired_value, unsigned int attempts, 46199a2dd95SBruce Richardson rte_thash_check_tuple_t fn, void *userdata); 46299a2dd95SBruce Richardson 463*6addb781SVladimir Medvedkin /** 464*6addb781SVladimir Medvedkin * @warning 465*6addb781SVladimir Medvedkin * @b EXPERIMENTAL: this API may change without prior notice. 466*6addb781SVladimir Medvedkin * 467*6addb781SVladimir Medvedkin * Modify RSS hash key such that subtuple bits corresponding to `entropy_sz` 468*6addb781SVladimir Medvedkin * bits starting from `entropy_start` will have the most even distribution with 469*6addb781SVladimir Medvedkin * this key with a given ReTa size. 470*6addb781SVladimir Medvedkin * 471*6addb781SVladimir Medvedkin * @param key 472*6addb781SVladimir Medvedkin * Pointer to the RSS hash key. 473*6addb781SVladimir Medvedkin * @param key_len 474*6addb781SVladimir Medvedkin * Length of the key. 475*6addb781SVladimir Medvedkin * @param reta_sz_log 476*6addb781SVladimir Medvedkin * Log2 of the size of RSS redirection table, 477*6addb781SVladimir Medvedkin * i.e. number of bits of the RSS hash value used to identify RSS ReTa entry. 478*6addb781SVladimir Medvedkin * @param entropy_start 479*6addb781SVladimir Medvedkin * Bit offset from the beginning of the tuple 480*6addb781SVladimir Medvedkin * where user expects best distribution of the subtuple values. 481*6addb781SVladimir Medvedkin * @param entropy_sz 482*6addb781SVladimir Medvedkin * Size in bits of the part of subtuple. 483*6addb781SVladimir Medvedkin * 484*6addb781SVladimir Medvedkin * @return 485*6addb781SVladimir Medvedkin * 0 on success negative otherwise 486*6addb781SVladimir Medvedkin */ 487*6addb781SVladimir Medvedkin __rte_experimental 488*6addb781SVladimir Medvedkin int 489*6addb781SVladimir Medvedkin rte_thash_gen_key(uint8_t *key, size_t key_len, size_t reta_sz_log, 490*6addb781SVladimir Medvedkin uint32_t entropy_start, size_t entropy_sz); 491*6addb781SVladimir Medvedkin 49299a2dd95SBruce Richardson #ifdef __cplusplus 49399a2dd95SBruce Richardson } 49499a2dd95SBruce Richardson #endif 49599a2dd95SBruce Richardson 49699a2dd95SBruce Richardson #endif /* _RTE_THASH_H */ 497