net/dpaa2: generate HW hash key
authorHemant Agrawal <hemant.agrawal@nxp.com>
Wed, 6 Oct 2021 17:01:26 +0000 (22:31 +0530)
committerThomas Monjalon <thomas@monjalon.net>
Thu, 7 Oct 2021 12:47:25 +0000 (14:47 +0200)
This patch add support to generate the hash key in software
equivalent to WRIOP key generation.

Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
drivers/net/dpaa2/base/dpaa2_tlu_hash.c [new file with mode: 0644]
drivers/net/dpaa2/meson.build
drivers/net/dpaa2/rte_pmd_dpaa2.h
drivers/net/dpaa2/version.map

diff --git a/drivers/net/dpaa2/base/dpaa2_tlu_hash.c b/drivers/net/dpaa2/base/dpaa2_tlu_hash.c
new file mode 100644 (file)
index 0000000..9eb127c
--- /dev/null
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 NXP
+ */
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <rte_pmd_dpaa2.h>
+
+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));
+}
index 20eaf0b..21b827a 100644 (file)
@@ -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',
index a68244c..8ea42ee 100644 (file)
@@ -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 */
index 3ab9634..2fe61f3 100644 (file)
@@ -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 {