10c6c8320SVladimir Medvedkin /* SPDX-License-Identifier: BSD-3-Clause 20c6c8320SVladimir Medvedkin * Copyright(c) 2015-2019 Vladimir Medvedkin <medvedkinv@gmail.com> 3a9de470cSBruce Richardson */ 4a9de470cSBruce Richardson 5a9de470cSBruce Richardson #include <rte_common.h> 6a9de470cSBruce Richardson #include <rte_eal.h> 7a9de470cSBruce Richardson #include <rte_ip.h> 828ebff11SVladimir Medvedkin #include <rte_random.h> 94fd8c4cbSVladimir Medvedkin #include <rte_malloc.h> 10*89398eceSVladimir Medvedkin #include <rte_byteorder.h> 11a9de470cSBruce Richardson 12a9de470cSBruce Richardson #include "test.h" 13a9de470cSBruce Richardson 14a9de470cSBruce Richardson #include <rte_thash.h> 15a9de470cSBruce Richardson 1628ebff11SVladimir Medvedkin #define HASH_MSK(reta_sz) ((1 << reta_sz) - 1) 1728ebff11SVladimir Medvedkin #define TUPLE_SZ (RTE_THASH_V4_L4_LEN * 4) 1828ebff11SVladimir Medvedkin 19a9de470cSBruce Richardson struct test_thash_v4 { 20a9de470cSBruce Richardson uint32_t dst_ip; 21a9de470cSBruce Richardson uint32_t src_ip; 22a9de470cSBruce Richardson uint16_t dst_port; 23a9de470cSBruce Richardson uint16_t src_port; 24a9de470cSBruce Richardson uint32_t hash_l3; 25a9de470cSBruce Richardson uint32_t hash_l3l4; 26a9de470cSBruce Richardson }; 27a9de470cSBruce Richardson 28a9de470cSBruce Richardson struct test_thash_v6 { 29431e6b9aSRobin Jarry struct rte_ipv6_addr dst_ip; 30431e6b9aSRobin Jarry struct rte_ipv6_addr src_ip; 31a9de470cSBruce Richardson uint16_t dst_port; 32a9de470cSBruce Richardson uint16_t src_port; 33a9de470cSBruce Richardson uint32_t hash_l3; 34a9de470cSBruce Richardson uint32_t hash_l3l4; 35a9de470cSBruce Richardson }; 36a9de470cSBruce Richardson 37a9de470cSBruce Richardson /*From 82599 Datasheet 7.1.2.8.3 RSS Verification Suite*/ 38a9de470cSBruce Richardson struct test_thash_v4 v4_tbl[] = { 390c9da755SDavid Marchand {RTE_IPV4(161, 142, 100, 80), RTE_IPV4(66, 9, 149, 187), 40a9de470cSBruce Richardson 1766, 2794, 0x323e8fc2, 0x51ccc178}, 410c9da755SDavid Marchand {RTE_IPV4(65, 69, 140, 83), RTE_IPV4(199, 92, 111, 2), 42a9de470cSBruce Richardson 4739, 14230, 0xd718262a, 0xc626b0ea}, 430c9da755SDavid Marchand {RTE_IPV4(12, 22, 207, 184), RTE_IPV4(24, 19, 198, 95), 44a9de470cSBruce Richardson 38024, 12898, 0xd2d0a5de, 0x5c2b394a}, 450c9da755SDavid Marchand {RTE_IPV4(209, 142, 163, 6), RTE_IPV4(38, 27, 205, 30), 46a9de470cSBruce Richardson 2217, 48228, 0x82989176, 0xafc7327f}, 470c9da755SDavid Marchand {RTE_IPV4(202, 188, 127, 2), RTE_IPV4(153, 39, 163, 191), 48a9de470cSBruce Richardson 1303, 44251, 0x5d1809c5, 0x10e828a2}, 49a9de470cSBruce Richardson }; 50a9de470cSBruce Richardson 51a9de470cSBruce Richardson struct test_thash_v6 v6_tbl[] = { 52a9de470cSBruce Richardson /*3ffe:2501:200:3::1*/ 53431e6b9aSRobin Jarry {RTE_IPV6(0x3ffe, 0x2501, 0x0200, 0x0003, 0, 0, 0, 0x0001), 54a9de470cSBruce Richardson /*3ffe:2501:200:1fff::7*/ 55431e6b9aSRobin Jarry RTE_IPV6(0x3ffe, 0x2501, 0x0200, 0x1fff, 0, 0, 0, 0x0007), 56a9de470cSBruce Richardson 1766, 2794, 0x2cc18cd5, 0x40207d3d}, 57a9de470cSBruce Richardson /*ff02::1*/ 58431e6b9aSRobin Jarry {RTE_IPV6(0xff02, 0, 0, 0, 0, 0, 0, 0x0001), 59a9de470cSBruce Richardson /*3ffe:501:8::260:97ff:fe40:efab*/ 60431e6b9aSRobin Jarry RTE_IPV6(0x3ffe, 0x0501, 0x0008, 0, 0x0260, 0x97ff, 0xfe40, 0xefab), 61a9de470cSBruce Richardson 4739, 14230, 0x0f0c461c, 0xdde51bbf}, 62a9de470cSBruce Richardson /*fe80::200:f8ff:fe21:67cf*/ 63431e6b9aSRobin Jarry {RTE_IPV6(0xfe80, 0, 0, 0, 0x0200, 0xf8ff, 0xfe21, 0x67cf), 64a9de470cSBruce Richardson /*3ffe:1900:4545:3:200:f8ff:fe21:67cf*/ 65431e6b9aSRobin Jarry RTE_IPV6(0x3ffe, 0x1900, 0x4545, 0x0003, 0x0200, 0xf8ff, 0xfe21, 0x67cf), 66a9de470cSBruce Richardson 38024, 44251, 0x4b61e985, 0x02d1feef}, 67a9de470cSBruce Richardson }; 68a9de470cSBruce Richardson 69a9de470cSBruce Richardson uint8_t default_rss_key[] = { 70a9de470cSBruce Richardson 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 71a9de470cSBruce Richardson 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 72a9de470cSBruce Richardson 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, 73a9de470cSBruce Richardson 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, 74a9de470cSBruce Richardson 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, 75a9de470cSBruce Richardson }; 76a9de470cSBruce Richardson 774fd8c4cbSVladimir Medvedkin static const uint8_t big_rss_key[] = { 784fd8c4cbSVladimir Medvedkin 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 794fd8c4cbSVladimir Medvedkin 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 804fd8c4cbSVladimir Medvedkin 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, 814fd8c4cbSVladimir Medvedkin 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, 824fd8c4cbSVladimir Medvedkin 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, 834fd8c4cbSVladimir Medvedkin 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 844fd8c4cbSVladimir Medvedkin 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 854fd8c4cbSVladimir Medvedkin 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, 864fd8c4cbSVladimir Medvedkin 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, 874fd8c4cbSVladimir Medvedkin 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, 884fd8c4cbSVladimir Medvedkin 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 894fd8c4cbSVladimir Medvedkin 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 904fd8c4cbSVladimir Medvedkin 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, 914fd8c4cbSVladimir Medvedkin 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, 924fd8c4cbSVladimir Medvedkin 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, 934fd8c4cbSVladimir Medvedkin 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 944fd8c4cbSVladimir Medvedkin 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 954fd8c4cbSVladimir Medvedkin 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, 964fd8c4cbSVladimir Medvedkin 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, 974fd8c4cbSVladimir Medvedkin 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, 984fd8c4cbSVladimir Medvedkin 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 994fd8c4cbSVladimir Medvedkin 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 1004fd8c4cbSVladimir Medvedkin 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, 1014fd8c4cbSVladimir Medvedkin 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, 1024fd8c4cbSVladimir Medvedkin 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, 1034fd8c4cbSVladimir Medvedkin }; 1044fd8c4cbSVladimir Medvedkin 105a9de470cSBruce Richardson static int 10628ebff11SVladimir Medvedkin test_toeplitz_hash_calc(void) 107a9de470cSBruce Richardson { 108431e6b9aSRobin Jarry uint32_t i; 109a9de470cSBruce Richardson union rte_thash_tuple tuple; 110a9de470cSBruce Richardson uint32_t rss_l3, rss_l3l4; 111a9de470cSBruce Richardson uint8_t rss_key_be[RTE_DIM(default_rss_key)]; 112a7c528e5SOlivier Matz struct rte_ipv6_hdr ipv6_hdr; 113a9de470cSBruce Richardson 114a9de470cSBruce Richardson /* Convert RSS key*/ 115a9de470cSBruce Richardson rte_convert_rss_key((uint32_t *)&default_rss_key, 116a9de470cSBruce Richardson (uint32_t *)rss_key_be, RTE_DIM(default_rss_key)); 117a9de470cSBruce Richardson 118a9de470cSBruce Richardson 119a9de470cSBruce Richardson for (i = 0; i < RTE_DIM(v4_tbl); i++) { 120a9de470cSBruce Richardson tuple.v4.src_addr = v4_tbl[i].src_ip; 121a9de470cSBruce Richardson tuple.v4.dst_addr = v4_tbl[i].dst_ip; 122a9de470cSBruce Richardson tuple.v4.sport = v4_tbl[i].src_port; 123a9de470cSBruce Richardson tuple.v4.dport = v4_tbl[i].dst_port; 124a9de470cSBruce Richardson /*Calculate hash with original key*/ 125a9de470cSBruce Richardson rss_l3 = rte_softrss((uint32_t *)&tuple, 126a9de470cSBruce Richardson RTE_THASH_V4_L3_LEN, default_rss_key); 127a9de470cSBruce Richardson rss_l3l4 = rte_softrss((uint32_t *)&tuple, 128a9de470cSBruce Richardson RTE_THASH_V4_L4_LEN, default_rss_key); 129a9de470cSBruce Richardson if ((rss_l3 != v4_tbl[i].hash_l3) || 130a9de470cSBruce Richardson (rss_l3l4 != v4_tbl[i].hash_l3l4)) 13128ebff11SVladimir Medvedkin return -TEST_FAILED; 132a9de470cSBruce Richardson /*Calculate hash with converted key*/ 133a9de470cSBruce Richardson rss_l3 = rte_softrss_be((uint32_t *)&tuple, 134a9de470cSBruce Richardson RTE_THASH_V4_L3_LEN, rss_key_be); 135a9de470cSBruce Richardson rss_l3l4 = rte_softrss_be((uint32_t *)&tuple, 136a9de470cSBruce Richardson RTE_THASH_V4_L4_LEN, rss_key_be); 137a9de470cSBruce Richardson if ((rss_l3 != v4_tbl[i].hash_l3) || 138a9de470cSBruce Richardson (rss_l3l4 != v4_tbl[i].hash_l3l4)) 13928ebff11SVladimir Medvedkin return -TEST_FAILED; 140a9de470cSBruce Richardson } 141a9de470cSBruce Richardson for (i = 0; i < RTE_DIM(v6_tbl); i++) { 142a9de470cSBruce Richardson /*Fill ipv6 hdr*/ 143431e6b9aSRobin Jarry ipv6_hdr.src_addr = v6_tbl[i].src_ip; 144431e6b9aSRobin Jarry ipv6_hdr.dst_addr = v6_tbl[i].dst_ip; 145a9de470cSBruce Richardson /*Load and convert ipv6 address into tuple*/ 146a9de470cSBruce Richardson rte_thash_load_v6_addrs(&ipv6_hdr, &tuple); 147a9de470cSBruce Richardson tuple.v6.sport = v6_tbl[i].src_port; 148a9de470cSBruce Richardson tuple.v6.dport = v6_tbl[i].dst_port; 149a9de470cSBruce Richardson /*Calculate hash with original key*/ 150a9de470cSBruce Richardson rss_l3 = rte_softrss((uint32_t *)&tuple, 151a9de470cSBruce Richardson RTE_THASH_V6_L3_LEN, default_rss_key); 152a9de470cSBruce Richardson rss_l3l4 = rte_softrss((uint32_t *)&tuple, 153a9de470cSBruce Richardson RTE_THASH_V6_L4_LEN, default_rss_key); 154a9de470cSBruce Richardson if ((rss_l3 != v6_tbl[i].hash_l3) || 155a9de470cSBruce Richardson (rss_l3l4 != v6_tbl[i].hash_l3l4)) 15628ebff11SVladimir Medvedkin return -TEST_FAILED; 157a9de470cSBruce Richardson /*Calculate hash with converted key*/ 158a9de470cSBruce Richardson rss_l3 = rte_softrss_be((uint32_t *)&tuple, 159a9de470cSBruce Richardson RTE_THASH_V6_L3_LEN, rss_key_be); 160a9de470cSBruce Richardson rss_l3l4 = rte_softrss_be((uint32_t *)&tuple, 161a9de470cSBruce Richardson RTE_THASH_V6_L4_LEN, rss_key_be); 162a9de470cSBruce Richardson if ((rss_l3 != v6_tbl[i].hash_l3) || 163a9de470cSBruce Richardson (rss_l3l4 != v6_tbl[i].hash_l3l4)) 16428ebff11SVladimir Medvedkin return -TEST_FAILED; 165a9de470cSBruce Richardson } 16628ebff11SVladimir Medvedkin return TEST_SUCCESS; 16728ebff11SVladimir Medvedkin } 16828ebff11SVladimir Medvedkin 16928ebff11SVladimir Medvedkin static int 1704fd8c4cbSVladimir Medvedkin test_toeplitz_hash_gfni(void) 1714fd8c4cbSVladimir Medvedkin { 172431e6b9aSRobin Jarry uint32_t i; 1734fd8c4cbSVladimir Medvedkin union rte_thash_tuple tuple; 1744fd8c4cbSVladimir Medvedkin uint32_t rss_l3, rss_l3l4; 1754fd8c4cbSVladimir Medvedkin uint64_t rss_key_matrixes[RTE_DIM(default_rss_key)]; 1764fd8c4cbSVladimir Medvedkin 1774fd8c4cbSVladimir Medvedkin if (!rte_thash_gfni_supported()) 1784fd8c4cbSVladimir Medvedkin return TEST_SKIPPED; 1794fd8c4cbSVladimir Medvedkin 1804fd8c4cbSVladimir Medvedkin /* Convert RSS key into matrixes */ 1814fd8c4cbSVladimir Medvedkin rte_thash_complete_matrix(rss_key_matrixes, default_rss_key, 1824fd8c4cbSVladimir Medvedkin RTE_DIM(default_rss_key)); 1834fd8c4cbSVladimir Medvedkin 1844fd8c4cbSVladimir Medvedkin for (i = 0; i < RTE_DIM(v4_tbl); i++) { 1854fd8c4cbSVladimir Medvedkin tuple.v4.src_addr = rte_cpu_to_be_32(v4_tbl[i].src_ip); 1864fd8c4cbSVladimir Medvedkin tuple.v4.dst_addr = rte_cpu_to_be_32(v4_tbl[i].dst_ip); 1874fd8c4cbSVladimir Medvedkin tuple.v4.sport = rte_cpu_to_be_16(v4_tbl[i].dst_port); 1884fd8c4cbSVladimir Medvedkin tuple.v4.dport = rte_cpu_to_be_16(v4_tbl[i].src_port); 1894fd8c4cbSVladimir Medvedkin 1904fd8c4cbSVladimir Medvedkin rss_l3 = rte_thash_gfni(rss_key_matrixes, (uint8_t *)&tuple, 1914fd8c4cbSVladimir Medvedkin RTE_THASH_V4_L3_LEN * 4); 1924fd8c4cbSVladimir Medvedkin rss_l3l4 = rte_thash_gfni(rss_key_matrixes, (uint8_t *)&tuple, 1934fd8c4cbSVladimir Medvedkin RTE_THASH_V4_L4_LEN * 4); 1944fd8c4cbSVladimir Medvedkin if ((rss_l3 != v4_tbl[i].hash_l3) || 1954fd8c4cbSVladimir Medvedkin (rss_l3l4 != v4_tbl[i].hash_l3l4)) 1964fd8c4cbSVladimir Medvedkin return -TEST_FAILED; 1974fd8c4cbSVladimir Medvedkin } 1984fd8c4cbSVladimir Medvedkin 1994fd8c4cbSVladimir Medvedkin for (i = 0; i < RTE_DIM(v6_tbl); i++) { 200431e6b9aSRobin Jarry tuple.v6.src_addr = v6_tbl[i].src_ip; 201431e6b9aSRobin Jarry tuple.v6.dst_addr = v6_tbl[i].dst_ip; 2024fd8c4cbSVladimir Medvedkin tuple.v6.sport = rte_cpu_to_be_16(v6_tbl[i].dst_port); 2034fd8c4cbSVladimir Medvedkin tuple.v6.dport = rte_cpu_to_be_16(v6_tbl[i].src_port); 2044fd8c4cbSVladimir Medvedkin rss_l3 = rte_thash_gfni(rss_key_matrixes, (uint8_t *)&tuple, 2054fd8c4cbSVladimir Medvedkin RTE_THASH_V6_L3_LEN * 4); 2064fd8c4cbSVladimir Medvedkin rss_l3l4 = rte_thash_gfni(rss_key_matrixes, (uint8_t *)&tuple, 2074fd8c4cbSVladimir Medvedkin RTE_THASH_V6_L4_LEN * 4); 2084fd8c4cbSVladimir Medvedkin if ((rss_l3 != v6_tbl[i].hash_l3) || 2094fd8c4cbSVladimir Medvedkin (rss_l3l4 != v6_tbl[i].hash_l3l4)) 2104fd8c4cbSVladimir Medvedkin return -TEST_FAILED; 2114fd8c4cbSVladimir Medvedkin } 2124fd8c4cbSVladimir Medvedkin 2134fd8c4cbSVladimir Medvedkin return TEST_SUCCESS; 2144fd8c4cbSVladimir Medvedkin } 2154fd8c4cbSVladimir Medvedkin 2164fd8c4cbSVladimir Medvedkin #define DATA_SZ 4 2174fd8c4cbSVladimir Medvedkin #define ITER 1000 2184fd8c4cbSVladimir Medvedkin 2194fd8c4cbSVladimir Medvedkin enum { 2204fd8c4cbSVladimir Medvedkin SCALAR_DATA_BUF_1_HASH_IDX = 0, 2214fd8c4cbSVladimir Medvedkin SCALAR_DATA_BUF_2_HASH_IDX, 2224fd8c4cbSVladimir Medvedkin GFNI_DATA_BUF_1_HASH_IDX, 2234fd8c4cbSVladimir Medvedkin GFNI_DATA_BUF_2_HASH_IDX, 22431d7c069SVladimir Medvedkin GFNI_BULK_DATA_BUF_1_HASH_IDX, 22531d7c069SVladimir Medvedkin GFNI_BULK_DATA_BUF_2_HASH_IDX, 2264fd8c4cbSVladimir Medvedkin HASH_IDXES 2274fd8c4cbSVladimir Medvedkin }; 2284fd8c4cbSVladimir Medvedkin 2294fd8c4cbSVladimir Medvedkin static int 2304fd8c4cbSVladimir Medvedkin test_toeplitz_hash_rand_data(void) 2314fd8c4cbSVladimir Medvedkin { 2324fd8c4cbSVladimir Medvedkin uint32_t data[2][DATA_SZ]; 2334fd8c4cbSVladimir Medvedkin uint32_t scalar_data[2][DATA_SZ]; 2344fd8c4cbSVladimir Medvedkin uint32_t hash[HASH_IDXES] = { 0 }; 2354fd8c4cbSVladimir Medvedkin uint64_t rss_key_matrixes[RTE_DIM(default_rss_key)]; 2364fd8c4cbSVladimir Medvedkin int i, j; 23731d7c069SVladimir Medvedkin uint8_t *bulk_data[2]; 2384fd8c4cbSVladimir Medvedkin 2394fd8c4cbSVladimir Medvedkin if (!rte_thash_gfni_supported()) 2404fd8c4cbSVladimir Medvedkin return TEST_SKIPPED; 2414fd8c4cbSVladimir Medvedkin 2424fd8c4cbSVladimir Medvedkin rte_thash_complete_matrix(rss_key_matrixes, default_rss_key, 2434fd8c4cbSVladimir Medvedkin RTE_DIM(default_rss_key)); 2444fd8c4cbSVladimir Medvedkin 24531d7c069SVladimir Medvedkin for (i = 0; i < 2; i++) 24631d7c069SVladimir Medvedkin bulk_data[i] = (uint8_t *)data[i]; 24731d7c069SVladimir Medvedkin 2484fd8c4cbSVladimir Medvedkin for (i = 0; i < ITER; i++) { 2494fd8c4cbSVladimir Medvedkin for (j = 0; j < DATA_SZ; j++) { 2504fd8c4cbSVladimir Medvedkin data[0][j] = rte_rand(); 2514fd8c4cbSVladimir Medvedkin data[1][j] = rte_rand(); 2524fd8c4cbSVladimir Medvedkin scalar_data[0][j] = rte_cpu_to_be_32(data[0][j]); 2534fd8c4cbSVladimir Medvedkin scalar_data[1][j] = rte_cpu_to_be_32(data[1][j]); 2544fd8c4cbSVladimir Medvedkin } 2554fd8c4cbSVladimir Medvedkin 2564fd8c4cbSVladimir Medvedkin hash[SCALAR_DATA_BUF_1_HASH_IDX] = rte_softrss(scalar_data[0], 2574fd8c4cbSVladimir Medvedkin DATA_SZ, default_rss_key); 2584fd8c4cbSVladimir Medvedkin hash[SCALAR_DATA_BUF_2_HASH_IDX] = rte_softrss(scalar_data[1], 2594fd8c4cbSVladimir Medvedkin DATA_SZ, default_rss_key); 2604fd8c4cbSVladimir Medvedkin hash[GFNI_DATA_BUF_1_HASH_IDX] = rte_thash_gfni( 2614fd8c4cbSVladimir Medvedkin rss_key_matrixes, (uint8_t *)data[0], 2624fd8c4cbSVladimir Medvedkin DATA_SZ * sizeof(uint32_t)); 2634fd8c4cbSVladimir Medvedkin hash[GFNI_DATA_BUF_2_HASH_IDX] = rte_thash_gfni( 2644fd8c4cbSVladimir Medvedkin rss_key_matrixes, (uint8_t *)data[1], 2654fd8c4cbSVladimir Medvedkin DATA_SZ * sizeof(uint32_t)); 26631d7c069SVladimir Medvedkin rte_thash_gfni_bulk(rss_key_matrixes, 26731d7c069SVladimir Medvedkin DATA_SZ * sizeof(uint32_t), bulk_data, 26831d7c069SVladimir Medvedkin &hash[GFNI_BULK_DATA_BUF_1_HASH_IDX], 2); 2694fd8c4cbSVladimir Medvedkin 2704fd8c4cbSVladimir Medvedkin if ((hash[SCALAR_DATA_BUF_1_HASH_IDX] != 2714fd8c4cbSVladimir Medvedkin hash[GFNI_DATA_BUF_1_HASH_IDX]) || 27231d7c069SVladimir Medvedkin (hash[SCALAR_DATA_BUF_1_HASH_IDX] != 27331d7c069SVladimir Medvedkin hash[GFNI_BULK_DATA_BUF_1_HASH_IDX]) || 2744fd8c4cbSVladimir Medvedkin (hash[SCALAR_DATA_BUF_2_HASH_IDX] != 27531d7c069SVladimir Medvedkin hash[GFNI_DATA_BUF_2_HASH_IDX]) || 27631d7c069SVladimir Medvedkin (hash[SCALAR_DATA_BUF_2_HASH_IDX] != 27731d7c069SVladimir Medvedkin hash[GFNI_BULK_DATA_BUF_2_HASH_IDX])) 2784fd8c4cbSVladimir Medvedkin 2794fd8c4cbSVladimir Medvedkin return -TEST_FAILED; 2804fd8c4cbSVladimir Medvedkin } 2814fd8c4cbSVladimir Medvedkin 2824fd8c4cbSVladimir Medvedkin return TEST_SUCCESS; 2834fd8c4cbSVladimir Medvedkin } 2844fd8c4cbSVladimir Medvedkin 2854fd8c4cbSVladimir Medvedkin enum { 2864fd8c4cbSVladimir Medvedkin RSS_V4_IDX, 2874fd8c4cbSVladimir Medvedkin RSS_V6_IDX 2884fd8c4cbSVladimir Medvedkin }; 2894fd8c4cbSVladimir Medvedkin 2904fd8c4cbSVladimir Medvedkin static int 29131d7c069SVladimir Medvedkin test_toeplitz_hash_gfni_bulk(void) 29231d7c069SVladimir Medvedkin { 293431e6b9aSRobin Jarry uint32_t i; 29431d7c069SVladimir Medvedkin union rte_thash_tuple tuple[2]; 29531d7c069SVladimir Medvedkin uint8_t *tuples[2]; 29631d7c069SVladimir Medvedkin uint32_t rss[2] = { 0 }; 29731d7c069SVladimir Medvedkin uint64_t rss_key_matrixes[RTE_DIM(default_rss_key)]; 29831d7c069SVladimir Medvedkin 29931d7c069SVladimir Medvedkin if (!rte_thash_gfni_supported()) 30031d7c069SVladimir Medvedkin return TEST_SKIPPED; 30131d7c069SVladimir Medvedkin 30231d7c069SVladimir Medvedkin /* Convert RSS key into matrixes */ 30331d7c069SVladimir Medvedkin rte_thash_complete_matrix(rss_key_matrixes, default_rss_key, 30431d7c069SVladimir Medvedkin RTE_DIM(default_rss_key)); 30531d7c069SVladimir Medvedkin 30631d7c069SVladimir Medvedkin for (i = 0; i < RTE_DIM(tuples); i++) { 30731d7c069SVladimir Medvedkin /* allocate memory enough for a biggest tuple */ 30831d7c069SVladimir Medvedkin tuples[i] = rte_zmalloc(NULL, RTE_THASH_V6_L4_LEN * 4, 0); 30931d7c069SVladimir Medvedkin if (tuples[i] == NULL) 31031d7c069SVladimir Medvedkin return -TEST_FAILED; 31131d7c069SVladimir Medvedkin } 31231d7c069SVladimir Medvedkin 31331d7c069SVladimir Medvedkin for (i = 0; i < RTE_MIN(RTE_DIM(v4_tbl), RTE_DIM(v6_tbl)); i++) { 31431d7c069SVladimir Medvedkin /*Load IPv4 headers and copy it into the corresponding tuple*/ 31531d7c069SVladimir Medvedkin tuple[0].v4.src_addr = rte_cpu_to_be_32(v4_tbl[i].src_ip); 31631d7c069SVladimir Medvedkin tuple[0].v4.dst_addr = rte_cpu_to_be_32(v4_tbl[i].dst_ip); 31731d7c069SVladimir Medvedkin tuple[0].v4.sport = rte_cpu_to_be_16(v4_tbl[i].dst_port); 31831d7c069SVladimir Medvedkin tuple[0].v4.dport = rte_cpu_to_be_16(v4_tbl[i].src_port); 31931d7c069SVladimir Medvedkin rte_memcpy(tuples[0], &tuple[0], RTE_THASH_V4_L4_LEN * 4); 32031d7c069SVladimir Medvedkin 32131d7c069SVladimir Medvedkin /*Load IPv6 headers and copy it into the corresponding tuple*/ 322431e6b9aSRobin Jarry tuple[1].v6.src_addr = v6_tbl[i].src_ip; 323431e6b9aSRobin Jarry tuple[1].v6.dst_addr = v6_tbl[i].dst_ip; 32431d7c069SVladimir Medvedkin tuple[1].v6.sport = rte_cpu_to_be_16(v6_tbl[i].dst_port); 32531d7c069SVladimir Medvedkin tuple[1].v6.dport = rte_cpu_to_be_16(v6_tbl[i].src_port); 32631d7c069SVladimir Medvedkin rte_memcpy(tuples[1], &tuple[1], RTE_THASH_V6_L4_LEN * 4); 32731d7c069SVladimir Medvedkin 32831d7c069SVladimir Medvedkin rte_thash_gfni_bulk(rss_key_matrixes, RTE_THASH_V6_L4_LEN * 4, 32931d7c069SVladimir Medvedkin tuples, rss, 2); 33031d7c069SVladimir Medvedkin 33131d7c069SVladimir Medvedkin if ((rss[RSS_V4_IDX] != v4_tbl[i].hash_l3l4) || 33231d7c069SVladimir Medvedkin (rss[RSS_V6_IDX] != v6_tbl[i].hash_l3l4)) 33331d7c069SVladimir Medvedkin return -TEST_FAILED; 33431d7c069SVladimir Medvedkin } 33531d7c069SVladimir Medvedkin 33631d7c069SVladimir Medvedkin return TEST_SUCCESS; 33731d7c069SVladimir Medvedkin } 33831d7c069SVladimir Medvedkin 33931d7c069SVladimir Medvedkin static int 3404fd8c4cbSVladimir Medvedkin test_big_tuple_gfni(void) 3414fd8c4cbSVladimir Medvedkin { 3424fd8c4cbSVladimir Medvedkin uint32_t arr[16]; 3434fd8c4cbSVladimir Medvedkin uint32_t arr_softrss[16]; 3444fd8c4cbSVladimir Medvedkin uint32_t hash_1, hash_2; 3454fd8c4cbSVladimir Medvedkin uint64_t rss_key_matrixes[RTE_DIM(big_rss_key)]; 3464fd8c4cbSVladimir Medvedkin unsigned int i, size = RTE_DIM(arr) * sizeof(uint32_t); 3474fd8c4cbSVladimir Medvedkin 3484fd8c4cbSVladimir Medvedkin if (!rte_thash_gfni_supported()) 3494fd8c4cbSVladimir Medvedkin return TEST_SKIPPED; 3504fd8c4cbSVladimir Medvedkin 3514fd8c4cbSVladimir Medvedkin /* Convert RSS key into matrixes */ 3524fd8c4cbSVladimir Medvedkin rte_thash_complete_matrix(rss_key_matrixes, big_rss_key, 3534fd8c4cbSVladimir Medvedkin RTE_DIM(big_rss_key)); 3544fd8c4cbSVladimir Medvedkin 3554fd8c4cbSVladimir Medvedkin for (i = 0; i < RTE_DIM(arr); i++) { 3564fd8c4cbSVladimir Medvedkin arr[i] = rte_rand(); 3574fd8c4cbSVladimir Medvedkin arr_softrss[i] = rte_be_to_cpu_32(arr[i]); 3584fd8c4cbSVladimir Medvedkin } 3594fd8c4cbSVladimir Medvedkin 3604fd8c4cbSVladimir Medvedkin hash_1 = rte_softrss(arr_softrss, RTE_DIM(arr), big_rss_key); 3614fd8c4cbSVladimir Medvedkin hash_2 = rte_thash_gfni(rss_key_matrixes, (uint8_t *)arr, size); 3624fd8c4cbSVladimir Medvedkin 3634fd8c4cbSVladimir Medvedkin if (hash_1 != hash_2) 3644fd8c4cbSVladimir Medvedkin return -TEST_FAILED; 3654fd8c4cbSVladimir Medvedkin 3664fd8c4cbSVladimir Medvedkin return TEST_SUCCESS; 3674fd8c4cbSVladimir Medvedkin } 3684fd8c4cbSVladimir Medvedkin 3694fd8c4cbSVladimir Medvedkin static int 37028ebff11SVladimir Medvedkin test_create_invalid(void) 37128ebff11SVladimir Medvedkin { 37228ebff11SVladimir Medvedkin struct rte_thash_ctx *ctx; 37328ebff11SVladimir Medvedkin int key_len = 40; 37428ebff11SVladimir Medvedkin int reta_sz = 7; 37528ebff11SVladimir Medvedkin 37628ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx(NULL, key_len, reta_sz, NULL, 0); 37728ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx == NULL, 37828ebff11SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 37928ebff11SVladimir Medvedkin 38028ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", 0, reta_sz, NULL, 0); 38128ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx == NULL, 38228ebff11SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 38328ebff11SVladimir Medvedkin 38428ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx(NULL, key_len, 1, NULL, 0); 38528ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx == NULL, 38628ebff11SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 38728ebff11SVladimir Medvedkin 38828ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx(NULL, key_len, 17, NULL, 0); 38928ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx == NULL, 39028ebff11SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 39128ebff11SVladimir Medvedkin 39228ebff11SVladimir Medvedkin return TEST_SUCCESS; 39328ebff11SVladimir Medvedkin } 39428ebff11SVladimir Medvedkin 39528ebff11SVladimir Medvedkin static int 39628ebff11SVladimir Medvedkin test_multiple_create(void) 39728ebff11SVladimir Medvedkin { 39828ebff11SVladimir Medvedkin struct rte_thash_ctx *ctx; 39928ebff11SVladimir Medvedkin int key_len = 40; 40028ebff11SVladimir Medvedkin int reta_sz = 7; 40128ebff11SVladimir Medvedkin int i; 40228ebff11SVladimir Medvedkin 40328ebff11SVladimir Medvedkin for (i = 0; i < 100; i++) { 40428ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", key_len, reta_sz, NULL, 0); 40528ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "Can not create CTX\n"); 40628ebff11SVladimir Medvedkin 40728ebff11SVladimir Medvedkin rte_thash_free_ctx(ctx); 40828ebff11SVladimir Medvedkin } 40928ebff11SVladimir Medvedkin 41028ebff11SVladimir Medvedkin return TEST_SUCCESS; 41128ebff11SVladimir Medvedkin } 41228ebff11SVladimir Medvedkin 41328ebff11SVladimir Medvedkin static int 41428ebff11SVladimir Medvedkin test_free_null(void) 41528ebff11SVladimir Medvedkin { 41628ebff11SVladimir Medvedkin struct rte_thash_ctx *ctx; 41728ebff11SVladimir Medvedkin 41828ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", 40, 7, NULL, 0); 41928ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "Can not create CTX\n"); 42028ebff11SVladimir Medvedkin 42128ebff11SVladimir Medvedkin rte_thash_free_ctx(ctx); 42228ebff11SVladimir Medvedkin rte_thash_free_ctx(NULL); 42328ebff11SVladimir Medvedkin 42428ebff11SVladimir Medvedkin return TEST_SUCCESS; 42528ebff11SVladimir Medvedkin } 42628ebff11SVladimir Medvedkin 42728ebff11SVladimir Medvedkin static int 42828ebff11SVladimir Medvedkin test_add_invalid_helper(void) 42928ebff11SVladimir Medvedkin { 43028ebff11SVladimir Medvedkin struct rte_thash_ctx *ctx; 43128ebff11SVladimir Medvedkin const int key_len = 40; 43228ebff11SVladimir Medvedkin int reta_sz = 7; 43328ebff11SVladimir Medvedkin int ret; 43428ebff11SVladimir Medvedkin 43528ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", key_len, reta_sz, NULL, 0); 43628ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 43728ebff11SVladimir Medvedkin 43828ebff11SVladimir Medvedkin ret = rte_thash_add_helper(NULL, "test", reta_sz, 0); 43928ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == -EINVAL, 44028ebff11SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 44128ebff11SVladimir Medvedkin 44228ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, NULL, reta_sz, 0); 44328ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == -EINVAL, 44428ebff11SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 44528ebff11SVladimir Medvedkin 44628ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "test", reta_sz - 1, 0); 44728ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == -EINVAL, 44828ebff11SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 44928ebff11SVladimir Medvedkin 45028ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "test", reta_sz, key_len * 8); 45128ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == -EINVAL, 45228ebff11SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 45328ebff11SVladimir Medvedkin 45428ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "first_range", reta_sz, 0); 45528ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Can not create helper\n"); 45628ebff11SVladimir Medvedkin 45728ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "first_range", reta_sz, 0); 45828ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == -EEXIST, 45928ebff11SVladimir Medvedkin "Call succeeded with duplicated name\n"); 46028ebff11SVladimir Medvedkin 46128ebff11SVladimir Medvedkin /* 46228ebff11SVladimir Medvedkin * Create second helper with offset 3 * reta_sz. 46328ebff11SVladimir Medvedkin * Note first_range helper created range in key: 46428ebff11SVladimir Medvedkin * [0, 32 + length{= reta_sz} - 1), i.e [0, 37). 46528ebff11SVladimir Medvedkin * second range is [44, 81) 46628ebff11SVladimir Medvedkin */ 46728ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "second_range", reta_sz, 46828ebff11SVladimir Medvedkin 32 + 2 * reta_sz); 46928ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Can not create helper\n"); 47028ebff11SVladimir Medvedkin 47128ebff11SVladimir Medvedkin /* 47228ebff11SVladimir Medvedkin * Try to create overlapping with first_ and second_ ranges, 47328ebff11SVladimir Medvedkin * i.e. [6, 49) 47428ebff11SVladimir Medvedkin */ 47528ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "third_range", 2 * reta_sz, reta_sz); 47628ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == -EEXIST, 47728ebff11SVladimir Medvedkin "Call succeeded with overlapping ranges\n"); 47828ebff11SVladimir Medvedkin 47928ebff11SVladimir Medvedkin rte_thash_free_ctx(ctx); 48028ebff11SVladimir Medvedkin 48128ebff11SVladimir Medvedkin return TEST_SUCCESS; 48228ebff11SVladimir Medvedkin } 48328ebff11SVladimir Medvedkin 48428ebff11SVladimir Medvedkin static int 48528ebff11SVladimir Medvedkin test_find_existing(void) 48628ebff11SVladimir Medvedkin { 48728ebff11SVladimir Medvedkin struct rte_thash_ctx *ctx, *ret_ctx; 48828ebff11SVladimir Medvedkin 48928ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", 40, 7, NULL, 0); 49028ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 49128ebff11SVladimir Medvedkin 49228ebff11SVladimir Medvedkin ret_ctx = rte_thash_find_existing("test"); 49328ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret_ctx != NULL, "can not find existing ctx\n"); 49428ebff11SVladimir Medvedkin 49528ebff11SVladimir Medvedkin rte_thash_free_ctx(ctx); 49628ebff11SVladimir Medvedkin 49728ebff11SVladimir Medvedkin return TEST_SUCCESS; 49828ebff11SVladimir Medvedkin } 49928ebff11SVladimir Medvedkin 50028ebff11SVladimir Medvedkin static int 50128ebff11SVladimir Medvedkin test_get_helper(void) 50228ebff11SVladimir Medvedkin { 50328ebff11SVladimir Medvedkin struct rte_thash_ctx *ctx; 50428ebff11SVladimir Medvedkin struct rte_thash_subtuple_helper *h; 50528ebff11SVladimir Medvedkin int ret; 50628ebff11SVladimir Medvedkin 50728ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", 40, 7, NULL, 0); 50828ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "Can not create thash ctx\n"); 50928ebff11SVladimir Medvedkin 51028ebff11SVladimir Medvedkin h = rte_thash_get_helper(NULL, "first_range"); 51128ebff11SVladimir Medvedkin RTE_TEST_ASSERT(h == NULL, "Call succeeded with invalid parameters\n"); 51228ebff11SVladimir Medvedkin 51328ebff11SVladimir Medvedkin h = rte_thash_get_helper(ctx, NULL); 51428ebff11SVladimir Medvedkin RTE_TEST_ASSERT(h == NULL, "Call succeeded with invalid parameters\n"); 51528ebff11SVladimir Medvedkin 51628ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "first_range", 8, 0); 51728ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Can not create helper\n"); 51828ebff11SVladimir Medvedkin 51928ebff11SVladimir Medvedkin h = rte_thash_get_helper(ctx, "first_range"); 52028ebff11SVladimir Medvedkin RTE_TEST_ASSERT(h != NULL, "Can not find helper\n"); 52128ebff11SVladimir Medvedkin 52228ebff11SVladimir Medvedkin rte_thash_free_ctx(ctx); 52328ebff11SVladimir Medvedkin 52428ebff11SVladimir Medvedkin return TEST_SUCCESS; 52528ebff11SVladimir Medvedkin } 52628ebff11SVladimir Medvedkin 52728ebff11SVladimir Medvedkin static int 52828ebff11SVladimir Medvedkin test_period_overflow(void) 52928ebff11SVladimir Medvedkin { 53028ebff11SVladimir Medvedkin struct rte_thash_ctx *ctx; 53128ebff11SVladimir Medvedkin int reta_sz = 7; /* reflects polynomial degree */ 53228ebff11SVladimir Medvedkin int ret; 53328ebff11SVladimir Medvedkin 53428ebff11SVladimir Medvedkin /* first create without RTE_THASH_IGNORE_PERIOD_OVERFLOW flag */ 53528ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", 40, reta_sz, NULL, 0); 53628ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "Can not create thash ctx\n"); 53728ebff11SVladimir Medvedkin 53828ebff11SVladimir Medvedkin /* requested range > (2^reta_sz) - 1 */ 53928ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "test", (1 << reta_sz), 0); 54028ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == -ENOSPC, 54128ebff11SVladimir Medvedkin "Call succeeded with invalid parameters\n"); 54228ebff11SVladimir Medvedkin 54328ebff11SVladimir Medvedkin /* requested range == len + 32 - 1, smaller than (2^reta_sz) - 1 */ 54428ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "test", (1 << reta_sz) - 32, 0); 54528ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Can not create helper\n"); 54628ebff11SVladimir Medvedkin 54728ebff11SVladimir Medvedkin rte_thash_free_ctx(ctx); 54828ebff11SVladimir Medvedkin 54928ebff11SVladimir Medvedkin /* create with RTE_THASH_IGNORE_PERIOD_OVERFLOW flag */ 55028ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", 40, reta_sz, NULL, 55128ebff11SVladimir Medvedkin RTE_THASH_IGNORE_PERIOD_OVERFLOW); 55228ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "Can not create thash ctx\n"); 55328ebff11SVladimir Medvedkin 55428ebff11SVladimir Medvedkin /* requested range > (2^reta_sz - 1) */ 55528ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "test", (1 << reta_sz) + 10, 0); 55628ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "Can not create helper\n"); 55728ebff11SVladimir Medvedkin 55828ebff11SVladimir Medvedkin rte_thash_free_ctx(ctx); 55928ebff11SVladimir Medvedkin 56028ebff11SVladimir Medvedkin return TEST_SUCCESS; 56128ebff11SVladimir Medvedkin } 56228ebff11SVladimir Medvedkin 56328ebff11SVladimir Medvedkin static int 56428ebff11SVladimir Medvedkin test_predictable_rss_min_seq(void) 56528ebff11SVladimir Medvedkin { 56628ebff11SVladimir Medvedkin struct rte_thash_ctx *ctx; 56728ebff11SVladimir Medvedkin struct rte_thash_subtuple_helper *h; 56828ebff11SVladimir Medvedkin const int key_len = 40; 56928ebff11SVladimir Medvedkin int reta_sz = 6; 57028ebff11SVladimir Medvedkin uint8_t initial_key[key_len]; 57128ebff11SVladimir Medvedkin const uint8_t *new_key; 57228ebff11SVladimir Medvedkin int ret; 57328ebff11SVladimir Medvedkin union rte_thash_tuple tuple; 57428ebff11SVladimir Medvedkin uint32_t orig_hash, adj_hash, adj; 57528ebff11SVladimir Medvedkin unsigned int desired_value = 27 & HASH_MSK(reta_sz); 57628ebff11SVladimir Medvedkin uint16_t port_value = 22; 57728ebff11SVladimir Medvedkin 57828ebff11SVladimir Medvedkin memset(initial_key, 0, key_len); 57928ebff11SVladimir Medvedkin 58028ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", key_len, reta_sz, initial_key, 58128ebff11SVladimir Medvedkin RTE_THASH_MINIMAL_SEQ); 58228ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 58328ebff11SVladimir Medvedkin 58428ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "snat", sizeof(uint16_t) * 8, 58528ebff11SVladimir Medvedkin offsetof(union rte_thash_tuple, v4.sport) * 8); 58628ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "can not add helper, ret %d\n", ret); 58728ebff11SVladimir Medvedkin 58828ebff11SVladimir Medvedkin h = rte_thash_get_helper(ctx, "snat"); 58928ebff11SVladimir Medvedkin RTE_TEST_ASSERT(h != NULL, "can not find helper\n"); 59028ebff11SVladimir Medvedkin 59128ebff11SVladimir Medvedkin new_key = rte_thash_get_key(ctx); 59228ebff11SVladimir Medvedkin tuple.v4.src_addr = RTE_IPV4(0, 0, 0, 0); 59328ebff11SVladimir Medvedkin tuple.v4.dst_addr = RTE_IPV4(0, 0, 0, 0); 59428ebff11SVladimir Medvedkin tuple.v4.sport = 0; 59528ebff11SVladimir Medvedkin tuple.v4.sport = rte_cpu_to_be_16(port_value); 59628ebff11SVladimir Medvedkin tuple.v4.dport = 0; 59728ebff11SVladimir Medvedkin tuple.v4.sctp_tag = rte_be_to_cpu_32(tuple.v4.sctp_tag); 59828ebff11SVladimir Medvedkin 59928ebff11SVladimir Medvedkin orig_hash = rte_softrss((uint32_t *)&tuple, 60028ebff11SVladimir Medvedkin RTE_THASH_V4_L4_LEN, new_key); 60128ebff11SVladimir Medvedkin adj = rte_thash_get_complement(h, orig_hash, desired_value); 60228ebff11SVladimir Medvedkin 60328ebff11SVladimir Medvedkin tuple.v4.sctp_tag = rte_cpu_to_be_32(tuple.v4.sctp_tag); 60428ebff11SVladimir Medvedkin tuple.v4.sport ^= rte_cpu_to_be_16(adj); 60528ebff11SVladimir Medvedkin tuple.v4.sctp_tag = rte_be_to_cpu_32(tuple.v4.sctp_tag); 60628ebff11SVladimir Medvedkin 60728ebff11SVladimir Medvedkin adj_hash = rte_softrss((uint32_t *)&tuple, 60828ebff11SVladimir Medvedkin RTE_THASH_V4_L4_LEN, new_key); 60928ebff11SVladimir Medvedkin RTE_TEST_ASSERT((adj_hash & HASH_MSK(reta_sz)) == 61028ebff11SVladimir Medvedkin desired_value, "bad desired value\n"); 61128ebff11SVladimir Medvedkin 61228ebff11SVladimir Medvedkin rte_thash_free_ctx(ctx); 61328ebff11SVladimir Medvedkin 61428ebff11SVladimir Medvedkin return TEST_SUCCESS; 61528ebff11SVladimir Medvedkin } 61628ebff11SVladimir Medvedkin 61728ebff11SVladimir Medvedkin /* 61828ebff11SVladimir Medvedkin * This test creates 7 subranges in the following order: 61928ebff11SVladimir Medvedkin * range_one = [56, 95), len = 8, offset = 56 62028ebff11SVladimir Medvedkin * range_two = [64, 103), len = 8, offset = 64 62128ebff11SVladimir Medvedkin * range_three = [120, 159), len = 8, offset = 120 62228ebff11SVladimir Medvedkin * range_four = [48, 87), len = 8, offset = 48 62328ebff11SVladimir Medvedkin * range_five = [57, 95), len = 7, offset = 57 62428ebff11SVladimir Medvedkin * range_six = [40, 111), len = 40, offset = 40 62528ebff11SVladimir Medvedkin * range_seven = [0, 39), len = 8, offset = 0 62628ebff11SVladimir Medvedkin */ 62728ebff11SVladimir Medvedkin struct range { 62828ebff11SVladimir Medvedkin const char *name; 62928ebff11SVladimir Medvedkin int len; 63028ebff11SVladimir Medvedkin int offset; 63128ebff11SVladimir Medvedkin int byte_idx; 63228ebff11SVladimir Medvedkin }; 63328ebff11SVladimir Medvedkin 63428ebff11SVladimir Medvedkin struct range rng_arr[] = { 63528ebff11SVladimir Medvedkin {"one", 8, 56, 7}, 63628ebff11SVladimir Medvedkin {"two", 8, 64, 8}, 63728ebff11SVladimir Medvedkin {"three", 8, 120, 15}, 63828ebff11SVladimir Medvedkin {"four", 8, 48, 6}, 63928ebff11SVladimir Medvedkin {"six", 40, 40, 9}, 64028ebff11SVladimir Medvedkin {"five", 7, 57, 7}, 64128ebff11SVladimir Medvedkin {"seven", 8, 0, 0} 64228ebff11SVladimir Medvedkin }; 64328ebff11SVladimir Medvedkin 64428ebff11SVladimir Medvedkin static int 64528ebff11SVladimir Medvedkin test_predictable_rss_multirange(void) 64628ebff11SVladimir Medvedkin { 64728ebff11SVladimir Medvedkin struct rte_thash_ctx *ctx; 64828ebff11SVladimir Medvedkin struct rte_thash_subtuple_helper *h[RTE_DIM(rng_arr)]; 64928ebff11SVladimir Medvedkin const uint8_t *new_key; 65028ebff11SVladimir Medvedkin const int key_len = 40; 65128ebff11SVladimir Medvedkin int reta_sz = 7; 65228ebff11SVladimir Medvedkin unsigned int i, j, k; 65328ebff11SVladimir Medvedkin int ret; 65428ebff11SVladimir Medvedkin uint32_t desired_value = rte_rand() & HASH_MSK(reta_sz); 65528ebff11SVladimir Medvedkin uint8_t tuples[RTE_DIM(rng_arr)][16] = { {0} }; 65628ebff11SVladimir Medvedkin uint32_t *ptr; 65728ebff11SVladimir Medvedkin uint32_t hashes[RTE_DIM(rng_arr)]; 65828ebff11SVladimir Medvedkin uint32_t adj_hashes[RTE_DIM(rng_arr)]; 65928ebff11SVladimir Medvedkin uint32_t adj; 66028ebff11SVladimir Medvedkin 66128ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", key_len, reta_sz, NULL, 0); 66228ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 66328ebff11SVladimir Medvedkin 66428ebff11SVladimir Medvedkin for (i = 0; i < RTE_DIM(rng_arr); i++) { 66528ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, rng_arr[i].name, 66628ebff11SVladimir Medvedkin rng_arr[i].len, rng_arr[i].offset); 66728ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "can not add helper\n"); 66828ebff11SVladimir Medvedkin 66928ebff11SVladimir Medvedkin h[i] = rte_thash_get_helper(ctx, rng_arr[i].name); 67028ebff11SVladimir Medvedkin RTE_TEST_ASSERT(h[i] != NULL, "can not find helper\n"); 67128ebff11SVladimir Medvedkin } 67228ebff11SVladimir Medvedkin new_key = rte_thash_get_key(ctx); 67328ebff11SVladimir Medvedkin 67428ebff11SVladimir Medvedkin /* 67528ebff11SVladimir Medvedkin * calculate hashes, complements, then adjust keys with 6767be78d02SJosh Soref * complements and recalculate hashes 67728ebff11SVladimir Medvedkin */ 67828ebff11SVladimir Medvedkin for (i = 0; i < RTE_DIM(rng_arr); i++) { 67928ebff11SVladimir Medvedkin for (k = 0; k < 100; k++) { 68028ebff11SVladimir Medvedkin /* init with random keys */ 68128ebff11SVladimir Medvedkin ptr = (uint32_t *)&tuples[i][0]; 68228ebff11SVladimir Medvedkin for (j = 0; j < 4; j++) 68328ebff11SVladimir Medvedkin ptr[j] = rte_rand(); 68428ebff11SVladimir Medvedkin /* convert keys from BE to CPU byte order */ 68528ebff11SVladimir Medvedkin for (j = 0; j < 4; j++) 68628ebff11SVladimir Medvedkin ptr[j] = rte_be_to_cpu_32(ptr[j]); 68728ebff11SVladimir Medvedkin 68828ebff11SVladimir Medvedkin hashes[i] = rte_softrss(ptr, 4, new_key); 68928ebff11SVladimir Medvedkin adj = rte_thash_get_complement(h[i], hashes[i], 69028ebff11SVladimir Medvedkin desired_value); 69128ebff11SVladimir Medvedkin /* convert back to BE to adjust the value */ 69228ebff11SVladimir Medvedkin for (j = 0; j < 4; j++) 69328ebff11SVladimir Medvedkin ptr[j] = rte_cpu_to_be_32(ptr[j]); 69428ebff11SVladimir Medvedkin 69528ebff11SVladimir Medvedkin tuples[i][rng_arr[i].byte_idx] ^= adj; 69628ebff11SVladimir Medvedkin 69728ebff11SVladimir Medvedkin for (j = 0; j < 4; j++) 69828ebff11SVladimir Medvedkin ptr[j] = rte_be_to_cpu_32(ptr[j]); 69928ebff11SVladimir Medvedkin 70028ebff11SVladimir Medvedkin adj_hashes[i] = rte_softrss(ptr, 4, new_key); 70128ebff11SVladimir Medvedkin RTE_TEST_ASSERT((adj_hashes[i] & HASH_MSK(reta_sz)) == 70228ebff11SVladimir Medvedkin desired_value, 70328ebff11SVladimir Medvedkin "bad desired value for %d tuple\n", i); 70428ebff11SVladimir Medvedkin } 70528ebff11SVladimir Medvedkin } 70628ebff11SVladimir Medvedkin 70728ebff11SVladimir Medvedkin rte_thash_free_ctx(ctx); 70828ebff11SVladimir Medvedkin 70928ebff11SVladimir Medvedkin return TEST_SUCCESS; 71028ebff11SVladimir Medvedkin } 71128ebff11SVladimir Medvedkin 71228ebff11SVladimir Medvedkin static int 71328ebff11SVladimir Medvedkin cmp_tuple_eq(void *userdata, uint8_t *tuple) 71428ebff11SVladimir Medvedkin { 71528ebff11SVladimir Medvedkin return memcmp(userdata, tuple, TUPLE_SZ); 71628ebff11SVladimir Medvedkin } 71728ebff11SVladimir Medvedkin 71828ebff11SVladimir Medvedkin static int 71928ebff11SVladimir Medvedkin test_adjust_tuple(void) 72028ebff11SVladimir Medvedkin { 72128ebff11SVladimir Medvedkin struct rte_thash_ctx *ctx; 72228ebff11SVladimir Medvedkin struct rte_thash_subtuple_helper *h; 72328ebff11SVladimir Medvedkin const int key_len = 40; 72428ebff11SVladimir Medvedkin const uint8_t *new_key; 72528ebff11SVladimir Medvedkin uint8_t tuple[TUPLE_SZ]; 72628ebff11SVladimir Medvedkin uint32_t tmp_tuple[TUPLE_SZ / sizeof(uint32_t)]; 72728ebff11SVladimir Medvedkin uint32_t tuple_copy[TUPLE_SZ / sizeof(uint32_t)]; 72828ebff11SVladimir Medvedkin uint32_t hash; 72928ebff11SVladimir Medvedkin int reta_sz = CHAR_BIT; 73028ebff11SVladimir Medvedkin int ret; 73128ebff11SVladimir Medvedkin unsigned int i, desired_value = rte_rand() & HASH_MSK(reta_sz); 73228ebff11SVladimir Medvedkin 73328ebff11SVladimir Medvedkin memset(tuple, 0xab, TUPLE_SZ); 73428ebff11SVladimir Medvedkin 73528ebff11SVladimir Medvedkin ctx = rte_thash_init_ctx("test", key_len, reta_sz, NULL, 0); 73628ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 73728ebff11SVladimir Medvedkin 73828ebff11SVladimir Medvedkin /* 73928ebff11SVladimir Medvedkin * set offset to be in the middle of a byte 74028ebff11SVladimir Medvedkin * set size of the subtuple to be 2 * rets_sz 74128ebff11SVladimir Medvedkin * to have the room for random bits 74228ebff11SVladimir Medvedkin */ 74328ebff11SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "test", reta_sz * 2, 74428ebff11SVladimir Medvedkin (5 * CHAR_BIT) + 4); 74528ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "can not add helper, ret %d\n", ret); 74628ebff11SVladimir Medvedkin 74728ebff11SVladimir Medvedkin new_key = rte_thash_get_key(ctx); 74828ebff11SVladimir Medvedkin 74928ebff11SVladimir Medvedkin h = rte_thash_get_helper(ctx, "test"); 75028ebff11SVladimir Medvedkin RTE_TEST_ASSERT(h != NULL, "can not find helper\n"); 75128ebff11SVladimir Medvedkin 75228ebff11SVladimir Medvedkin ret = rte_thash_adjust_tuple(ctx, h, tuple, TUPLE_SZ, desired_value, 75328ebff11SVladimir Medvedkin 1, NULL, NULL); 75428ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "can not adjust tuple, ret %d\n", ret); 75528ebff11SVladimir Medvedkin 75628ebff11SVladimir Medvedkin for (i = 0; i < (TUPLE_SZ / 4); i++) 75728ebff11SVladimir Medvedkin tmp_tuple[i] = 75828ebff11SVladimir Medvedkin rte_be_to_cpu_32(*(uint32_t *)&tuple[i * 4]); 75928ebff11SVladimir Medvedkin 76028ebff11SVladimir Medvedkin hash = rte_softrss(tmp_tuple, TUPLE_SZ / 4, new_key); 76128ebff11SVladimir Medvedkin RTE_TEST_ASSERT((hash & HASH_MSK(reta_sz)) == 76228ebff11SVladimir Medvedkin desired_value, "bad desired value\n"); 76328ebff11SVladimir Medvedkin 76428ebff11SVladimir Medvedkin 76528ebff11SVladimir Medvedkin /* Pass previously calculated tuple to callback function */ 76628ebff11SVladimir Medvedkin memcpy(tuple_copy, tuple, TUPLE_SZ); 76728ebff11SVladimir Medvedkin 76828ebff11SVladimir Medvedkin memset(tuple, 0xab, TUPLE_SZ); 76928ebff11SVladimir Medvedkin ret = rte_thash_adjust_tuple(ctx, h, tuple, TUPLE_SZ, desired_value, 77028ebff11SVladimir Medvedkin 1, cmp_tuple_eq, tuple_copy); 77128ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == -EEXIST, 77228ebff11SVladimir Medvedkin "adjust tuple didn't indicate collision\n"); 77328ebff11SVladimir Medvedkin 77428ebff11SVladimir Medvedkin /* 77528ebff11SVladimir Medvedkin * Make the function to generate random bits into subtuple 77628ebff11SVladimir Medvedkin * after first adjustment attempt. 77728ebff11SVladimir Medvedkin */ 77828ebff11SVladimir Medvedkin memset(tuple, 0xab, TUPLE_SZ); 77928ebff11SVladimir Medvedkin ret = rte_thash_adjust_tuple(ctx, h, tuple, TUPLE_SZ, desired_value, 78028ebff11SVladimir Medvedkin 2, cmp_tuple_eq, tuple_copy); 78128ebff11SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "can not adjust tuple, ret %d\n", ret); 78228ebff11SVladimir Medvedkin 78328ebff11SVladimir Medvedkin for (i = 0; i < (TUPLE_SZ / 4); i++) 78428ebff11SVladimir Medvedkin tmp_tuple[i] = 78528ebff11SVladimir Medvedkin rte_be_to_cpu_32(*(uint32_t *)&tuple[i * 4]); 78628ebff11SVladimir Medvedkin 78728ebff11SVladimir Medvedkin hash = rte_softrss(tmp_tuple, TUPLE_SZ / 4, new_key); 78828ebff11SVladimir Medvedkin RTE_TEST_ASSERT((hash & HASH_MSK(reta_sz)) == 78928ebff11SVladimir Medvedkin desired_value, "bad desired value\n"); 79028ebff11SVladimir Medvedkin 79128ebff11SVladimir Medvedkin rte_thash_free_ctx(ctx); 79228ebff11SVladimir Medvedkin 79328ebff11SVladimir Medvedkin return TEST_SUCCESS; 79428ebff11SVladimir Medvedkin } 79528ebff11SVladimir Medvedkin 796ed4f8e02SVladimir Medvedkin static uint32_t 797ed4f8e02SVladimir Medvedkin calc_tuple_hash(const uint8_t tuple[TUPLE_SZ], const uint8_t *key) 798ed4f8e02SVladimir Medvedkin { 799ed4f8e02SVladimir Medvedkin uint32_t i, hash; 800ed4f8e02SVladimir Medvedkin uint32_t tmp[TUPLE_SZ / sizeof(uint32_t)]; 801ed4f8e02SVladimir Medvedkin 802ed4f8e02SVladimir Medvedkin for (i = 0; i < RTE_DIM(tmp); i++) 803ed4f8e02SVladimir Medvedkin tmp[i] = rte_be_to_cpu_32( 804ed4f8e02SVladimir Medvedkin *(const uint32_t *)&tuple[i * sizeof(uint32_t)]); 805ed4f8e02SVladimir Medvedkin 806ed4f8e02SVladimir Medvedkin hash = rte_softrss(tmp, RTE_DIM(tmp), key); 807ed4f8e02SVladimir Medvedkin return hash; 808ed4f8e02SVladimir Medvedkin } 809ed4f8e02SVladimir Medvedkin 810ed4f8e02SVladimir Medvedkin static int 811ed4f8e02SVladimir Medvedkin check_adj_tuple(const uint8_t tuple[TUPLE_SZ], const uint8_t *key, 812ed4f8e02SVladimir Medvedkin uint32_t dhv, uint32_t ohv, uint32_t adjust, uint32_t reta_sz, 813ed4f8e02SVladimir Medvedkin const char *prefix) 814ed4f8e02SVladimir Medvedkin { 815ed4f8e02SVladimir Medvedkin uint32_t hash, hashlsb; 816ed4f8e02SVladimir Medvedkin 817ed4f8e02SVladimir Medvedkin hash = calc_tuple_hash(tuple, key); 818ed4f8e02SVladimir Medvedkin hashlsb = hash & HASH_MSK(reta_sz); 819ed4f8e02SVladimir Medvedkin 820ed4f8e02SVladimir Medvedkin printf("%s(%s) for tuple:\n", __func__, prefix); 821ed4f8e02SVladimir Medvedkin rte_memdump(stdout, NULL, tuple, TUPLE_SZ); 822ed4f8e02SVladimir Medvedkin printf("\treta_sz: %u,\n" 823ed4f8e02SVladimir Medvedkin "\torig hash: %#x,\n" 824ed4f8e02SVladimir Medvedkin "\tdesired: %#x,\n" 825ed4f8e02SVladimir Medvedkin "\tadjust: %#x,\n" 826ed4f8e02SVladimir Medvedkin "\tactual: %#x,\n", 827ed4f8e02SVladimir Medvedkin reta_sz, ohv, dhv, adjust, hashlsb); 828ed4f8e02SVladimir Medvedkin 829ed4f8e02SVladimir Medvedkin if (dhv == hashlsb) { 830ed4f8e02SVladimir Medvedkin printf("\t***Succeeded\n"); 831ed4f8e02SVladimir Medvedkin return 0; 832ed4f8e02SVladimir Medvedkin } 833ed4f8e02SVladimir Medvedkin 834ed4f8e02SVladimir Medvedkin printf("\t***Failed\n"); 835ed4f8e02SVladimir Medvedkin return -1; 836ed4f8e02SVladimir Medvedkin } 837ed4f8e02SVladimir Medvedkin 838ed4f8e02SVladimir Medvedkin static int 839ed4f8e02SVladimir Medvedkin test_adjust_tuple_mb(uint32_t reta_sz, uint32_t bofs) 840ed4f8e02SVladimir Medvedkin { 841ed4f8e02SVladimir Medvedkin struct rte_thash_ctx *ctx; 842ed4f8e02SVladimir Medvedkin struct rte_thash_subtuple_helper *h; 843ed4f8e02SVladimir Medvedkin const int key_len = 40; 844ed4f8e02SVladimir Medvedkin const uint8_t *new_key; 845ed4f8e02SVladimir Medvedkin uint8_t orig_tuple[TUPLE_SZ]; 846ed4f8e02SVladimir Medvedkin uint8_t tuple_1[TUPLE_SZ]; 847ed4f8e02SVladimir Medvedkin uint8_t tuple_2[TUPLE_SZ]; 848ed4f8e02SVladimir Medvedkin uint32_t orig_hash; 849ed4f8e02SVladimir Medvedkin int rc, ret; 850ed4f8e02SVladimir Medvedkin uint32_t adj_bits; 851ed4f8e02SVladimir Medvedkin unsigned int random = rte_rand(); 852ed4f8e02SVladimir Medvedkin unsigned int desired_value = random & HASH_MSK(reta_sz); 853ed4f8e02SVladimir Medvedkin 854ed4f8e02SVladimir Medvedkin const uint32_t h_offset = offsetof(union rte_thash_tuple, v4.dport) * CHAR_BIT; 855ed4f8e02SVladimir Medvedkin const uint32_t h_size = sizeof(uint16_t) * CHAR_BIT - bofs; 856ed4f8e02SVladimir Medvedkin 857ed4f8e02SVladimir Medvedkin printf("===%s(reta_sz=%u,bofs=%u)===\n", __func__, reta_sz, bofs); 858ed4f8e02SVladimir Medvedkin 859ed4f8e02SVladimir Medvedkin memset(orig_tuple, 0xab, sizeof(orig_tuple)); 860ed4f8e02SVladimir Medvedkin 861ed4f8e02SVladimir Medvedkin ctx = rte_thash_init_ctx("test", key_len, reta_sz, NULL, 0); 862ed4f8e02SVladimir Medvedkin RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 863ed4f8e02SVladimir Medvedkin 864ed4f8e02SVladimir Medvedkin ret = rte_thash_add_helper(ctx, "test", h_size, h_offset); 865ed4f8e02SVladimir Medvedkin RTE_TEST_ASSERT(ret == 0, "can not add helper, ret %d\n", ret); 866ed4f8e02SVladimir Medvedkin 867ed4f8e02SVladimir Medvedkin new_key = rte_thash_get_key(ctx); 868ed4f8e02SVladimir Medvedkin 869ed4f8e02SVladimir Medvedkin h = rte_thash_get_helper(ctx, "test"); 870ed4f8e02SVladimir Medvedkin 871ed4f8e02SVladimir Medvedkin orig_hash = calc_tuple_hash(orig_tuple, new_key); 872ed4f8e02SVladimir Medvedkin 873ed4f8e02SVladimir Medvedkin adj_bits = rte_thash_get_complement(h, orig_hash, desired_value); 874ed4f8e02SVladimir Medvedkin 875ed4f8e02SVladimir Medvedkin /* use method #1, update tuple manually */ 876ed4f8e02SVladimir Medvedkin memcpy(tuple_1, orig_tuple, sizeof(tuple_1)); 877ed4f8e02SVladimir Medvedkin { 878ed4f8e02SVladimir Medvedkin uint16_t nv, ov, *p; 879ed4f8e02SVladimir Medvedkin 880ed4f8e02SVladimir Medvedkin p = (uint16_t *)(tuple_1 + h_offset / CHAR_BIT); 881ed4f8e02SVladimir Medvedkin ov = p[0]; 882ed4f8e02SVladimir Medvedkin nv = ov ^ rte_cpu_to_be_16(adj_bits << bofs); 883ed4f8e02SVladimir Medvedkin printf("%s#%d: ov=%#hx, nv=%#hx, adj=%#x;\n", 884ed4f8e02SVladimir Medvedkin __func__, __LINE__, ov, nv, adj_bits); 885ed4f8e02SVladimir Medvedkin p[0] = nv; 886ed4f8e02SVladimir Medvedkin } 887ed4f8e02SVladimir Medvedkin 888ed4f8e02SVladimir Medvedkin rc = check_adj_tuple(tuple_1, new_key, desired_value, orig_hash, 889ed4f8e02SVladimir Medvedkin adj_bits, reta_sz, "method #1"); 890ed4f8e02SVladimir Medvedkin if (h_offset % CHAR_BIT == 0) 891ed4f8e02SVladimir Medvedkin ret |= rc; 892ed4f8e02SVladimir Medvedkin 893ed4f8e02SVladimir Medvedkin /* use method #2, use library function to adjust tuple */ 894ed4f8e02SVladimir Medvedkin memcpy(tuple_2, orig_tuple, sizeof(tuple_2)); 895ed4f8e02SVladimir Medvedkin 896ed4f8e02SVladimir Medvedkin rte_thash_adjust_tuple(ctx, h, tuple_2, sizeof(tuple_2), 897ed4f8e02SVladimir Medvedkin desired_value, 1, NULL, NULL); 898ed4f8e02SVladimir Medvedkin ret |= check_adj_tuple(tuple_2, new_key, desired_value, orig_hash, 899ed4f8e02SVladimir Medvedkin adj_bits, reta_sz, "method #2"); 900ed4f8e02SVladimir Medvedkin 901ed4f8e02SVladimir Medvedkin rte_thash_free_ctx(ctx); 902ed4f8e02SVladimir Medvedkin 903ed4f8e02SVladimir Medvedkin ret |= memcmp(tuple_1, tuple_2, sizeof(tuple_1)); 904ed4f8e02SVladimir Medvedkin 905ed4f8e02SVladimir Medvedkin printf("%s EXIT=======\n", __func__); 906ed4f8e02SVladimir Medvedkin return ret; 907ed4f8e02SVladimir Medvedkin } 908ed4f8e02SVladimir Medvedkin 909ed4f8e02SVladimir Medvedkin static int 910ed4f8e02SVladimir Medvedkin test_adjust_tuple_mult_reta(void) 911ed4f8e02SVladimir Medvedkin { 912ed4f8e02SVladimir Medvedkin uint32_t i, j, np, nt; 913ed4f8e02SVladimir Medvedkin 914ed4f8e02SVladimir Medvedkin nt = 0, np = 0; 915ed4f8e02SVladimir Medvedkin for (i = 0; i < CHAR_BIT; i++) { 916ed4f8e02SVladimir Medvedkin for (j = 6; j <= RTE_THASH_RETA_SZ_MAX - i; j++) { 917ed4f8e02SVladimir Medvedkin np += (test_adjust_tuple_mb(j, i) == 0); 918ed4f8e02SVladimir Medvedkin nt++; 919ed4f8e02SVladimir Medvedkin } 920ed4f8e02SVladimir Medvedkin } 921ed4f8e02SVladimir Medvedkin 922ed4f8e02SVladimir Medvedkin printf("%s: tests executed: %u, test passed: %u\n", __func__, nt, np); 923ed4f8e02SVladimir Medvedkin RTE_TEST_ASSERT(nt == np, "%u subtests failed", nt - np); 924ed4f8e02SVladimir Medvedkin return TEST_SUCCESS; 925ed4f8e02SVladimir Medvedkin } 926ed4f8e02SVladimir Medvedkin 927*89398eceSVladimir Medvedkin #define RETA_SZ_LOG 11 928*89398eceSVladimir Medvedkin #define RSS_KEY_SZ 40 929*89398eceSVladimir Medvedkin #define RETA_SZ (1 << RETA_SZ_LOG) 930*89398eceSVladimir Medvedkin #define NB_HASH_ITER RETA_SZ 931*89398eceSVladimir Medvedkin #define NB_TEST_ITER 10 932*89398eceSVladimir Medvedkin 933*89398eceSVladimir Medvedkin static inline void 934*89398eceSVladimir Medvedkin run_hash_calc_loop(uint8_t *key, union rte_thash_tuple *tuple, 935*89398eceSVladimir Medvedkin unsigned int *rss_reta_hits) 936*89398eceSVladimir Medvedkin { 937*89398eceSVladimir Medvedkin uint32_t rss_hash; 938*89398eceSVladimir Medvedkin int i; 939*89398eceSVladimir Medvedkin 940*89398eceSVladimir Medvedkin for (i = 0; i < NB_HASH_ITER; i++) { 941*89398eceSVladimir Medvedkin /* variable part starts from the most significant bit */ 942*89398eceSVladimir Medvedkin tuple->v4.dport = (i << (sizeof(tuple->v4.dport) * CHAR_BIT - 943*89398eceSVladimir Medvedkin RETA_SZ_LOG)); 944*89398eceSVladimir Medvedkin /* 945*89398eceSVladimir Medvedkin * swap sport and dport on LE arch since rte_softrss() 946*89398eceSVladimir Medvedkin * works with host byte order uint32_t values 947*89398eceSVladimir Medvedkin */ 948*89398eceSVladimir Medvedkin tuple->v4.dport = rte_cpu_to_be_16(tuple->v4.dport); 949*89398eceSVladimir Medvedkin tuple->v4.sctp_tag = rte_be_to_cpu_32(tuple->v4.sctp_tag); 950*89398eceSVladimir Medvedkin rss_hash = rte_softrss((uint32_t *)tuple, 951*89398eceSVladimir Medvedkin RTE_THASH_V4_L4_LEN, key); 952*89398eceSVladimir Medvedkin /* unroll swap, required only for sport */ 953*89398eceSVladimir Medvedkin tuple->v4.sctp_tag = rte_cpu_to_be_32(tuple->v4.sctp_tag); 954*89398eceSVladimir Medvedkin rss_reta_hits[rss_hash & (RETA_SZ - 1)]++; 955*89398eceSVladimir Medvedkin } 956*89398eceSVladimir Medvedkin } 957*89398eceSVladimir Medvedkin 958*89398eceSVladimir Medvedkin static int 959*89398eceSVladimir Medvedkin hash_calc_iteration(unsigned int *min_before, unsigned int *max_before, 960*89398eceSVladimir Medvedkin unsigned int *min_after, unsigned int *max_after, 961*89398eceSVladimir Medvedkin unsigned int *min_default, unsigned int *max_default) 962*89398eceSVladimir Medvedkin { 963*89398eceSVladimir Medvedkin uint8_t key[RSS_KEY_SZ] = {0}; 964*89398eceSVladimir Medvedkin union rte_thash_tuple tuple; 965*89398eceSVladimir Medvedkin unsigned int rss_reta_hits_before_adjust[RETA_SZ] = {0}; 966*89398eceSVladimir Medvedkin unsigned int rss_reta_hits_after_adjust[RETA_SZ] = {0}; 967*89398eceSVladimir Medvedkin unsigned int rss_reta_hits_default_key[RETA_SZ] = {0}; 968*89398eceSVladimir Medvedkin int i; 969*89398eceSVladimir Medvedkin 970*89398eceSVladimir Medvedkin for (i = 0; i < RSS_KEY_SZ; i++) 971*89398eceSVladimir Medvedkin key[i] = rte_rand(); 972*89398eceSVladimir Medvedkin 973*89398eceSVladimir Medvedkin tuple.v4.src_addr = rte_rand(); 974*89398eceSVladimir Medvedkin tuple.v4.dst_addr = rte_rand(); 975*89398eceSVladimir Medvedkin tuple.v4.sport = rte_rand(); 976*89398eceSVladimir Medvedkin 977*89398eceSVladimir Medvedkin run_hash_calc_loop(key, &tuple, rss_reta_hits_before_adjust); 978*89398eceSVladimir Medvedkin 979*89398eceSVladimir Medvedkin int ret = rte_thash_gen_key(key, RSS_KEY_SZ, RETA_SZ_LOG, 980*89398eceSVladimir Medvedkin offsetof(union rte_thash_tuple, v4.dport)*CHAR_BIT, 981*89398eceSVladimir Medvedkin RETA_SZ_LOG); 982*89398eceSVladimir Medvedkin 983*89398eceSVladimir Medvedkin if (ret) { 984*89398eceSVladimir Medvedkin printf("Can't generate key\n"); 985*89398eceSVladimir Medvedkin return -1; 986*89398eceSVladimir Medvedkin } 987*89398eceSVladimir Medvedkin 988*89398eceSVladimir Medvedkin run_hash_calc_loop(key, &tuple, rss_reta_hits_after_adjust); 989*89398eceSVladimir Medvedkin 990*89398eceSVladimir Medvedkin run_hash_calc_loop(default_rss_key, &tuple, rss_reta_hits_default_key); 991*89398eceSVladimir Medvedkin 992*89398eceSVladimir Medvedkin for (i = 0; i < RETA_SZ; i++) { 993*89398eceSVladimir Medvedkin *min_before = RTE_MIN(*min_before, rss_reta_hits_before_adjust[i]); 994*89398eceSVladimir Medvedkin *max_before = RTE_MAX(*max_before, rss_reta_hits_before_adjust[i]); 995*89398eceSVladimir Medvedkin *min_after = RTE_MIN(*min_after, rss_reta_hits_after_adjust[i]); 996*89398eceSVladimir Medvedkin *max_after = RTE_MAX(*max_after, rss_reta_hits_after_adjust[i]); 997*89398eceSVladimir Medvedkin *min_default = RTE_MIN(*min_default, rss_reta_hits_default_key[i]); 998*89398eceSVladimir Medvedkin *max_default = RTE_MAX(*max_default, rss_reta_hits_default_key[i]); 999*89398eceSVladimir Medvedkin } 1000*89398eceSVladimir Medvedkin 1001*89398eceSVladimir Medvedkin return 0; 1002*89398eceSVladimir Medvedkin } 1003*89398eceSVladimir Medvedkin 1004*89398eceSVladimir Medvedkin static int 1005*89398eceSVladimir Medvedkin test_keygen(void) 1006*89398eceSVladimir Medvedkin { 1007*89398eceSVladimir Medvedkin int i, ret; 1008*89398eceSVladimir Medvedkin unsigned int min_before = UINT32_MAX; 1009*89398eceSVladimir Medvedkin unsigned int min_after = UINT32_MAX; 1010*89398eceSVladimir Medvedkin unsigned int min_default = UINT32_MAX; 1011*89398eceSVladimir Medvedkin unsigned int max_before = 0; 1012*89398eceSVladimir Medvedkin unsigned int max_after = 0; 1013*89398eceSVladimir Medvedkin unsigned int max_default = 0; 1014*89398eceSVladimir Medvedkin 1015*89398eceSVladimir Medvedkin for (i = 0; i < NB_TEST_ITER; i++) { 1016*89398eceSVladimir Medvedkin /* calculates the worst distribution for each key */ 1017*89398eceSVladimir Medvedkin ret = hash_calc_iteration(&min_before, &max_before, &min_after, 1018*89398eceSVladimir Medvedkin &max_after, &min_default, &max_default); 1019*89398eceSVladimir Medvedkin if (ret) 1020*89398eceSVladimir Medvedkin return ret; 1021*89398eceSVladimir Medvedkin } 1022*89398eceSVladimir Medvedkin 1023*89398eceSVladimir Medvedkin printf("RSS before key adjustment: min=%d, max=%d\n", 1024*89398eceSVladimir Medvedkin min_before, max_before); 1025*89398eceSVladimir Medvedkin printf("RSS after key adjustment: min=%d, max=%d\n", 1026*89398eceSVladimir Medvedkin min_after, max_after); 1027*89398eceSVladimir Medvedkin printf("RSS default key: min=%d, max=%d\n", 1028*89398eceSVladimir Medvedkin min_default, max_default); 1029*89398eceSVladimir Medvedkin 1030*89398eceSVladimir Medvedkin return TEST_SUCCESS; 1031*89398eceSVladimir Medvedkin } 1032*89398eceSVladimir Medvedkin 103328ebff11SVladimir Medvedkin static struct unit_test_suite thash_tests = { 103428ebff11SVladimir Medvedkin .suite_name = "thash autotest", 103528ebff11SVladimir Medvedkin .setup = NULL, 103628ebff11SVladimir Medvedkin .teardown = NULL, 103728ebff11SVladimir Medvedkin .unit_test_cases = { 103828ebff11SVladimir Medvedkin TEST_CASE(test_toeplitz_hash_calc), 10394fd8c4cbSVladimir Medvedkin TEST_CASE(test_toeplitz_hash_gfni), 10404fd8c4cbSVladimir Medvedkin TEST_CASE(test_toeplitz_hash_rand_data), 104131d7c069SVladimir Medvedkin TEST_CASE(test_toeplitz_hash_gfni_bulk), 10424fd8c4cbSVladimir Medvedkin TEST_CASE(test_big_tuple_gfni), 104328ebff11SVladimir Medvedkin TEST_CASE(test_create_invalid), 104428ebff11SVladimir Medvedkin TEST_CASE(test_multiple_create), 104528ebff11SVladimir Medvedkin TEST_CASE(test_free_null), 104628ebff11SVladimir Medvedkin TEST_CASE(test_add_invalid_helper), 104728ebff11SVladimir Medvedkin TEST_CASE(test_find_existing), 104828ebff11SVladimir Medvedkin TEST_CASE(test_get_helper), 104928ebff11SVladimir Medvedkin TEST_CASE(test_period_overflow), 105028ebff11SVladimir Medvedkin TEST_CASE(test_predictable_rss_min_seq), 105128ebff11SVladimir Medvedkin TEST_CASE(test_predictable_rss_multirange), 105228ebff11SVladimir Medvedkin TEST_CASE(test_adjust_tuple), 1053ed4f8e02SVladimir Medvedkin TEST_CASE(test_adjust_tuple_mult_reta), 1054*89398eceSVladimir Medvedkin TEST_CASE(test_keygen), 105528ebff11SVladimir Medvedkin TEST_CASES_END() 105628ebff11SVladimir Medvedkin } 105728ebff11SVladimir Medvedkin }; 105828ebff11SVladimir Medvedkin 105928ebff11SVladimir Medvedkin static int 106028ebff11SVladimir Medvedkin test_thash(void) 106128ebff11SVladimir Medvedkin { 106228ebff11SVladimir Medvedkin return unit_test_suite_runner(&thash_tests); 1063a9de470cSBruce Richardson } 1064a9de470cSBruce Richardson 1065e0a8442cSBruce Richardson REGISTER_FAST_TEST(thash_autotest, true, true, test_thash); 1066