1b56a8975SPeter Spreadborough /* SPDX-License-Identifier: BSD-3-Clause
2b56a8975SPeter Spreadborough * Copyright(c) 2019-2021 Broadcom
3b56a8975SPeter Spreadborough * All rights reserved.
4b56a8975SPeter Spreadborough */
5b56a8975SPeter Spreadborough
6b56a8975SPeter Spreadborough #include <stdint.h>
7b56a8975SPeter Spreadborough #include <stdlib.h>
8b56a8975SPeter Spreadborough #include <stdbool.h>
9b56a8975SPeter Spreadborough #include <string.h>
10b56a8975SPeter Spreadborough #include "lookup3.h"
11b56a8975SPeter Spreadborough #include "rand.h"
12b56a8975SPeter Spreadborough
13b56a8975SPeter Spreadborough #include "hcapi_cfa_defs.h"
14b56a8975SPeter Spreadborough
15b56a8975SPeter Spreadborough static uint32_t hcapi_cfa_lkup_lkup3_init_cfg;
16b56a8975SPeter Spreadborough static uint32_t hcapi_cfa_lkup_em_seed_mem[HCAPI_CFA_LKUP_SEED_MEM_SIZE];
17b56a8975SPeter Spreadborough static bool hcapi_cfa_lkup_init;
18b56a8975SPeter Spreadborough
hcapi_cfa_seeds_init(void)19b56a8975SPeter Spreadborough static void hcapi_cfa_seeds_init(void)
20b56a8975SPeter Spreadborough {
21b56a8975SPeter Spreadborough int i;
22b56a8975SPeter Spreadborough uint32_t r;
23b56a8975SPeter Spreadborough
24b56a8975SPeter Spreadborough if (hcapi_cfa_lkup_init)
25b56a8975SPeter Spreadborough return;
26b56a8975SPeter Spreadborough
27b56a8975SPeter Spreadborough hcapi_cfa_lkup_init = true;
28b56a8975SPeter Spreadborough
29b56a8975SPeter Spreadborough /* Initialize the lfsr */
30b56a8975SPeter Spreadborough rand_init();
31b56a8975SPeter Spreadborough
32b56a8975SPeter Spreadborough /* RX and TX use the same seed values */
33b56a8975SPeter Spreadborough hcapi_cfa_lkup_lkup3_init_cfg = rand32();
34b56a8975SPeter Spreadborough
35b56a8975SPeter Spreadborough for (i = 0; i < HCAPI_CFA_LKUP_SEED_MEM_SIZE / 2; i++) {
36b56a8975SPeter Spreadborough r = rand32();
37b56a8975SPeter Spreadborough hcapi_cfa_lkup_em_seed_mem[i * 2] = r;
38b56a8975SPeter Spreadborough r = rand32();
39b56a8975SPeter Spreadborough hcapi_cfa_lkup_em_seed_mem[i * 2 + 1] = (r & 0x1);
40b56a8975SPeter Spreadborough }
41b56a8975SPeter Spreadborough }
42b56a8975SPeter Spreadborough
hcapi_cfa_crc32_hash(uint8_t * key)43b56a8975SPeter Spreadborough static uint32_t hcapi_cfa_crc32_hash(uint8_t *key)
44b56a8975SPeter Spreadborough {
45b56a8975SPeter Spreadborough int i;
46b56a8975SPeter Spreadborough uint32_t index;
47b56a8975SPeter Spreadborough uint32_t val1, val2;
48b56a8975SPeter Spreadborough uint8_t temp[4];
49b56a8975SPeter Spreadborough uint8_t *kptr = key;
50b56a8975SPeter Spreadborough
51b56a8975SPeter Spreadborough /* Do byte-wise XOR of the 52-byte HASH key first. */
52b56a8975SPeter Spreadborough index = *key;
53b56a8975SPeter Spreadborough kptr--;
54b56a8975SPeter Spreadborough
55b56a8975SPeter Spreadborough for (i = CFA_P58_EEM_KEY_MAX_SIZE - 2; i >= 0; i--) {
56b56a8975SPeter Spreadborough index = index ^ *kptr;
57b56a8975SPeter Spreadborough kptr--;
58b56a8975SPeter Spreadborough }
59b56a8975SPeter Spreadborough
60b56a8975SPeter Spreadborough /* Get seeds */
61b56a8975SPeter Spreadborough val1 = hcapi_cfa_lkup_em_seed_mem[index * 2];
62b56a8975SPeter Spreadborough val2 = hcapi_cfa_lkup_em_seed_mem[index * 2 + 1];
63b56a8975SPeter Spreadborough
64b56a8975SPeter Spreadborough temp[3] = (uint8_t)(val1 >> 24);
65b56a8975SPeter Spreadborough temp[2] = (uint8_t)(val1 >> 16);
66b56a8975SPeter Spreadborough temp[1] = (uint8_t)(val1 >> 8);
67b56a8975SPeter Spreadborough temp[0] = (uint8_t)(val1 & 0xff);
68b56a8975SPeter Spreadborough val1 = 0;
69b56a8975SPeter Spreadborough
70b56a8975SPeter Spreadborough /* Start with seed */
71b56a8975SPeter Spreadborough if (!(val2 & 0x1))
72b56a8975SPeter Spreadborough val1 = hcapi_cfa_crc32i(~val1, temp, 4);
73b56a8975SPeter Spreadborough
74b56a8975SPeter Spreadborough val1 = hcapi_cfa_crc32i(~val1,
75b56a8975SPeter Spreadborough (key - (CFA_P58_EEM_KEY_MAX_SIZE - 1)),
76b56a8975SPeter Spreadborough CFA_P58_EEM_KEY_MAX_SIZE);
77b56a8975SPeter Spreadborough
78b56a8975SPeter Spreadborough /* End with seed */
79b56a8975SPeter Spreadborough if (val2 & 0x1)
80b56a8975SPeter Spreadborough val1 = hcapi_cfa_crc32i(~val1, temp, 4);
81b56a8975SPeter Spreadborough
82b56a8975SPeter Spreadborough return val1;
83b56a8975SPeter Spreadborough }
84b56a8975SPeter Spreadborough
hcapi_cfa_lookup3_hash(uint8_t * in_key)85b56a8975SPeter Spreadborough static uint32_t hcapi_cfa_lookup3_hash(uint8_t *in_key)
86b56a8975SPeter Spreadborough {
87b56a8975SPeter Spreadborough uint32_t val1;
88b56a8975SPeter Spreadborough
89*08e1af1aSFarah Smith val1 = hashword(((uint32_t *)in_key),
90b56a8975SPeter Spreadborough CFA_P58_EEM_KEY_MAX_SIZE / (sizeof(uint32_t)),
91b56a8975SPeter Spreadborough hcapi_cfa_lkup_lkup3_init_cfg);
92b56a8975SPeter Spreadborough
93b56a8975SPeter Spreadborough return val1;
94b56a8975SPeter Spreadborough }
95b56a8975SPeter Spreadborough
96b56a8975SPeter Spreadborough
97b56a8975SPeter Spreadborough /** Approximation of HCAPI hcapi_cfa_key_hash()
98b56a8975SPeter Spreadborough *
99b56a8975SPeter Spreadborough * Return:
100b56a8975SPeter Spreadborough *
101b56a8975SPeter Spreadborough */
hcapi_cfa_p58_key_hash(uint64_t * key_data,uint16_t bitlen)102b56a8975SPeter Spreadborough uint64_t hcapi_cfa_p58_key_hash(uint64_t *key_data,
103b56a8975SPeter Spreadborough uint16_t bitlen)
104b56a8975SPeter Spreadborough {
105b56a8975SPeter Spreadborough uint32_t key0_hash;
106b56a8975SPeter Spreadborough uint32_t key1_hash;
107b56a8975SPeter Spreadborough
108b56a8975SPeter Spreadborough /*
109b56a8975SPeter Spreadborough * Init the seeds if needed
110b56a8975SPeter Spreadborough */
111b56a8975SPeter Spreadborough if (!hcapi_cfa_lkup_init)
112b56a8975SPeter Spreadborough hcapi_cfa_seeds_init();
113b56a8975SPeter Spreadborough
114b56a8975SPeter Spreadborough key0_hash = hcapi_cfa_crc32_hash(((uint8_t *)key_data) +
115b56a8975SPeter Spreadborough (bitlen / 8) - 1);
116b56a8975SPeter Spreadborough
117b56a8975SPeter Spreadborough key1_hash = hcapi_cfa_lookup3_hash((uint8_t *)key_data);
118b56a8975SPeter Spreadborough
119b56a8975SPeter Spreadborough return ((uint64_t)key0_hash) << 32 | (uint64_t)key1_hash;
120b56a8975SPeter Spreadborough }
121