xref: /dpdk/lib/hash/rte_thash.h (revision 6addb78158c232bfbb13561c8cbb7be33fb0d4a1)
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