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 } 2281