Merge tag 'powerpc-6.10-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[linux-block.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
15 #include "rvu_struct.h"
16 #include "rvu_reg.h"
17 #include "rvu.h"
18 #include "npc.h"
19 #include "cgx.h"
20 #include "rvu_npc_fs.h"
21 #include "rvu_npc_hash.h"
22
23 static u64 rvu_npc_wide_extract(const u64 input[], size_t start_bit,
24                                 size_t width_bits)
25 {
26         const u64 mask = ~(u64)((~(__uint128_t)0) << width_bits);
27         const size_t msb = start_bit + width_bits - 1;
28         const size_t lword = start_bit >> 6;
29         const size_t uword = msb >> 6;
30         size_t lbits;
31         u64 hi, lo;
32
33         if (lword == uword)
34                 return (input[lword] >> (start_bit & 63)) & mask;
35
36         lbits = 64 - (start_bit & 63);
37         hi = input[uword];
38         lo = (input[lword] >> (start_bit & 63));
39         return ((hi << lbits) | lo) & mask;
40 }
41
42 static void rvu_npc_lshift_key(u64 *key, size_t key_bit_len)
43 {
44         u64 prev_orig_word = 0;
45         u64 cur_orig_word = 0;
46         size_t extra = key_bit_len % 64;
47         size_t max_idx = key_bit_len / 64;
48         size_t i;
49
50         if (extra)
51                 max_idx++;
52
53         for (i = 0; i < max_idx; i++) {
54                 cur_orig_word = key[i];
55                 key[i] = key[i] << 1;
56                 key[i] |= ((prev_orig_word >> 63) & 0x1);
57                 prev_orig_word = cur_orig_word;
58         }
59 }
60
61 static u32 rvu_npc_toeplitz_hash(const u64 *data, u64 *key, size_t data_bit_len,
62                                  size_t key_bit_len)
63 {
64         u32 hash_out = 0;
65         u64 temp_data = 0;
66         int i;
67
68         for (i = data_bit_len - 1; i >= 0; i--) {
69                 temp_data = (data[i / 64]);
70                 temp_data = temp_data >> (i % 64);
71                 temp_data &= 0x1;
72                 if (temp_data)
73                         hash_out ^= (u32)(rvu_npc_wide_extract(key, key_bit_len - 32, 32));
74
75                 rvu_npc_lshift_key(key, key_bit_len);
76         }
77
78         return hash_out;
79 }
80
81 u32 npc_field_hash_calc(u64 *ldata, struct npc_get_field_hash_info_rsp rsp,
82                         u8 intf, u8 hash_idx)
83 {
84         u64 hash_key[3];
85         u64 data_padded[2];
86         u32 field_hash;
87
88         hash_key[0] = rsp.secret_key[1] << 31;
89         hash_key[0] |= rsp.secret_key[2];
90         hash_key[1] = rsp.secret_key[1] >> 33;
91         hash_key[1] |= rsp.secret_key[0] << 31;
92         hash_key[2] = rsp.secret_key[0] >> 33;
93
94         data_padded[0] = rsp.hash_mask[intf][hash_idx][0] & ldata[0];
95         data_padded[1] = rsp.hash_mask[intf][hash_idx][1] & ldata[1];
96         field_hash = rvu_npc_toeplitz_hash(data_padded, hash_key, 128, 159);
97
98         field_hash &= FIELD_GET(GENMASK(63, 32), rsp.hash_ctrl[intf][hash_idx]);
99         field_hash += FIELD_GET(GENMASK(31, 0), rsp.hash_ctrl[intf][hash_idx]);
100         return field_hash;
101 }
102
103 static u64 npc_update_use_hash(struct rvu *rvu, int blkaddr,
104                                u8 intf, int lid, int lt, int ld)
105 {
106         u8 hdr, key;
107         u64 cfg;
108
109         cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, lid, lt, ld));
110         hdr = FIELD_GET(NPC_HDR_OFFSET, cfg);
111         key = FIELD_GET(NPC_KEY_OFFSET, cfg);
112
113         /* Update use_hash(bit-20) to 'true' and
114          * bytesm1(bit-16:19) to '0x3' in KEX_LD_CFG
115          */
116         cfg = KEX_LD_CFG_USE_HASH(0x1, 0x03,
117                                   hdr, 0x1, 0x0, key);
118
119         return cfg;
120 }
121
122 static void npc_program_mkex_hash_rx(struct rvu *rvu, int blkaddr,
123                                      u8 intf)
124 {
125         struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
126         int lid, lt, ld, hash_cnt = 0;
127
128         if (is_npc_intf_tx(intf))
129                 return;
130
131         /* Program HASH_CFG */
132         for (lid = 0; lid < NPC_MAX_LID; lid++) {
133                 for (lt = 0; lt < NPC_MAX_LT; lt++) {
134                         for (ld = 0; ld < NPC_MAX_LD; ld++) {
135                                 if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
136                                         u64 cfg;
137
138                                         if (hash_cnt == NPC_MAX_HASH)
139                                                 return;
140
141                                         cfg = npc_update_use_hash(rvu, blkaddr,
142                                                                   intf, lid, lt, ld);
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                                         hash_cnt++;
156                                 }
157                         }
158                 }
159         }
160 }
161
162 static void npc_program_mkex_hash_tx(struct rvu *rvu, int blkaddr,
163                                      u8 intf)
164 {
165         struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
166         int lid, lt, ld, hash_cnt = 0;
167
168         if (is_npc_intf_rx(intf))
169                 return;
170
171         /* Program HASH_CFG */
172         for (lid = 0; lid < NPC_MAX_LID; lid++) {
173                 for (lt = 0; lt < NPC_MAX_LT; lt++) {
174                         for (ld = 0; ld < NPC_MAX_LD; ld++)
175                                 if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
176                                         u64 cfg;
177
178                                         if (hash_cnt == NPC_MAX_HASH)
179                                                 return;
180
181                                         cfg = npc_update_use_hash(rvu, blkaddr,
182                                                                   intf, lid, lt, ld);
183                                         /* Set updated KEX configuration */
184                                         SET_KEX_LD(intf, lid, lt, ld, cfg);
185                                         /* Set HASH configuration */
186                                         SET_KEX_LD_HASH(intf, ld,
187                                                         mkex_hash->hash[intf][ld]);
188                                         SET_KEX_LD_HASH_MASK(intf, ld, 0,
189                                                              mkex_hash->hash_mask[intf][ld][0]);
190                                         SET_KEX_LD_HASH_MASK(intf, ld, 1,
191                                                              mkex_hash->hash_mask[intf][ld][1]);
192                                         SET_KEX_LD_HASH_CTRL(intf, ld,
193                                                              mkex_hash->hash_ctrl[intf][ld]);
194                                         hash_cnt++;
195                                 }
196                 }
197         }
198 }
199
200 void npc_config_secret_key(struct rvu *rvu, int blkaddr)
201 {
202         struct hw_cap *hwcap = &rvu->hw->cap;
203         struct rvu_hwinfo *hw = rvu->hw;
204         u8 intf;
205
206         if (!hwcap->npc_hash_extract)
207                 return;
208
209         for (intf = 0; intf < hw->npc_intfs; intf++) {
210                 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY0(intf),
211                             RVU_NPC_HASH_SECRET_KEY0);
212                 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf),
213                             RVU_NPC_HASH_SECRET_KEY1);
214                 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf),
215                             RVU_NPC_HASH_SECRET_KEY2);
216         }
217 }
218
219 void npc_program_mkex_hash(struct rvu *rvu, int blkaddr)
220 {
221         struct npc_mcam_kex_hash *mh = rvu->kpu.mkex_hash;
222         struct hw_cap *hwcap = &rvu->hw->cap;
223         u8 intf, ld, hdr_offset, byte_len;
224         struct rvu_hwinfo *hw = rvu->hw;
225         u64 cfg;
226
227         /* Check if hardware supports hash extraction */
228         if (!hwcap->npc_hash_extract)
229                 return;
230
231         /* Check if IPv6 source/destination address
232          * should be hash enabled.
233          * Hashing reduces 128bit SIP/DIP fields to 32bit
234          * so that 224 bit X2 key can be used for IPv6 based filters as well,
235          * which in turn results in more number of MCAM entries available for
236          * use.
237          *
238          * Hashing of IPV6 SIP/DIP is enabled in below scenarios
239          * 1. If the silicon variant supports hashing feature
240          * 2. If the number of bytes of IP addr being extracted is 4 bytes ie
241          *    32bit. The assumption here is that if user wants 8bytes of LSB of
242          *    IP addr or full 16 bytes then his intention is not to use 32bit
243          *    hash.
244          */
245         for (intf = 0; intf < hw->npc_intfs; intf++) {
246                 for (ld = 0; ld < NPC_MAX_LD; ld++) {
247                         cfg = rvu_read64(rvu, blkaddr,
248                                          NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf,
249                                                                        NPC_LID_LC,
250                                                                        NPC_LT_LC_IP6,
251                                                                        ld));
252                         hdr_offset = FIELD_GET(NPC_HDR_OFFSET, cfg);
253                         byte_len = FIELD_GET(NPC_BYTESM, cfg);
254                         /* Hashing of IPv6 source/destination address should be
255                          * enabled if,
256                          * hdr_offset == 8 (offset of source IPv6 address) or
257                          * hdr_offset == 24 (offset of destination IPv6)
258                          * address) and the number of byte to be
259                          * extracted is 4. As per hardware configuration
260                          * byte_len should be == actual byte_len - 1.
261                          * Hence byte_len is checked against 3 but nor 4.
262                          */
263                         if ((hdr_offset == 8 || hdr_offset == 24) && byte_len == 3)
264                                 mh->lid_lt_ld_hash_en[intf][NPC_LID_LC][NPC_LT_LC_IP6][ld] = true;
265                 }
266         }
267
268         /* Update hash configuration if the field is hash enabled */
269         for (intf = 0; intf < hw->npc_intfs; intf++) {
270                 npc_program_mkex_hash_rx(rvu, blkaddr, intf);
271                 npc_program_mkex_hash_tx(rvu, blkaddr, intf);
272         }
273 }
274
275 void npc_update_field_hash(struct rvu *rvu, u8 intf,
276                            struct mcam_entry *entry,
277                            int blkaddr,
278                            u64 features,
279                            struct flow_msg *pkt,
280                            struct flow_msg *mask,
281                            struct flow_msg *opkt,
282                            struct flow_msg *omask)
283 {
284         struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
285         struct npc_get_field_hash_info_req req;
286         struct npc_get_field_hash_info_rsp rsp;
287         u64 ldata[2], cfg;
288         u32 field_hash;
289         u8 hash_idx;
290
291         if (!rvu->hw->cap.npc_hash_extract) {
292                 dev_dbg(rvu->dev, "%s: Field hash extract feature is not supported\n", __func__);
293                 return;
294         }
295
296         req.intf = intf;
297         rvu_mbox_handler_npc_get_field_hash_info(rvu, &req, &rsp);
298
299         for (hash_idx = 0; hash_idx < NPC_MAX_HASH; hash_idx++) {
300                 cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_HASHX_CFG(intf, hash_idx));
301                 if ((cfg & BIT_ULL(11)) && (cfg & BIT_ULL(12))) {
302                         u8 lid = (cfg & GENMASK_ULL(10, 8)) >> 8;
303                         u8 ltype = (cfg & GENMASK_ULL(7, 4)) >> 4;
304                         u8 ltype_mask = cfg & GENMASK_ULL(3, 0);
305
306                         if (mkex_hash->lid_lt_ld_hash_en[intf][lid][ltype][hash_idx]) {
307                                 switch (ltype & ltype_mask) {
308                                 /* If hash extract enabled is supported for IPv6 then
309                                  * 128 bit IPv6 source and destination addressed
310                                  * is hashed to 32 bit value.
311                                  */
312                                 case NPC_LT_LC_IP6:
313                                         /* ld[0] == hash_idx[0] == Source IPv6
314                                          * ld[1] == hash_idx[1] == Destination IPv6
315                                          */
316                                         if ((features & BIT_ULL(NPC_SIP_IPV6)) && !hash_idx) {
317                                                 u32 src_ip[IPV6_WORDS];
318
319                                                 be32_to_cpu_array(src_ip, pkt->ip6src, IPV6_WORDS);
320                                                 ldata[1] = (u64)src_ip[0] << 32 | src_ip[1];
321                                                 ldata[0] = (u64)src_ip[2] << 32 | src_ip[3];
322                                                 field_hash = npc_field_hash_calc(ldata,
323                                                                                  rsp,
324                                                                                  intf,
325                                                                                  hash_idx);
326                                                 npc_update_entry(rvu, NPC_SIP_IPV6, entry,
327                                                                  field_hash, 0,
328                                                                  GENMASK(31, 0), 0, intf);
329                                                 memcpy(&opkt->ip6src, &pkt->ip6src,
330                                                        sizeof(pkt->ip6src));
331                                                 memcpy(&omask->ip6src, &mask->ip6src,
332                                                        sizeof(mask->ip6src));
333                                         } else if ((features & BIT_ULL(NPC_DIP_IPV6)) && hash_idx) {
334                                                 u32 dst_ip[IPV6_WORDS];
335
336                                                 be32_to_cpu_array(dst_ip, pkt->ip6dst, IPV6_WORDS);
337                                                 ldata[1] = (u64)dst_ip[0] << 32 | dst_ip[1];
338                                                 ldata[0] = (u64)dst_ip[2] << 32 | dst_ip[3];
339                                                 field_hash = npc_field_hash_calc(ldata,
340                                                                                  rsp,
341                                                                                  intf,
342                                                                                  hash_idx);
343                                                 npc_update_entry(rvu, NPC_DIP_IPV6, entry,
344                                                                  field_hash, 0,
345                                                                  GENMASK(31, 0), 0, intf);
346                                                 memcpy(&opkt->ip6dst, &pkt->ip6dst,
347                                                        sizeof(pkt->ip6dst));
348                                                 memcpy(&omask->ip6dst, &mask->ip6dst,
349                                                        sizeof(mask->ip6dst));
350                                         }
351
352                                         break;
353                                 }
354                         }
355                 }
356         }
357 }
358
359 int rvu_mbox_handler_npc_get_field_hash_info(struct rvu *rvu,
360                                              struct npc_get_field_hash_info_req *req,
361                                              struct npc_get_field_hash_info_rsp *rsp)
362 {
363         u64 *secret_key = rsp->secret_key;
364         u8 intf = req->intf;
365         int i, j, blkaddr;
366
367         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
368         if (blkaddr < 0) {
369                 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
370                 return -EINVAL;
371         }
372
373         secret_key[0] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY0(intf));
374         secret_key[1] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf));
375         secret_key[2] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf));
376
377         for (i = 0; i < NPC_MAX_HASH; i++) {
378                 for (j = 0; j < NPC_MAX_HASH_MASK; j++) {
379                         rsp->hash_mask[NIX_INTF_RX][i][j] =
380                                 GET_KEX_LD_HASH_MASK(NIX_INTF_RX, i, j);
381                         rsp->hash_mask[NIX_INTF_TX][i][j] =
382                                 GET_KEX_LD_HASH_MASK(NIX_INTF_TX, i, j);
383                 }
384         }
385
386         for (i = 0; i < NPC_MAX_INTF; i++)
387                 for (j = 0; j < NPC_MAX_HASH; j++)
388                         rsp->hash_ctrl[i][j] = GET_KEX_LD_HASH_CTRL(i, j);
389
390         return 0;
391 }
392
393 /**
394  *      rvu_exact_prepare_mdata - Make mdata for mcam entry
395  *      @mac: MAC address
396  *      @chan: Channel number.
397  *      @ctype: Channel Type.
398  *      @mask: LDATA mask.
399  *      Return: Meta data
400  */
401 static u64 rvu_exact_prepare_mdata(u8 *mac, u16 chan, u16 ctype, u64 mask)
402 {
403         u64 ldata = ether_addr_to_u64(mac);
404
405         /* Please note that mask is 48bit which excludes chan and ctype.
406          * Increase mask bits if we need to include them as well.
407          */
408         ldata |= ((u64)chan << 48);
409         ldata |= ((u64)ctype  << 60);
410         ldata &= mask;
411         ldata = ldata << 2;
412
413         return ldata;
414 }
415
416 /**
417  *      rvu_exact_calculate_hash - calculate hash index to mem table.
418  *      @rvu: resource virtualization unit.
419  *      @chan: Channel number
420  *      @ctype: Channel type.
421  *      @mac: MAC address
422  *      @mask: HASH mask.
423  *      @table_depth: Depth of table.
424  *      Return: Hash value
425  */
426 static u32 rvu_exact_calculate_hash(struct rvu *rvu, u16 chan, u16 ctype, u8 *mac,
427                                     u64 mask, u32 table_depth)
428 {
429         struct npc_exact_table *table = rvu->hw->table;
430         u64 hash_key[2];
431         u64 key_in[2];
432         u64 ldata;
433         u32 hash;
434
435         key_in[0] = RVU_NPC_HASH_SECRET_KEY0;
436         key_in[1] = RVU_NPC_HASH_SECRET_KEY2;
437
438         hash_key[0] = key_in[0] << 31;
439         hash_key[0] |= key_in[1];
440         hash_key[1] = key_in[0] >> 33;
441
442         ldata = rvu_exact_prepare_mdata(mac, chan, ctype, mask);
443
444         dev_dbg(rvu->dev, "%s: ldata=0x%llx hash_key0=0x%llx hash_key2=0x%llx\n", __func__,
445                 ldata, hash_key[1], hash_key[0]);
446         hash = rvu_npc_toeplitz_hash(&ldata, (u64 *)hash_key, 64, 95);
447
448         hash &= table->mem_table.hash_mask;
449         hash += table->mem_table.hash_offset;
450         dev_dbg(rvu->dev, "%s: hash=%x\n", __func__,  hash);
451
452         return hash;
453 }
454
455 /**
456  *      rvu_npc_exact_alloc_mem_table_entry - find free entry in 4 way table.
457  *      @rvu: resource virtualization unit.
458  *      @way: Indicate way to table.
459  *      @index: Hash index to 4 way table.
460  *      @hash: Hash value.
461  *
462  *      Searches 4 way table using hash index. Returns 0 on success.
463  *      Return: 0 upon success.
464  */
465 static int rvu_npc_exact_alloc_mem_table_entry(struct rvu *rvu, u8 *way,
466                                                u32 *index, unsigned int hash)
467 {
468         struct npc_exact_table *table;
469         int depth, i;
470
471         table = rvu->hw->table;
472         depth = table->mem_table.depth;
473
474         /* Check all the 4 ways for a free slot. */
475         mutex_lock(&table->lock);
476         for (i = 0; i <  table->mem_table.ways; i++) {
477                 if (test_bit(hash + i * depth, table->mem_table.bmap))
478                         continue;
479
480                 set_bit(hash + i * depth, table->mem_table.bmap);
481                 mutex_unlock(&table->lock);
482
483                 dev_dbg(rvu->dev, "%s: mem table entry alloc success (way=%d index=%d)\n",
484                         __func__, i, hash);
485
486                 *way = i;
487                 *index = hash;
488                 return 0;
489         }
490         mutex_unlock(&table->lock);
491
492         dev_dbg(rvu->dev, "%s: No space in 4 way exact way, weight=%u\n", __func__,
493                 bitmap_weight(table->mem_table.bmap, table->mem_table.depth));
494         return -ENOSPC;
495 }
496
497 /**
498  *      rvu_npc_exact_free_id - Free seq id from bitmat.
499  *      @rvu: Resource virtualization unit.
500  *      @seq_id: Sequence identifier to be freed.
501  */
502 static void rvu_npc_exact_free_id(struct rvu *rvu, u32 seq_id)
503 {
504         struct npc_exact_table *table;
505
506         table = rvu->hw->table;
507         mutex_lock(&table->lock);
508         clear_bit(seq_id, table->id_bmap);
509         mutex_unlock(&table->lock);
510         dev_dbg(rvu->dev, "%s: freed id %d\n", __func__, seq_id);
511 }
512
513 /**
514  *      rvu_npc_exact_alloc_id - Alloc seq id from bitmap.
515  *      @rvu: Resource virtualization unit.
516  *      @seq_id: Sequence identifier.
517  *      Return: True or false.
518  */
519 static bool rvu_npc_exact_alloc_id(struct rvu *rvu, u32 *seq_id)
520 {
521         struct npc_exact_table *table;
522         u32 idx;
523
524         table = rvu->hw->table;
525
526         mutex_lock(&table->lock);
527         idx = find_first_zero_bit(table->id_bmap, table->tot_ids);
528         if (idx == table->tot_ids) {
529                 mutex_unlock(&table->lock);
530                 dev_err(rvu->dev, "%s: No space in id bitmap (%d)\n",
531                         __func__, table->tot_ids);
532
533                 return false;
534         }
535
536         /* Mark bit map to indicate that slot is used.*/
537         set_bit(idx, table->id_bmap);
538         mutex_unlock(&table->lock);
539
540         *seq_id = idx;
541         dev_dbg(rvu->dev, "%s: Allocated id (%d)\n", __func__, *seq_id);
542
543         return true;
544 }
545
546 /**
547  *      rvu_npc_exact_alloc_cam_table_entry - find free slot in fully associative table.
548  *      @rvu: resource virtualization unit.
549  *      @index: Index to exact CAM table.
550  *      Return: 0 upon success; else error number.
551  */
552 static int rvu_npc_exact_alloc_cam_table_entry(struct rvu *rvu, int *index)
553 {
554         struct npc_exact_table *table;
555         u32 idx;
556
557         table = rvu->hw->table;
558
559         mutex_lock(&table->lock);
560         idx = find_first_zero_bit(table->cam_table.bmap, table->cam_table.depth);
561         if (idx == table->cam_table.depth) {
562                 mutex_unlock(&table->lock);
563                 dev_info(rvu->dev, "%s: No space in exact cam table, weight=%u\n", __func__,
564                          bitmap_weight(table->cam_table.bmap, table->cam_table.depth));
565                 return -ENOSPC;
566         }
567
568         /* Mark bit map to indicate that slot is used.*/
569         set_bit(idx, table->cam_table.bmap);
570         mutex_unlock(&table->lock);
571
572         *index = idx;
573         dev_dbg(rvu->dev, "%s: cam table entry alloc success (index=%d)\n",
574                 __func__, idx);
575         return 0;
576 }
577
578 /**
579  *      rvu_exact_prepare_table_entry - Data for exact match table entry.
580  *      @rvu: Resource virtualization unit.
581  *      @enable: Enable/Disable entry
582  *      @ctype: Software defined channel type. Currently set as 0.
583  *      @chan: Channel number.
584  *      @mac_addr: Destination mac address.
585  *      Return: mdata for exact match table.
586  */
587 static u64 rvu_exact_prepare_table_entry(struct rvu *rvu, bool enable,
588                                          u8 ctype, u16 chan, u8 *mac_addr)
589
590 {
591         u64 ldata = ether_addr_to_u64(mac_addr);
592
593         /* Enable or disable */
594         u64 mdata = FIELD_PREP(GENMASK_ULL(63, 63), enable ? 1 : 0);
595
596         /* Set Ctype */
597         mdata |= FIELD_PREP(GENMASK_ULL(61, 60), ctype);
598
599         /* Set chan */
600         mdata |= FIELD_PREP(GENMASK_ULL(59, 48), chan);
601
602         /* MAC address */
603         mdata |= FIELD_PREP(GENMASK_ULL(47, 0), ldata);
604
605         return mdata;
606 }
607
608 /**
609  *      rvu_exact_config_secret_key - Configure secret key.
610  *      @rvu: Resource virtualization unit.
611  */
612 static void rvu_exact_config_secret_key(struct rvu *rvu)
613 {
614         int blkaddr;
615
616         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
617         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET0(NIX_INTF_RX),
618                     RVU_NPC_HASH_SECRET_KEY0);
619
620         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET1(NIX_INTF_RX),
621                     RVU_NPC_HASH_SECRET_KEY1);
622
623         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET2(NIX_INTF_RX),
624                     RVU_NPC_HASH_SECRET_KEY2);
625 }
626
627 /**
628  *      rvu_exact_config_search_key - Configure search key
629  *      @rvu: Resource virtualization unit.
630  */
631 static void rvu_exact_config_search_key(struct rvu *rvu)
632 {
633         int blkaddr;
634         u64 reg_val;
635
636         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
637
638         /* HDR offset */
639         reg_val = FIELD_PREP(GENMASK_ULL(39, 32), 0);
640
641         /* BYTESM1, number of bytes - 1 */
642         reg_val |= FIELD_PREP(GENMASK_ULL(18, 16), ETH_ALEN - 1);
643
644         /* Enable LID and set LID to  NPC_LID_LA */
645         reg_val |= FIELD_PREP(GENMASK_ULL(11, 11), 1);
646         reg_val |= FIELD_PREP(GENMASK_ULL(10, 8),  NPC_LID_LA);
647
648         /* Clear layer type based extraction */
649
650         /* Disable LT_EN */
651         reg_val |= FIELD_PREP(GENMASK_ULL(12, 12), 0);
652
653         /* Set LTYPE_MATCH to 0 */
654         reg_val |= FIELD_PREP(GENMASK_ULL(7, 4), 0);
655
656         /* Set LTYPE_MASK to 0 */
657         reg_val |= FIELD_PREP(GENMASK_ULL(3, 0), 0);
658
659         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_CFG(NIX_INTF_RX), reg_val);
660 }
661
662 /**
663  *      rvu_exact_config_result_ctrl - Set exact table hash control
664  *      @rvu: Resource virtualization unit.
665  *      @depth: Depth of Exact match table.
666  *
667  *      Sets mask and offset for hash for mem table.
668  */
669 static void rvu_exact_config_result_ctrl(struct rvu *rvu, uint32_t depth)
670 {
671         int blkaddr;
672         u64 reg = 0;
673
674         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
675
676         /* Set mask. Note that depth is a power of 2 */
677         rvu->hw->table->mem_table.hash_mask = (depth - 1);
678         reg |= FIELD_PREP(GENMASK_ULL(42, 32), (depth - 1));
679
680         /* Set offset as 0 */
681         rvu->hw->table->mem_table.hash_offset = 0;
682         reg |= FIELD_PREP(GENMASK_ULL(10, 0), 0);
683
684         /* Set reg for RX */
685         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_RESULT_CTL(NIX_INTF_RX), reg);
686         /* Store hash mask and offset for s/w algorithm */
687 }
688
689 /**
690  *      rvu_exact_config_table_mask - Set exact table mask.
691  *      @rvu: Resource virtualization unit.
692  */
693 static void rvu_exact_config_table_mask(struct rvu *rvu)
694 {
695         int blkaddr;
696         u64 mask = 0;
697
698         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
699
700         /* Don't use Ctype */
701         mask |= FIELD_PREP(GENMASK_ULL(61, 60), 0);
702
703         /* Set chan */
704         mask |= GENMASK_ULL(59, 48);
705
706         /* Full ldata */
707         mask |= GENMASK_ULL(47, 0);
708
709         /* Store mask for s/w hash calcualtion */
710         rvu->hw->table->mem_table.mask = mask;
711
712         /* Set mask for RX.*/
713         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_MASK(NIX_INTF_RX), mask);
714 }
715
716 /**
717  *      rvu_npc_exact_get_max_entries - Get total number of entries in table.
718  *      @rvu: resource virtualization unit.
719  *      Return: Maximum table entries possible.
720  */
721 u32 rvu_npc_exact_get_max_entries(struct rvu *rvu)
722 {
723         struct npc_exact_table *table;
724
725         table = rvu->hw->table;
726         return table->tot_ids;
727 }
728
729 /**
730  *      rvu_npc_exact_has_match_table - Checks support for exact match.
731  *      @rvu: resource virtualization unit.
732  *      Return: True if exact match table is supported/enabled.
733  */
734 bool rvu_npc_exact_has_match_table(struct rvu *rvu)
735 {
736         return  rvu->hw->cap.npc_exact_match_enabled;
737 }
738
739 /**
740  *      __rvu_npc_exact_find_entry_by_seq_id - find entry by id
741  *      @rvu: resource virtualization unit.
742  *      @seq_id: Sequence identifier.
743  *
744  *      Caller should acquire the lock.
745  *      Return: Pointer to table entry.
746  */
747 static struct npc_exact_table_entry *
748 __rvu_npc_exact_find_entry_by_seq_id(struct rvu *rvu, u32 seq_id)
749 {
750         struct npc_exact_table *table = rvu->hw->table;
751         struct npc_exact_table_entry *entry = NULL;
752         struct list_head *lhead;
753
754         lhead = &table->lhead_gbl;
755
756         /* traverse to find the matching entry */
757         list_for_each_entry(entry, lhead, glist) {
758                 if (entry->seq_id != seq_id)
759                         continue;
760
761                 return entry;
762         }
763
764         return NULL;
765 }
766
767 /**
768  *      rvu_npc_exact_add_to_list - Add entry to list
769  *      @rvu: resource virtualization unit.
770  *      @opc_type: OPCODE to select MEM/CAM table.
771  *      @ways: MEM table ways.
772  *      @index: Index in MEM/CAM table.
773  *      @cgx_id: CGX identifier.
774  *      @lmac_id: LMAC identifier.
775  *      @mac_addr: MAC address.
776  *      @chan: Channel number.
777  *      @ctype: Channel Type.
778  *      @seq_id: Sequence identifier
779  *      @cmd: True if function is called by ethtool cmd
780  *      @mcam_idx: NPC mcam index of DMAC entry in NPC mcam.
781  *      @pcifunc: pci function
782  *      Return: 0 upon success.
783  */
784 static int rvu_npc_exact_add_to_list(struct rvu *rvu, enum npc_exact_opc_type opc_type, u8 ways,
785                                      u32 index, u8 cgx_id, u8 lmac_id, u8 *mac_addr, u16 chan,
786                                      u8 ctype, u32 *seq_id, bool cmd, u32 mcam_idx, u16 pcifunc)
787 {
788         struct npc_exact_table_entry *entry, *tmp, *iter;
789         struct npc_exact_table *table = rvu->hw->table;
790         struct list_head *lhead, *pprev;
791
792         WARN_ON(ways >= NPC_EXACT_TBL_MAX_WAYS);
793
794         if (!rvu_npc_exact_alloc_id(rvu, seq_id)) {
795                 dev_err(rvu->dev, "%s: Generate seq id failed\n", __func__);
796                 return -EFAULT;
797         }
798
799         entry = kmalloc(sizeof(*entry), GFP_KERNEL);
800         if (!entry) {
801                 rvu_npc_exact_free_id(rvu, *seq_id);
802                 dev_err(rvu->dev, "%s: Memory allocation failed\n", __func__);
803                 return -ENOMEM;
804         }
805
806         mutex_lock(&table->lock);
807         switch (opc_type) {
808         case NPC_EXACT_OPC_CAM:
809                 lhead = &table->lhead_cam_tbl_entry;
810                 table->cam_tbl_entry_cnt++;
811                 break;
812
813         case NPC_EXACT_OPC_MEM:
814                 lhead = &table->lhead_mem_tbl_entry[ways];
815                 table->mem_tbl_entry_cnt++;
816                 break;
817
818         default:
819                 mutex_unlock(&table->lock);
820                 kfree(entry);
821                 rvu_npc_exact_free_id(rvu, *seq_id);
822
823                 dev_err(rvu->dev, "%s: Unknown opc type%d\n", __func__, opc_type);
824                 return  -EINVAL;
825         }
826
827         /* Add to global list */
828         INIT_LIST_HEAD(&entry->glist);
829         list_add_tail(&entry->glist, &table->lhead_gbl);
830         INIT_LIST_HEAD(&entry->list);
831         entry->index = index;
832         entry->ways = ways;
833         entry->opc_type = opc_type;
834
835         entry->pcifunc = pcifunc;
836
837         ether_addr_copy(entry->mac, mac_addr);
838         entry->chan = chan;
839         entry->ctype = ctype;
840         entry->cgx_id = cgx_id;
841         entry->lmac_id = lmac_id;
842
843         entry->seq_id = *seq_id;
844
845         entry->mcam_idx = mcam_idx;
846         entry->cmd = cmd;
847
848         pprev = lhead;
849
850         /* Insert entry in ascending order of index */
851         list_for_each_entry_safe(iter, tmp, lhead, list) {
852                 if (index < iter->index)
853                         break;
854
855                 pprev = &iter->list;
856         }
857
858         /* Add to each table list */
859         list_add(&entry->list, pprev);
860         mutex_unlock(&table->lock);
861         return 0;
862 }
863
864 /**
865  *      rvu_npc_exact_mem_table_write - Wrapper for register write
866  *      @rvu: resource virtualization unit.
867  *      @blkaddr: Block address
868  *      @ways: ways for MEM table.
869  *      @index: Index in MEM
870  *      @mdata: Meta data to be written to register.
871  */
872 static void rvu_npc_exact_mem_table_write(struct rvu *rvu, int blkaddr, u8 ways,
873                                           u32 index, u64 mdata)
874 {
875         rvu_write64(rvu, blkaddr, NPC_AF_EXACT_MEM_ENTRY(ways, index), mdata);
876 }
877
878 /**
879  *      rvu_npc_exact_cam_table_write - Wrapper for register write
880  *      @rvu: resource virtualization unit.
881  *      @blkaddr: Block address
882  *      @index: Index in MEM
883  *      @mdata: Meta data to be written to register.
884  */
885 static void rvu_npc_exact_cam_table_write(struct rvu *rvu, int blkaddr,
886                                           u32 index, u64 mdata)
887 {
888         rvu_write64(rvu, blkaddr, NPC_AF_EXACT_CAM_ENTRY(index), mdata);
889 }
890
891 /**
892  *      rvu_npc_exact_dealloc_table_entry - dealloc table entry
893  *      @rvu: resource virtualization unit.
894  *      @opc_type: OPCODE for selection of table(MEM or CAM)
895  *      @ways: ways if opc_type is MEM table.
896  *      @index: Index of MEM or CAM table.
897  *      Return: 0 upon success.
898  */
899 static int rvu_npc_exact_dealloc_table_entry(struct rvu *rvu, enum npc_exact_opc_type opc_type,
900                                              u8 ways, u32 index)
901 {
902         int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
903         struct npc_exact_table *table;
904         u8 null_dmac[6] = { 0 };
905         int depth;
906
907         /* Prepare entry with all fields set to zero */
908         u64 null_mdata = rvu_exact_prepare_table_entry(rvu, false, 0, 0, null_dmac);
909
910         table = rvu->hw->table;
911         depth = table->mem_table.depth;
912
913         mutex_lock(&table->lock);
914
915         switch (opc_type) {
916         case NPC_EXACT_OPC_CAM:
917
918                 /* Check whether entry is used already */
919                 if (!test_bit(index, table->cam_table.bmap)) {
920                         mutex_unlock(&table->lock);
921                         dev_err(rvu->dev, "%s: Trying to free an unused entry ways=%d index=%d\n",
922                                 __func__, ways, index);
923                         return -EINVAL;
924                 }
925
926                 rvu_npc_exact_cam_table_write(rvu, blkaddr, index, null_mdata);
927                 clear_bit(index, table->cam_table.bmap);
928                 break;
929
930         case NPC_EXACT_OPC_MEM:
931
932                 /* Check whether entry is used already */
933                 if (!test_bit(index + ways * depth, table->mem_table.bmap)) {
934                         mutex_unlock(&table->lock);
935                         dev_err(rvu->dev, "%s: Trying to free an unused entry index=%d\n",
936                                 __func__, index);
937                         return -EINVAL;
938                 }
939
940                 rvu_npc_exact_mem_table_write(rvu, blkaddr, ways, index, null_mdata);
941                 clear_bit(index + ways * depth, table->mem_table.bmap);
942                 break;
943
944         default:
945                 mutex_unlock(&table->lock);
946                 dev_err(rvu->dev, "%s: invalid opc type %d", __func__, opc_type);
947                 return -ENOSPC;
948         }
949
950         mutex_unlock(&table->lock);
951
952         dev_dbg(rvu->dev, "%s: Successfully deleted entry (index=%d, ways=%d opc_type=%d\n",
953                 __func__, index,  ways, opc_type);
954
955         return 0;
956 }
957
958 /**
959  *      rvu_npc_exact_alloc_table_entry - Allociate an entry
960  *      @rvu: resource virtualization unit.
961  *      @mac: MAC address.
962  *      @chan: Channel number.
963  *      @ctype: Channel Type.
964  *      @index: Index of MEM table or CAM table.
965  *      @ways: Ways. Only valid for MEM table.
966  *      @opc_type: OPCODE to select table (MEM or CAM)
967  *
968  *      Try allocating a slot from MEM table. If all 4 ways
969  *      slot are full for a hash index, check availability in
970  *      32-entry CAM table for allocation.
971  *      Return: 0 upon success.
972  */
973 static int rvu_npc_exact_alloc_table_entry(struct rvu *rvu,  char *mac, u16 chan, u8 ctype,
974                                            u32 *index, u8 *ways, enum npc_exact_opc_type *opc_type)
975 {
976         struct npc_exact_table *table;
977         unsigned int hash;
978         int err;
979
980         table = rvu->hw->table;
981
982         /* Check in 4-ways mem entry for free slote */
983         hash =  rvu_exact_calculate_hash(rvu, chan, ctype, mac, table->mem_table.mask,
984                                          table->mem_table.depth);
985         err = rvu_npc_exact_alloc_mem_table_entry(rvu, ways, index, hash);
986         if (!err) {
987                 *opc_type = NPC_EXACT_OPC_MEM;
988                 dev_dbg(rvu->dev, "%s: inserted in 4 ways hash table ways=%d, index=%d\n",
989                         __func__, *ways, *index);
990                 return 0;
991         }
992
993         dev_dbg(rvu->dev, "%s: failed to insert in 4 ways hash table\n", __func__);
994
995         /* wayss is 0 for cam table */
996         *ways = 0;
997         err = rvu_npc_exact_alloc_cam_table_entry(rvu, index);
998         if (!err) {
999                 *opc_type = NPC_EXACT_OPC_CAM;
1000                 dev_dbg(rvu->dev, "%s: inserted in fully associative hash table index=%u\n",
1001                         __func__, *index);
1002                 return 0;
1003         }
1004
1005         dev_err(rvu->dev, "%s: failed to insert in fully associative hash table\n", __func__);
1006         return -ENOSPC;
1007 }
1008
1009 /**
1010  *      rvu_npc_exact_save_drop_rule_chan_and_mask - Save drop rules info in data base.
1011  *      @rvu: resource virtualization unit.
1012  *      @drop_mcam_idx: Drop rule index in NPC mcam.
1013  *      @chan_val: Channel value.
1014  *      @chan_mask: Channel Mask.
1015  *      @pcifunc: pcifunc of interface.
1016  *      Return: True upon success.
1017  */
1018 static bool rvu_npc_exact_save_drop_rule_chan_and_mask(struct rvu *rvu, int drop_mcam_idx,
1019                                                        u64 chan_val, u64 chan_mask, u16 pcifunc)
1020 {
1021         struct npc_exact_table *table;
1022         int i;
1023
1024         table = rvu->hw->table;
1025
1026         for (i = 0; i < NPC_MCAM_DROP_RULE_MAX; i++) {
1027                 if (!table->drop_rule_map[i].valid)
1028                         break;
1029
1030                 if (table->drop_rule_map[i].chan_val != (u16)chan_val)
1031                         continue;
1032
1033                 if (table->drop_rule_map[i].chan_mask != (u16)chan_mask)
1034                         continue;
1035
1036                 return false;
1037         }
1038
1039         if (i == NPC_MCAM_DROP_RULE_MAX)
1040                 return false;
1041
1042         table->drop_rule_map[i].drop_rule_idx = drop_mcam_idx;
1043         table->drop_rule_map[i].chan_val = (u16)chan_val;
1044         table->drop_rule_map[i].chan_mask = (u16)chan_mask;
1045         table->drop_rule_map[i].pcifunc = pcifunc;
1046         table->drop_rule_map[i].valid = true;
1047         return true;
1048 }
1049
1050 /**
1051  *      rvu_npc_exact_calc_drop_rule_chan_and_mask - Calculate Channel number and mask.
1052  *      @rvu: resource virtualization unit.
1053  *      @intf_type: Interface type (SDK, LBK or CGX)
1054  *      @cgx_id: CGX identifier.
1055  *      @lmac_id: LAMC identifier.
1056  *      @val: Channel number.
1057  *      @mask: Channel mask.
1058  *      Return: True upon success.
1059  */
1060 static bool rvu_npc_exact_calc_drop_rule_chan_and_mask(struct rvu *rvu, u8 intf_type,
1061                                                        u8 cgx_id, u8 lmac_id,
1062                                                        u64 *val, u64 *mask)
1063 {
1064         u16 chan_val, chan_mask;
1065
1066         /* No support for SDP and LBK */
1067         if (intf_type != NIX_INTF_TYPE_CGX)
1068                 return false;
1069
1070         chan_val = rvu_nix_chan_cgx(rvu, cgx_id, lmac_id, 0);
1071         chan_mask = 0xfff;
1072
1073         if (val)
1074                 *val = chan_val;
1075
1076         if (mask)
1077                 *mask = chan_mask;
1078
1079         return true;
1080 }
1081
1082 /**
1083  *      rvu_npc_exact_drop_rule_to_pcifunc - Retrieve pcifunc
1084  *      @rvu: resource virtualization unit.
1085  *      @drop_rule_idx: Drop rule index in NPC mcam.
1086  *
1087  *      Debugfs (exact_drop_cnt) entry displays pcifunc for interface
1088  *      by retrieving the pcifunc value from data base.
1089  *      Return: Drop rule index.
1090  */
1091 u16 rvu_npc_exact_drop_rule_to_pcifunc(struct rvu *rvu, u32 drop_rule_idx)
1092 {
1093         struct npc_exact_table *table;
1094         int i;
1095
1096         table = rvu->hw->table;
1097
1098         for (i = 0; i < NPC_MCAM_DROP_RULE_MAX; i++) {
1099                 if (!table->drop_rule_map[i].valid)
1100                         break;
1101
1102                 if (table->drop_rule_map[i].drop_rule_idx != drop_rule_idx)
1103                         continue;
1104
1105                 return table->drop_rule_map[i].pcifunc;
1106         }
1107
1108         dev_err(rvu->dev, "%s: drop mcam rule index (%d) >= NPC_MCAM_DROP_RULE_MAX\n",
1109                 __func__, drop_rule_idx);
1110         return -1;
1111 }
1112
1113 /**
1114  *      rvu_npc_exact_get_drop_rule_info - Get drop rule information.
1115  *      @rvu: resource virtualization unit.
1116  *      @intf_type: Interface type (CGX, SDP or LBK)
1117  *      @cgx_id: CGX identifier.
1118  *      @lmac_id: LMAC identifier.
1119  *      @drop_mcam_idx: NPC mcam drop rule index.
1120  *      @val: Channel value.
1121  *      @mask: Channel mask.
1122  *      @pcifunc: pcifunc of interface corresponding to the drop rule.
1123  *      Return: True upon success.
1124  */
1125 static bool rvu_npc_exact_get_drop_rule_info(struct rvu *rvu, u8 intf_type, u8 cgx_id,
1126                                              u8 lmac_id, u32 *drop_mcam_idx, u64 *val,
1127                                              u64 *mask, u16 *pcifunc)
1128 {
1129         struct npc_exact_table *table;
1130         u64 chan_val, chan_mask;
1131         bool rc;
1132         int i;
1133
1134         table = rvu->hw->table;
1135
1136         if (intf_type != NIX_INTF_TYPE_CGX) {
1137                 dev_err(rvu->dev, "%s: No drop rule for LBK/SDP mode\n", __func__);
1138                 return false;
1139         }
1140
1141         rc = rvu_npc_exact_calc_drop_rule_chan_and_mask(rvu, intf_type, cgx_id,
1142                                                         lmac_id, &chan_val, &chan_mask);
1143         if (!rc)
1144                 return false;
1145
1146         for (i = 0; i < NPC_MCAM_DROP_RULE_MAX; i++) {
1147                 if (!table->drop_rule_map[i].valid)
1148                         break;
1149
1150                 if (table->drop_rule_map[i].chan_val != (u16)chan_val)
1151                         continue;
1152
1153                 if (val)
1154                         *val = table->drop_rule_map[i].chan_val;
1155                 if (mask)
1156                         *mask = table->drop_rule_map[i].chan_mask;
1157                 if (pcifunc)
1158                         *pcifunc = table->drop_rule_map[i].pcifunc;
1159
1160                 *drop_mcam_idx = i;
1161                 return true;
1162         }
1163
1164         if (i == NPC_MCAM_DROP_RULE_MAX) {
1165                 dev_err(rvu->dev, "%s: drop mcam rule index (%d) >= NPC_MCAM_DROP_RULE_MAX\n",
1166                         __func__, *drop_mcam_idx);
1167                 return false;
1168         }
1169
1170         dev_err(rvu->dev, "%s: Could not retrieve for cgx=%d, lmac=%d\n",
1171                 __func__, cgx_id, lmac_id);
1172         return false;
1173 }
1174
1175 /**
1176  *      __rvu_npc_exact_cmd_rules_cnt_update - Update number dmac rules against a drop rule.
1177  *      @rvu: resource virtualization unit.
1178  *      @drop_mcam_idx: NPC mcam drop rule index.
1179  *      @val: +1 or -1.
1180  *      @enable_or_disable_cam: If no exact match rules against a drop rule, disable it.
1181  *
1182  *      when first exact match entry against a drop rule is added, enable_or_disable_cam
1183  *      is set to true. When last exact match entry against a drop rule is deleted,
1184  *      enable_or_disable_cam is set to true.
1185  *      Return: Number of rules
1186  */
1187 static u16 __rvu_npc_exact_cmd_rules_cnt_update(struct rvu *rvu, int drop_mcam_idx,
1188                                                 int val, bool *enable_or_disable_cam)
1189 {
1190         struct npc_exact_table *table;
1191         u16 *cnt, old_cnt;
1192         bool promisc;
1193
1194         table = rvu->hw->table;
1195         promisc = table->promisc_mode[drop_mcam_idx];
1196
1197         cnt = &table->cnt_cmd_rules[drop_mcam_idx];
1198         old_cnt = *cnt;
1199
1200         *cnt += val;
1201
1202         if (!enable_or_disable_cam)
1203                 goto done;
1204
1205         *enable_or_disable_cam = false;
1206
1207         if (promisc)
1208                 goto done;
1209
1210         /* If all rules are deleted and not already in promisc mode;
1211          * disable cam
1212          */
1213         if (!*cnt && val < 0) {
1214                 *enable_or_disable_cam = true;
1215                 goto done;
1216         }
1217
1218         /* If rule got added and not already in promisc mode; enable cam */
1219         if (!old_cnt && val > 0) {
1220                 *enable_or_disable_cam = true;
1221                 goto done;
1222         }
1223
1224 done:
1225         return *cnt;
1226 }
1227
1228 /**
1229  *      rvu_npc_exact_del_table_entry_by_id - Delete and free table entry.
1230  *      @rvu: resource virtualization unit.
1231  *      @seq_id: Sequence identifier of the entry.
1232  *
1233  *      Deletes entry from linked lists and free up slot in HW MEM or CAM
1234  *      table.
1235  *      Return: 0 upon success.
1236  */
1237 static int rvu_npc_exact_del_table_entry_by_id(struct rvu *rvu, u32 seq_id)
1238 {
1239         struct npc_exact_table_entry *entry = NULL;
1240         struct npc_exact_table *table;
1241         bool disable_cam = false;
1242         u32 drop_mcam_idx = -1;
1243         int *cnt;
1244         bool rc;
1245
1246         table = rvu->hw->table;
1247
1248         mutex_lock(&table->lock);
1249
1250         /* Lookup for entry which needs to be updated */
1251         entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, seq_id);
1252         if (!entry) {
1253                 dev_dbg(rvu->dev, "%s: failed to find entry for id=%d\n", __func__, seq_id);
1254                 mutex_unlock(&table->lock);
1255                 return -ENODATA;
1256         }
1257
1258         cnt = (entry->opc_type == NPC_EXACT_OPC_CAM) ? &table->cam_tbl_entry_cnt :
1259                                 &table->mem_tbl_entry_cnt;
1260
1261         /* delete from lists */
1262         list_del_init(&entry->list);
1263         list_del_init(&entry->glist);
1264
1265         (*cnt)--;
1266
1267         rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, entry->cgx_id,
1268                                               entry->lmac_id, &drop_mcam_idx, NULL, NULL, NULL);
1269         if (!rc) {
1270                 dev_dbg(rvu->dev, "%s: failed to retrieve drop info for id=0x%x\n",
1271                         __func__, seq_id);
1272                 mutex_unlock(&table->lock);
1273                 return -ENODATA;
1274         }
1275
1276         if (entry->cmd)
1277                 __rvu_npc_exact_cmd_rules_cnt_update(rvu, drop_mcam_idx, -1, &disable_cam);
1278
1279         /* No dmac filter rules; disable drop on hit rule */
1280         if (disable_cam) {
1281                 rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, false);
1282                 dev_dbg(rvu->dev, "%s: Disabling mcam idx %d\n",
1283                         __func__, drop_mcam_idx);
1284         }
1285
1286         mutex_unlock(&table->lock);
1287
1288         rvu_npc_exact_dealloc_table_entry(rvu, entry->opc_type, entry->ways, entry->index);
1289
1290         rvu_npc_exact_free_id(rvu, seq_id);
1291
1292         dev_dbg(rvu->dev, "%s: delete entry success for id=0x%x, mca=%pM\n",
1293                 __func__, seq_id, entry->mac);
1294         kfree(entry);
1295
1296         return 0;
1297 }
1298
1299 /**
1300  *      rvu_npc_exact_add_table_entry - Adds a table entry
1301  *      @rvu: resource virtualization unit.
1302  *      @cgx_id: cgx identifier.
1303  *      @lmac_id: lmac identifier.
1304  *      @mac: MAC address.
1305  *      @chan: Channel number.
1306  *      @ctype: Channel Type.
1307  *      @seq_id: Sequence number.
1308  *      @cmd: Whether it is invoked by ethtool cmd.
1309  *      @mcam_idx: NPC mcam index corresponding to MAC
1310  *      @pcifunc: PCI func.
1311  *
1312  *      Creates a new exact match table entry in either CAM or
1313  *      MEM table.
1314  *      Return: 0 upon success.
1315  */
1316 static int rvu_npc_exact_add_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_id, u8 *mac,
1317                                          u16 chan, u8 ctype, u32 *seq_id, bool cmd,
1318                                          u32 mcam_idx, u16 pcifunc)
1319 {
1320         int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1321         enum npc_exact_opc_type opc_type;
1322         bool enable_cam = false;
1323         u32 drop_mcam_idx;
1324         u32 index;
1325         u64 mdata;
1326         bool rc;
1327         int err;
1328         u8 ways;
1329
1330         ctype = 0;
1331
1332         err = rvu_npc_exact_alloc_table_entry(rvu, mac, chan, ctype, &index, &ways, &opc_type);
1333         if (err) {
1334                 dev_err(rvu->dev, "%s: Could not alloc in exact match table\n", __func__);
1335                 return err;
1336         }
1337
1338         /* Write mdata to table */
1339         mdata = rvu_exact_prepare_table_entry(rvu, true, ctype, chan, mac);
1340
1341         if (opc_type == NPC_EXACT_OPC_CAM)
1342                 rvu_npc_exact_cam_table_write(rvu, blkaddr, index, mdata);
1343         else
1344                 rvu_npc_exact_mem_table_write(rvu, blkaddr, ways, index,  mdata);
1345
1346         /* Insert entry to linked list */
1347         err = rvu_npc_exact_add_to_list(rvu, opc_type, ways, index, cgx_id, lmac_id,
1348                                         mac, chan, ctype, seq_id, cmd, mcam_idx, pcifunc);
1349         if (err) {
1350                 rvu_npc_exact_dealloc_table_entry(rvu, opc_type, ways, index);
1351                 dev_err(rvu->dev, "%s: could not add to exact match table\n", __func__);
1352                 return err;
1353         }
1354
1355         rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, cgx_id, lmac_id,
1356                                               &drop_mcam_idx, NULL, NULL, NULL);
1357         if (!rc) {
1358                 rvu_npc_exact_dealloc_table_entry(rvu, opc_type, ways, index);
1359                 dev_dbg(rvu->dev, "%s: failed to get drop rule info cgx=%d lmac=%d\n",
1360                         __func__, cgx_id, lmac_id);
1361                 return -EINVAL;
1362         }
1363
1364         if (cmd)
1365                 __rvu_npc_exact_cmd_rules_cnt_update(rvu, drop_mcam_idx, 1, &enable_cam);
1366
1367         /* First command rule; enable drop on hit rule */
1368         if (enable_cam) {
1369                 rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, true);
1370                 dev_dbg(rvu->dev, "%s: Enabling mcam idx %d\n",
1371                         __func__, drop_mcam_idx);
1372         }
1373
1374         dev_dbg(rvu->dev,
1375                 "%s: Successfully added entry (index=%d, dmac=%pM, ways=%d opc_type=%d\n",
1376                 __func__, index, mac, ways, opc_type);
1377
1378         return 0;
1379 }
1380
1381 /**
1382  *      rvu_npc_exact_update_table_entry - Update exact match table.
1383  *      @rvu: resource virtualization unit.
1384  *      @cgx_id: CGX identifier.
1385  *      @lmac_id: LMAC identifier.
1386  *      @old_mac: Existing MAC address entry.
1387  *      @new_mac: New MAC address entry.
1388  *      @seq_id: Sequence identifier of the entry.
1389  *
1390  *      Updates MAC address of an entry. If entry is in MEM table, new
1391  *      hash value may not match with old one.
1392  *      Return: 0 upon success.
1393  */
1394 static int rvu_npc_exact_update_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_id,
1395                                             u8 *old_mac, u8 *new_mac, u32 *seq_id)
1396 {
1397         int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1398         struct npc_exact_table_entry *entry;
1399         struct npc_exact_table *table;
1400         u32 hash_index;
1401         u64 mdata;
1402
1403         table = rvu->hw->table;
1404
1405         mutex_lock(&table->lock);
1406
1407         /* Lookup for entry which needs to be updated */
1408         entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, *seq_id);
1409         if (!entry) {
1410                 mutex_unlock(&table->lock);
1411                 dev_dbg(rvu->dev,
1412                         "%s: failed to find entry for cgx_id=%d lmac_id=%d old_mac=%pM\n",
1413                         __func__, cgx_id, lmac_id, old_mac);
1414                 return -ENODATA;
1415         }
1416
1417         /* If entry is in mem table and new hash index is different than old
1418          * hash index, we cannot update the entry. Fail in these scenarios.
1419          */
1420         if (entry->opc_type == NPC_EXACT_OPC_MEM) {
1421                 hash_index =  rvu_exact_calculate_hash(rvu, entry->chan, entry->ctype,
1422                                                        new_mac, table->mem_table.mask,
1423                                                        table->mem_table.depth);
1424                 if (hash_index != entry->index) {
1425                         dev_dbg(rvu->dev,
1426                                 "%s: Update failed due to index mismatch(new=0x%x, old=%x)\n",
1427                                 __func__, hash_index, entry->index);
1428                         mutex_unlock(&table->lock);
1429                         return -EINVAL;
1430                 }
1431         }
1432
1433         mdata = rvu_exact_prepare_table_entry(rvu, true, entry->ctype, entry->chan, new_mac);
1434
1435         if (entry->opc_type == NPC_EXACT_OPC_MEM)
1436                 rvu_npc_exact_mem_table_write(rvu, blkaddr, entry->ways, entry->index, mdata);
1437         else
1438                 rvu_npc_exact_cam_table_write(rvu, blkaddr, entry->index, mdata);
1439
1440         /* Update entry fields */
1441         ether_addr_copy(entry->mac, new_mac);
1442         *seq_id = entry->seq_id;
1443
1444         dev_dbg(rvu->dev,
1445                 "%s: Successfully updated entry (index=%d, dmac=%pM, ways=%d opc_type=%d\n",
1446                 __func__, entry->index, entry->mac, entry->ways, entry->opc_type);
1447
1448         dev_dbg(rvu->dev, "%s: Successfully updated entry (old mac=%pM new_mac=%pM\n",
1449                 __func__, old_mac, new_mac);
1450
1451         mutex_unlock(&table->lock);
1452         return 0;
1453 }
1454
1455 /**
1456  *      rvu_npc_exact_promisc_disable - Disable promiscuous mode.
1457  *      @rvu: resource virtualization unit.
1458  *      @pcifunc: pcifunc
1459  *
1460  *      Drop rule is against each PF. We dont support DMAC filter for
1461  *      VF.
1462  *      Return: 0 upon success
1463  */
1464
1465 int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc)
1466 {
1467         struct npc_exact_table *table;
1468         int pf = rvu_get_pf(pcifunc);
1469         u8 cgx_id, lmac_id;
1470         u32 drop_mcam_idx;
1471         bool *promisc;
1472         bool rc;
1473
1474         table = rvu->hw->table;
1475
1476         rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1477         rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, cgx_id, lmac_id,
1478                                               &drop_mcam_idx, NULL, NULL, NULL);
1479         if (!rc) {
1480                 dev_dbg(rvu->dev, "%s: failed to get drop rule info cgx=%d lmac=%d\n",
1481                         __func__, cgx_id, lmac_id);
1482                 return -EINVAL;
1483         }
1484
1485         mutex_lock(&table->lock);
1486         promisc = &table->promisc_mode[drop_mcam_idx];
1487
1488         if (!*promisc) {
1489                 mutex_unlock(&table->lock);
1490                 dev_dbg(rvu->dev, "%s: Err Already promisc mode disabled (cgx=%d lmac=%d)\n",
1491                         __func__, cgx_id, lmac_id);
1492                 return LMAC_AF_ERR_INVALID_PARAM;
1493         }
1494         *promisc = false;
1495         mutex_unlock(&table->lock);
1496
1497         /* Enable drop rule */
1498         rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX,
1499                                            true);
1500
1501         dev_dbg(rvu->dev, "%s: disabled  promisc mode (cgx=%d lmac=%d)\n",
1502                 __func__, cgx_id, lmac_id);
1503         return 0;
1504 }
1505
1506 /**
1507  *      rvu_npc_exact_promisc_enable - Enable promiscuous mode.
1508  *      @rvu: resource virtualization unit.
1509  *      @pcifunc: pcifunc.
1510  *      Return: 0 upon success
1511  */
1512 int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc)
1513 {
1514         struct npc_exact_table *table;
1515         int pf = rvu_get_pf(pcifunc);
1516         u8 cgx_id, lmac_id;
1517         u32 drop_mcam_idx;
1518         bool *promisc;
1519         bool rc;
1520
1521         table = rvu->hw->table;
1522
1523         rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1524         rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, cgx_id, lmac_id,
1525                                               &drop_mcam_idx, NULL, NULL, NULL);
1526         if (!rc) {
1527                 dev_dbg(rvu->dev, "%s: failed to get drop rule info cgx=%d lmac=%d\n",
1528                         __func__, cgx_id, lmac_id);
1529                 return -EINVAL;
1530         }
1531
1532         mutex_lock(&table->lock);
1533         promisc = &table->promisc_mode[drop_mcam_idx];
1534
1535         if (*promisc) {
1536                 mutex_unlock(&table->lock);
1537                 dev_dbg(rvu->dev, "%s: Already in promisc mode (cgx=%d lmac=%d)\n",
1538                         __func__, cgx_id, lmac_id);
1539                 return LMAC_AF_ERR_INVALID_PARAM;
1540         }
1541         *promisc = true;
1542         mutex_unlock(&table->lock);
1543
1544         /*  disable drop rule */
1545         rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX,
1546                                            false);
1547
1548         dev_dbg(rvu->dev, "%s: Enabled promisc mode (cgx=%d lmac=%d)\n",
1549                 __func__, cgx_id, lmac_id);
1550         return 0;
1551 }
1552
1553 /**
1554  *      rvu_npc_exact_mac_addr_reset - Delete PF mac address.
1555  *      @rvu: resource virtualization unit.
1556  *      @req: Reset request
1557  *      @rsp: Reset response.
1558  *      Return: 0 upon success
1559  */
1560 int rvu_npc_exact_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req,
1561                                  struct msg_rsp *rsp)
1562 {
1563         int pf = rvu_get_pf(req->hdr.pcifunc);
1564         u32 seq_id = req->index;
1565         struct rvu_pfvf *pfvf;
1566         u8 cgx_id, lmac_id;
1567         int rc;
1568
1569         rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1570
1571         pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
1572
1573         rc = rvu_npc_exact_del_table_entry_by_id(rvu, seq_id);
1574         if (rc) {
1575                 /* TODO: how to handle this error case ? */
1576                 dev_err(rvu->dev, "%s MAC (%pM) del PF=%d failed\n", __func__, pfvf->mac_addr, pf);
1577                 return 0;
1578         }
1579
1580         dev_dbg(rvu->dev, "%s MAC (%pM) del PF=%d success (seq_id=%u)\n",
1581                 __func__, pfvf->mac_addr, pf, seq_id);
1582         return 0;
1583 }
1584
1585 /**
1586  *      rvu_npc_exact_mac_addr_update - Update mac address field with new value.
1587  *      @rvu: resource virtualization unit.
1588  *      @req: Update request.
1589  *      @rsp: Update response.
1590  *      Return: 0 upon success
1591  */
1592 int rvu_npc_exact_mac_addr_update(struct rvu *rvu,
1593                                   struct cgx_mac_addr_update_req *req,
1594                                   struct cgx_mac_addr_update_rsp *rsp)
1595 {
1596         int pf = rvu_get_pf(req->hdr.pcifunc);
1597         struct npc_exact_table_entry *entry;
1598         struct npc_exact_table *table;
1599         struct rvu_pfvf *pfvf;
1600         u32 seq_id, mcam_idx;
1601         u8 old_mac[ETH_ALEN];
1602         u8 cgx_id, lmac_id;
1603         int rc;
1604
1605         if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
1606                 return LMAC_AF_ERR_PERM_DENIED;
1607
1608         dev_dbg(rvu->dev, "%s: Update request for seq_id=%d, mac=%pM\n",
1609                 __func__, req->index, req->mac_addr);
1610
1611         rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1612
1613         pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
1614
1615         table = rvu->hw->table;
1616
1617         mutex_lock(&table->lock);
1618
1619         /* Lookup for entry which needs to be updated */
1620         entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, req->index);
1621         if (!entry) {
1622                 dev_err(rvu->dev, "%s: failed to find entry for id=0x%x\n", __func__, req->index);
1623                 mutex_unlock(&table->lock);
1624                 return LMAC_AF_ERR_EXACT_MATCH_TBL_LOOK_UP_FAILED;
1625         }
1626         ether_addr_copy(old_mac, entry->mac);
1627         seq_id = entry->seq_id;
1628         mcam_idx = entry->mcam_idx;
1629         mutex_unlock(&table->lock);
1630
1631         rc = rvu_npc_exact_update_table_entry(rvu, cgx_id, lmac_id,  old_mac,
1632                                               req->mac_addr, &seq_id);
1633         if (!rc) {
1634                 rsp->index = seq_id;
1635                 dev_dbg(rvu->dev, "%s  mac:%pM (pfvf:%pM default:%pM) update to PF=%d success\n",
1636                         __func__, req->mac_addr, pfvf->mac_addr, pfvf->default_mac, pf);
1637                 ether_addr_copy(pfvf->mac_addr, req->mac_addr);
1638                 return 0;
1639         }
1640
1641         /* Try deleting and adding it again */
1642         rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
1643         if (rc) {
1644                 /* This could be a new entry */
1645                 dev_dbg(rvu->dev, "%s MAC (%pM) del PF=%d failed\n", __func__,
1646                         pfvf->mac_addr, pf);
1647         }
1648
1649         rc = rvu_npc_exact_add_table_entry(rvu, cgx_id, lmac_id, req->mac_addr,
1650                                            pfvf->rx_chan_base, 0, &seq_id, true,
1651                                            mcam_idx, req->hdr.pcifunc);
1652         if (rc) {
1653                 dev_err(rvu->dev, "%s MAC (%pM) add PF=%d failed\n", __func__,
1654                         req->mac_addr, pf);
1655                 return LMAC_AF_ERR_EXACT_MATCH_TBL_ADD_FAILED;
1656         }
1657
1658         rsp->index = seq_id;
1659         dev_dbg(rvu->dev,
1660                 "%s MAC (new:%pM, old=%pM default:%pM) del and add to PF=%d success (seq_id=%u)\n",
1661                 __func__, req->mac_addr, pfvf->mac_addr, pfvf->default_mac, pf, seq_id);
1662
1663         ether_addr_copy(pfvf->mac_addr, req->mac_addr);
1664         return 0;
1665 }
1666
1667 /**
1668  *      rvu_npc_exact_mac_addr_add - Adds MAC address to exact match table.
1669  *      @rvu: resource virtualization unit.
1670  *      @req: Add request.
1671  *      @rsp: Add response.
1672  *      Return: 0 upon success
1673  */
1674 int rvu_npc_exact_mac_addr_add(struct rvu *rvu,
1675                                struct cgx_mac_addr_add_req *req,
1676                                struct cgx_mac_addr_add_rsp *rsp)
1677 {
1678         int pf = rvu_get_pf(req->hdr.pcifunc);
1679         struct rvu_pfvf *pfvf;
1680         u8 cgx_id, lmac_id;
1681         int rc = 0;
1682         u32 seq_id;
1683
1684         rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1685         pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
1686
1687         rc = rvu_npc_exact_add_table_entry(rvu, cgx_id, lmac_id, req->mac_addr,
1688                                            pfvf->rx_chan_base, 0, &seq_id,
1689                                            true, -1, req->hdr.pcifunc);
1690
1691         if (!rc) {
1692                 rsp->index = seq_id;
1693                 dev_dbg(rvu->dev, "%s MAC (%pM) add to PF=%d success (seq_id=%u)\n",
1694                         __func__, req->mac_addr, pf, seq_id);
1695                 return 0;
1696         }
1697
1698         dev_err(rvu->dev, "%s MAC (%pM) add to PF=%d failed\n", __func__,
1699                 req->mac_addr, pf);
1700         return LMAC_AF_ERR_EXACT_MATCH_TBL_ADD_FAILED;
1701 }
1702
1703 /**
1704  *      rvu_npc_exact_mac_addr_del - Delete DMAC filter
1705  *      @rvu: resource virtualization unit.
1706  *      @req: Delete request.
1707  *      @rsp: Delete response.
1708  *      Return: 0 upon success
1709  */
1710 int rvu_npc_exact_mac_addr_del(struct rvu *rvu,
1711                                struct cgx_mac_addr_del_req *req,
1712                                struct msg_rsp *rsp)
1713 {
1714         int pf = rvu_get_pf(req->hdr.pcifunc);
1715         int rc;
1716
1717         rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
1718         if (!rc) {
1719                 dev_dbg(rvu->dev, "%s del to PF=%d success (seq_id=%u)\n",
1720                         __func__, pf, req->index);
1721                 return 0;
1722         }
1723
1724         dev_err(rvu->dev, "%s del to PF=%d failed (seq_id=%u)\n",
1725                 __func__,  pf, req->index);
1726         return LMAC_AF_ERR_EXACT_MATCH_TBL_DEL_FAILED;
1727 }
1728
1729 /**
1730  *      rvu_npc_exact_mac_addr_set - Add PF mac address to dmac filter.
1731  *      @rvu: resource virtualization unit.
1732  *      @req: Set request.
1733  *      @rsp: Set response.
1734  *      Return: 0 upon success
1735  */
1736 int rvu_npc_exact_mac_addr_set(struct rvu *rvu, struct cgx_mac_addr_set_or_get *req,
1737                                struct cgx_mac_addr_set_or_get *rsp)
1738 {
1739         int pf = rvu_get_pf(req->hdr.pcifunc);
1740         u32 seq_id = req->index;
1741         struct rvu_pfvf *pfvf;
1742         u8 cgx_id, lmac_id;
1743         u32 mcam_idx = -1;
1744         int rc, nixlf;
1745
1746         rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1747
1748         pfvf = &rvu->pf[pf];
1749
1750         /* If table does not have an entry; both update entry and del table entry API
1751          * below fails. Those are not failure conditions.
1752          */
1753         rc = rvu_npc_exact_update_table_entry(rvu, cgx_id, lmac_id, pfvf->mac_addr,
1754                                               req->mac_addr, &seq_id);
1755         if (!rc) {
1756                 rsp->index = seq_id;
1757                 ether_addr_copy(pfvf->mac_addr, req->mac_addr);
1758                 ether_addr_copy(rsp->mac_addr, req->mac_addr);
1759                 dev_dbg(rvu->dev, "%s MAC (%pM) update to PF=%d success\n",
1760                         __func__, req->mac_addr, pf);
1761                 return 0;
1762         }
1763
1764         /* Try deleting and adding it again */
1765         rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
1766         if (rc) {
1767                 dev_dbg(rvu->dev, "%s MAC (%pM) del PF=%d failed\n",
1768                         __func__, pfvf->mac_addr, pf);
1769         }
1770
1771         /* find mcam entry if exist */
1772         rc = nix_get_nixlf(rvu, req->hdr.pcifunc, &nixlf, NULL);
1773         if (!rc) {
1774                 mcam_idx = npc_get_nixlf_mcam_index(&rvu->hw->mcam, req->hdr.pcifunc,
1775                                                     nixlf, NIXLF_UCAST_ENTRY);
1776         }
1777
1778         rc = rvu_npc_exact_add_table_entry(rvu, cgx_id, lmac_id, req->mac_addr,
1779                                            pfvf->rx_chan_base, 0, &seq_id,
1780                                            true, mcam_idx, req->hdr.pcifunc);
1781         if (rc) {
1782                 dev_err(rvu->dev, "%s MAC (%pM) add PF=%d failed\n",
1783                         __func__, req->mac_addr, pf);
1784                 return LMAC_AF_ERR_EXACT_MATCH_TBL_ADD_FAILED;
1785         }
1786
1787         rsp->index = seq_id;
1788         ether_addr_copy(rsp->mac_addr, req->mac_addr);
1789         ether_addr_copy(pfvf->mac_addr, req->mac_addr);
1790         dev_dbg(rvu->dev,
1791                 "%s MAC (%pM) del and add to PF=%d success (seq_id=%u)\n",
1792                 __func__, req->mac_addr, pf, seq_id);
1793         return 0;
1794 }
1795
1796 /**
1797  *      rvu_npc_exact_can_disable_feature - Check if feature can be disabled.
1798  *      @rvu: resource virtualization unit.
1799  *      Return: True if exact match feature is supported.
1800  */
1801 bool rvu_npc_exact_can_disable_feature(struct rvu *rvu)
1802 {
1803         struct npc_exact_table *table = rvu->hw->table;
1804         bool empty;
1805
1806         if (!rvu->hw->cap.npc_exact_match_enabled)
1807                 return false;
1808
1809         mutex_lock(&table->lock);
1810         empty = list_empty(&table->lhead_gbl);
1811         mutex_unlock(&table->lock);
1812
1813         return empty;
1814 }
1815
1816 /**
1817  *      rvu_npc_exact_disable_feature - Disable feature.
1818  *      @rvu: resource virtualization unit.
1819  */
1820 void rvu_npc_exact_disable_feature(struct rvu *rvu)
1821 {
1822         rvu->hw->cap.npc_exact_match_enabled = false;
1823 }
1824
1825 /**
1826  *      rvu_npc_exact_reset - Delete and free all entry which match pcifunc.
1827  *      @rvu: resource virtualization unit.
1828  *      @pcifunc: PCI func to match.
1829  */
1830 void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc)
1831 {
1832         struct npc_exact_table *table = rvu->hw->table;
1833         struct npc_exact_table_entry *tmp, *iter;
1834         u32 seq_id;
1835
1836         mutex_lock(&table->lock);
1837         list_for_each_entry_safe(iter, tmp, &table->lhead_gbl, glist) {
1838                 if (pcifunc != iter->pcifunc)
1839                         continue;
1840
1841                 seq_id = iter->seq_id;
1842                 dev_dbg(rvu->dev, "%s: resetting pcifun=%d seq_id=%u\n", __func__,
1843                         pcifunc, seq_id);
1844
1845                 mutex_unlock(&table->lock);
1846                 rvu_npc_exact_del_table_entry_by_id(rvu, seq_id);
1847                 mutex_lock(&table->lock);
1848         }
1849         mutex_unlock(&table->lock);
1850 }
1851
1852 /**
1853  *      rvu_npc_exact_init - initialize exact match table
1854  *      @rvu: resource virtualization unit.
1855  *
1856  *      Initialize HW and SW resources to manage 4way-2K table and fully
1857  *      associative 32-entry mcam table.
1858  *      Return: 0 upon success.
1859  */
1860 int rvu_npc_exact_init(struct rvu *rvu)
1861 {
1862         u64 bcast_mcast_val, bcast_mcast_mask;
1863         struct npc_exact_table *table;
1864         u64 exact_val, exact_mask;
1865         u64 chan_val, chan_mask;
1866         u8 cgx_id, lmac_id;
1867         u32 *drop_mcam_idx;
1868         u16 max_lmac_cnt;
1869         u64 npc_const3;
1870         int table_size;
1871         int blkaddr;
1872         u16 pcifunc;
1873         int err, i;
1874         u64 cfg;
1875         bool rc;
1876
1877         /* Read NPC_AF_CONST3 and check for have exact
1878          * match functionality is present
1879          */
1880         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1881         if (blkaddr < 0) {
1882                 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
1883                 return -EINVAL;
1884         }
1885
1886         /* Check exact match feature is supported */
1887         npc_const3 = rvu_read64(rvu, blkaddr, NPC_AF_CONST3);
1888         if (!(npc_const3 & BIT_ULL(62)))
1889                 return 0;
1890
1891         /* Check if kex profile has enabled EXACT match nibble */
1892         cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX));
1893         if (!(cfg & NPC_EXACT_NIBBLE_HIT))
1894                 return 0;
1895
1896         /* Set capability to true */
1897         rvu->hw->cap.npc_exact_match_enabled = true;
1898
1899         table = kzalloc(sizeof(*table), GFP_KERNEL);
1900         if (!table)
1901                 return -ENOMEM;
1902
1903         dev_dbg(rvu->dev, "%s: Memory allocation for table success\n", __func__);
1904         rvu->hw->table = table;
1905
1906         /* Read table size, ways and depth */
1907         table->mem_table.ways = FIELD_GET(GENMASK_ULL(19, 16), npc_const3);
1908         table->mem_table.depth = FIELD_GET(GENMASK_ULL(15, 0), npc_const3);
1909         table->cam_table.depth = FIELD_GET(GENMASK_ULL(31, 24), npc_const3);
1910
1911         dev_dbg(rvu->dev, "%s: NPC exact match 4way_2k table(ways=%d, depth=%d)\n",
1912                 __func__,  table->mem_table.ways, table->cam_table.depth);
1913
1914         /* Check if depth of table is not a sequre of 2
1915          * TODO: why _builtin_popcount() is not working ?
1916          */
1917         if ((table->mem_table.depth & (table->mem_table.depth - 1)) != 0) {
1918                 dev_err(rvu->dev,
1919                         "%s: NPC exact match 4way_2k table depth(%d) is not square of 2\n",
1920                         __func__,  table->mem_table.depth);
1921                 return -EINVAL;
1922         }
1923
1924         table_size = table->mem_table.depth * table->mem_table.ways;
1925
1926         /* Allocate bitmap for 4way 2K table */
1927         table->mem_table.bmap = devm_bitmap_zalloc(rvu->dev, table_size,
1928                                                    GFP_KERNEL);
1929         if (!table->mem_table.bmap)
1930                 return -ENOMEM;
1931
1932         dev_dbg(rvu->dev, "%s: Allocated bitmap for 4way 2K entry table\n", __func__);
1933
1934         /* Allocate bitmap for 32 entry mcam */
1935         table->cam_table.bmap = devm_bitmap_zalloc(rvu->dev, 32, GFP_KERNEL);
1936
1937         if (!table->cam_table.bmap)
1938                 return -ENOMEM;
1939
1940         dev_dbg(rvu->dev, "%s: Allocated bitmap for 32 entry cam\n", __func__);
1941
1942         table->tot_ids = table_size + table->cam_table.depth;
1943         table->id_bmap = devm_bitmap_zalloc(rvu->dev, table->tot_ids,
1944                                             GFP_KERNEL);
1945
1946         if (!table->id_bmap)
1947                 return -ENOMEM;
1948
1949         dev_dbg(rvu->dev, "%s: Allocated bitmap for id map (total=%d)\n",
1950                 __func__, table->tot_ids);
1951
1952         /* Initialize list heads for npc_exact_table entries.
1953          * This entry is used by debugfs to show entries in
1954          * exact match table.
1955          */
1956         for (i = 0; i < NPC_EXACT_TBL_MAX_WAYS; i++)
1957                 INIT_LIST_HEAD(&table->lhead_mem_tbl_entry[i]);
1958
1959         INIT_LIST_HEAD(&table->lhead_cam_tbl_entry);
1960         INIT_LIST_HEAD(&table->lhead_gbl);
1961
1962         mutex_init(&table->lock);
1963
1964         rvu_exact_config_secret_key(rvu);
1965         rvu_exact_config_search_key(rvu);
1966
1967         rvu_exact_config_table_mask(rvu);
1968         rvu_exact_config_result_ctrl(rvu, table->mem_table.depth);
1969
1970         /* - No drop rule for LBK
1971          * - Drop rules for SDP and each LMAC.
1972          */
1973         exact_val = !NPC_EXACT_RESULT_HIT;
1974         exact_mask = NPC_EXACT_RESULT_HIT;
1975
1976         /* nibble - 3   2  1   0
1977          *         L3B L3M L2B L2M
1978          */
1979         bcast_mcast_val = 0b0000;
1980         bcast_mcast_mask = 0b0011;
1981
1982         /* Install SDP drop rule */
1983         drop_mcam_idx = &table->num_drop_rules;
1984
1985         max_lmac_cnt = rvu->cgx_cnt_max * rvu->hw->lmac_per_cgx +
1986                        PF_CGXMAP_BASE;
1987
1988         for (i = PF_CGXMAP_BASE; i < max_lmac_cnt; i++) {
1989                 if (rvu->pf2cgxlmac_map[i] == 0xFF)
1990                         continue;
1991
1992                 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[i], &cgx_id, &lmac_id);
1993
1994                 rc = rvu_npc_exact_calc_drop_rule_chan_and_mask(rvu, NIX_INTF_TYPE_CGX, cgx_id,
1995                                                                 lmac_id, &chan_val, &chan_mask);
1996                 if (!rc) {
1997                         dev_err(rvu->dev,
1998                                 "%s: failed, info chan_val=0x%llx chan_mask=0x%llx rule_id=%d\n",
1999                                 __func__, chan_val, chan_mask, *drop_mcam_idx);
2000                         return -EINVAL;
2001                 }
2002
2003                 /* Filter rules are only for PF */
2004                 pcifunc = RVU_PFFUNC(i, 0);
2005
2006                 dev_dbg(rvu->dev,
2007                         "%s:Drop rule cgx=%d lmac=%d chan(val=0x%llx, mask=0x%llx\n",
2008                         __func__, cgx_id, lmac_id, chan_val, chan_mask);
2009
2010                 rc = rvu_npc_exact_save_drop_rule_chan_and_mask(rvu, table->num_drop_rules,
2011                                                                 chan_val, chan_mask, pcifunc);
2012                 if (!rc) {
2013                         dev_err(rvu->dev,
2014                                 "%s: failed to set drop info for cgx=%d, lmac=%d, chan=%llx\n",
2015                                 __func__, cgx_id, lmac_id, chan_val);
2016                         return -EINVAL;
2017                 }
2018
2019                 err = npc_install_mcam_drop_rule(rvu, *drop_mcam_idx,
2020                                                  &table->counter_idx[*drop_mcam_idx],
2021                                                  chan_val, chan_mask,
2022                                                  exact_val, exact_mask,
2023                                                  bcast_mcast_val, bcast_mcast_mask);
2024                 if (err) {
2025                         dev_err(rvu->dev,
2026                                 "failed to configure drop rule (cgx=%d lmac=%d)\n",
2027                                 cgx_id, lmac_id);
2028                         return err;
2029                 }
2030
2031                 (*drop_mcam_idx)++;
2032         }
2033
2034         dev_info(rvu->dev, "initialized exact match table successfully\n");
2035         return 0;
2036 }