From 0b83e8b1b72674f886f0054c6ebcc1ea8bc75a47 Mon Sep 17 00:00:00 2001 From: Hemant Agrawal Date: Wed, 6 Oct 2021 22:31:26 +0530 Subject: [PATCH] net/dpaa2: generate HW hash key This patch add support to generate the hash key in software equivalent to WRIOP key generation. Signed-off-by: Hemant Agrawal --- drivers/net/dpaa2/base/dpaa2_tlu_hash.c | 153 ++++++++++++++++++++++++ drivers/net/dpaa2/meson.build | 1 + drivers/net/dpaa2/rte_pmd_dpaa2.h | 19 +++ drivers/net/dpaa2/version.map | 2 + 4 files changed, 175 insertions(+) create mode 100644 drivers/net/dpaa2/base/dpaa2_tlu_hash.c diff --git a/drivers/net/dpaa2/base/dpaa2_tlu_hash.c b/drivers/net/dpaa2/base/dpaa2_tlu_hash.c new file mode 100644 index 0000000000..9eb127c07c --- /dev/null +++ b/drivers/net/dpaa2/base/dpaa2_tlu_hash.c @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2021 NXP + */ +#include +#include +#include +#include + +static unsigned int sbox(unsigned int x) +{ + unsigned int a, b, c, d; + unsigned int oa, ob, oc, od; + + a = x & 0x1; + b = (x >> 1) & 0x1; + c = (x >> 2) & 0x1; + d = (x >> 3) & 0x1; + + oa = ((a & ~b & ~c & d) | (~a & b) | (~a & ~c & ~d) | (b & c)) & 0x1; + ob = ((a & ~b & d) | (~a & c & ~d) | (b & ~c)) & 0x1; + oc = ((a & ~b & c) | (a & ~b & ~d) | (~a & b & ~d) | (~a & c & ~d) | + (b & c & d)) & 0x1; + od = ((a & ~b & c) | (~a & b & ~c) | (a & b & ~d) | (~a & c & d)) & 0x1; + + return ((od << 3) | (oc << 2) | (ob << 1) | oa); +} + +static unsigned int sbox_tbl[16]; + +static int pbox_tbl[16] = {5, 9, 0, 13, + 7, 2, 11, 14, + 1, 4, 12, 8, + 3, 15, 6, 10 }; + +static unsigned int mix_tbl[8][16]; + +static unsigned int stage(unsigned int input) +{ + int sbox_out = 0; + int pbox_out = 0; + int i; + + /* mix */ + input ^= input >> 16; /* xor lower */ + input ^= input << 16; /* move original lower to upper */ + + for (i = 0; i < 32; i += 4) /* sbox stage */ + sbox_out |= (sbox_tbl[(input >> i) & 0xf]) << i; + + /* permutation */ + for (i = 0; i < 16; i++) + pbox_out |= ((sbox_out >> i) & 0x10001) << pbox_tbl[i]; + + return pbox_out; +} + +static unsigned int fast_stage(unsigned int input) +{ + int pbox_out = 0; + int i; + + /* mix */ + input ^= input >> 16; /* xor lower */ + input ^= input << 16; /* move original lower to upper */ + + for (i = 0; i < 32; i += 4) /* sbox stage */ + pbox_out |= mix_tbl[i >> 2][(input >> i) & 0xf]; + + return pbox_out; +} + +static unsigned int fast_hash32(unsigned int x) +{ + int i; + + for (i = 0; i < 4; i++) + x = fast_stage(x); + return x; +} + +static unsigned int +byte_crc32(unsigned char data /* new byte for the crc calculation */, + unsigned old_crc /* crc result of the last iteration */) +{ + int i; + unsigned int crc, polynom = 0xedb88320; + /* the polynomial is built on the reversed version of + * the CRC polynomial with out the x64 element. + */ + + crc = old_crc; + for (i = 0; i < 8; i++, data >>= 1) + crc = (crc >> 1) ^ (((crc ^ data) & 0x1) ? polynom : 0); + /* xor with polynomial is lsb of crc^data is 1 */ + + return crc; +} + +static unsigned int crc32_table[256]; + +static void init_crc32_table(void) +{ + int i; + + for (i = 0; i < 256; i++) + crc32_table[i] = byte_crc32((unsigned char)i, 0LL); +} + +static unsigned int +crc32_string(unsigned char *data, + int size, unsigned int old_crc) +{ + unsigned int crc; + int i; + + crc = old_crc; + for (i = 0; i < size; i++) + crc = (crc >> 8) ^ crc32_table[(crc ^ data[i]) & 0xff]; + + return crc; +} + +static void hash_init(void) +{ + init_crc32_table(); + int i, j; + + for (i = 0; i < 16; i++) + sbox_tbl[i] = sbox(i); + + for (i = 0; i < 32; i += 4) + for (j = 0; j < 16; j++) { + /* (a,b) + * (b,a^b)=(X,Y) + * (X^Y,X) + */ + unsigned int input = (0x88888888 ^ (8 << i)) | (j << i); + + input ^= input << 16; /* (X^Y,Y) */ + input ^= input >> 16; /* (X^Y,X) */ + mix_tbl[i >> 2][j] = stage(input); + } +} + +uint32_t rte_pmd_dpaa2_get_tlu_hash(uint8_t *data, int size) +{ + static int init; + + if (~init) + hash_init(); + init = 1; + return fast_hash32(crc32_string(data, size, 0x0)); +} diff --git a/drivers/net/dpaa2/meson.build b/drivers/net/dpaa2/meson.build index 20eaf0b8e4..21b827a259 100644 --- a/drivers/net/dpaa2/meson.build +++ b/drivers/net/dpaa2/meson.build @@ -9,6 +9,7 @@ endif deps += ['mempool_dpaa2'] sources = files( 'base/dpaa2_hw_dpni.c', + 'base/dpaa2_tlu_hash.c', 'dpaa2_tm.c', 'dpaa2_mux.c', 'dpaa2_ethdev.c', diff --git a/drivers/net/dpaa2/rte_pmd_dpaa2.h b/drivers/net/dpaa2/rte_pmd_dpaa2.h index a68244c974..8ea42ee130 100644 --- a/drivers/net/dpaa2/rte_pmd_dpaa2.h +++ b/drivers/net/dpaa2/rte_pmd_dpaa2.h @@ -82,4 +82,23 @@ __rte_experimental void rte_pmd_dpaa2_thread_init(void); +/** + * @warning + * @b EXPERIMENTAL: this API may change, or be removed, without prior notice + * + * Generate the DPAA2 WRIOP based hash value + * + * @param key + * Array of key data + * @param size + * Size of the hash input key in bytes + * + * @return + * - 0 if successful. + * - Negative in case of failure. + */ + +__rte_experimental +uint32_t +rte_pmd_dpaa2_get_tlu_hash(uint8_t *key, int size); #endif /* _RTE_PMD_DPAA2_H */ diff --git a/drivers/net/dpaa2/version.map b/drivers/net/dpaa2/version.map index 3ab96344c4..2fe61f3442 100644 --- a/drivers/net/dpaa2/version.map +++ b/drivers/net/dpaa2/version.map @@ -14,6 +14,8 @@ EXPERIMENTAL { rte_pmd_dpaa2_mux_rx_frame_len; # added in 21.08 rte_pmd_dpaa2_thread_init; + # added in 21.11 + rte_pmd_dpaa2_get_tlu_hash; }; INTERNAL { -- 2.20.1