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