octeontx2-af: FLR handler for exact match table.
[platform/kernel/linux-rpi.git] / drivers / net / ethernet / marvell / octeontx2 / af / rvu_npc_hash.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell RVU Admin Function driver
3  *
4  * Copyright (C) 2022 Marvell.
5  *
6  */
7
8 #include <linux/bitfield.h>
9 #include <linux/module.h>
10 #include <linux/pci.h>
11 #include <linux/firmware.h>
12 #include <linux/stddef.h>
13 #include <linux/debugfs.h>
14 #include <linux/bitfield.h>
15
16 #include "rvu_struct.h"
17 #include "rvu_reg.h"
18 #include "rvu.h"
19 #include "npc.h"
20 #include "cgx.h"
21 #include "rvu_npc_hash.h"
22 #include "rvu_npc_fs.h"
23 #include "rvu_npc_hash.h"
24
25 static u64 rvu_npc_wide_extract(const u64 input[], size_t start_bit,
26                                 size_t width_bits)
27 {
28         const u64 mask = ~(u64)((~(__uint128_t)0) << width_bits);
29         const size_t msb = start_bit + width_bits - 1;
30         const size_t lword = start_bit >> 6;
31         const size_t uword = msb >> 6;
32         size_t lbits;
33         u64 hi, lo;
34
35         if (lword == uword)
36                 return (input[lword] >> (start_bit & 63)) & mask;
37
38         lbits = 64 - (start_bit & 63);
39         hi = input[uword];
40         lo = (input[lword] >> (start_bit & 63));
41         return ((hi << lbits) | lo) & mask;
42 }
43
44 static void rvu_npc_lshift_key(u64 *key, size_t key_bit_len)
45 {
46         u64 prev_orig_word = 0;
47         u64 cur_orig_word = 0;
48         size_t extra = key_bit_len % 64;
49         size_t max_idx = key_bit_len / 64;
50         size_t i;
51
52         if (extra)
53                 max_idx++;
54
55         for (i = 0; i < max_idx; i++) {
56                 cur_orig_word = key[i];
57                 key[i] = key[i] << 1;
58                 key[i] |= ((prev_orig_word >> 63) & 0x1);
59                 prev_orig_word = cur_orig_word;
60         }
61 }
62
63 static u32 rvu_npc_toeplitz_hash(const u64 *data, u64 *key, size_t data_bit_len,
64                                  size_t key_bit_len)
65 {
66         u32 hash_out = 0;
67         u64 temp_data = 0;
68         int i;
69
70         for (i = data_bit_len - 1; i >= 0; i--) {
71                 temp_data = (data[i / 64]);
72                 temp_data = temp_data >> (i % 64);
73                 temp_data &= 0x1;
74                 if (temp_data)
75                         hash_out ^= (u32)(rvu_npc_wide_extract(key, key_bit_len - 32, 32));
76
77                 rvu_npc_lshift_key(key, key_bit_len);
78         }
79
80         return hash_out;
81 }
82
83 u32 npc_field_hash_calc(u64 *ldata, struct npc_mcam_kex_hash *mkex_hash,
84                         u64 *secret_key, u8 intf, u8 hash_idx)
85 {
86         u64 hash_key[3];
87         u64 data_padded[2];
88         u32 field_hash;
89
90         hash_key[0] = secret_key[1] << 31;
91         hash_key[0] |= secret_key[2];
92         hash_key[1] = secret_key[1] >> 33;
93         hash_key[1] |= secret_key[0] << 31;
94         hash_key[2] = secret_key[0] >> 33;
95
96         data_padded[0] = mkex_hash->hash_mask[intf][hash_idx][0] & ldata[0];
97         data_padded[1] = mkex_hash->hash_mask[intf][hash_idx][1] & ldata[1];
98         field_hash = rvu_npc_toeplitz_hash(data_padded, hash_key, 128, 159);
99
100         field_hash &= mkex_hash->hash_ctrl[intf][hash_idx] >> 32;
101         field_hash |= mkex_hash->hash_ctrl[intf][hash_idx];
102         return field_hash;
103 }
104
105 static u64 npc_update_use_hash(int lt, int ld)
106 {
107         u64 cfg = 0;
108
109         switch (lt) {
110         case NPC_LT_LC_IP6:
111                 /* Update use_hash(bit-20) and bytesm1 (bit-16:19)
112                  * in KEX_LD_CFG
113                  */
114                 cfg = KEX_LD_CFG_USE_HASH(0x1, 0x03,
115                                           ld ? 0x8 : 0x18,
116                                           0x1, 0x0, 0x10);
117                 break;
118         }
119
120         return cfg;
121 }
122
123 static void npc_program_mkex_hash_rx(struct rvu *rvu, int blkaddr,
124                                      u8 intf)
125 {
126         struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
127         int lid, lt, ld, hash_cnt = 0;
128
129         if (is_npc_intf_tx(intf))
130                 return;
131
132         /* Program HASH_CFG */
133         for (lid = 0; lid < NPC_MAX_LID; lid++) {
134                 for (lt = 0; lt < NPC_MAX_LT; lt++) {
135                         for (ld = 0; ld < NPC_MAX_LD; ld++) {
136                                 if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
137                                         u64 cfg = npc_update_use_hash(lt, ld);
138
139                                         hash_cnt++;
140                                         if (hash_cnt == NPC_MAX_HASH)
141                                                 return;
142
143                                         /* Set updated KEX configuration */
144                                         SET_KEX_LD(intf, lid, lt, ld, cfg);
145                                         /* Set HASH configuration */
146                                         SET_KEX_LD_HASH(intf, ld,
147                                                         mkex_hash->hash[intf][ld]);
148                                         SET_KEX_LD_HASH_MASK(intf, ld, 0,
149                                                              mkex_hash->hash_mask[intf][ld][0]);
150                                         SET_KEX_LD_HASH_MASK(intf, ld, 1,
151                                                              mkex_hash->hash_mask[intf][ld][1]);
152                                         SET_KEX_LD_HASH_CTRL(intf, ld,
153                                                              mkex_hash->hash_ctrl[intf][ld]);
154                                 }
155                         }
156                 }
157         }
158 }
159
160 static void npc_program_mkex_hash_tx(struct rvu *rvu, int blkaddr,
161                                      u8 intf)
162 {
163         struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
164         int lid, lt, ld, hash_cnt = 0;
165
166         if (is_npc_intf_rx(intf))
167                 return;
168
169         /* Program HASH_CFG */
170         for (lid = 0; lid < NPC_MAX_LID; lid++) {
171                 for (lt = 0; lt < NPC_MAX_LT; lt++) {
172                         for (ld = 0; ld < NPC_MAX_LD; ld++)
173                                 if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
174                                         u64 cfg = npc_update_use_hash(lt, ld);
175
176                                         hash_cnt++;
177                                         if (hash_cnt == NPC_MAX_HASH)
178                                                 return;
179
180                                         /* Set updated KEX configuration */
181                                         SET_KEX_LD(intf, lid, lt, ld, cfg);
182                                         /* Set HASH configuration */
183                                         SET_KEX_LD_HASH(intf, ld,
184                                                         mkex_hash->hash[intf][ld]);
185                                         SET_KEX_LD_HASH_MASK(intf, ld, 0,
186                                                              mkex_hash->hash_mask[intf][ld][0]);
187                                         SET_KEX_LD_HASH_MASK(intf, ld, 1,
188                                                              mkex_hash->hash_mask[intf][ld][1]);
189                                         SET_KEX_LD_HASH_CTRL(intf, ld,
190                                                              mkex_hash->hash_ctrl[intf][ld]);
191                                         hash_cnt++;
192                                         if (hash_cnt == NPC_MAX_HASH)
193                                                 return;
194                                 }
195                 }
196         }
197 }
198
199 void npc_config_secret_key(struct rvu *rvu, int blkaddr)
200 {
201         struct hw_cap *hwcap = &rvu->hw->cap;
202         struct rvu_hwinfo *hw = rvu->hw;
203         u8 intf;
204
205         if (!hwcap->npc_hash_extract) {
206                 dev_info(rvu->dev, "HW does not support secret key configuration\n");
207                 return;
208         }
209
210         for (intf = 0; intf < hw->npc_intfs; intf++) {
211                 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY0(intf),
212                             RVU_NPC_HASH_SECRET_KEY0);
213                 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf),
214                             RVU_NPC_HASH_SECRET_KEY1);
215                 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf),
216                             RVU_NPC_HASH_SECRET_KEY2);
217         }
218 }
219
220 void npc_program_mkex_hash(struct rvu *rvu, int blkaddr)
221 {
222         struct hw_cap *hwcap = &rvu->hw->cap;
223         struct rvu_hwinfo *hw = rvu->hw;
224         u8 intf;
225
226         if (!hwcap->npc_hash_extract) {
227                 dev_dbg(rvu->dev, "Field hash extract feature is not supported\n");
228                 return;
229         }
230
231         for (intf = 0; intf < hw->npc_intfs; intf++) {
232                 npc_program_mkex_hash_rx(rvu, blkaddr, intf);
233                 npc_program_mkex_hash_tx(rvu, blkaddr, intf);
234         }
235 }
236
237 void npc_update_field_hash(struct rvu *rvu, u8 intf,
238                            struct mcam_entry *entry,
239                            int blkaddr,
240                            u64 features,
241                            struct flow_msg *pkt,
242                            struct flow_msg *mask,
243                            struct flow_msg *opkt,
244                            struct flow_msg *omask)
245 {
246         struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
247         struct npc_get_secret_key_req req;
248         struct npc_get_secret_key_rsp rsp;
249         u64 ldata[2], cfg;
250         u32 field_hash;
251         u8 hash_idx;
252
253         if (!rvu->hw->cap.npc_hash_extract) {
254                 dev_dbg(rvu->dev, "%s: Field hash extract feature is not supported\n", __func__);
255                 return;
256         }
257
258         req.intf = intf;
259         rvu_mbox_handler_npc_get_secret_key(rvu, &req, &rsp);
260
261         for (hash_idx = 0; hash_idx < NPC_MAX_HASH; hash_idx++) {
262                 cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_HASHX_CFG(intf, hash_idx));
263                 if ((cfg & BIT_ULL(11)) && (cfg & BIT_ULL(12))) {
264                         u8 lid = (cfg & GENMASK_ULL(10, 8)) >> 8;
265                         u8 ltype = (cfg & GENMASK_ULL(7, 4)) >> 4;
266                         u8 ltype_mask = cfg & GENMASK_ULL(3, 0);
267
268                         if (mkex_hash->lid_lt_ld_hash_en[intf][lid][ltype][hash_idx]) {
269                                 switch (ltype & ltype_mask) {
270                                 /* If hash extract enabled is supported for IPv6 then
271                                  * 128 bit IPv6 source and destination addressed
272                                  * is hashed to 32 bit value.
273                                  */
274                                 case NPC_LT_LC_IP6:
275                                         if (features & BIT_ULL(NPC_SIP_IPV6)) {
276                                                 u32 src_ip[IPV6_WORDS];
277
278                                                 be32_to_cpu_array(src_ip, pkt->ip6src, IPV6_WORDS);
279                                                 ldata[0] = (u64)src_ip[0] << 32 | src_ip[1];
280                                                 ldata[1] = (u64)src_ip[2] << 32 | src_ip[3];
281                                                 field_hash = npc_field_hash_calc(ldata,
282                                                                                  mkex_hash,
283                                                                                  rsp.secret_key,
284                                                                                  intf,
285                                                                                  hash_idx);
286                                                 npc_update_entry(rvu, NPC_SIP_IPV6, entry,
287                                                                  field_hash, 0, 32, 0, intf);
288                                                 memcpy(&opkt->ip6src, &pkt->ip6src,
289                                                        sizeof(pkt->ip6src));
290                                                 memcpy(&omask->ip6src, &mask->ip6src,
291                                                        sizeof(mask->ip6src));
292                                                 break;
293                                         }
294
295                                         if (features & BIT_ULL(NPC_DIP_IPV6)) {
296                                                 u32 dst_ip[IPV6_WORDS];
297
298                                                 be32_to_cpu_array(dst_ip, pkt->ip6dst, IPV6_WORDS);
299                                                 ldata[0] = (u64)dst_ip[0] << 32 | dst_ip[1];
300                                                 ldata[1] = (u64)dst_ip[2] << 32 | dst_ip[3];
301                                                 field_hash = npc_field_hash_calc(ldata,
302                                                                                  mkex_hash,
303                                                                                  rsp.secret_key,
304                                                                                  intf,
305                                                                                  hash_idx);
306                                                 npc_update_entry(rvu, NPC_DIP_IPV6, entry,
307                                                                  field_hash, 0, 32, 0, intf);
308                                                 memcpy(&opkt->ip6dst, &pkt->ip6dst,
309                                                        sizeof(pkt->ip6dst));
310                                                 memcpy(&omask->ip6dst, &mask->ip6dst,
311                                                        sizeof(mask->ip6dst));
312                                         }
313                                         break;
314                                 }
315                         }
316                 }
317         }
318 }
319
320 int rvu_mbox_handler_npc_get_secret_key(struct rvu *rvu,
321                                         struct npc_get_secret_key_req *req,
322                                         struct npc_get_secret_key_rsp *rsp)
323 {
324         u64 *secret_key = rsp->secret_key;
325         u8 intf = req->intf;
326         int blkaddr;
327
328         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
329         if (blkaddr < 0) {
330                 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
331                 return -EINVAL;
332         }
333
334         secret_key[0] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY0(intf));
335         secret_key[1] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf));
336         secret_key[2] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf));
337
338         return 0;
339 }
340
341 /**
342  *      rvu_npc_exact_mac2u64 - utility function to convert mac address to u64.
343  *      @macaddr: MAC address.
344  *      Returns mdata for exact match table.
345  */
346 static u64 rvu_npc_exact_mac2u64(u8 *mac_addr)
347 {
348         u64 mac = 0;
349         int index;
350
351         for (index = ETH_ALEN - 1; index >= 0; index--)
352                 mac |= ((u64)*mac_addr++) << (8 * index);
353
354         return mac;
355 }
356
357 /**
358  *      rvu_exact_prepare_mdata - Make mdata for mcam entry
359  *      @mac: MAC address
360  *      @chan: Channel number.
361  *      @ctype: Channel Type.
362  *      @mask: LDATA mask.
363  */
364 static u64 rvu_exact_prepare_mdata(u8 *mac, u16 chan, u16 ctype, u64 mask)
365 {
366         u64 ldata = rvu_npc_exact_mac2u64(mac);
367
368         /* Please note that mask is 48bit which excludes chan and ctype.
369          * Increase mask bits if we need to include them as well.
370          */
371         ldata |= ((u64)chan << 48);
372         ldata |= ((u64)ctype  << 60);
373         ldata &= mask;
374         ldata = ldata << 2;
375
376         return ldata;
377 }
378
379 /**
380  *      rvu_exact_calculate_hash - calculate hash index to mem table.
381  *      @rvu: resource virtualization unit.
382  *      @chan: Channel number
383  *      @ctype: Channel type.
384  *      @mac: MAC address
385  *      @mask: HASH mask.
386  *      @table_depth: Depth of table.
387  */
388 u32 rvu_exact_calculate_hash(struct rvu *rvu, u16 chan, u16 ctype, u8 *mac,
389                              u64 mask, u32 table_depth)
390 {
391         struct npc_exact_table *table = rvu->hw->table;
392         u64 hash_key[2];
393         u64 key_in[2];
394         u64 ldata;
395         u32 hash;
396
397         key_in[0] = RVU_NPC_HASH_SECRET_KEY0;
398         key_in[1] = RVU_NPC_HASH_SECRET_KEY2;
399
400         hash_key[0] = key_in[0] << 31;
401         hash_key[0] |= key_in[1];
402         hash_key[1] = key_in[0] >> 33;
403
404         ldata = rvu_exact_prepare_mdata(mac, chan, ctype, mask);
405
406         dev_dbg(rvu->dev, "%s: ldata=0x%llx hash_key0=0x%llx hash_key2=0x%llx\n", __func__,
407                 ldata, hash_key[1], hash_key[0]);
408         hash = rvu_npc_toeplitz_hash(&ldata, (u64 *)hash_key, 64, 95);
409
410         hash &= table->mem_table.hash_mask;
411         hash += table->mem_table.hash_offset;
412         dev_dbg(rvu->dev, "%s: hash=%x\n", __func__,  hash);
413
414         return hash;
415 }
416
417 /**
418  *      rvu_npc_exact_alloc_mem_table_entry - find free entry in 4 way table.
419  *      @rvu: resource virtualization unit.
420  *      @way: Indicate way to table.
421  *      @index: Hash index to 4 way table.
422  *
423  *      Searches 4 way table using hash index. Returns 0 on success.
424  */
425 static int rvu_npc_exact_alloc_mem_table_entry(struct rvu *rvu, u8 *way,
426                                                u32 *index, unsigned int hash)
427 {
428         struct npc_exact_table *table;
429         int depth, i;
430
431         table = rvu->hw->table;
432         depth = table->mem_table.depth;
433
434         /* Check all the 4 ways for a free slot. */
435         mutex_lock(&table->lock);
436         for (i = 0; i <  table->mem_table.ways; i++) {
437                 if (test_bit(hash + i * depth, table->mem_table.bmap))
438                         continue;
439
440                 set_bit(hash + i * depth, table->mem_table.bmap);
441                 mutex_unlock(&table->lock);
442
443                 dev_dbg(rvu->dev, "%s: mem table entry alloc success (way=%d index=%d)\n",
444                         __func__, i, hash);
445
446                 *way = i;
447                 *index = hash;
448                 return 0;
449         }
450         mutex_unlock(&table->lock);
451
452         dev_dbg(rvu->dev, "%s: No space in 4 way exact way, weight=%u\n", __func__,
453                 bitmap_weight(table->mem_table.bmap, table->mem_table.depth));
454         return -ENOSPC;
455 }
456
457 /**
458  *      rvu_npc_exact_free_id - Free seq id from bitmat.
459  *      @rvu: Resource virtualization unit.
460  *      @seq_id: Sequence identifier to be freed.
461  */
462 static void rvu_npc_exact_free_id(struct rvu *rvu, u32 seq_id)
463 {
464         struct npc_exact_table *table;
465
466         table = rvu->hw->table;
467         mutex_lock(&table->lock);
468         clear_bit(seq_id, table->id_bmap);
469         mutex_unlock(&table->lock);
470         dev_dbg(rvu->dev, "%s: freed id %d\n", __func__, seq_id);
471 }
472
473 /**
474  *      rvu_npc_exact_alloc_id - Alloc seq id from bitmap.
475  *      @rvu: Resource virtualization unit.
476  *      @seq_id: Sequence identifier.
477  */
478 static bool rvu_npc_exact_alloc_id(struct rvu *rvu, u32 *seq_id)
479 {
480         struct npc_exact_table *table;
481         u32 idx;
482
483         table = rvu->hw->table;
484
485         mutex_lock(&table->lock);
486         idx = find_first_zero_bit(table->id_bmap, table->tot_ids);
487         if (idx == table->tot_ids) {
488                 mutex_unlock(&table->lock);
489                 dev_err(rvu->dev, "%s: No space in id bitmap (%d)\n",
490                         __func__, bitmap_weight(table->id_bmap, table->tot_ids));
491
492                 return false;
493         }
494
495         /* Mark bit map to indicate that slot is used.*/
496         set_bit(idx, table->id_bmap);
497         mutex_unlock(&table->lock);
498
499         *seq_id = idx;
500         dev_dbg(rvu->dev, "%s: Allocated id (%d)\n", __func__, *seq_id);
501
502         return true;
503 }
504
505 /**
506  *      rvu_npc_exact_alloc_cam_table_entry - find free slot in fully associative table.
507  *      @rvu: resource virtualization unit.
508  *      @index: Index to exact CAM table.
509  */
510 static int rvu_npc_exact_alloc_cam_table_entry(struct rvu *rvu, int *index)
511 {
512         struct npc_exact_table *table;
513         u32 idx;
514
515         table = rvu->hw->table;
516
517         mutex_lock(&table->lock);
518         idx = find_first_zero_bit(table->cam_table.bmap, table->cam_table.depth);
519         if (idx == table->cam_table.depth) {
520                 mutex_unlock(&table->lock);
521                 dev_info(rvu->dev, "%s: No space in exact cam table, weight=%u\n", __func__,
522                          bitmap_weight(table->cam_table.bmap, table->cam_table.depth));
523                 return -ENOSPC;
524         }
525
526         /* Mark bit map to indicate that slot is used.*/
527         set_bit(idx, table->cam_table.bmap);
528         mutex_unlock(&table->lock);
529
530         *index = idx;
531         dev_dbg(rvu->dev, "%s: cam table entry alloc success (index=%d)\n",
532                 __func__, idx);
533         return 0;
534 }
535
536 /**
537  *      rvu_exact_prepare_table_entry - Data for exact match table entry.
538  *      @rvu: Resource virtualization unit.
539  *      @enable: Enable/Disable entry
540  *      @ctype: Software defined channel type. Currently set as 0.
541  *      @chan: Channel number.
542  *      @mac_addr: Destination mac address.
543  *      returns mdata for exact match table.
544  */
545 static u64 rvu_exact_prepare_table_entry(struct rvu *rvu, bool enable,
546                                          u8 ctype, u16 chan, u8 *mac_addr)
547
548 {
549         u64 ldata = rvu_npc_exact_mac2u64(mac_addr);
550
551         /* Enable or disable */
552         u64 mdata = FIELD_PREP(GENMASK_ULL(63, 63), !!enable);
553
554         /* Set Ctype */
555         mdata |= FIELD_PREP(GENMASK_ULL(61, 60), ctype);
556
557         /* Set chan */
558         mdata |= FIELD_PREP(GENMASK_ULL(59, 48), chan);
559
560         /* MAC address */
561         mdata |= FIELD_PREP(GENMASK_ULL(47, 0), ldata);
562
563         return mdata;
564 }
565
566 /**
567  *      rvu_exact_config_secret_key - Configure secret key.
568  *      Returns mdata for exact match table.
569  */
570 static void rvu_exact_config_secret_key(struct rvu *rvu)
571 {
572         int blkaddr;
573
574         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
575         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET0(NIX_INTF_RX),
576                     RVU_NPC_HASH_SECRET_KEY0);
577
578         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET1(NIX_INTF_RX),
579                     RVU_NPC_HASH_SECRET_KEY1);
580
581         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET2(NIX_INTF_RX),
582                     RVU_NPC_HASH_SECRET_KEY2);
583 }
584
585 /**
586  *      rvu_exact_config_search_key - Configure search key
587  *      Returns mdata for exact match table.
588  */
589 static void rvu_exact_config_search_key(struct rvu *rvu)
590 {
591         int blkaddr;
592         u64 reg_val;
593
594         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
595
596         /* HDR offset */
597         reg_val = FIELD_PREP(GENMASK_ULL(39, 32), 0);
598
599         /* BYTESM1, number of bytes - 1 */
600         reg_val |= FIELD_PREP(GENMASK_ULL(18, 16), ETH_ALEN - 1);
601
602         /* Enable LID and set LID to  NPC_LID_LA */
603         reg_val |= FIELD_PREP(GENMASK_ULL(11, 11), 1);
604         reg_val |= FIELD_PREP(GENMASK_ULL(10, 8),  NPC_LID_LA);
605
606         /* Clear layer type based extraction */
607
608         /* Disable LT_EN */
609         reg_val |= FIELD_PREP(GENMASK_ULL(12, 12), 0);
610
611         /* Set LTYPE_MATCH to 0 */
612         reg_val |= FIELD_PREP(GENMASK_ULL(7, 4), 0);
613
614         /* Set LTYPE_MASK to 0 */
615         reg_val |= FIELD_PREP(GENMASK_ULL(3, 0), 0);
616
617         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_CFG(NIX_INTF_RX), reg_val);
618 }
619
620 /**
621  *      rvu_exact_config_result_ctrl - Set exact table hash control
622  *      @rvu: Resource virtualization unit.
623  *      @depth: Depth of Exact match table.
624  *
625  *      Sets mask and offset for hash for mem table.
626  */
627 static void rvu_exact_config_result_ctrl(struct rvu *rvu, uint32_t depth)
628 {
629         int blkaddr;
630         u64 reg = 0;
631
632         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
633
634         /* Set mask. Note that depth is a power of 2 */
635         rvu->hw->table->mem_table.hash_mask = (depth - 1);
636         reg |= FIELD_PREP(GENMASK_ULL(42, 32), (depth - 1));
637
638         /* Set offset as 0 */
639         rvu->hw->table->mem_table.hash_offset = 0;
640         reg |= FIELD_PREP(GENMASK_ULL(10, 0), 0);
641
642         /* Set reg for RX */
643         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_RESULT_CTL(NIX_INTF_RX), reg);
644         /* Store hash mask and offset for s/w algorithm */
645 }
646
647 /**
648  *      rvu_exact_config_table_mask - Set exact table mask.
649  *      @rvu: Resource virtualization unit.
650  */
651 static void rvu_exact_config_table_mask(struct rvu *rvu)
652 {
653         int blkaddr;
654         u64 mask = 0;
655
656         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
657
658         /* Don't use Ctype */
659         mask |= FIELD_PREP(GENMASK_ULL(61, 60), 0);
660
661         /* Set chan */
662         mask |= GENMASK_ULL(59, 48);
663
664         /* Full ldata */
665         mask |= GENMASK_ULL(47, 0);
666
667         /* Store mask for s/w hash calcualtion */
668         rvu->hw->table->mem_table.mask = mask;
669
670         /* Set mask for RX.*/
671         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_MASK(NIX_INTF_RX), mask);
672 }
673
674 /**
675  *      rvu_npc_exact_get_max_entries - Get total number of entries in table.
676  *      @rvu: resource virtualization unit.
677  */
678 u32 rvu_npc_exact_get_max_entries(struct rvu *rvu)
679 {
680         struct npc_exact_table *table;
681
682         table = rvu->hw->table;
683         return table->tot_ids;
684 }
685
686 /**
687  *      rvu_npc_exact_has_match_table - Checks support for exact match.
688  *      @rvu: resource virtualization unit.
689  *
690  */
691 bool rvu_npc_exact_has_match_table(struct rvu *rvu)
692 {
693         return  rvu->hw->cap.npc_exact_match_enabled;
694 }
695
696 /**
697  *      __rvu_npc_exact_find_entry_by_seq_id - find entry by id
698  *      @rvu: resource virtualization unit.
699  *      @seq_id: Sequence identifier.
700  *
701  *      Caller should acquire the lock.
702  */
703 static struct npc_exact_table_entry *
704 __rvu_npc_exact_find_entry_by_seq_id(struct rvu *rvu, u32 seq_id)
705 {
706         struct npc_exact_table *table = rvu->hw->table;
707         struct npc_exact_table_entry *entry = NULL;
708         struct list_head *lhead;
709
710         lhead = &table->lhead_gbl;
711
712         /* traverse to find the matching entry */
713         list_for_each_entry(entry, lhead, glist) {
714                 if (entry->seq_id != seq_id)
715                         continue;
716
717                 return entry;
718         }
719
720         return NULL;
721 }
722
723 /**
724  *      rvu_npc_exact_add_to_list - Add entry to list
725  *      @rvu: resource virtualization unit.
726  *      @opc_type: OPCODE to select MEM/CAM table.
727  *      @ways: MEM table ways.
728  *      @index: Index in MEM/CAM table.
729  *      @cgx_id: CGX identifier.
730  *      @lamc_id: LMAC identifier.
731  *      @mac_addr: MAC address.
732  *      @chan: Channel number.
733  *      @ctype: Channel Type.
734  *      @seq_id: Sequence identifier
735  *      @cmd: True if function is called by ethtool cmd
736  *      @mcam_idx: NPC mcam index of DMAC entry in NPC mcam.
737  *      @pcifunc: pci function
738  */
739 static int rvu_npc_exact_add_to_list(struct rvu *rvu, enum npc_exact_opc_type opc_type, u8 ways,
740                                      u32 index, u8 cgx_id, u8 lmac_id, u8 *mac_addr, u16 chan,
741                                      u8 ctype, u32 *seq_id, bool cmd, u32 mcam_idx, u16 pcifunc)
742 {
743         struct npc_exact_table_entry *entry, *tmp, *iter;
744         struct npc_exact_table *table = rvu->hw->table;
745         struct list_head *lhead, *pprev;
746
747         WARN_ON(ways >= NPC_EXACT_TBL_MAX_WAYS);
748
749         if (!rvu_npc_exact_alloc_id(rvu, seq_id)) {
750                 dev_err(rvu->dev, "%s: Generate seq id failed\n", __func__);
751                 return -EFAULT;
752         }
753
754         entry = kmalloc(sizeof(*entry), GFP_KERNEL);
755         if (!entry) {
756                 rvu_npc_exact_free_id(rvu, *seq_id);
757                 dev_err(rvu->dev, "%s: Memory allocation failed\n", __func__);
758                 return -ENOMEM;
759         }
760
761         mutex_lock(&table->lock);
762         switch (opc_type) {
763         case NPC_EXACT_OPC_CAM:
764                 lhead = &table->lhead_cam_tbl_entry;
765                 table->cam_tbl_entry_cnt++;
766                 break;
767
768         case NPC_EXACT_OPC_MEM:
769                 lhead = &table->lhead_mem_tbl_entry[ways];
770                 table->mem_tbl_entry_cnt++;
771                 break;
772
773         default:
774                 mutex_unlock(&table->lock);
775                 kfree(entry);
776                 rvu_npc_exact_free_id(rvu, *seq_id);
777
778                 dev_err(rvu->dev, "%s: Unknown opc type%d\n", __func__, opc_type);
779                 return  -EINVAL;
780         }
781
782         /* Add to global list */
783         INIT_LIST_HEAD(&entry->glist);
784         list_add_tail(&entry->glist, &table->lhead_gbl);
785         INIT_LIST_HEAD(&entry->list);
786         entry->index = index;
787         entry->ways = ways;
788         entry->opc_type = opc_type;
789
790         entry->pcifunc = pcifunc;
791
792         ether_addr_copy(entry->mac, mac_addr);
793         entry->chan = chan;
794         entry->ctype = ctype;
795         entry->cgx_id = cgx_id;
796         entry->lmac_id = lmac_id;
797
798         entry->seq_id = *seq_id;
799
800         entry->mcam_idx = mcam_idx;
801         entry->cmd = cmd;
802
803         pprev = lhead;
804
805         /* Insert entry in ascending order of index */
806         list_for_each_entry_safe(iter, tmp, lhead, list) {
807                 if (index < iter->index)
808                         break;
809
810                 pprev = &iter->list;
811         }
812
813         /* Add to each table list */
814         list_add(&entry->list, pprev);
815         mutex_unlock(&table->lock);
816         return 0;
817 }
818
819 /**
820  *      rvu_npc_exact_mem_table_write - Wrapper for register write
821  *      @rvu: resource virtualization unit.
822  *      @blkaddr: Block address
823  *      @ways: ways for MEM table.
824  *      @index: Index in MEM
825  *      @mdata: Meta data to be written to register.
826  */
827 static void rvu_npc_exact_mem_table_write(struct rvu *rvu, int blkaddr, u8 ways,
828                                           u32 index, u64 mdata)
829 {
830         rvu_write64(rvu, blkaddr, NPC_AF_EXACT_MEM_ENTRY(ways, index), mdata);
831 }
832
833 /**
834  *      rvu_npc_exact_cam_table_write - Wrapper for register write
835  *      @rvu: resource virtualization unit.
836  *      @blkaddr: Block address
837  *      @index: Index in MEM
838  *      @mdata: Meta data to be written to register.
839  */
840 static void rvu_npc_exact_cam_table_write(struct rvu *rvu, int blkaddr,
841                                           u32 index, u64 mdata)
842 {
843         rvu_write64(rvu, blkaddr, NPC_AF_EXACT_CAM_ENTRY(index), mdata);
844 }
845
846 /**
847  *      rvu_npc_exact_dealloc_table_entry - dealloc table entry
848  *      @rvu: resource virtualization unit.
849  *      @opc_type: OPCODE for selection of table(MEM or CAM)
850  *      @ways: ways if opc_type is MEM table.
851  *      @index: Index of MEM or CAM table.
852  */
853 static int rvu_npc_exact_dealloc_table_entry(struct rvu *rvu, enum npc_exact_opc_type opc_type,
854                                              u8 ways, u32 index)
855 {
856         int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
857         struct npc_exact_table *table;
858         u8 null_dmac[6] = { 0 };
859         int depth;
860
861         /* Prepare entry with all fields set to zero */
862         u64 null_mdata = rvu_exact_prepare_table_entry(rvu, false, 0, 0, null_dmac);
863
864         table = rvu->hw->table;
865         depth = table->mem_table.depth;
866
867         mutex_lock(&table->lock);
868
869         switch (opc_type) {
870         case NPC_EXACT_OPC_CAM:
871
872                 /* Check whether entry is used already */
873                 if (!test_bit(index, table->cam_table.bmap)) {
874                         mutex_unlock(&table->lock);
875                         dev_err(rvu->dev, "%s: Trying to free an unused entry ways=%d index=%d\n",
876                                 __func__, ways, index);
877                         return -EINVAL;
878                 }
879
880                 rvu_npc_exact_cam_table_write(rvu, blkaddr, index, null_mdata);
881                 clear_bit(index, table->cam_table.bmap);
882                 break;
883
884         case NPC_EXACT_OPC_MEM:
885
886                 /* Check whether entry is used already */
887                 if (!test_bit(index + ways * depth, table->mem_table.bmap)) {
888                         mutex_unlock(&table->lock);
889                         dev_err(rvu->dev, "%s: Trying to free an unused entry index=%d\n",
890                                 __func__, index);
891                         return -EINVAL;
892                 }
893
894                 rvu_npc_exact_mem_table_write(rvu, blkaddr, ways, index, null_mdata);
895                 clear_bit(index + ways * depth, table->mem_table.bmap);
896                 break;
897
898         default:
899                 mutex_unlock(&table->lock);
900                 dev_err(rvu->dev, "%s: invalid opc type %d", __func__, opc_type);
901                 return -ENOSPC;
902         }
903
904         mutex_unlock(&table->lock);
905
906         dev_dbg(rvu->dev, "%s: Successfully deleted entry (index=%d, ways=%d opc_type=%d\n",
907                 __func__, index,  ways, opc_type);
908
909         return 0;
910 }
911
912 /**
913  *      rvu_npc_exact_alloc_table_entry - Allociate an entry
914  *      @rvu: resource virtualization unit.
915  *      @mac: MAC address.
916  *      @chan: Channel number.
917  *      @ctype: Channel Type.
918  *      @index: Index of MEM table or CAM table.
919  *      @ways: Ways. Only valid for MEM table.
920  *      @opc_type: OPCODE to select table (MEM or CAM)
921  *
922  *      Try allocating a slot from MEM table. If all 4 ways
923  *      slot are full for a hash index, check availability in
924  *      32-entry CAM table for allocation.
925  */
926 static int rvu_npc_exact_alloc_table_entry(struct rvu *rvu,  char *mac, u16 chan, u8 ctype,
927                                            u32 *index, u8 *ways, enum npc_exact_opc_type *opc_type)
928 {
929         struct npc_exact_table *table;
930         unsigned int hash;
931         int err;
932
933         table = rvu->hw->table;
934
935         /* Check in 4-ways mem entry for free slote */
936         hash =  rvu_exact_calculate_hash(rvu, chan, ctype, mac, table->mem_table.mask,
937                                          table->mem_table.depth);
938         err = rvu_npc_exact_alloc_mem_table_entry(rvu, ways, index, hash);
939         if (!err) {
940                 *opc_type = NPC_EXACT_OPC_MEM;
941                 dev_dbg(rvu->dev, "%s: inserted in 4 ways hash table ways=%d, index=%d\n",
942                         __func__, *ways, *index);
943                 return 0;
944         }
945
946         dev_dbg(rvu->dev, "%s: failed to insert in 4 ways hash table\n", __func__);
947
948         /* wayss is 0 for cam table */
949         *ways = 0;
950         err = rvu_npc_exact_alloc_cam_table_entry(rvu, index);
951         if (!err) {
952                 *opc_type = NPC_EXACT_OPC_CAM;
953                 dev_dbg(rvu->dev, "%s: inserted in fully associative hash table index=%u\n",
954                         __func__, *index);
955                 return 0;
956         }
957
958         dev_err(rvu->dev, "%s: failed to insert in fully associative hash table\n", __func__);
959         return -ENOSPC;
960 }
961
962 /**
963  *      rvu_npc_exact_del_table_entry_by_id - Delete and free table entry.
964  *      @rvu: resource virtualization unit.
965  *      @seq_id: Sequence identifier of the entry.
966  *
967  *      Deletes entry from linked lists and free up slot in HW MEM or CAM
968  *      table.
969  */
970 int rvu_npc_exact_del_table_entry_by_id(struct rvu *rvu, u32 seq_id)
971 {
972         struct npc_exact_table_entry *entry = NULL;
973         struct npc_exact_table *table;
974         int *cnt;
975
976         table = rvu->hw->table;
977
978         mutex_lock(&table->lock);
979
980         /* Lookup for entry which needs to be updated */
981         entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, seq_id);
982         if (!entry) {
983                 dev_dbg(rvu->dev, "%s: failed to find entry for id=0x%x\n", __func__, seq_id);
984                 mutex_unlock(&table->lock);
985                 return -ENODATA;
986         }
987
988         cnt = (entry->opc_type == NPC_EXACT_OPC_CAM) ? &table->cam_tbl_entry_cnt :
989                                 &table->mem_tbl_entry_cnt;
990
991         /* delete from lists */
992         list_del_init(&entry->list);
993         list_del_init(&entry->glist);
994
995         (*cnt)--;
996
997         mutex_unlock(&table->lock);
998
999         rvu_npc_exact_dealloc_table_entry(rvu, entry->opc_type, entry->ways, entry->index);
1000
1001         rvu_npc_exact_free_id(rvu, seq_id);
1002
1003         dev_dbg(rvu->dev, "%s: delete entry success for id=0x%x, mca=%pM\n",
1004                 __func__, seq_id, entry->mac);
1005         kfree(entry);
1006
1007         return 0;
1008 }
1009
1010 /**
1011  *      rvu_npc_exact_add_table_entry - Adds a table entry
1012  *      @rvu: resource virtualization unit.
1013  *      @cgx_id: cgx identifier.
1014  *      @lmac_id: lmac identifier.
1015  *      @mac: MAC address.
1016  *      @chan: Channel number.
1017  *      @ctype: Channel Type.
1018  *      @seq_id: Sequence number.
1019  *      @cmd: Whether it is invoked by ethtool cmd.
1020  *      @mcam_idx: NPC mcam index corresponding to MAC
1021  *      @pcifunc: PCI func.
1022  *
1023  *      Creates a new exact match table entry in either CAM or
1024  *      MEM table.
1025  */
1026 int rvu_npc_exact_add_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_id, u8 *mac,
1027                                   u16 chan, u8 ctype, u32 *seq_id, bool cmd,
1028                                   u32 mcam_idx, u16 pcifunc)
1029 {
1030         int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1031         enum npc_exact_opc_type opc_type;
1032         struct npc_exact_table *table;
1033         u32 index;
1034         u64 mdata;
1035         int err;
1036         u8 ways;
1037
1038         table = rvu->hw->table;
1039
1040         ctype = 0;
1041
1042         err = rvu_npc_exact_alloc_table_entry(rvu, mac, chan, ctype, &index, &ways, &opc_type);
1043         if (err) {
1044                 dev_err(rvu->dev, "%s: Could not alloc in exact match table\n", __func__);
1045                 return err;
1046         }
1047
1048         /* Write mdata to table */
1049         mdata = rvu_exact_prepare_table_entry(rvu, true, ctype, chan, mac);
1050
1051         if (opc_type == NPC_EXACT_OPC_CAM)
1052                 rvu_npc_exact_cam_table_write(rvu, blkaddr, index, mdata);
1053         else
1054                 rvu_npc_exact_mem_table_write(rvu, blkaddr, ways, index,  mdata);
1055
1056         /* Insert entry to linked list */
1057         err = rvu_npc_exact_add_to_list(rvu, opc_type, ways, index, cgx_id, lmac_id,
1058                                         mac, chan, ctype, seq_id, cmd, mcam_idx, pcifunc);
1059         if (err) {
1060                 rvu_npc_exact_dealloc_table_entry(rvu, opc_type, ways, index);
1061                 dev_err(rvu->dev, "%s: could not add to exact match table\n", __func__);
1062                 return err;
1063         }
1064
1065         dev_dbg(rvu->dev,
1066                 "%s: Successfully added entry (index=%d, dmac=%pM, ways=%d opc_type=%d\n",
1067                 __func__, index, mac, ways, opc_type);
1068
1069         return 0;
1070 }
1071
1072 /**
1073  *      rvu_npc_exact_update_table_entry - Update exact match table.
1074  *      @rvu: resource virtualization unit.
1075  *      @cgx_id: CGX identifier.
1076  *      @lamc_id: LMAC identifier.
1077  *      @old_mac: Existing MAC address entry.
1078  *      @new_mac: New MAC address entry.
1079  *      @seq_id: Sequence identifier of the entry.
1080  *
1081  *      Updates MAC address of an entry. If entry is in MEM table, new
1082  *      hash value may not match with old one.
1083  */
1084 int rvu_npc_exact_update_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_id,
1085                                      u8 *old_mac, u8 *new_mac, u32 *seq_id)
1086 {
1087         int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1088         struct npc_exact_table_entry *entry;
1089         struct npc_exact_table *table;
1090         u32 hash_index;
1091         u64 mdata;
1092
1093         table = rvu->hw->table;
1094
1095         mutex_lock(&table->lock);
1096
1097         /* Lookup for entry which needs to be updated */
1098         entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, *seq_id);
1099         if (!entry) {
1100                 mutex_unlock(&table->lock);
1101                 dev_dbg(rvu->dev,
1102                         "%s: failed to find entry for cgx_id=%d lmac_id=%d old_mac=%pM\n",
1103                         __func__, cgx_id, lmac_id, old_mac);
1104                 return -ENODATA;
1105         }
1106
1107         /* If entry is in mem table and new hash index is different than old
1108          * hash index, we cannot update the entry. Fail in these scenarios.
1109          */
1110         if (entry->opc_type == NPC_EXACT_OPC_MEM) {
1111                 hash_index =  rvu_exact_calculate_hash(rvu, entry->chan, entry->ctype,
1112                                                        new_mac, table->mem_table.mask,
1113                                                        table->mem_table.depth);
1114                 if (hash_index != entry->index) {
1115                         dev_err(rvu->dev,
1116                                 "%s: Update failed due to index mismatch(new=0x%x, old=%x)\n",
1117                                 __func__, hash_index, entry->index);
1118                         mutex_unlock(&table->lock);
1119                         return -EINVAL;
1120                 }
1121         }
1122
1123         mdata = rvu_exact_prepare_table_entry(rvu, true, entry->ctype, entry->chan, new_mac);
1124
1125         if (entry->opc_type == NPC_EXACT_OPC_MEM)
1126                 rvu_npc_exact_mem_table_write(rvu, blkaddr, entry->ways, entry->index, mdata);
1127         else
1128                 rvu_npc_exact_cam_table_write(rvu, blkaddr, entry->index, mdata);
1129
1130         /* Update entry fields */
1131         ether_addr_copy(entry->mac, new_mac);
1132         *seq_id = entry->seq_id;
1133
1134         dev_dbg(rvu->dev,
1135                 "%s: Successfully updated entry (index=%d, dmac=%pM, ways=%d opc_type=%d\n",
1136                 __func__, hash_index, entry->mac, entry->ways, entry->opc_type);
1137
1138         dev_dbg(rvu->dev, "%s: Successfully updated entry (old mac=%pM new_mac=%pM\n",
1139                 __func__, old_mac, new_mac);
1140
1141         mutex_unlock(&table->lock);
1142         return 0;
1143 }
1144
1145 /**
1146  *      rvu_npc_exact_can_disable_feature - Check if feature can be disabled.
1147  *      @rvu: resource virtualization unit.
1148  */
1149 bool rvu_npc_exact_can_disable_feature(struct rvu *rvu)
1150 {
1151         struct npc_exact_table *table = rvu->hw->table;
1152         bool empty;
1153
1154         if (!rvu->hw->cap.npc_exact_match_enabled)
1155                 return false;
1156
1157         mutex_lock(&table->lock);
1158         empty = list_empty(&table->lhead_gbl);
1159         mutex_unlock(&table->lock);
1160
1161         return empty;
1162 }
1163
1164 /**
1165  *      rvu_npc_exact_disable_feature - Disable feature.
1166  *      @rvu: resource virtualization unit.
1167  */
1168 void rvu_npc_exact_disable_feature(struct rvu *rvu)
1169 {
1170         rvu->hw->cap.npc_exact_match_enabled = false;
1171 }
1172
1173 /**
1174  *      rvu_npc_exact_reset - Delete and free all entry which match pcifunc.
1175  *      @rvu: resource virtualization unit.
1176  *      @pcifunc: PCI func to match.
1177  */
1178 void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc)
1179 {
1180         struct npc_exact_table *table = rvu->hw->table;
1181         struct npc_exact_table_entry *tmp, *iter;
1182         u32 seq_id;
1183
1184         mutex_lock(&table->lock);
1185         list_for_each_entry_safe(iter, tmp, &table->lhead_gbl, glist) {
1186                 if (pcifunc != iter->pcifunc)
1187                         continue;
1188
1189                 seq_id = iter->seq_id;
1190                 dev_dbg(rvu->dev, "%s: resetting pcifun=%d seq_id=%u\n", __func__,
1191                         pcifunc, seq_id);
1192
1193                 mutex_unlock(&table->lock);
1194                 rvu_npc_exact_del_table_entry_by_id(rvu, seq_id);
1195                 mutex_lock(&table->lock);
1196         }
1197         mutex_unlock(&table->lock);
1198 }
1199
1200 /**
1201  *      rvu_npc_exact_init - initialize exact match table
1202  *      @rvu: resource virtualization unit.
1203  *
1204  *      Initialize HW and SW resources to manage 4way-2K table and fully
1205  *      associative 32-entry mcam table.
1206  */
1207 int rvu_npc_exact_init(struct rvu *rvu)
1208 {
1209         struct npc_exact_table *table;
1210         u64 npc_const3;
1211         int table_size;
1212         int blkaddr;
1213         u64 cfg;
1214         int i;
1215
1216         /* Read NPC_AF_CONST3 and check for have exact
1217          * match functionality is present
1218          */
1219         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1220         if (blkaddr < 0) {
1221                 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
1222                 return -EINVAL;
1223         }
1224
1225         /* Check exact match feature is supported */
1226         npc_const3 = rvu_read64(rvu, blkaddr, NPC_AF_CONST3);
1227         if (!(npc_const3 & BIT_ULL(62))) {
1228                 dev_info(rvu->dev, "%s: No support for exact match support\n",
1229                          __func__);
1230                 return 0;
1231         }
1232
1233         /* Check if kex profile has enabled EXACT match nibble */
1234         cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX));
1235         if (!(cfg & NPC_EXACT_NIBBLE_HIT)) {
1236                 dev_info(rvu->dev, "%s: NPC exact match nibble not enabled in KEX profile\n",
1237                          __func__);
1238                 return 0;
1239         }
1240
1241         /* Set capability to true */
1242         rvu->hw->cap.npc_exact_match_enabled = true;
1243
1244         table = kmalloc(sizeof(*table), GFP_KERNEL);
1245         if (!table)
1246                 return -ENOMEM;
1247
1248         dev_dbg(rvu->dev, "%s: Memory allocation for table success\n", __func__);
1249         memset(table, 0, sizeof(*table));
1250         rvu->hw->table = table;
1251
1252         /* Read table size, ways and depth */
1253         table->mem_table.depth = FIELD_GET(GENMASK_ULL(31, 24), npc_const3);
1254         table->mem_table.ways = FIELD_GET(GENMASK_ULL(19, 16), npc_const3);
1255         table->cam_table.depth = FIELD_GET(GENMASK_ULL(15, 0), npc_const3);
1256
1257         dev_dbg(rvu->dev, "%s: NPC exact match 4way_2k table(ways=%d, depth=%d)\n",
1258                 __func__,  table->mem_table.ways, table->cam_table.depth);
1259
1260         /* Check if depth of table is not a sequre of 2
1261          * TODO: why _builtin_popcount() is not working ?
1262          */
1263         if ((table->mem_table.depth & (table->mem_table.depth - 1)) != 0) {
1264                 dev_err(rvu->dev,
1265                         "%s: NPC exact match 4way_2k table depth(%d) is not square of 2\n",
1266                         __func__,  table->mem_table.depth);
1267                 return -EINVAL;
1268         }
1269
1270         table_size = table->mem_table.depth * table->mem_table.ways;
1271
1272         /* Allocate bitmap for 4way 2K table */
1273         table->mem_table.bmap = devm_kcalloc(rvu->dev, BITS_TO_LONGS(table_size),
1274                                              sizeof(long), GFP_KERNEL);
1275         if (!table->mem_table.bmap)
1276                 return -ENOMEM;
1277
1278         dev_dbg(rvu->dev, "%s: Allocated bitmap for 4way 2K entry table\n", __func__);
1279
1280         /* Allocate bitmap for 32 entry mcam */
1281         table->cam_table.bmap = devm_kcalloc(rvu->dev, 1, sizeof(long), GFP_KERNEL);
1282
1283         if (!table->cam_table.bmap)
1284                 return -ENOMEM;
1285
1286         dev_dbg(rvu->dev, "%s: Allocated bitmap for 32 entry cam\n", __func__);
1287
1288         table->tot_ids = (table->mem_table.depth * table->mem_table.ways) + table->cam_table.depth;
1289         table->id_bmap = devm_kcalloc(rvu->dev, BITS_TO_LONGS(table->tot_ids),
1290                                       table->tot_ids, GFP_KERNEL);
1291
1292         if (!table->id_bmap)
1293                 return -ENOMEM;
1294
1295         dev_dbg(rvu->dev, "%s: Allocated bitmap for id map (total=%d)\n",
1296                 __func__, table->tot_ids);
1297
1298         /* Initialize list heads for npc_exact_table entries.
1299          * This entry is used by debugfs to show entries in
1300          * exact match table.
1301          */
1302         for (i = 0; i < NPC_EXACT_TBL_MAX_WAYS; i++)
1303                 INIT_LIST_HEAD(&table->lhead_mem_tbl_entry[i]);
1304
1305         INIT_LIST_HEAD(&table->lhead_cam_tbl_entry);
1306         INIT_LIST_HEAD(&table->lhead_gbl);
1307
1308         mutex_init(&table->lock);
1309
1310         rvu_exact_config_secret_key(rvu);
1311         rvu_exact_config_search_key(rvu);
1312
1313         rvu_exact_config_table_mask(rvu);
1314         rvu_exact_config_result_ctrl(rvu, table->mem_table.depth);
1315
1316         dev_info(rvu->dev, "initialized exact match table successfully\n");
1317         return 0;
1318 }