Merge tag 'pwm/for-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry...
[linux-2.6-microblaze.git] / drivers / net / ethernet / marvell / octeontx2 / af / rvu_npc.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell OcteonTx2 RVU Admin Function driver
3  *
4  * Copyright (C) 2018 Marvell International Ltd.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/bitfield.h>
12 #include <linux/module.h>
13 #include <linux/pci.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 "npc_profile.h"
21
22 #define RSVD_MCAM_ENTRIES_PER_PF        2 /* Bcast & Promisc */
23 #define RSVD_MCAM_ENTRIES_PER_NIXLF     1 /* Ucast for LFs */
24
25 #define NIXLF_UCAST_ENTRY       0
26 #define NIXLF_BCAST_ENTRY       1
27 #define NIXLF_PROMISC_ENTRY     2
28
29 #define NPC_PARSE_RESULT_DMAC_OFFSET    8
30 #define NPC_HW_TSTAMP_OFFSET            8
31
32 static const char def_pfl_name[] = "default";
33
34 static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
35                                       int blkaddr, u16 pcifunc);
36 static void npc_mcam_free_all_counters(struct rvu *rvu, struct npc_mcam *mcam,
37                                        u16 pcifunc);
38
39 void rvu_npc_set_pkind(struct rvu *rvu, int pkind, struct rvu_pfvf *pfvf)
40 {
41         int blkaddr;
42         u64 val = 0;
43
44         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
45         if (blkaddr < 0)
46                 return;
47
48         /* Config CPI base for the PKIND */
49         val = pkind | 1ULL << 62;
50         rvu_write64(rvu, blkaddr, NPC_AF_PKINDX_CPI_DEFX(pkind, 0), val);
51 }
52
53 int rvu_npc_get_pkind(struct rvu *rvu, u16 pf)
54 {
55         struct npc_pkind *pkind = &rvu->hw->pkind;
56         u32 map;
57         int i;
58
59         for (i = 0; i < pkind->rsrc.max; i++) {
60                 map = pkind->pfchan_map[i];
61                 if (((map >> 16) & 0x3F) == pf)
62                         return i;
63         }
64         return -1;
65 }
66
67 #define NPC_AF_ACTION0_PTR_ADVANCE      GENMASK_ULL(27, 20)
68
69 int npc_config_ts_kpuaction(struct rvu *rvu, int pf, u16 pcifunc, bool enable)
70 {
71         int pkind, blkaddr;
72         u64 val;
73
74         pkind = rvu_npc_get_pkind(rvu, pf);
75         if (pkind < 0) {
76                 dev_err(rvu->dev, "%s: pkind not mapped\n", __func__);
77                 return -EINVAL;
78         }
79
80         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, pcifunc);
81         if (blkaddr < 0) {
82                 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
83                 return -EINVAL;
84         }
85
86         val = rvu_read64(rvu, blkaddr, NPC_AF_PKINDX_ACTION0(pkind));
87         val &= ~NPC_AF_ACTION0_PTR_ADVANCE;
88         /* If timestamp is enabled then configure NPC to shift 8 bytes */
89         if (enable)
90                 val |= FIELD_PREP(NPC_AF_ACTION0_PTR_ADVANCE,
91                                   NPC_HW_TSTAMP_OFFSET);
92         rvu_write64(rvu, blkaddr, NPC_AF_PKINDX_ACTION0(pkind), val);
93
94         return 0;
95 }
96
97 static int npc_get_nixlf_mcam_index(struct npc_mcam *mcam,
98                                     u16 pcifunc, int nixlf, int type)
99 {
100         int pf = rvu_get_pf(pcifunc);
101         int index;
102
103         /* Check if this is for a PF */
104         if (pf && !(pcifunc & RVU_PFVF_FUNC_MASK)) {
105                 /* Reserved entries exclude PF0 */
106                 pf--;
107                 index = mcam->pf_offset + (pf * RSVD_MCAM_ENTRIES_PER_PF);
108                 /* Broadcast address matching entry should be first so
109                  * that the packet can be replicated to all VFs.
110                  */
111                 if (type == NIXLF_BCAST_ENTRY)
112                         return index;
113                 else if (type == NIXLF_PROMISC_ENTRY)
114                         return index + 1;
115         }
116
117         return (mcam->nixlf_offset + (nixlf * RSVD_MCAM_ENTRIES_PER_NIXLF));
118 }
119
120 static int npc_get_bank(struct npc_mcam *mcam, int index)
121 {
122         int bank = index / mcam->banksize;
123
124         /* 0,1 & 2,3 banks are combined for this keysize */
125         if (mcam->keysize == NPC_MCAM_KEY_X2)
126                 return bank ? 2 : 0;
127
128         return bank;
129 }
130
131 static bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam,
132                                   int blkaddr, int index)
133 {
134         int bank = npc_get_bank(mcam, index);
135         u64 cfg;
136
137         index &= (mcam->banksize - 1);
138         cfg = rvu_read64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_CFG(index, bank));
139         return (cfg & 1);
140 }
141
142 static void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
143                                   int blkaddr, int index, bool enable)
144 {
145         int bank = npc_get_bank(mcam, index);
146         int actbank = bank;
147
148         index &= (mcam->banksize - 1);
149         for (; bank < (actbank + mcam->banks_per_entry); bank++) {
150                 rvu_write64(rvu, blkaddr,
151                             NPC_AF_MCAMEX_BANKX_CFG(index, bank),
152                             enable ? 1 : 0);
153         }
154 }
155
156 static void npc_clear_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
157                                  int blkaddr, int index)
158 {
159         int bank = npc_get_bank(mcam, index);
160         int actbank = bank;
161
162         index &= (mcam->banksize - 1);
163         for (; bank < (actbank + mcam->banks_per_entry); bank++) {
164                 rvu_write64(rvu, blkaddr,
165                             NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 1), 0);
166                 rvu_write64(rvu, blkaddr,
167                             NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 0), 0);
168
169                 rvu_write64(rvu, blkaddr,
170                             NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 1), 0);
171                 rvu_write64(rvu, blkaddr,
172                             NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 0), 0);
173
174                 rvu_write64(rvu, blkaddr,
175                             NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 1), 0);
176                 rvu_write64(rvu, blkaddr,
177                             NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 0), 0);
178         }
179 }
180
181 static void npc_get_keyword(struct mcam_entry *entry, int idx,
182                             u64 *cam0, u64 *cam1)
183 {
184         u64 kw_mask = 0x00;
185
186 #define CAM_MASK(n)     (BIT_ULL(n) - 1)
187
188         /* 0, 2, 4, 6 indices refer to BANKX_CAMX_W0 and
189          * 1, 3, 5, 7 indices refer to BANKX_CAMX_W1.
190          *
191          * Also, only 48 bits of BANKX_CAMX_W1 are valid.
192          */
193         switch (idx) {
194         case 0:
195                 /* BANK(X)_CAM_W0<63:0> = MCAM_KEY[KW0]<63:0> */
196                 *cam1 = entry->kw[0];
197                 kw_mask = entry->kw_mask[0];
198                 break;
199         case 1:
200                 /* BANK(X)_CAM_W1<47:0> = MCAM_KEY[KW1]<47:0> */
201                 *cam1 = entry->kw[1] & CAM_MASK(48);
202                 kw_mask = entry->kw_mask[1] & CAM_MASK(48);
203                 break;
204         case 2:
205                 /* BANK(X + 1)_CAM_W0<15:0> = MCAM_KEY[KW1]<63:48>
206                  * BANK(X + 1)_CAM_W0<63:16> = MCAM_KEY[KW2]<47:0>
207                  */
208                 *cam1 = (entry->kw[1] >> 48) & CAM_MASK(16);
209                 *cam1 |= ((entry->kw[2] & CAM_MASK(48)) << 16);
210                 kw_mask = (entry->kw_mask[1] >> 48) & CAM_MASK(16);
211                 kw_mask |= ((entry->kw_mask[2] & CAM_MASK(48)) << 16);
212                 break;
213         case 3:
214                 /* BANK(X + 1)_CAM_W1<15:0> = MCAM_KEY[KW2]<63:48>
215                  * BANK(X + 1)_CAM_W1<47:16> = MCAM_KEY[KW3]<31:0>
216                  */
217                 *cam1 = (entry->kw[2] >> 48) & CAM_MASK(16);
218                 *cam1 |= ((entry->kw[3] & CAM_MASK(32)) << 16);
219                 kw_mask = (entry->kw_mask[2] >> 48) & CAM_MASK(16);
220                 kw_mask |= ((entry->kw_mask[3] & CAM_MASK(32)) << 16);
221                 break;
222         case 4:
223                 /* BANK(X + 2)_CAM_W0<31:0> = MCAM_KEY[KW3]<63:32>
224                  * BANK(X + 2)_CAM_W0<63:32> = MCAM_KEY[KW4]<31:0>
225                  */
226                 *cam1 = (entry->kw[3] >> 32) & CAM_MASK(32);
227                 *cam1 |= ((entry->kw[4] & CAM_MASK(32)) << 32);
228                 kw_mask = (entry->kw_mask[3] >> 32) & CAM_MASK(32);
229                 kw_mask |= ((entry->kw_mask[4] & CAM_MASK(32)) << 32);
230                 break;
231         case 5:
232                 /* BANK(X + 2)_CAM_W1<31:0> = MCAM_KEY[KW4]<63:32>
233                  * BANK(X + 2)_CAM_W1<47:32> = MCAM_KEY[KW5]<15:0>
234                  */
235                 *cam1 = (entry->kw[4] >> 32) & CAM_MASK(32);
236                 *cam1 |= ((entry->kw[5] & CAM_MASK(16)) << 32);
237                 kw_mask = (entry->kw_mask[4] >> 32) & CAM_MASK(32);
238                 kw_mask |= ((entry->kw_mask[5] & CAM_MASK(16)) << 32);
239                 break;
240         case 6:
241                 /* BANK(X + 3)_CAM_W0<47:0> = MCAM_KEY[KW5]<63:16>
242                  * BANK(X + 3)_CAM_W0<63:48> = MCAM_KEY[KW6]<15:0>
243                  */
244                 *cam1 = (entry->kw[5] >> 16) & CAM_MASK(48);
245                 *cam1 |= ((entry->kw[6] & CAM_MASK(16)) << 48);
246                 kw_mask = (entry->kw_mask[5] >> 16) & CAM_MASK(48);
247                 kw_mask |= ((entry->kw_mask[6] & CAM_MASK(16)) << 48);
248                 break;
249         case 7:
250                 /* BANK(X + 3)_CAM_W1<47:0> = MCAM_KEY[KW6]<63:16> */
251                 *cam1 = (entry->kw[6] >> 16) & CAM_MASK(48);
252                 kw_mask = (entry->kw_mask[6] >> 16) & CAM_MASK(48);
253                 break;
254         }
255
256         *cam1 &= kw_mask;
257         *cam0 = ~*cam1 & kw_mask;
258 }
259
260 static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
261                                   int blkaddr, int index, u8 intf,
262                                   struct mcam_entry *entry, bool enable)
263 {
264         int bank = npc_get_bank(mcam, index);
265         int kw = 0, actbank, actindex;
266         u64 cam0, cam1;
267
268         actbank = bank; /* Save bank id, to set action later on */
269         actindex = index;
270         index &= (mcam->banksize - 1);
271
272         /* Disable before mcam entry update */
273         npc_enable_mcam_entry(rvu, mcam, blkaddr, actindex, false);
274
275         /* Clear mcam entry to avoid writes being suppressed by NPC */
276         npc_clear_mcam_entry(rvu, mcam, blkaddr, actindex);
277
278         /* CAM1 takes the comparison value and
279          * CAM0 specifies match for a bit in key being '0' or '1' or 'dontcare'.
280          * CAM1<n> = 0 & CAM0<n> = 1 => match if key<n> = 0
281          * CAM1<n> = 1 & CAM0<n> = 0 => match if key<n> = 1
282          * CAM1<n> = 0 & CAM0<n> = 0 => always match i.e dontcare.
283          */
284         for (; bank < (actbank + mcam->banks_per_entry); bank++, kw = kw + 2) {
285                 /* Interface should be set in all banks */
286                 rvu_write64(rvu, blkaddr,
287                             NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 1),
288                             intf);
289                 rvu_write64(rvu, blkaddr,
290                             NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 0),
291                             ~intf & 0x3);
292
293                 /* Set the match key */
294                 npc_get_keyword(entry, kw, &cam0, &cam1);
295                 rvu_write64(rvu, blkaddr,
296                             NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 1), cam1);
297                 rvu_write64(rvu, blkaddr,
298                             NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 0), cam0);
299
300                 npc_get_keyword(entry, kw + 1, &cam0, &cam1);
301                 rvu_write64(rvu, blkaddr,
302                             NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 1), cam1);
303                 rvu_write64(rvu, blkaddr,
304                             NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 0), cam0);
305         }
306
307         /* Set 'action' */
308         rvu_write64(rvu, blkaddr,
309                     NPC_AF_MCAMEX_BANKX_ACTION(index, actbank), entry->action);
310
311         /* Set TAG 'action' */
312         rvu_write64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_TAG_ACT(index, actbank),
313                     entry->vtag_action);
314
315         /* Enable the entry */
316         if (enable)
317                 npc_enable_mcam_entry(rvu, mcam, blkaddr, actindex, true);
318 }
319
320 static void npc_copy_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
321                                 int blkaddr, u16 src, u16 dest)
322 {
323         int dbank = npc_get_bank(mcam, dest);
324         int sbank = npc_get_bank(mcam, src);
325         u64 cfg, sreg, dreg;
326         int bank, i;
327
328         src &= (mcam->banksize - 1);
329         dest &= (mcam->banksize - 1);
330
331         /* Copy INTF's, W0's, W1's CAM0 and CAM1 configuration */
332         for (bank = 0; bank < mcam->banks_per_entry; bank++) {
333                 sreg = NPC_AF_MCAMEX_BANKX_CAMX_INTF(src, sbank + bank, 0);
334                 dreg = NPC_AF_MCAMEX_BANKX_CAMX_INTF(dest, dbank + bank, 0);
335                 for (i = 0; i < 6; i++) {
336                         cfg = rvu_read64(rvu, blkaddr, sreg + (i * 8));
337                         rvu_write64(rvu, blkaddr, dreg + (i * 8), cfg);
338                 }
339         }
340
341         /* Copy action */
342         cfg = rvu_read64(rvu, blkaddr,
343                          NPC_AF_MCAMEX_BANKX_ACTION(src, sbank));
344         rvu_write64(rvu, blkaddr,
345                     NPC_AF_MCAMEX_BANKX_ACTION(dest, dbank), cfg);
346
347         /* Copy TAG action */
348         cfg = rvu_read64(rvu, blkaddr,
349                          NPC_AF_MCAMEX_BANKX_TAG_ACT(src, sbank));
350         rvu_write64(rvu, blkaddr,
351                     NPC_AF_MCAMEX_BANKX_TAG_ACT(dest, dbank), cfg);
352
353         /* Enable or disable */
354         cfg = rvu_read64(rvu, blkaddr,
355                          NPC_AF_MCAMEX_BANKX_CFG(src, sbank));
356         rvu_write64(rvu, blkaddr,
357                     NPC_AF_MCAMEX_BANKX_CFG(dest, dbank), cfg);
358 }
359
360 static u64 npc_get_mcam_action(struct rvu *rvu, struct npc_mcam *mcam,
361                                int blkaddr, int index)
362 {
363         int bank = npc_get_bank(mcam, index);
364
365         index &= (mcam->banksize - 1);
366         return rvu_read64(rvu, blkaddr,
367                           NPC_AF_MCAMEX_BANKX_ACTION(index, bank));
368 }
369
370 void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc,
371                                  int nixlf, u64 chan, u8 *mac_addr)
372 {
373         struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
374         struct npc_mcam *mcam = &rvu->hw->mcam;
375         struct mcam_entry entry = { {0} };
376         struct nix_rx_action action;
377         int blkaddr, index, kwi;
378         u64 mac = 0;
379
380         /* AF's VFs work in promiscuous mode */
381         if (is_afvf(pcifunc))
382                 return;
383
384         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
385         if (blkaddr < 0)
386                 return;
387
388         for (index = ETH_ALEN - 1; index >= 0; index--)
389                 mac |= ((u64)*mac_addr++) << (8 * index);
390
391         index = npc_get_nixlf_mcam_index(mcam, pcifunc,
392                                          nixlf, NIXLF_UCAST_ENTRY);
393
394         /* Match ingress channel and DMAC */
395         entry.kw[0] = chan;
396         entry.kw_mask[0] = 0xFFFULL;
397
398         kwi = NPC_PARSE_RESULT_DMAC_OFFSET / sizeof(u64);
399         entry.kw[kwi] = mac;
400         entry.kw_mask[kwi] = BIT_ULL(48) - 1;
401
402         /* Don't change the action if entry is already enabled
403          * Otherwise RSS action may get overwritten.
404          */
405         if (is_mcam_entry_enabled(rvu, mcam, blkaddr, index)) {
406                 *(u64 *)&action = npc_get_mcam_action(rvu, mcam,
407                                                       blkaddr, index);
408         } else {
409                 *(u64 *)&action = 0x00;
410                 action.op = NIX_RX_ACTIONOP_UCAST;
411                 action.pf_func = pcifunc;
412         }
413
414         entry.action = *(u64 *)&action;
415         npc_config_mcam_entry(rvu, mcam, blkaddr, index,
416                               NIX_INTF_RX, &entry, true);
417
418         /* add VLAN matching, setup action and save entry back for later */
419         entry.kw[0] |= (NPC_LT_LB_STAG_QINQ | NPC_LT_LB_CTAG) << 20;
420         entry.kw_mask[0] |= (NPC_LT_LB_STAG_QINQ & NPC_LT_LB_CTAG) << 20;
421
422         entry.vtag_action = VTAG0_VALID_BIT |
423                             FIELD_PREP(VTAG0_TYPE_MASK, 0) |
424                             FIELD_PREP(VTAG0_LID_MASK, NPC_LID_LA) |
425                             FIELD_PREP(VTAG0_RELPTR_MASK, 12);
426
427         memcpy(&pfvf->entry, &entry, sizeof(entry));
428 }
429
430 void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc,
431                                    int nixlf, u64 chan, bool allmulti)
432 {
433         struct npc_mcam *mcam = &rvu->hw->mcam;
434         int blkaddr, ucast_idx, index, kwi;
435         struct mcam_entry entry = { {0} };
436         struct nix_rx_action action = { };
437
438         /* Only PF or AF VF can add a promiscuous entry */
439         if ((pcifunc & RVU_PFVF_FUNC_MASK) && !is_afvf(pcifunc))
440                 return;
441
442         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
443         if (blkaddr < 0)
444                 return;
445
446         index = npc_get_nixlf_mcam_index(mcam, pcifunc,
447                                          nixlf, NIXLF_PROMISC_ENTRY);
448
449         entry.kw[0] = chan;
450         entry.kw_mask[0] = 0xFFFULL;
451
452         if (allmulti) {
453                 kwi = NPC_KEXOF_DMAC / sizeof(u64);
454                 entry.kw[kwi] = BIT_ULL(40); /* LSB bit of 1st byte in DMAC */
455                 entry.kw_mask[kwi] = BIT_ULL(40);
456         }
457
458         ucast_idx = npc_get_nixlf_mcam_index(mcam, pcifunc,
459                                              nixlf, NIXLF_UCAST_ENTRY);
460
461         /* If the corresponding PF's ucast action is RSS,
462          * use the same action for promisc also
463          */
464         if (is_mcam_entry_enabled(rvu, mcam, blkaddr, ucast_idx))
465                 *(u64 *)&action = npc_get_mcam_action(rvu, mcam,
466                                                         blkaddr, ucast_idx);
467
468         if (action.op != NIX_RX_ACTIONOP_RSS) {
469                 *(u64 *)&action = 0x00;
470                 action.op = NIX_RX_ACTIONOP_UCAST;
471                 action.pf_func = pcifunc;
472         }
473
474         entry.action = *(u64 *)&action;
475         npc_config_mcam_entry(rvu, mcam, blkaddr, index,
476                               NIX_INTF_RX, &entry, true);
477 }
478
479 static void npc_enadis_promisc_entry(struct rvu *rvu, u16 pcifunc,
480                                      int nixlf, bool enable)
481 {
482         struct npc_mcam *mcam = &rvu->hw->mcam;
483         int blkaddr, index;
484
485         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
486         if (blkaddr < 0)
487                 return;
488
489         /* Only PF's have a promiscuous entry */
490         if (pcifunc & RVU_PFVF_FUNC_MASK)
491                 return;
492
493         index = npc_get_nixlf_mcam_index(mcam, pcifunc,
494                                          nixlf, NIXLF_PROMISC_ENTRY);
495         npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
496 }
497
498 void rvu_npc_disable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf)
499 {
500         npc_enadis_promisc_entry(rvu, pcifunc, nixlf, false);
501 }
502
503 void rvu_npc_enable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf)
504 {
505         npc_enadis_promisc_entry(rvu, pcifunc, nixlf, true);
506 }
507
508 void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
509                                        int nixlf, u64 chan)
510 {
511         struct npc_mcam *mcam = &rvu->hw->mcam;
512         struct mcam_entry entry = { {0} };
513         struct rvu_hwinfo *hw = rvu->hw;
514         struct nix_rx_action action;
515         struct rvu_pfvf *pfvf;
516         int blkaddr, index;
517
518         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
519         if (blkaddr < 0)
520                 return;
521
522         /* Skip LBK VFs */
523         if (is_afvf(pcifunc))
524                 return;
525
526         /* If pkt replication is not supported,
527          * then only PF is allowed to add a bcast match entry.
528          */
529         if (!hw->cap.nix_rx_multicast && pcifunc & RVU_PFVF_FUNC_MASK)
530                 return;
531
532         /* Get 'pcifunc' of PF device */
533         pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK;
534         index = npc_get_nixlf_mcam_index(mcam, pcifunc,
535                                          nixlf, NIXLF_BCAST_ENTRY);
536
537         /* Match ingress channel */
538         entry.kw[0] = chan;
539         entry.kw_mask[0] = 0xfffull;
540
541         /* Match broadcast MAC address.
542          * DMAC is extracted at 0th bit of PARSE_KEX::KW1
543          */
544         entry.kw[1] = 0xffffffffffffull;
545         entry.kw_mask[1] = 0xffffffffffffull;
546
547         *(u64 *)&action = 0x00;
548         if (!hw->cap.nix_rx_multicast) {
549                 /* Early silicon doesn't support pkt replication,
550                  * so install entry with UCAST action, so that PF
551                  * receives all broadcast packets.
552                  */
553                 action.op = NIX_RX_ACTIONOP_UCAST;
554                 action.pf_func = pcifunc;
555         } else {
556                 pfvf = rvu_get_pfvf(rvu, pcifunc);
557                 action.index = pfvf->bcast_mce_idx;
558                 action.op = NIX_RX_ACTIONOP_MCAST;
559         }
560
561         entry.action = *(u64 *)&action;
562         npc_config_mcam_entry(rvu, mcam, blkaddr, index,
563                               NIX_INTF_RX, &entry, true);
564 }
565
566 void rvu_npc_enable_bcast_entry(struct rvu *rvu, u16 pcifunc, bool enable)
567 {
568         struct npc_mcam *mcam = &rvu->hw->mcam;
569         int blkaddr, index;
570
571         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
572         if (blkaddr < 0)
573                 return;
574
575         /* Get 'pcifunc' of PF device */
576         pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK;
577
578         index = npc_get_nixlf_mcam_index(mcam, pcifunc, 0, NIXLF_BCAST_ENTRY);
579         npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
580 }
581
582 void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
583                                     int group, int alg_idx, int mcam_index)
584 {
585         struct npc_mcam *mcam = &rvu->hw->mcam;
586         struct nix_rx_action action;
587         int blkaddr, index, bank;
588
589         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
590         if (blkaddr < 0)
591                 return;
592
593         /* Check if this is for reserved default entry */
594         if (mcam_index < 0) {
595                 if (group != DEFAULT_RSS_CONTEXT_GROUP)
596                         return;
597                 index = npc_get_nixlf_mcam_index(mcam, pcifunc,
598                                                  nixlf, NIXLF_UCAST_ENTRY);
599         } else {
600                 /* TODO: validate this mcam index */
601                 index = mcam_index;
602         }
603
604         if (index >= mcam->total_entries)
605                 return;
606
607         bank = npc_get_bank(mcam, index);
608         index &= (mcam->banksize - 1);
609
610         *(u64 *)&action = rvu_read64(rvu, blkaddr,
611                                      NPC_AF_MCAMEX_BANKX_ACTION(index, bank));
612         /* Ignore if no action was set earlier */
613         if (!*(u64 *)&action)
614                 return;
615
616         action.op = NIX_RX_ACTIONOP_RSS;
617         action.pf_func = pcifunc;
618         action.index = group;
619         action.flow_key_alg = alg_idx;
620
621         rvu_write64(rvu, blkaddr,
622                     NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action);
623
624         index = npc_get_nixlf_mcam_index(mcam, pcifunc,
625                                          nixlf, NIXLF_PROMISC_ENTRY);
626
627         /* If PF's promiscuous entry is enabled,
628          * Set RSS action for that entry as well
629          */
630         if (is_mcam_entry_enabled(rvu, mcam, blkaddr, index)) {
631                 bank = npc_get_bank(mcam, index);
632                 index &= (mcam->banksize - 1);
633
634                 rvu_write64(rvu, blkaddr,
635                             NPC_AF_MCAMEX_BANKX_ACTION(index, bank),
636                             *(u64 *)&action);
637         }
638
639         rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);
640 }
641
642 static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc,
643                                        int nixlf, bool enable)
644 {
645         struct npc_mcam *mcam = &rvu->hw->mcam;
646         struct nix_rx_action action;
647         int index, bank, blkaddr;
648
649         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
650         if (blkaddr < 0)
651                 return;
652
653         /* Ucast MCAM match entry of this PF/VF */
654         index = npc_get_nixlf_mcam_index(mcam, pcifunc,
655                                          nixlf, NIXLF_UCAST_ENTRY);
656         npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
657
658         /* For PF, ena/dis promisc and bcast MCAM match entries.
659          * For VFs add/delete from bcast list when RX multicast
660          * feature is present.
661          */
662         if (pcifunc & RVU_PFVF_FUNC_MASK && !rvu->hw->cap.nix_rx_multicast)
663                 return;
664
665         /* For bcast, enable/disable only if it's action is not
666          * packet replication, incase if action is replication
667          * then this PF/VF's nixlf is removed from bcast replication
668          * list.
669          */
670         index = npc_get_nixlf_mcam_index(mcam, pcifunc & ~RVU_PFVF_FUNC_MASK,
671                                          nixlf, NIXLF_BCAST_ENTRY);
672         bank = npc_get_bank(mcam, index);
673         *(u64 *)&action = rvu_read64(rvu, blkaddr,
674              NPC_AF_MCAMEX_BANKX_ACTION(index & (mcam->banksize - 1), bank));
675
676         /* VFs will not have BCAST entry */
677         if (action.op != NIX_RX_ACTIONOP_MCAST &&
678             !(pcifunc & RVU_PFVF_FUNC_MASK)) {
679                 npc_enable_mcam_entry(rvu, mcam,
680                                       blkaddr, index, enable);
681         } else {
682                 nix_update_bcast_mce_list(rvu, pcifunc, enable);
683                 /* Enable PF's BCAST entry for packet replication */
684                 rvu_npc_enable_bcast_entry(rvu, pcifunc, enable);
685         }
686
687         if (enable)
688                 rvu_npc_enable_promisc_entry(rvu, pcifunc, nixlf);
689         else
690                 rvu_npc_disable_promisc_entry(rvu, pcifunc, nixlf);
691
692         rvu_npc_update_rxvlan(rvu, pcifunc, nixlf);
693 }
694
695 void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
696 {
697         npc_enadis_default_entries(rvu, pcifunc, nixlf, false);
698 }
699
700 void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
701 {
702         npc_enadis_default_entries(rvu, pcifunc, nixlf, true);
703 }
704
705 void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf)
706 {
707         struct npc_mcam *mcam = &rvu->hw->mcam;
708         int blkaddr;
709
710         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
711         if (blkaddr < 0)
712                 return;
713
714         mutex_lock(&mcam->lock);
715
716         /* Disable and free all MCAM entries mapped to this 'pcifunc' */
717         npc_mcam_free_all_entries(rvu, mcam, blkaddr, pcifunc);
718
719         /* Free all MCAM counters mapped to this 'pcifunc' */
720         npc_mcam_free_all_counters(rvu, mcam, pcifunc);
721
722         mutex_unlock(&mcam->lock);
723
724         rvu_npc_disable_default_entries(rvu, pcifunc, nixlf);
725 }
726
727 #define SET_KEX_LD(intf, lid, ltype, ld, cfg)   \
728         rvu_write64(rvu, blkaddr,                       \
729                 NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, lid, ltype, ld), cfg)
730
731 #define SET_KEX_LDFLAGS(intf, ld, flags, cfg)   \
732         rvu_write64(rvu, blkaddr,                       \
733                 NPC_AF_INTFX_LDATAX_FLAGSX_CFG(intf, ld, flags), cfg)
734
735 static void npc_program_mkex_profile(struct rvu *rvu, int blkaddr,
736                                      const struct npc_mcam_kex *mkex)
737 {
738         int lid, lt, ld, fl;
739
740         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX),
741                     mkex->keyx_cfg[NIX_INTF_RX]);
742         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_TX),
743                     mkex->keyx_cfg[NIX_INTF_TX]);
744
745         for (ld = 0; ld < NPC_MAX_LD; ld++)
746                 rvu_write64(rvu, blkaddr, NPC_AF_KEX_LDATAX_FLAGS_CFG(ld),
747                             mkex->kex_ld_flags[ld]);
748
749         for (lid = 0; lid < NPC_MAX_LID; lid++) {
750                 for (lt = 0; lt < NPC_MAX_LT; lt++) {
751                         for (ld = 0; ld < NPC_MAX_LD; ld++) {
752                                 SET_KEX_LD(NIX_INTF_RX, lid, lt, ld,
753                                            mkex->intf_lid_lt_ld[NIX_INTF_RX]
754                                            [lid][lt][ld]);
755
756                                 SET_KEX_LD(NIX_INTF_TX, lid, lt, ld,
757                                            mkex->intf_lid_lt_ld[NIX_INTF_TX]
758                                            [lid][lt][ld]);
759                         }
760                 }
761         }
762
763         for (ld = 0; ld < NPC_MAX_LD; ld++) {
764                 for (fl = 0; fl < NPC_MAX_LFL; fl++) {
765                         SET_KEX_LDFLAGS(NIX_INTF_RX, ld, fl,
766                                         mkex->intf_ld_flags[NIX_INTF_RX]
767                                         [ld][fl]);
768
769                         SET_KEX_LDFLAGS(NIX_INTF_TX, ld, fl,
770                                         mkex->intf_ld_flags[NIX_INTF_TX]
771                                         [ld][fl]);
772                 }
773         }
774 }
775
776 #define MKEX_END_SIGN  0xdeadbeef
777
778 static void npc_load_mkex_profile(struct rvu *rvu, int blkaddr,
779                                   const char *mkex_profile)
780 {
781         struct device *dev = &rvu->pdev->dev;
782         struct npc_mcam_kex *mcam_kex;
783         void *mkex_prfl_addr = NULL;
784         u64 prfl_addr, prfl_sz;
785
786         /* If user not selected mkex profile */
787         if (!strncmp(mkex_profile, def_pfl_name, MKEX_NAME_LEN))
788                 goto program_mkex;
789
790         if (!rvu->fwdata)
791                 goto program_mkex;
792         prfl_addr = rvu->fwdata->mcam_addr;
793         prfl_sz = rvu->fwdata->mcam_sz;
794
795         if (!prfl_addr || !prfl_sz)
796                 goto program_mkex;
797
798         mkex_prfl_addr = memremap(prfl_addr, prfl_sz, MEMREMAP_WC);
799         if (!mkex_prfl_addr)
800                 goto program_mkex;
801
802         mcam_kex = (struct npc_mcam_kex *)mkex_prfl_addr;
803
804         while (((s64)prfl_sz > 0) && (mcam_kex->mkex_sign != MKEX_END_SIGN)) {
805                 /* Compare with mkex mod_param name string */
806                 if (mcam_kex->mkex_sign == MKEX_SIGN &&
807                     !strncmp(mcam_kex->name, mkex_profile, MKEX_NAME_LEN)) {
808                         /* Due to an errata (35786) in A0/B0 pass silicon,
809                          * parse nibble enable configuration has to be
810                          * identical for both Rx and Tx interfaces.
811                          */
812                         if (!is_rvu_96xx_B0(rvu) ||
813                             mcam_kex->keyx_cfg[NIX_INTF_RX] == mcam_kex->keyx_cfg[NIX_INTF_TX])
814                                 rvu->kpu.mkex = mcam_kex;
815                         goto program_mkex;
816                 }
817
818                 mcam_kex++;
819                 prfl_sz -= sizeof(struct npc_mcam_kex);
820         }
821         dev_warn(dev, "Failed to load requested profile: %s\n", mkex_profile);
822
823 program_mkex:
824         dev_info(rvu->dev, "Using %s mkex profile\n", rvu->kpu.mkex->name);
825         /* Program selected mkex profile */
826         npc_program_mkex_profile(rvu, blkaddr, rvu->kpu.mkex);
827         if (mkex_prfl_addr)
828                 memunmap(mkex_prfl_addr);
829 }
830
831 static void npc_config_kpuaction(struct rvu *rvu, int blkaddr,
832                                  const struct npc_kpu_profile_action *kpuaction,
833                                  int kpu, int entry, bool pkind)
834 {
835         struct npc_kpu_action0 action0 = {0};
836         struct npc_kpu_action1 action1 = {0};
837         u64 reg;
838
839         action1.errlev = kpuaction->errlev;
840         action1.errcode = kpuaction->errcode;
841         action1.dp0_offset = kpuaction->dp0_offset;
842         action1.dp1_offset = kpuaction->dp1_offset;
843         action1.dp2_offset = kpuaction->dp2_offset;
844
845         if (pkind)
846                 reg = NPC_AF_PKINDX_ACTION1(entry);
847         else
848                 reg = NPC_AF_KPUX_ENTRYX_ACTION1(kpu, entry);
849
850         rvu_write64(rvu, blkaddr, reg, *(u64 *)&action1);
851
852         action0.byp_count = kpuaction->bypass_count;
853         action0.capture_ena = kpuaction->cap_ena;
854         action0.parse_done = kpuaction->parse_done;
855         action0.next_state = kpuaction->next_state;
856         action0.capture_lid = kpuaction->lid;
857         action0.capture_ltype = kpuaction->ltype;
858         action0.capture_flags = kpuaction->flags;
859         action0.ptr_advance = kpuaction->ptr_advance;
860         action0.var_len_offset = kpuaction->offset;
861         action0.var_len_mask = kpuaction->mask;
862         action0.var_len_right = kpuaction->right;
863         action0.var_len_shift = kpuaction->shift;
864
865         if (pkind)
866                 reg = NPC_AF_PKINDX_ACTION0(entry);
867         else
868                 reg = NPC_AF_KPUX_ENTRYX_ACTION0(kpu, entry);
869
870         rvu_write64(rvu, blkaddr, reg, *(u64 *)&action0);
871 }
872
873 static void npc_config_kpucam(struct rvu *rvu, int blkaddr,
874                               const struct npc_kpu_profile_cam *kpucam,
875                               int kpu, int entry)
876 {
877         struct npc_kpu_cam cam0 = {0};
878         struct npc_kpu_cam cam1 = {0};
879
880         cam1.state = kpucam->state & kpucam->state_mask;
881         cam1.dp0_data = kpucam->dp0 & kpucam->dp0_mask;
882         cam1.dp1_data = kpucam->dp1 & kpucam->dp1_mask;
883         cam1.dp2_data = kpucam->dp2 & kpucam->dp2_mask;
884
885         cam0.state = ~kpucam->state & kpucam->state_mask;
886         cam0.dp0_data = ~kpucam->dp0 & kpucam->dp0_mask;
887         cam0.dp1_data = ~kpucam->dp1 & kpucam->dp1_mask;
888         cam0.dp2_data = ~kpucam->dp2 & kpucam->dp2_mask;
889
890         rvu_write64(rvu, blkaddr,
891                     NPC_AF_KPUX_ENTRYX_CAMX(kpu, entry, 0), *(u64 *)&cam0);
892         rvu_write64(rvu, blkaddr,
893                     NPC_AF_KPUX_ENTRYX_CAMX(kpu, entry, 1), *(u64 *)&cam1);
894 }
895
896 static inline u64 enable_mask(int count)
897 {
898         return (((count) < 64) ? ~(BIT_ULL(count) - 1) : (0x00ULL));
899 }
900
901 static void npc_program_kpu_profile(struct rvu *rvu, int blkaddr, int kpu,
902                                     const struct npc_kpu_profile *profile)
903 {
904         int entry, num_entries, max_entries;
905
906         if (profile->cam_entries != profile->action_entries) {
907                 dev_err(rvu->dev,
908                         "KPU%d: CAM and action entries [%d != %d] not equal\n",
909                         kpu, profile->cam_entries, profile->action_entries);
910         }
911
912         max_entries = rvu_read64(rvu, blkaddr, NPC_AF_CONST1) & 0xFFF;
913
914         /* Program CAM match entries for previous KPU extracted data */
915         num_entries = min_t(int, profile->cam_entries, max_entries);
916         for (entry = 0; entry < num_entries; entry++)
917                 npc_config_kpucam(rvu, blkaddr,
918                                   &profile->cam[entry], kpu, entry);
919
920         /* Program this KPU's actions */
921         num_entries = min_t(int, profile->action_entries, max_entries);
922         for (entry = 0; entry < num_entries; entry++)
923                 npc_config_kpuaction(rvu, blkaddr, &profile->action[entry],
924                                      kpu, entry, false);
925
926         /* Enable all programmed entries */
927         num_entries = min_t(int, profile->action_entries, profile->cam_entries);
928         rvu_write64(rvu, blkaddr,
929                     NPC_AF_KPUX_ENTRY_DISX(kpu, 0), enable_mask(num_entries));
930         if (num_entries > 64) {
931                 rvu_write64(rvu, blkaddr,
932                             NPC_AF_KPUX_ENTRY_DISX(kpu, 1),
933                             enable_mask(num_entries - 64));
934         }
935
936         /* Enable this KPU */
937         rvu_write64(rvu, blkaddr, NPC_AF_KPUX_CFG(kpu), 0x01);
938 }
939
940 static int npc_prepare_default_kpu(struct npc_kpu_profile_adapter *profile)
941 {
942         profile->name = def_pfl_name;
943         profile->version = NPC_KPU_PROFILE_VER;
944         profile->ikpu = ikpu_action_entries;
945         profile->pkinds = ARRAY_SIZE(ikpu_action_entries);
946         profile->kpu = npc_kpu_profiles;
947         profile->kpus = ARRAY_SIZE(npc_kpu_profiles);
948         profile->lt_def = &npc_lt_defaults;
949         profile->mkex = &npc_mkex_default;
950
951         return 0;
952 }
953
954 static void npc_load_kpu_profile(struct rvu *rvu)
955 {
956         struct npc_kpu_profile_adapter *profile = &rvu->kpu;
957
958         npc_prepare_default_kpu(profile);
959 }
960
961 static void npc_parser_profile_init(struct rvu *rvu, int blkaddr)
962 {
963         struct rvu_hwinfo *hw = rvu->hw;
964         int num_pkinds, num_kpus, idx;
965         struct npc_pkind *pkind;
966
967         /* Get HW limits */
968         hw->npc_kpus = (rvu_read64(rvu, blkaddr, NPC_AF_CONST) >> 8) & 0x1F;
969
970         /* Disable all KPUs and their entries */
971         for (idx = 0; idx < hw->npc_kpus; idx++) {
972                 rvu_write64(rvu, blkaddr,
973                             NPC_AF_KPUX_ENTRY_DISX(idx, 0), ~0ULL);
974                 rvu_write64(rvu, blkaddr,
975                             NPC_AF_KPUX_ENTRY_DISX(idx, 1), ~0ULL);
976                 rvu_write64(rvu, blkaddr, NPC_AF_KPUX_CFG(idx), 0x00);
977         }
978
979         /* Load and customize KPU profile. */
980         npc_load_kpu_profile(rvu);
981
982         /* First program IKPU profile i.e PKIND configs.
983          * Check HW max count to avoid configuring junk or
984          * writing to unsupported CSR addresses.
985          */
986         pkind = &hw->pkind;
987         num_pkinds = rvu->kpu.pkinds;
988         num_pkinds = min_t(int, pkind->rsrc.max, num_pkinds);
989
990         for (idx = 0; idx < num_pkinds; idx++)
991                 npc_config_kpuaction(rvu, blkaddr, &rvu->kpu.ikpu[idx], 0, idx, true);
992
993         /* Program KPU CAM and Action profiles */
994         num_kpus = rvu->kpu.kpus;
995         num_kpus = min_t(int, hw->npc_kpus, num_kpus);
996
997         for (idx = 0; idx < num_kpus; idx++)
998                 npc_program_kpu_profile(rvu, blkaddr, idx, &rvu->kpu.kpu[idx]);
999 }
1000
1001 static int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr)
1002 {
1003         int nixlf_count = rvu_get_nixlf_count(rvu);
1004         struct npc_mcam *mcam = &rvu->hw->mcam;
1005         int rsvd, err;
1006         u64 cfg;
1007
1008         /* Get HW limits */
1009         cfg = rvu_read64(rvu, blkaddr, NPC_AF_CONST);
1010         mcam->banks = (cfg >> 44) & 0xF;
1011         mcam->banksize = (cfg >> 28) & 0xFFFF;
1012         mcam->counters.max = (cfg >> 48) & 0xFFFF;
1013
1014         /* Actual number of MCAM entries vary by entry size */
1015         cfg = (rvu_read64(rvu, blkaddr,
1016                           NPC_AF_INTFX_KEX_CFG(0)) >> 32) & 0x07;
1017         mcam->total_entries = (mcam->banks / BIT_ULL(cfg)) * mcam->banksize;
1018         mcam->keysize = cfg;
1019
1020         /* Number of banks combined per MCAM entry */
1021         if (cfg == NPC_MCAM_KEY_X4)
1022                 mcam->banks_per_entry = 4;
1023         else if (cfg == NPC_MCAM_KEY_X2)
1024                 mcam->banks_per_entry = 2;
1025         else
1026                 mcam->banks_per_entry = 1;
1027
1028         /* Reserve one MCAM entry for each of the NIX LF to
1029          * guarantee space to install default matching DMAC rule.
1030          * Also reserve 2 MCAM entries for each PF for default
1031          * channel based matching or 'bcast & promisc' matching to
1032          * support BCAST and PROMISC modes of operation for PFs.
1033          * PF0 is excluded.
1034          */
1035         rsvd = (nixlf_count * RSVD_MCAM_ENTRIES_PER_NIXLF) +
1036                 ((rvu->hw->total_pfs - 1) * RSVD_MCAM_ENTRIES_PER_PF);
1037         if (mcam->total_entries <= rsvd) {
1038                 dev_warn(rvu->dev,
1039                          "Insufficient NPC MCAM size %d for pkt I/O, exiting\n",
1040                          mcam->total_entries);
1041                 return -ENOMEM;
1042         }
1043
1044         mcam->bmap_entries = mcam->total_entries - rsvd;
1045         mcam->nixlf_offset = mcam->bmap_entries;
1046         mcam->pf_offset = mcam->nixlf_offset + nixlf_count;
1047
1048         /* Allocate bitmaps for managing MCAM entries */
1049         mcam->bmap = devm_kcalloc(rvu->dev, BITS_TO_LONGS(mcam->bmap_entries),
1050                                   sizeof(long), GFP_KERNEL);
1051         if (!mcam->bmap)
1052                 return -ENOMEM;
1053
1054         mcam->bmap_reverse = devm_kcalloc(rvu->dev,
1055                                           BITS_TO_LONGS(mcam->bmap_entries),
1056                                           sizeof(long), GFP_KERNEL);
1057         if (!mcam->bmap_reverse)
1058                 return -ENOMEM;
1059
1060         mcam->bmap_fcnt = mcam->bmap_entries;
1061
1062         /* Alloc memory for saving entry to RVU PFFUNC allocation mapping */
1063         mcam->entry2pfvf_map = devm_kcalloc(rvu->dev, mcam->bmap_entries,
1064                                             sizeof(u16), GFP_KERNEL);
1065         if (!mcam->entry2pfvf_map)
1066                 return -ENOMEM;
1067
1068         /* Reserve 1/8th of MCAM entries at the bottom for low priority
1069          * allocations and another 1/8th at the top for high priority
1070          * allocations.
1071          */
1072         mcam->lprio_count = mcam->bmap_entries / 8;
1073         if (mcam->lprio_count > BITS_PER_LONG)
1074                 mcam->lprio_count = round_down(mcam->lprio_count,
1075                                                BITS_PER_LONG);
1076         mcam->lprio_start = mcam->bmap_entries - mcam->lprio_count;
1077         mcam->hprio_count = mcam->lprio_count;
1078         mcam->hprio_end = mcam->hprio_count;
1079
1080         /* Reserve last counter for MCAM RX miss action which is set to
1081          * drop pkt. This way we will know how many pkts didn't match
1082          * any MCAM entry.
1083          */
1084         mcam->counters.max--;
1085         mcam->rx_miss_act_cntr = mcam->counters.max;
1086
1087         /* Allocate bitmap for managing MCAM counters and memory
1088          * for saving counter to RVU PFFUNC allocation mapping.
1089          */
1090         err = rvu_alloc_bitmap(&mcam->counters);
1091         if (err)
1092                 return err;
1093
1094         mcam->cntr2pfvf_map = devm_kcalloc(rvu->dev, mcam->counters.max,
1095                                            sizeof(u16), GFP_KERNEL);
1096         if (!mcam->cntr2pfvf_map)
1097                 goto free_mem;
1098
1099         /* Alloc memory for MCAM entry to counter mapping and for tracking
1100          * counter's reference count.
1101          */
1102         mcam->entry2cntr_map = devm_kcalloc(rvu->dev, mcam->bmap_entries,
1103                                             sizeof(u16), GFP_KERNEL);
1104         if (!mcam->entry2cntr_map)
1105                 goto free_mem;
1106
1107         mcam->cntr_refcnt = devm_kcalloc(rvu->dev, mcam->counters.max,
1108                                          sizeof(u16), GFP_KERNEL);
1109         if (!mcam->cntr_refcnt)
1110                 goto free_mem;
1111
1112         mutex_init(&mcam->lock);
1113
1114         return 0;
1115
1116 free_mem:
1117         kfree(mcam->counters.bmap);
1118         return -ENOMEM;
1119 }
1120
1121 int rvu_npc_init(struct rvu *rvu)
1122 {
1123         struct npc_kpu_profile_adapter *kpu = &rvu->kpu;
1124         struct npc_pkind *pkind = &rvu->hw->pkind;
1125         struct npc_mcam *mcam = &rvu->hw->mcam;
1126         u64 cfg, nibble_ena, rx_kex, tx_kex;
1127         int blkaddr, entry, bank, err;
1128
1129         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1130         if (blkaddr < 0) {
1131                 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
1132                 return -ENODEV;
1133         }
1134
1135         /* First disable all MCAM entries, to stop traffic towards NIXLFs */
1136         cfg = rvu_read64(rvu, blkaddr, NPC_AF_CONST);
1137         for (bank = 0; bank < ((cfg >> 44) & 0xF); bank++) {
1138                 for (entry = 0; entry < ((cfg >> 28) & 0xFFFF); entry++)
1139                         rvu_write64(rvu, blkaddr,
1140                                     NPC_AF_MCAMEX_BANKX_CFG(entry, bank), 0);
1141         }
1142
1143         /* Allocate resource bimap for pkind*/
1144         pkind->rsrc.max = (rvu_read64(rvu, blkaddr,
1145                                       NPC_AF_CONST1) >> 12) & 0xFF;
1146         err = rvu_alloc_bitmap(&pkind->rsrc);
1147         if (err)
1148                 return err;
1149
1150         /* Allocate mem for pkind to PF and channel mapping info */
1151         pkind->pfchan_map = devm_kcalloc(rvu->dev, pkind->rsrc.max,
1152                                          sizeof(u32), GFP_KERNEL);
1153         if (!pkind->pfchan_map)
1154                 return -ENOMEM;
1155
1156         /* Configure KPU profile */
1157         npc_parser_profile_init(rvu, blkaddr);
1158
1159         /* Config Outer L2, IPv4's NPC layer info */
1160         rvu_write64(rvu, blkaddr, NPC_AF_PCK_DEF_OL2,
1161                     (kpu->lt_def->pck_ol2.lid << 8) | (kpu->lt_def->pck_ol2.ltype_match << 4) |
1162                     kpu->lt_def->pck_ol2.ltype_mask);
1163         rvu_write64(rvu, blkaddr, NPC_AF_PCK_DEF_OIP4,
1164                     (kpu->lt_def->pck_oip4.lid << 8) | (kpu->lt_def->pck_oip4.ltype_match << 4) |
1165                     kpu->lt_def->pck_oip4.ltype_mask);
1166
1167         /* Config Inner IPV4 NPC layer info */
1168         rvu_write64(rvu, blkaddr, NPC_AF_PCK_DEF_IIP4,
1169                     (kpu->lt_def->pck_iip4.lid << 8) | (kpu->lt_def->pck_iip4.ltype_match << 4) |
1170                     kpu->lt_def->pck_iip4.ltype_mask);
1171
1172         /* Enable below for Rx pkts.
1173          * - Outer IPv4 header checksum validation.
1174          * - Detect outer L2 broadcast address and set NPC_RESULT_S[L2M].
1175          * - Inner IPv4 header checksum validation.
1176          * - Set non zero checksum error code value
1177          */
1178         rvu_write64(rvu, blkaddr, NPC_AF_PCK_CFG,
1179                     rvu_read64(rvu, blkaddr, NPC_AF_PCK_CFG) |
1180                     BIT_ULL(32) | BIT_ULL(24) | BIT_ULL(6) |
1181                     BIT_ULL(2) | BIT_ULL(1));
1182
1183         /* Set RX and TX side MCAM search key size.
1184          * LA..LD (ltype only) + Channel
1185          */
1186         rx_kex = npc_mkex_default.keyx_cfg[NIX_INTF_RX];
1187         tx_kex = npc_mkex_default.keyx_cfg[NIX_INTF_TX];
1188         nibble_ena = FIELD_GET(NPC_PARSE_NIBBLE, rx_kex);
1189         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX), rx_kex);
1190         /* Due to an errata (35786) in A0 pass silicon, parse nibble enable
1191          * configuration has to be identical for both Rx and Tx interfaces.
1192          */
1193         if (is_rvu_96xx_B0(rvu)) {
1194                 tx_kex &= ~NPC_PARSE_NIBBLE;
1195                 tx_kex |= FIELD_PREP(NPC_PARSE_NIBBLE, nibble_ena);
1196         }
1197         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_TX), tx_kex);
1198
1199         err = npc_mcam_rsrcs_init(rvu, blkaddr);
1200         if (err)
1201                 return err;
1202
1203         /* Configure MKEX profile */
1204         npc_load_mkex_profile(rvu, blkaddr, rvu->mkex_pfl_name);
1205
1206         /* Set TX miss action to UCAST_DEFAULT i.e
1207          * transmit the packet on NIX LF SQ's default channel.
1208          */
1209         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_MISS_ACT(NIX_INTF_TX),
1210                     NIX_TX_ACTIONOP_UCAST_DEFAULT);
1211
1212         /* If MCAM lookup doesn't result in a match, drop the received packet.
1213          * And map this action to a counter to count dropped pkts.
1214          */
1215         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_MISS_ACT(NIX_INTF_RX),
1216                     NIX_RX_ACTIONOP_DROP);
1217         rvu_write64(rvu, blkaddr, NPC_AF_INTFX_MISS_STAT_ACT(NIX_INTF_RX),
1218                     BIT_ULL(9) | mcam->rx_miss_act_cntr);
1219
1220         return 0;
1221 }
1222
1223 void rvu_npc_freemem(struct rvu *rvu)
1224 {
1225         struct npc_pkind *pkind = &rvu->hw->pkind;
1226         struct npc_mcam *mcam = &rvu->hw->mcam;
1227
1228         kfree(pkind->rsrc.bmap);
1229         kfree(mcam->counters.bmap);
1230         mutex_destroy(&mcam->lock);
1231 }
1232
1233 void rvu_npc_get_mcam_entry_alloc_info(struct rvu *rvu, u16 pcifunc,
1234                                        int blkaddr, int *alloc_cnt,
1235                                        int *enable_cnt)
1236 {
1237         struct npc_mcam *mcam = &rvu->hw->mcam;
1238         int entry;
1239
1240         *alloc_cnt = 0;
1241         *enable_cnt = 0;
1242
1243         for (entry = 0; entry < mcam->bmap_entries; entry++) {
1244                 if (mcam->entry2pfvf_map[entry] == pcifunc) {
1245                         (*alloc_cnt)++;
1246                         if (is_mcam_entry_enabled(rvu, mcam, blkaddr, entry))
1247                                 (*enable_cnt)++;
1248                 }
1249         }
1250 }
1251
1252 void rvu_npc_get_mcam_counter_alloc_info(struct rvu *rvu, u16 pcifunc,
1253                                          int blkaddr, int *alloc_cnt,
1254                                          int *enable_cnt)
1255 {
1256         struct npc_mcam *mcam = &rvu->hw->mcam;
1257         int cntr;
1258
1259         *alloc_cnt = 0;
1260         *enable_cnt = 0;
1261
1262         for (cntr = 0; cntr < mcam->counters.max; cntr++) {
1263                 if (mcam->cntr2pfvf_map[cntr] == pcifunc) {
1264                         (*alloc_cnt)++;
1265                         if (mcam->cntr_refcnt[cntr])
1266                                 (*enable_cnt)++;
1267                 }
1268         }
1269 }
1270
1271 static int npc_mcam_verify_entry(struct npc_mcam *mcam,
1272                                  u16 pcifunc, int entry)
1273 {
1274         /* Verify if entry is valid and if it is indeed
1275          * allocated to the requesting PFFUNC.
1276          */
1277         if (entry >= mcam->bmap_entries)
1278                 return NPC_MCAM_INVALID_REQ;
1279
1280         if (pcifunc != mcam->entry2pfvf_map[entry])
1281                 return NPC_MCAM_PERM_DENIED;
1282
1283         return 0;
1284 }
1285
1286 static int npc_mcam_verify_counter(struct npc_mcam *mcam,
1287                                    u16 pcifunc, int cntr)
1288 {
1289         /* Verify if counter is valid and if it is indeed
1290          * allocated to the requesting PFFUNC.
1291          */
1292         if (cntr >= mcam->counters.max)
1293                 return NPC_MCAM_INVALID_REQ;
1294
1295         if (pcifunc != mcam->cntr2pfvf_map[cntr])
1296                 return NPC_MCAM_PERM_DENIED;
1297
1298         return 0;
1299 }
1300
1301 static void npc_map_mcam_entry_and_cntr(struct rvu *rvu, struct npc_mcam *mcam,
1302                                         int blkaddr, u16 entry, u16 cntr)
1303 {
1304         u16 index = entry & (mcam->banksize - 1);
1305         u16 bank = npc_get_bank(mcam, entry);
1306
1307         /* Set mapping and increment counter's refcnt */
1308         mcam->entry2cntr_map[entry] = cntr;
1309         mcam->cntr_refcnt[cntr]++;
1310         /* Enable stats */
1311         rvu_write64(rvu, blkaddr,
1312                     NPC_AF_MCAMEX_BANKX_STAT_ACT(index, bank),
1313                     BIT_ULL(9) | cntr);
1314 }
1315
1316 static void npc_unmap_mcam_entry_and_cntr(struct rvu *rvu,
1317                                           struct npc_mcam *mcam,
1318                                           int blkaddr, u16 entry, u16 cntr)
1319 {
1320         u16 index = entry & (mcam->banksize - 1);
1321         u16 bank = npc_get_bank(mcam, entry);
1322
1323         /* Remove mapping and reduce counter's refcnt */
1324         mcam->entry2cntr_map[entry] = NPC_MCAM_INVALID_MAP;
1325         mcam->cntr_refcnt[cntr]--;
1326         /* Disable stats */
1327         rvu_write64(rvu, blkaddr,
1328                     NPC_AF_MCAMEX_BANKX_STAT_ACT(index, bank), 0x00);
1329 }
1330
1331 /* Sets MCAM entry in bitmap as used. Update
1332  * reverse bitmap too. Should be called with
1333  * 'mcam->lock' held.
1334  */
1335 static void npc_mcam_set_bit(struct npc_mcam *mcam, u16 index)
1336 {
1337         u16 entry, rentry;
1338
1339         entry = index;
1340         rentry = mcam->bmap_entries - index - 1;
1341
1342         __set_bit(entry, mcam->bmap);
1343         __set_bit(rentry, mcam->bmap_reverse);
1344         mcam->bmap_fcnt--;
1345 }
1346
1347 /* Sets MCAM entry in bitmap as free. Update
1348  * reverse bitmap too. Should be called with
1349  * 'mcam->lock' held.
1350  */
1351 static void npc_mcam_clear_bit(struct npc_mcam *mcam, u16 index)
1352 {
1353         u16 entry, rentry;
1354
1355         entry = index;
1356         rentry = mcam->bmap_entries - index - 1;
1357
1358         __clear_bit(entry, mcam->bmap);
1359         __clear_bit(rentry, mcam->bmap_reverse);
1360         mcam->bmap_fcnt++;
1361 }
1362
1363 static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
1364                                       int blkaddr, u16 pcifunc)
1365 {
1366         u16 index, cntr;
1367
1368         /* Scan all MCAM entries and free the ones mapped to 'pcifunc' */
1369         for (index = 0; index < mcam->bmap_entries; index++) {
1370                 if (mcam->entry2pfvf_map[index] == pcifunc) {
1371                         mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP;
1372                         /* Free the entry in bitmap */
1373                         npc_mcam_clear_bit(mcam, index);
1374                         /* Disable the entry */
1375                         npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
1376
1377                         /* Update entry2counter mapping */
1378                         cntr = mcam->entry2cntr_map[index];
1379                         if (cntr != NPC_MCAM_INVALID_MAP)
1380                                 npc_unmap_mcam_entry_and_cntr(rvu, mcam,
1381                                                               blkaddr, index,
1382                                                               cntr);
1383                 }
1384         }
1385 }
1386
1387 static void npc_mcam_free_all_counters(struct rvu *rvu, struct npc_mcam *mcam,
1388                                        u16 pcifunc)
1389 {
1390         u16 cntr;
1391
1392         /* Scan all MCAM counters and free the ones mapped to 'pcifunc' */
1393         for (cntr = 0; cntr < mcam->counters.max; cntr++) {
1394                 if (mcam->cntr2pfvf_map[cntr] == pcifunc) {
1395                         mcam->cntr2pfvf_map[cntr] = NPC_MCAM_INVALID_MAP;
1396                         mcam->cntr_refcnt[cntr] = 0;
1397                         rvu_free_rsrc(&mcam->counters, cntr);
1398                         /* This API is expected to be called after freeing
1399                          * MCAM entries, which inturn will remove
1400                          * 'entry to counter' mapping.
1401                          * No need to do it again.
1402                          */
1403                 }
1404         }
1405 }
1406
1407 /* Find area of contiguous free entries of size 'nr'.
1408  * If not found return max contiguous free entries available.
1409  */
1410 static u16 npc_mcam_find_zero_area(unsigned long *map, u16 size, u16 start,
1411                                    u16 nr, u16 *max_area)
1412 {
1413         u16 max_area_start = 0;
1414         u16 index, next, end;
1415
1416         *max_area = 0;
1417
1418 again:
1419         index = find_next_zero_bit(map, size, start);
1420         if (index >= size)
1421                 return max_area_start;
1422
1423         end = ((index + nr) >= size) ? size : index + nr;
1424         next = find_next_bit(map, end, index);
1425         if (*max_area < (next - index)) {
1426                 *max_area = next - index;
1427                 max_area_start = index;
1428         }
1429
1430         if (next < end) {
1431                 start = next + 1;
1432                 goto again;
1433         }
1434
1435         return max_area_start;
1436 }
1437
1438 /* Find number of free MCAM entries available
1439  * within range i.e in between 'start' and 'end'.
1440  */
1441 static u16 npc_mcam_get_free_count(unsigned long *map, u16 start, u16 end)
1442 {
1443         u16 index, next;
1444         u16 fcnt = 0;
1445
1446 again:
1447         if (start >= end)
1448                 return fcnt;
1449
1450         index = find_next_zero_bit(map, end, start);
1451         if (index >= end)
1452                 return fcnt;
1453
1454         next = find_next_bit(map, end, index);
1455         if (next <= end) {
1456                 fcnt += next - index;
1457                 start = next + 1;
1458                 goto again;
1459         }
1460
1461         fcnt += end - index;
1462         return fcnt;
1463 }
1464
1465 static void
1466 npc_get_mcam_search_range_priority(struct npc_mcam *mcam,
1467                                    struct npc_mcam_alloc_entry_req *req,
1468                                    u16 *start, u16 *end, bool *reverse)
1469 {
1470         u16 fcnt;
1471
1472         if (req->priority == NPC_MCAM_HIGHER_PRIO)
1473                 goto hprio;
1474
1475         /* For a low priority entry allocation
1476          * - If reference entry is not in hprio zone then
1477          *      search range: ref_entry to end.
1478          * - If reference entry is in hprio zone and if
1479          *   request can be accomodated in non-hprio zone then
1480          *      search range: 'start of middle zone' to 'end'
1481          * - else search in reverse, so that less number of hprio
1482          *   zone entries are allocated.
1483          */
1484
1485         *reverse = false;
1486         *start = req->ref_entry + 1;
1487         *end = mcam->bmap_entries;
1488
1489         if (req->ref_entry >= mcam->hprio_end)
1490                 return;
1491
1492         fcnt = npc_mcam_get_free_count(mcam->bmap,
1493                                        mcam->hprio_end, mcam->bmap_entries);
1494         if (fcnt > req->count)
1495                 *start = mcam->hprio_end;
1496         else
1497                 *reverse = true;
1498         return;
1499
1500 hprio:
1501         /* For a high priority entry allocation, search is always
1502          * in reverse to preserve hprio zone entries.
1503          * - If reference entry is not in lprio zone then
1504          *      search range: 0 to ref_entry.
1505          * - If reference entry is in lprio zone and if
1506          *   request can be accomodated in middle zone then
1507          *      search range: 'hprio_end' to 'lprio_start'
1508          */
1509
1510         *reverse = true;
1511         *start = 0;
1512         *end = req->ref_entry;
1513
1514         if (req->ref_entry <= mcam->lprio_start)
1515                 return;
1516
1517         fcnt = npc_mcam_get_free_count(mcam->bmap,
1518                                        mcam->hprio_end, mcam->lprio_start);
1519         if (fcnt < req->count)
1520                 return;
1521         *start = mcam->hprio_end;
1522         *end = mcam->lprio_start;
1523 }
1524
1525 static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc,
1526                                   struct npc_mcam_alloc_entry_req *req,
1527                                   struct npc_mcam_alloc_entry_rsp *rsp)
1528 {
1529         u16 entry_list[NPC_MAX_NONCONTIG_ENTRIES];
1530         u16 fcnt, hp_fcnt, lp_fcnt;
1531         u16 start, end, index;
1532         int entry, next_start;
1533         bool reverse = false;
1534         unsigned long *bmap;
1535         u16 max_contig;
1536
1537         mutex_lock(&mcam->lock);
1538
1539         /* Check if there are any free entries */
1540         if (!mcam->bmap_fcnt) {
1541                 mutex_unlock(&mcam->lock);
1542                 return NPC_MCAM_ALLOC_FAILED;
1543         }
1544
1545         /* MCAM entries are divided into high priority, middle and
1546          * low priority zones. Idea is to not allocate top and lower
1547          * most entries as much as possible, this is to increase
1548          * probability of honouring priority allocation requests.
1549          *
1550          * Two bitmaps are used for mcam entry management,
1551          * mcam->bmap for forward search i.e '0 to mcam->bmap_entries'.
1552          * mcam->bmap_reverse for reverse search i.e 'mcam->bmap_entries to 0'.
1553          *
1554          * Reverse bitmap is used to allocate entries
1555          * - when a higher priority entry is requested
1556          * - when available free entries are less.
1557          * Lower priority ones out of avaialble free entries are always
1558          * chosen when 'high vs low' question arises.
1559          */
1560
1561         /* Get the search range for priority allocation request */
1562         if (req->priority) {
1563                 npc_get_mcam_search_range_priority(mcam, req,
1564                                                    &start, &end, &reverse);
1565                 goto alloc;
1566         }
1567
1568         /* Find out the search range for non-priority allocation request
1569          *
1570          * Get MCAM free entry count in middle zone.
1571          */
1572         lp_fcnt = npc_mcam_get_free_count(mcam->bmap,
1573                                           mcam->lprio_start,
1574                                           mcam->bmap_entries);
1575         hp_fcnt = npc_mcam_get_free_count(mcam->bmap, 0, mcam->hprio_end);
1576         fcnt = mcam->bmap_fcnt - lp_fcnt - hp_fcnt;
1577
1578         /* Check if request can be accomodated in the middle zone */
1579         if (fcnt > req->count) {
1580                 start = mcam->hprio_end;
1581                 end = mcam->lprio_start;
1582         } else if ((fcnt + (hp_fcnt / 2) + (lp_fcnt / 2)) > req->count) {
1583                 /* Expand search zone from half of hprio zone to
1584                  * half of lprio zone.
1585                  */
1586                 start = mcam->hprio_end / 2;
1587                 end = mcam->bmap_entries - (mcam->lprio_count / 2);
1588                 reverse = true;
1589         } else {
1590                 /* Not enough free entries, search all entries in reverse,
1591                  * so that low priority ones will get used up.
1592                  */
1593                 reverse = true;
1594                 start = 0;
1595                 end = mcam->bmap_entries;
1596         }
1597
1598 alloc:
1599         if (reverse) {
1600                 bmap = mcam->bmap_reverse;
1601                 start = mcam->bmap_entries - start;
1602                 end = mcam->bmap_entries - end;
1603                 index = start;
1604                 start = end;
1605                 end = index;
1606         } else {
1607                 bmap = mcam->bmap;
1608         }
1609
1610         if (req->contig) {
1611                 /* Allocate requested number of contiguous entries, if
1612                  * unsuccessful find max contiguous entries available.
1613                  */
1614                 index = npc_mcam_find_zero_area(bmap, end, start,
1615                                                 req->count, &max_contig);
1616                 rsp->count = max_contig;
1617                 if (reverse)
1618                         rsp->entry = mcam->bmap_entries - index - max_contig;
1619                 else
1620                         rsp->entry = index;
1621         } else {
1622                 /* Allocate requested number of non-contiguous entries,
1623                  * if unsuccessful allocate as many as possible.
1624                  */
1625                 rsp->count = 0;
1626                 next_start = start;
1627                 for (entry = 0; entry < req->count; entry++) {
1628                         index = find_next_zero_bit(bmap, end, next_start);
1629                         if (index >= end)
1630                                 break;
1631
1632                         next_start = start + (index - start) + 1;
1633
1634                         /* Save the entry's index */
1635                         if (reverse)
1636                                 index = mcam->bmap_entries - index - 1;
1637                         entry_list[entry] = index;
1638                         rsp->count++;
1639                 }
1640         }
1641
1642         /* If allocating requested no of entries is unsucessful,
1643          * expand the search range to full bitmap length and retry.
1644          */
1645         if (!req->priority && (rsp->count < req->count) &&
1646             ((end - start) != mcam->bmap_entries)) {
1647                 reverse = true;
1648                 start = 0;
1649                 end = mcam->bmap_entries;
1650                 goto alloc;
1651         }
1652
1653         /* For priority entry allocation requests, if allocation is
1654          * failed then expand search to max possible range and retry.
1655          */
1656         if (req->priority && rsp->count < req->count) {
1657                 if (req->priority == NPC_MCAM_LOWER_PRIO &&
1658                     (start != (req->ref_entry + 1))) {
1659                         start = req->ref_entry + 1;
1660                         end = mcam->bmap_entries;
1661                         reverse = false;
1662                         goto alloc;
1663                 } else if ((req->priority == NPC_MCAM_HIGHER_PRIO) &&
1664                            ((end - start) != req->ref_entry)) {
1665                         start = 0;
1666                         end = req->ref_entry;
1667                         reverse = true;
1668                         goto alloc;
1669                 }
1670         }
1671
1672         /* Copy MCAM entry indices into mbox response entry_list.
1673          * Requester always expects indices in ascending order, so
1674          * so reverse the list if reverse bitmap is used for allocation.
1675          */
1676         if (!req->contig && rsp->count) {
1677                 index = 0;
1678                 for (entry = rsp->count - 1; entry >= 0; entry--) {
1679                         if (reverse)
1680                                 rsp->entry_list[index++] = entry_list[entry];
1681                         else
1682                                 rsp->entry_list[entry] = entry_list[entry];
1683                 }
1684         }
1685
1686         /* Mark the allocated entries as used and set nixlf mapping */
1687         for (entry = 0; entry < rsp->count; entry++) {
1688                 index = req->contig ?
1689                         (rsp->entry + entry) : rsp->entry_list[entry];
1690                 npc_mcam_set_bit(mcam, index);
1691                 mcam->entry2pfvf_map[index] = pcifunc;
1692                 mcam->entry2cntr_map[index] = NPC_MCAM_INVALID_MAP;
1693         }
1694
1695         /* Update available free count in mbox response */
1696         rsp->free_count = mcam->bmap_fcnt;
1697
1698         mutex_unlock(&mcam->lock);
1699         return 0;
1700 }
1701
1702 int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu *rvu,
1703                                           struct npc_mcam_alloc_entry_req *req,
1704                                           struct npc_mcam_alloc_entry_rsp *rsp)
1705 {
1706         struct npc_mcam *mcam = &rvu->hw->mcam;
1707         u16 pcifunc = req->hdr.pcifunc;
1708         int blkaddr;
1709
1710         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1711         if (blkaddr < 0)
1712                 return NPC_MCAM_INVALID_REQ;
1713
1714         rsp->entry = NPC_MCAM_ENTRY_INVALID;
1715         rsp->free_count = 0;
1716
1717         /* Check if ref_entry is within range */
1718         if (req->priority && req->ref_entry >= mcam->bmap_entries)
1719                 return NPC_MCAM_INVALID_REQ;
1720
1721         /* ref_entry can't be '0' if requested priority is high.
1722          * Can't be last entry if requested priority is low.
1723          */
1724         if ((!req->ref_entry && req->priority == NPC_MCAM_HIGHER_PRIO) ||
1725             ((req->ref_entry == (mcam->bmap_entries - 1)) &&
1726              req->priority == NPC_MCAM_LOWER_PRIO))
1727                 return NPC_MCAM_INVALID_REQ;
1728
1729         /* Since list of allocated indices needs to be sent to requester,
1730          * max number of non-contiguous entries per mbox msg is limited.
1731          */
1732         if (!req->contig && req->count > NPC_MAX_NONCONTIG_ENTRIES)
1733                 return NPC_MCAM_INVALID_REQ;
1734
1735         /* Alloc request from PFFUNC with no NIXLF attached should be denied */
1736         if (!is_nixlf_attached(rvu, pcifunc))
1737                 return NPC_MCAM_ALLOC_DENIED;
1738
1739         return npc_mcam_alloc_entries(mcam, pcifunc, req, rsp);
1740 }
1741
1742 int rvu_mbox_handler_npc_mcam_free_entry(struct rvu *rvu,
1743                                          struct npc_mcam_free_entry_req *req,
1744                                          struct msg_rsp *rsp)
1745 {
1746         struct npc_mcam *mcam = &rvu->hw->mcam;
1747         u16 pcifunc = req->hdr.pcifunc;
1748         int blkaddr, rc = 0;
1749         u16 cntr;
1750
1751         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1752         if (blkaddr < 0)
1753                 return NPC_MCAM_INVALID_REQ;
1754
1755         /* Free request from PFFUNC with no NIXLF attached, ignore */
1756         if (!is_nixlf_attached(rvu, pcifunc))
1757                 return NPC_MCAM_INVALID_REQ;
1758
1759         mutex_lock(&mcam->lock);
1760
1761         if (req->all)
1762                 goto free_all;
1763
1764         rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry);
1765         if (rc)
1766                 goto exit;
1767
1768         mcam->entry2pfvf_map[req->entry] = 0;
1769         npc_mcam_clear_bit(mcam, req->entry);
1770         npc_enable_mcam_entry(rvu, mcam, blkaddr, req->entry, false);
1771
1772         /* Update entry2counter mapping */
1773         cntr = mcam->entry2cntr_map[req->entry];
1774         if (cntr != NPC_MCAM_INVALID_MAP)
1775                 npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr,
1776                                               req->entry, cntr);
1777
1778         goto exit;
1779
1780 free_all:
1781         /* Free up all entries allocated to requesting PFFUNC */
1782         npc_mcam_free_all_entries(rvu, mcam, blkaddr, pcifunc);
1783 exit:
1784         mutex_unlock(&mcam->lock);
1785         return rc;
1786 }
1787
1788 int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu,
1789                                           struct npc_mcam_write_entry_req *req,
1790                                           struct msg_rsp *rsp)
1791 {
1792         struct npc_mcam *mcam = &rvu->hw->mcam;
1793         u16 pcifunc = req->hdr.pcifunc;
1794         int blkaddr, rc;
1795
1796         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1797         if (blkaddr < 0)
1798                 return NPC_MCAM_INVALID_REQ;
1799
1800         mutex_lock(&mcam->lock);
1801         rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry);
1802         if (rc)
1803                 goto exit;
1804
1805         if (req->set_cntr &&
1806             npc_mcam_verify_counter(mcam, pcifunc, req->cntr)) {
1807                 rc = NPC_MCAM_INVALID_REQ;
1808                 goto exit;
1809         }
1810
1811         if (req->intf != NIX_INTF_RX && req->intf != NIX_INTF_TX) {
1812                 rc = NPC_MCAM_INVALID_REQ;
1813                 goto exit;
1814         }
1815
1816         npc_config_mcam_entry(rvu, mcam, blkaddr, req->entry, req->intf,
1817                               &req->entry_data, req->enable_entry);
1818
1819         if (req->set_cntr)
1820                 npc_map_mcam_entry_and_cntr(rvu, mcam, blkaddr,
1821                                             req->entry, req->cntr);
1822
1823         rc = 0;
1824 exit:
1825         mutex_unlock(&mcam->lock);
1826         return rc;
1827 }
1828
1829 int rvu_mbox_handler_npc_mcam_ena_entry(struct rvu *rvu,
1830                                         struct npc_mcam_ena_dis_entry_req *req,
1831                                         struct msg_rsp *rsp)
1832 {
1833         struct npc_mcam *mcam = &rvu->hw->mcam;
1834         u16 pcifunc = req->hdr.pcifunc;
1835         int blkaddr, rc;
1836
1837         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1838         if (blkaddr < 0)
1839                 return NPC_MCAM_INVALID_REQ;
1840
1841         mutex_lock(&mcam->lock);
1842         rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry);
1843         mutex_unlock(&mcam->lock);
1844         if (rc)
1845                 return rc;
1846
1847         npc_enable_mcam_entry(rvu, mcam, blkaddr, req->entry, true);
1848
1849         return 0;
1850 }
1851
1852 int rvu_mbox_handler_npc_mcam_dis_entry(struct rvu *rvu,
1853                                         struct npc_mcam_ena_dis_entry_req *req,
1854                                         struct msg_rsp *rsp)
1855 {
1856         struct npc_mcam *mcam = &rvu->hw->mcam;
1857         u16 pcifunc = req->hdr.pcifunc;
1858         int blkaddr, rc;
1859
1860         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1861         if (blkaddr < 0)
1862                 return NPC_MCAM_INVALID_REQ;
1863
1864         mutex_lock(&mcam->lock);
1865         rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry);
1866         mutex_unlock(&mcam->lock);
1867         if (rc)
1868                 return rc;
1869
1870         npc_enable_mcam_entry(rvu, mcam, blkaddr, req->entry, false);
1871
1872         return 0;
1873 }
1874
1875 int rvu_mbox_handler_npc_mcam_shift_entry(struct rvu *rvu,
1876                                           struct npc_mcam_shift_entry_req *req,
1877                                           struct npc_mcam_shift_entry_rsp *rsp)
1878 {
1879         struct npc_mcam *mcam = &rvu->hw->mcam;
1880         u16 pcifunc = req->hdr.pcifunc;
1881         u16 old_entry, new_entry;
1882         u16 index, cntr;
1883         int blkaddr, rc;
1884
1885         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1886         if (blkaddr < 0)
1887                 return NPC_MCAM_INVALID_REQ;
1888
1889         if (req->shift_count > NPC_MCAM_MAX_SHIFTS)
1890                 return NPC_MCAM_INVALID_REQ;
1891
1892         mutex_lock(&mcam->lock);
1893         for (index = 0; index < req->shift_count; index++) {
1894                 old_entry = req->curr_entry[index];
1895                 new_entry = req->new_entry[index];
1896
1897                 /* Check if both old and new entries are valid and
1898                  * does belong to this PFFUNC or not.
1899                  */
1900                 rc = npc_mcam_verify_entry(mcam, pcifunc, old_entry);
1901                 if (rc)
1902                         break;
1903
1904                 rc = npc_mcam_verify_entry(mcam, pcifunc, new_entry);
1905                 if (rc)
1906                         break;
1907
1908                 /* new_entry should not have a counter mapped */
1909                 if (mcam->entry2cntr_map[new_entry] != NPC_MCAM_INVALID_MAP) {
1910                         rc = NPC_MCAM_PERM_DENIED;
1911                         break;
1912                 }
1913
1914                 /* Disable the new_entry */
1915                 npc_enable_mcam_entry(rvu, mcam, blkaddr, new_entry, false);
1916
1917                 /* Copy rule from old entry to new entry */
1918                 npc_copy_mcam_entry(rvu, mcam, blkaddr, old_entry, new_entry);
1919
1920                 /* Copy counter mapping, if any */
1921                 cntr = mcam->entry2cntr_map[old_entry];
1922                 if (cntr != NPC_MCAM_INVALID_MAP) {
1923                         npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr,
1924                                                       old_entry, cntr);
1925                         npc_map_mcam_entry_and_cntr(rvu, mcam, blkaddr,
1926                                                     new_entry, cntr);
1927                 }
1928
1929                 /* Enable new_entry and disable old_entry */
1930                 npc_enable_mcam_entry(rvu, mcam, blkaddr, new_entry, true);
1931                 npc_enable_mcam_entry(rvu, mcam, blkaddr, old_entry, false);
1932         }
1933
1934         /* If shift has failed then report the failed index */
1935         if (index != req->shift_count) {
1936                 rc = NPC_MCAM_PERM_DENIED;
1937                 rsp->failed_entry_idx = index;
1938         }
1939
1940         mutex_unlock(&mcam->lock);
1941         return rc;
1942 }
1943
1944 int rvu_mbox_handler_npc_mcam_alloc_counter(struct rvu *rvu,
1945                         struct npc_mcam_alloc_counter_req *req,
1946                         struct npc_mcam_alloc_counter_rsp *rsp)
1947 {
1948         struct npc_mcam *mcam = &rvu->hw->mcam;
1949         u16 pcifunc = req->hdr.pcifunc;
1950         u16 max_contig, cntr;
1951         int blkaddr, index;
1952
1953         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1954         if (blkaddr < 0)
1955                 return NPC_MCAM_INVALID_REQ;
1956
1957         /* If the request is from a PFFUNC with no NIXLF attached, ignore */
1958         if (!is_nixlf_attached(rvu, pcifunc))
1959                 return NPC_MCAM_INVALID_REQ;
1960
1961         /* Since list of allocated counter IDs needs to be sent to requester,
1962          * max number of non-contiguous counters per mbox msg is limited.
1963          */
1964         if (!req->contig && req->count > NPC_MAX_NONCONTIG_COUNTERS)
1965                 return NPC_MCAM_INVALID_REQ;
1966
1967         mutex_lock(&mcam->lock);
1968
1969         /* Check if unused counters are available or not */
1970         if (!rvu_rsrc_free_count(&mcam->counters)) {
1971                 mutex_unlock(&mcam->lock);
1972                 return NPC_MCAM_ALLOC_FAILED;
1973         }
1974
1975         rsp->count = 0;
1976
1977         if (req->contig) {
1978                 /* Allocate requested number of contiguous counters, if
1979                  * unsuccessful find max contiguous entries available.
1980                  */
1981                 index = npc_mcam_find_zero_area(mcam->counters.bmap,
1982                                                 mcam->counters.max, 0,
1983                                                 req->count, &max_contig);
1984                 rsp->count = max_contig;
1985                 rsp->cntr = index;
1986                 for (cntr = index; cntr < (index + max_contig); cntr++) {
1987                         __set_bit(cntr, mcam->counters.bmap);
1988                         mcam->cntr2pfvf_map[cntr] = pcifunc;
1989                 }
1990         } else {
1991                 /* Allocate requested number of non-contiguous counters,
1992                  * if unsuccessful allocate as many as possible.
1993                  */
1994                 for (cntr = 0; cntr < req->count; cntr++) {
1995                         index = rvu_alloc_rsrc(&mcam->counters);
1996                         if (index < 0)
1997                                 break;
1998                         rsp->cntr_list[cntr] = index;
1999                         rsp->count++;
2000                         mcam->cntr2pfvf_map[index] = pcifunc;
2001                 }
2002         }
2003
2004         mutex_unlock(&mcam->lock);
2005         return 0;
2006 }
2007
2008 int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu,
2009                 struct npc_mcam_oper_counter_req *req, struct msg_rsp *rsp)
2010 {
2011         struct npc_mcam *mcam = &rvu->hw->mcam;
2012         u16 index, entry = 0;
2013         int blkaddr, err;
2014
2015         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
2016         if (blkaddr < 0)
2017                 return NPC_MCAM_INVALID_REQ;
2018
2019         mutex_lock(&mcam->lock);
2020         err = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr);
2021         if (err) {
2022                 mutex_unlock(&mcam->lock);
2023                 return err;
2024         }
2025
2026         /* Mark counter as free/unused */
2027         mcam->cntr2pfvf_map[req->cntr] = NPC_MCAM_INVALID_MAP;
2028         rvu_free_rsrc(&mcam->counters, req->cntr);
2029
2030         /* Disable all MCAM entry's stats which are using this counter */
2031         while (entry < mcam->bmap_entries) {
2032                 if (!mcam->cntr_refcnt[req->cntr])
2033                         break;
2034
2035                 index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry);
2036                 if (index >= mcam->bmap_entries)
2037                         break;
2038                 if (mcam->entry2cntr_map[index] != req->cntr)
2039                         continue;
2040
2041                 entry = index + 1;
2042                 npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr,
2043                                               index, req->cntr);
2044         }
2045
2046         mutex_unlock(&mcam->lock);
2047         return 0;
2048 }
2049
2050 int rvu_mbox_handler_npc_mcam_unmap_counter(struct rvu *rvu,
2051                 struct npc_mcam_unmap_counter_req *req, struct msg_rsp *rsp)
2052 {
2053         struct npc_mcam *mcam = &rvu->hw->mcam;
2054         u16 index, entry = 0;
2055         int blkaddr, rc;
2056
2057         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
2058         if (blkaddr < 0)
2059                 return NPC_MCAM_INVALID_REQ;
2060
2061         mutex_lock(&mcam->lock);
2062         rc = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr);
2063         if (rc)
2064                 goto exit;
2065
2066         /* Unmap the MCAM entry and counter */
2067         if (!req->all) {
2068                 rc = npc_mcam_verify_entry(mcam, req->hdr.pcifunc, req->entry);
2069                 if (rc)
2070                         goto exit;
2071                 npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr,
2072                                               req->entry, req->cntr);
2073                 goto exit;
2074         }
2075
2076         /* Disable all MCAM entry's stats which are using this counter */
2077         while (entry < mcam->bmap_entries) {
2078                 if (!mcam->cntr_refcnt[req->cntr])
2079                         break;
2080
2081                 index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry);
2082                 if (index >= mcam->bmap_entries)
2083                         break;
2084                 if (mcam->entry2cntr_map[index] != req->cntr)
2085                         continue;
2086
2087                 entry = index + 1;
2088                 npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr,
2089                                               index, req->cntr);
2090         }
2091 exit:
2092         mutex_unlock(&mcam->lock);
2093         return rc;
2094 }
2095
2096 int rvu_mbox_handler_npc_mcam_clear_counter(struct rvu *rvu,
2097                 struct npc_mcam_oper_counter_req *req, struct msg_rsp *rsp)
2098 {
2099         struct npc_mcam *mcam = &rvu->hw->mcam;
2100         int blkaddr, err;
2101
2102         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
2103         if (blkaddr < 0)
2104                 return NPC_MCAM_INVALID_REQ;
2105
2106         mutex_lock(&mcam->lock);
2107         err = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr);
2108         mutex_unlock(&mcam->lock);
2109         if (err)
2110                 return err;
2111
2112         rvu_write64(rvu, blkaddr, NPC_AF_MATCH_STATX(req->cntr), 0x00);
2113
2114         return 0;
2115 }
2116
2117 int rvu_mbox_handler_npc_mcam_counter_stats(struct rvu *rvu,
2118                         struct npc_mcam_oper_counter_req *req,
2119                         struct npc_mcam_oper_counter_rsp *rsp)
2120 {
2121         struct npc_mcam *mcam = &rvu->hw->mcam;
2122         int blkaddr, err;
2123
2124         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
2125         if (blkaddr < 0)
2126                 return NPC_MCAM_INVALID_REQ;
2127
2128         mutex_lock(&mcam->lock);
2129         err = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr);
2130         mutex_unlock(&mcam->lock);
2131         if (err)
2132                 return err;
2133
2134         rsp->stat = rvu_read64(rvu, blkaddr, NPC_AF_MATCH_STATX(req->cntr));
2135         rsp->stat &= BIT_ULL(48) - 1;
2136
2137         return 0;
2138 }
2139
2140 int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(struct rvu *rvu,
2141                           struct npc_mcam_alloc_and_write_entry_req *req,
2142                           struct npc_mcam_alloc_and_write_entry_rsp *rsp)
2143 {
2144         struct npc_mcam_alloc_counter_req cntr_req;
2145         struct npc_mcam_alloc_counter_rsp cntr_rsp;
2146         struct npc_mcam_alloc_entry_req entry_req;
2147         struct npc_mcam_alloc_entry_rsp entry_rsp;
2148         struct npc_mcam *mcam = &rvu->hw->mcam;
2149         u16 entry = NPC_MCAM_ENTRY_INVALID;
2150         u16 cntr = NPC_MCAM_ENTRY_INVALID;
2151         int blkaddr, rc;
2152
2153         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
2154         if (blkaddr < 0)
2155                 return NPC_MCAM_INVALID_REQ;
2156
2157         if (req->intf != NIX_INTF_RX && req->intf != NIX_INTF_TX)
2158                 return NPC_MCAM_INVALID_REQ;
2159
2160         /* Try to allocate a MCAM entry */
2161         entry_req.hdr.pcifunc = req->hdr.pcifunc;
2162         entry_req.contig = true;
2163         entry_req.priority = req->priority;
2164         entry_req.ref_entry = req->ref_entry;
2165         entry_req.count = 1;
2166
2167         rc = rvu_mbox_handler_npc_mcam_alloc_entry(rvu,
2168                                                    &entry_req, &entry_rsp);
2169         if (rc)
2170                 return rc;
2171
2172         if (!entry_rsp.count)
2173                 return NPC_MCAM_ALLOC_FAILED;
2174
2175         entry = entry_rsp.entry;
2176
2177         if (!req->alloc_cntr)
2178                 goto write_entry;
2179
2180         /* Now allocate counter */
2181         cntr_req.hdr.pcifunc = req->hdr.pcifunc;
2182         cntr_req.contig = true;
2183         cntr_req.count = 1;
2184
2185         rc = rvu_mbox_handler_npc_mcam_alloc_counter(rvu, &cntr_req, &cntr_rsp);
2186         if (rc) {
2187                 /* Free allocated MCAM entry */
2188                 mutex_lock(&mcam->lock);
2189                 mcam->entry2pfvf_map[entry] = 0;
2190                 npc_mcam_clear_bit(mcam, entry);
2191                 mutex_unlock(&mcam->lock);
2192                 return rc;
2193         }
2194
2195         cntr = cntr_rsp.cntr;
2196
2197 write_entry:
2198         mutex_lock(&mcam->lock);
2199         npc_config_mcam_entry(rvu, mcam, blkaddr, entry, req->intf,
2200                               &req->entry_data, req->enable_entry);
2201
2202         if (req->alloc_cntr)
2203                 npc_map_mcam_entry_and_cntr(rvu, mcam, blkaddr, entry, cntr);
2204         mutex_unlock(&mcam->lock);
2205
2206         rsp->entry = entry;
2207         rsp->cntr = cntr;
2208
2209         return 0;
2210 }
2211
2212 #define GET_KEX_CFG(intf) \
2213         rvu_read64(rvu, BLKADDR_NPC, NPC_AF_INTFX_KEX_CFG(intf))
2214
2215 #define GET_KEX_FLAGS(ld) \
2216         rvu_read64(rvu, BLKADDR_NPC, NPC_AF_KEX_LDATAX_FLAGS_CFG(ld))
2217
2218 #define GET_KEX_LD(intf, lid, lt, ld)   \
2219         rvu_read64(rvu, BLKADDR_NPC,    \
2220                 NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, lid, lt, ld))
2221
2222 #define GET_KEX_LDFLAGS(intf, ld, fl)   \
2223         rvu_read64(rvu, BLKADDR_NPC,    \
2224                 NPC_AF_INTFX_LDATAX_FLAGSX_CFG(intf, ld, fl))
2225
2226 int rvu_mbox_handler_npc_get_kex_cfg(struct rvu *rvu, struct msg_req *req,
2227                                      struct npc_get_kex_cfg_rsp *rsp)
2228 {
2229         int lid, lt, ld, fl;
2230
2231         rsp->rx_keyx_cfg = GET_KEX_CFG(NIX_INTF_RX);
2232         rsp->tx_keyx_cfg = GET_KEX_CFG(NIX_INTF_TX);
2233         for (lid = 0; lid < NPC_MAX_LID; lid++) {
2234                 for (lt = 0; lt < NPC_MAX_LT; lt++) {
2235                         for (ld = 0; ld < NPC_MAX_LD; ld++) {
2236                                 rsp->intf_lid_lt_ld[NIX_INTF_RX][lid][lt][ld] =
2237                                         GET_KEX_LD(NIX_INTF_RX, lid, lt, ld);
2238                                 rsp->intf_lid_lt_ld[NIX_INTF_TX][lid][lt][ld] =
2239                                         GET_KEX_LD(NIX_INTF_TX, lid, lt, ld);
2240                         }
2241                 }
2242         }
2243         for (ld = 0; ld < NPC_MAX_LD; ld++)
2244                 rsp->kex_ld_flags[ld] = GET_KEX_FLAGS(ld);
2245
2246         for (ld = 0; ld < NPC_MAX_LD; ld++) {
2247                 for (fl = 0; fl < NPC_MAX_LFL; fl++) {
2248                         rsp->intf_ld_flags[NIX_INTF_RX][ld][fl] =
2249                                         GET_KEX_LDFLAGS(NIX_INTF_RX, ld, fl);
2250                         rsp->intf_ld_flags[NIX_INTF_TX][ld][fl] =
2251                                         GET_KEX_LDFLAGS(NIX_INTF_TX, ld, fl);
2252                 }
2253         }
2254         memcpy(rsp->mkex_pfl_name, rvu->mkex_pfl_name, MKEX_NAME_LEN);
2255         return 0;
2256 }
2257
2258 int rvu_npc_update_rxvlan(struct rvu *rvu, u16 pcifunc, int nixlf)
2259 {
2260         struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
2261         struct npc_mcam *mcam = &rvu->hw->mcam;
2262         int blkaddr, index;
2263         bool enable;
2264
2265         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
2266         if (blkaddr < 0)
2267                 return NIX_AF_ERR_AF_LF_INVALID;
2268
2269         if (!pfvf->rxvlan)
2270                 return 0;
2271
2272         index = npc_get_nixlf_mcam_index(mcam, pcifunc, nixlf,
2273                                          NIXLF_UCAST_ENTRY);
2274         pfvf->entry.action = npc_get_mcam_action(rvu, mcam, blkaddr, index);
2275         enable = is_mcam_entry_enabled(rvu, mcam, blkaddr, index);
2276         npc_config_mcam_entry(rvu, mcam, blkaddr, pfvf->rxvlan_index,
2277                               NIX_INTF_RX, &pfvf->entry, enable);
2278
2279         return 0;
2280 }