1 // SPDX-License-Identifier: GPL-2.0 2 /* Marvell RVU Admin Function driver 3 * 4 * Copyright (C) 2018 Marvell. 5 * 6 */ 7 8 #include <linux/bitfield.h> 9 #include <linux/module.h> 10 #include <linux/pci.h> 11 12 #include "rvu_struct.h" 13 #include "rvu_reg.h" 14 #include "rvu.h" 15 #include "npc.h" 16 #include "cgx.h" 17 #include "npc_profile.h" 18 #include "rvu_npc_hash.h" 19 #include "cn20k/npc.h" 20 #include "rvu_npc.h" 21 #include "cn20k/reg.h" 22 23 #define RSVD_MCAM_ENTRIES_PER_PF 3 /* Broadcast, Promisc and AllMulticast */ 24 #define RSVD_MCAM_ENTRIES_PER_NIXLF 1 /* Ucast for LFs */ 25 26 #define NPC_PARSE_RESULT_DMAC_OFFSET 8 27 #define NPC_HW_TSTAMP_OFFSET 8ULL 28 #define NPC_KEX_CHAN_MASK 0xFFFULL 29 #define NPC_KEX_PF_FUNC_MASK 0xFFFFULL 30 31 #define ALIGN_8B_CEIL(__a) (((__a) + 7) & (-8)) 32 33 static const char def_pfl_name[] = "default"; 34 35 static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam, 36 int blkaddr, u16 pcifunc); 37 static void npc_mcam_free_all_counters(struct rvu *rvu, struct npc_mcam *mcam, 38 u16 pcifunc); 39 40 bool is_npc_intf_tx(u8 intf) 41 { 42 return !!(intf & 0x1); 43 } 44 45 bool is_npc_intf_rx(u8 intf) 46 { 47 return !(intf & 0x1); 48 } 49 50 bool is_npc_interface_valid(struct rvu *rvu, u8 intf) 51 { 52 struct rvu_hwinfo *hw = rvu->hw; 53 54 return intf < hw->npc_intfs; 55 } 56 57 int rvu_npc_get_tx_nibble_cfg(struct rvu *rvu, u64 nibble_ena) 58 { 59 /* Due to a HW issue in these silicon versions, parse nibble enable 60 * configuration has to be identical for both Rx and Tx interfaces. 61 */ 62 if (is_rvu_96xx_B0(rvu)) 63 return nibble_ena; 64 return 0; 65 } 66 67 void rvu_npc_set_pkind(struct rvu *rvu, int pkind, struct rvu_pfvf *pfvf) 68 { 69 int blkaddr; 70 u64 val = 0; 71 72 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 73 if (blkaddr < 0) 74 return; 75 76 /* Config CPI base for the PKIND */ 77 val = pkind | 1ULL << 62; 78 rvu_write64(rvu, blkaddr, NPC_AF_PKINDX_CPI_DEFX(pkind, 0), val); 79 } 80 81 int rvu_npc_get_pkind(struct rvu *rvu, u16 pf) 82 { 83 struct npc_pkind *pkind = &rvu->hw->pkind; 84 u32 map; 85 int i; 86 87 for (i = 0; i < pkind->rsrc.max; i++) { 88 map = pkind->pfchan_map[i]; 89 if (((map >> 16) & 0x3F) == pf) 90 return i; 91 } 92 return -1; 93 } 94 95 #define NPC_AF_ACTION0_PTR_ADVANCE GENMASK_ULL(27, 20) 96 97 int npc_config_ts_kpuaction(struct rvu *rvu, int pf, u16 pcifunc, bool enable) 98 { 99 int pkind, blkaddr; 100 u64 val; 101 102 pkind = rvu_npc_get_pkind(rvu, pf); 103 if (pkind < 0) { 104 dev_err(rvu->dev, "%s: pkind not mapped\n", __func__); 105 return -EINVAL; 106 } 107 108 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, pcifunc); 109 if (blkaddr < 0) { 110 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__); 111 return -EINVAL; 112 } 113 114 val = rvu_read64(rvu, blkaddr, NPC_AF_PKINDX_ACTION0(pkind)); 115 val &= ~NPC_AF_ACTION0_PTR_ADVANCE; 116 /* If timestamp is enabled then configure NPC to shift 8 bytes */ 117 if (enable) 118 val |= FIELD_PREP(NPC_AF_ACTION0_PTR_ADVANCE, 119 NPC_HW_TSTAMP_OFFSET); 120 rvu_write64(rvu, blkaddr, NPC_AF_PKINDX_ACTION0(pkind), val); 121 122 return 0; 123 } 124 125 static int npc_get_ucast_mcam_index(struct npc_mcam *mcam, u16 pcifunc, 126 int nixlf) 127 { 128 struct rvu_hwinfo *hw = container_of(mcam, struct rvu_hwinfo, mcam); 129 struct rvu *rvu = hw->rvu; 130 int blkaddr = 0, max = 0; 131 struct rvu_block *block; 132 struct rvu_pfvf *pfvf; 133 134 pfvf = rvu_get_pfvf(rvu, pcifunc); 135 /* Given a PF/VF and NIX LF number calculate the unicast mcam 136 * entry index based on the NIX block assigned to the PF/VF. 137 */ 138 blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr); 139 while (blkaddr) { 140 if (pfvf->nix_blkaddr == blkaddr) 141 break; 142 block = &rvu->hw->block[blkaddr]; 143 max += block->lf.max; 144 blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr); 145 } 146 147 return mcam->nixlf_offset + (max + nixlf) * RSVD_MCAM_ENTRIES_PER_NIXLF; 148 } 149 150 int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, 151 u16 pcifunc, int nixlf, int type) 152 { 153 struct rvu_hwinfo *hw = container_of(mcam, struct rvu_hwinfo, mcam); 154 struct rvu *rvu = hw->rvu; 155 u16 bcast, mcast, promisc, ucast; 156 int index; 157 int rc; 158 int pf; 159 160 if (is_cn20k(rvu->pdev)) { 161 rc = npc_cn20k_dft_rules_idx_get(rvu, pcifunc, &bcast, &mcast, 162 &promisc, &ucast); 163 if (rc) 164 return -EFAULT; 165 166 if (is_lbk_vf(rvu, pcifunc)) { 167 if (promisc == USHRT_MAX) 168 return -EINVAL; 169 return promisc; 170 } 171 172 if (is_cgx_vf(rvu, pcifunc)) { 173 if (ucast == USHRT_MAX) 174 return -EINVAL; 175 176 return ucast; 177 } 178 179 switch (type) { 180 case NIXLF_BCAST_ENTRY: 181 if (bcast == USHRT_MAX) 182 return -EINVAL; 183 return bcast; 184 case NIXLF_ALLMULTI_ENTRY: 185 if (mcast == USHRT_MAX) 186 return -EINVAL; 187 return mcast; 188 case NIXLF_PROMISC_ENTRY: 189 if (promisc == USHRT_MAX) 190 return -EINVAL; 191 return promisc; 192 case NIXLF_UCAST_ENTRY: 193 if (ucast == USHRT_MAX) 194 return -EINVAL; 195 return ucast; 196 default: 197 return -EINVAL; 198 } 199 } 200 201 /* Check if this is for a PF */ 202 pf = rvu_get_pf(rvu->pdev, pcifunc); 203 if (pf && !(pcifunc & RVU_PFVF_FUNC_MASK)) { 204 /* Reserved entries exclude PF0 */ 205 pf--; 206 index = mcam->pf_offset + (pf * RSVD_MCAM_ENTRIES_PER_PF); 207 /* Broadcast address matching entry should be first so 208 * that the packet can be replicated to all VFs. 209 */ 210 if (type == NIXLF_BCAST_ENTRY) 211 return index; 212 else if (type == NIXLF_ALLMULTI_ENTRY) 213 return index + 1; 214 else if (type == NIXLF_PROMISC_ENTRY) 215 return index + 2; 216 } 217 218 return npc_get_ucast_mcam_index(mcam, pcifunc, nixlf); 219 } 220 221 int npc_get_bank(struct npc_mcam *mcam, int index) 222 { 223 struct rvu_hwinfo *hw = container_of(mcam, struct rvu_hwinfo, mcam); 224 int bank = index / mcam->banksize; 225 struct rvu *rvu = hw->rvu; 226 227 if (is_cn20k(rvu->pdev)) 228 return bank; 229 230 /* 0,1 & 2,3 banks are combined for this keysize */ 231 if (mcam->keysize == NPC_MCAM_KEY_X2) 232 return bank ? 2 : 0; 233 234 return bank; 235 } 236 237 bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, 238 int blkaddr, int index) 239 { 240 int bank = npc_get_bank(mcam, index); 241 u64 cfg; 242 243 index &= (mcam->banksize - 1); 244 if (is_cn20k(rvu->pdev)) 245 cfg = rvu_read64(rvu, blkaddr, 246 NPC_AF_CN20K_MCAMEX_BANKX_CFG_EXT(index, 247 bank)); 248 else 249 cfg = rvu_read64(rvu, blkaddr, 250 NPC_AF_MCAMEX_BANKX_CFG(index, bank)); 251 252 return (cfg & 1); 253 } 254 255 void npc_enable_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, 256 int blkaddr, int index, bool enable) 257 { 258 int bank = npc_get_bank(mcam, index); 259 int actbank = bank; 260 261 if (is_cn20k(rvu->pdev)) { 262 if (npc_cn20k_enable_mcam_entry(rvu, blkaddr, index, enable)) 263 dev_err(rvu->dev, "Error to %s mcam %u entry\n", 264 enable ? "enable" : "disable", index); 265 return; 266 } 267 268 index &= (mcam->banksize - 1); 269 for (; bank < (actbank + mcam->banks_per_entry); bank++) { 270 rvu_write64(rvu, blkaddr, 271 NPC_AF_MCAMEX_BANKX_CFG(index, bank), 272 enable ? 1 : 0); 273 } 274 } 275 276 static void npc_clear_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, 277 int blkaddr, int index) 278 { 279 int bank = npc_get_bank(mcam, index); 280 int actbank = bank; 281 282 if (is_cn20k(rvu->pdev)) { 283 if (npc_cn20k_clear_mcam_entry(rvu, blkaddr, index)) 284 dev_err(rvu->dev, "%s Failed to clear mcam %u\n", 285 __func__, index); 286 return; 287 } 288 289 index &= (mcam->banksize - 1); 290 for (; bank < (actbank + mcam->banks_per_entry); bank++) { 291 rvu_write64(rvu, blkaddr, 292 NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 1), 0); 293 rvu_write64(rvu, blkaddr, 294 NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 0), 0); 295 296 rvu_write64(rvu, blkaddr, 297 NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 1), 0); 298 rvu_write64(rvu, blkaddr, 299 NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 0), 0); 300 301 rvu_write64(rvu, blkaddr, 302 NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 1), 0); 303 rvu_write64(rvu, blkaddr, 304 NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 0), 0); 305 } 306 } 307 308 static void npc_get_keyword(struct mcam_entry *entry, int idx, 309 u64 *cam0, u64 *cam1) 310 { 311 u64 kw_mask = 0x00; 312 313 #define CAM_MASK(n) (BIT_ULL(n) - 1) 314 315 /* 0, 2, 4, 6 indices refer to BANKX_CAMX_W0 and 316 * 1, 3, 5, 7 indices refer to BANKX_CAMX_W1. 317 * 318 * Also, only 48 bits of BANKX_CAMX_W1 are valid. 319 */ 320 switch (idx) { 321 case 0: 322 /* BANK(X)_CAM_W0<63:0> = MCAM_KEY[KW0]<63:0> */ 323 *cam1 = entry->kw[0]; 324 kw_mask = entry->kw_mask[0]; 325 break; 326 case 1: 327 /* BANK(X)_CAM_W1<47:0> = MCAM_KEY[KW1]<47:0> */ 328 *cam1 = entry->kw[1] & CAM_MASK(48); 329 kw_mask = entry->kw_mask[1] & CAM_MASK(48); 330 break; 331 case 2: 332 /* BANK(X + 1)_CAM_W0<15:0> = MCAM_KEY[KW1]<63:48> 333 * BANK(X + 1)_CAM_W0<63:16> = MCAM_KEY[KW2]<47:0> 334 */ 335 *cam1 = (entry->kw[1] >> 48) & CAM_MASK(16); 336 *cam1 |= ((entry->kw[2] & CAM_MASK(48)) << 16); 337 kw_mask = (entry->kw_mask[1] >> 48) & CAM_MASK(16); 338 kw_mask |= ((entry->kw_mask[2] & CAM_MASK(48)) << 16); 339 break; 340 case 3: 341 /* BANK(X + 1)_CAM_W1<15:0> = MCAM_KEY[KW2]<63:48> 342 * BANK(X + 1)_CAM_W1<47:16> = MCAM_KEY[KW3]<31:0> 343 */ 344 *cam1 = (entry->kw[2] >> 48) & CAM_MASK(16); 345 *cam1 |= ((entry->kw[3] & CAM_MASK(32)) << 16); 346 kw_mask = (entry->kw_mask[2] >> 48) & CAM_MASK(16); 347 kw_mask |= ((entry->kw_mask[3] & CAM_MASK(32)) << 16); 348 break; 349 case 4: 350 /* BANK(X + 2)_CAM_W0<31:0> = MCAM_KEY[KW3]<63:32> 351 * BANK(X + 2)_CAM_W0<63:32> = MCAM_KEY[KW4]<31:0> 352 */ 353 *cam1 = (entry->kw[3] >> 32) & CAM_MASK(32); 354 *cam1 |= ((entry->kw[4] & CAM_MASK(32)) << 32); 355 kw_mask = (entry->kw_mask[3] >> 32) & CAM_MASK(32); 356 kw_mask |= ((entry->kw_mask[4] & CAM_MASK(32)) << 32); 357 break; 358 case 5: 359 /* BANK(X + 2)_CAM_W1<31:0> = MCAM_KEY[KW4]<63:32> 360 * BANK(X + 2)_CAM_W1<47:32> = MCAM_KEY[KW5]<15:0> 361 */ 362 *cam1 = (entry->kw[4] >> 32) & CAM_MASK(32); 363 *cam1 |= ((entry->kw[5] & CAM_MASK(16)) << 32); 364 kw_mask = (entry->kw_mask[4] >> 32) & CAM_MASK(32); 365 kw_mask |= ((entry->kw_mask[5] & CAM_MASK(16)) << 32); 366 break; 367 case 6: 368 /* BANK(X + 3)_CAM_W0<47:0> = MCAM_KEY[KW5]<63:16> 369 * BANK(X + 3)_CAM_W0<63:48> = MCAM_KEY[KW6]<15:0> 370 */ 371 *cam1 = (entry->kw[5] >> 16) & CAM_MASK(48); 372 *cam1 |= ((entry->kw[6] & CAM_MASK(16)) << 48); 373 kw_mask = (entry->kw_mask[5] >> 16) & CAM_MASK(48); 374 kw_mask |= ((entry->kw_mask[6] & CAM_MASK(16)) << 48); 375 break; 376 case 7: 377 /* BANK(X + 3)_CAM_W1<47:0> = MCAM_KEY[KW6]<63:16> */ 378 *cam1 = (entry->kw[6] >> 16) & CAM_MASK(48); 379 kw_mask = (entry->kw_mask[6] >> 16) & CAM_MASK(48); 380 break; 381 } 382 383 *cam1 &= kw_mask; 384 *cam0 = ~*cam1 & kw_mask; 385 } 386 387 static void npc_fill_entryword(struct mcam_entry *entry, int idx, 388 u64 cam0, u64 cam1) 389 { 390 /* Similar to npc_get_keyword, but fills mcam_entry structure from 391 * CAM registers. 392 */ 393 switch (idx) { 394 case 0: 395 entry->kw[0] = cam1; 396 entry->kw_mask[0] = cam1 ^ cam0; 397 break; 398 case 1: 399 entry->kw[1] = cam1; 400 entry->kw_mask[1] = cam1 ^ cam0; 401 break; 402 case 2: 403 entry->kw[1] |= (cam1 & CAM_MASK(16)) << 48; 404 entry->kw[2] = (cam1 >> 16) & CAM_MASK(48); 405 entry->kw_mask[1] |= ((cam1 ^ cam0) & CAM_MASK(16)) << 48; 406 entry->kw_mask[2] = ((cam1 ^ cam0) >> 16) & CAM_MASK(48); 407 break; 408 case 3: 409 entry->kw[2] |= (cam1 & CAM_MASK(16)) << 48; 410 entry->kw[3] = (cam1 >> 16) & CAM_MASK(32); 411 entry->kw_mask[2] |= ((cam1 ^ cam0) & CAM_MASK(16)) << 48; 412 entry->kw_mask[3] = ((cam1 ^ cam0) >> 16) & CAM_MASK(32); 413 break; 414 case 4: 415 entry->kw[3] |= (cam1 & CAM_MASK(32)) << 32; 416 entry->kw[4] = (cam1 >> 32) & CAM_MASK(32); 417 entry->kw_mask[3] |= ((cam1 ^ cam0) & CAM_MASK(32)) << 32; 418 entry->kw_mask[4] = ((cam1 ^ cam0) >> 32) & CAM_MASK(32); 419 break; 420 case 5: 421 entry->kw[4] |= (cam1 & CAM_MASK(32)) << 32; 422 entry->kw[5] = (cam1 >> 32) & CAM_MASK(16); 423 entry->kw_mask[4] |= ((cam1 ^ cam0) & CAM_MASK(32)) << 32; 424 entry->kw_mask[5] = ((cam1 ^ cam0) >> 32) & CAM_MASK(16); 425 break; 426 case 6: 427 entry->kw[5] |= (cam1 & CAM_MASK(48)) << 16; 428 entry->kw[6] = (cam1 >> 48) & CAM_MASK(16); 429 entry->kw_mask[5] |= ((cam1 ^ cam0) & CAM_MASK(48)) << 16; 430 entry->kw_mask[6] = ((cam1 ^ cam0) >> 48) & CAM_MASK(16); 431 break; 432 case 7: 433 entry->kw[6] |= (cam1 & CAM_MASK(48)) << 16; 434 entry->kw_mask[6] |= ((cam1 ^ cam0) & CAM_MASK(48)) << 16; 435 break; 436 } 437 } 438 439 static u64 npc_get_default_entry_action(struct rvu *rvu, struct npc_mcam *mcam, 440 int blkaddr, u16 pf_func) 441 { 442 int bank, nixlf, index; 443 u64 reg; 444 445 /* get ucast entry rule entry index */ 446 if (nix_get_nixlf(rvu, pf_func, &nixlf, NULL)) { 447 dev_err(rvu->dev, "%s: nixlf not attached to pcifunc:0x%x\n", 448 __func__, pf_func); 449 /* Action 0 is drop */ 450 return 0; 451 } 452 453 index = npc_get_nixlf_mcam_index(mcam, pf_func, nixlf, 454 NIXLF_UCAST_ENTRY); 455 456 if (index < 0) { 457 dev_err(rvu->dev, 458 "%s: failed to get ucast entry pcifunc:0x%x\n", 459 __func__, pf_func); 460 /* Action 0 is drop */ 461 return 0; 462 } 463 464 bank = npc_get_bank(mcam, index); 465 index &= (mcam->banksize - 1); 466 467 if (is_cn20k(rvu->pdev)) 468 reg = NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, bank, 0); 469 else 470 reg = NPC_AF_MCAMEX_BANKX_ACTION(index, bank); 471 472 return rvu_read64(rvu, blkaddr, reg); 473 } 474 475 static void npc_fixup_vf_rule(struct rvu *rvu, struct npc_mcam *mcam, 476 int blkaddr, int index, struct mcam_entry *entry, 477 bool *enable) 478 { 479 struct rvu_npc_mcam_rule *rule; 480 u16 owner, target_func; 481 struct rvu_pfvf *pfvf; 482 u64 rx_action; 483 484 owner = mcam->entry2pfvf_map[index]; 485 target_func = (entry->action >> 4) & 0xffff; 486 /* do nothing when target is LBK/PF or owner is not PF */ 487 if (is_pffunc_af(owner) || is_lbk_vf(rvu, target_func) || 488 (owner & RVU_PFVF_FUNC_MASK) || 489 !(target_func & RVU_PFVF_FUNC_MASK)) 490 return; 491 492 /* save entry2target_pffunc */ 493 pfvf = rvu_get_pfvf(rvu, target_func); 494 mcam->entry2target_pffunc[index] = target_func; 495 496 /* don't enable rule when nixlf not attached or initialized */ 497 if (!(is_nixlf_attached(rvu, target_func) && 498 test_bit(NIXLF_INITIALIZED, &pfvf->flags))) 499 *enable = false; 500 501 /* fix up not needed for the rules added by user(ntuple filters) */ 502 list_for_each_entry(rule, &mcam->mcam_rules, list) { 503 if (rule->entry == index) 504 return; 505 } 506 507 /* AF modifies given action iff PF/VF has requested for it */ 508 if ((entry->action & 0xFULL) != NIX_RX_ACTION_DEFAULT) 509 return; 510 511 /* copy VF default entry action to the VF mcam entry */ 512 rx_action = npc_get_default_entry_action(rvu, mcam, blkaddr, 513 target_func); 514 if (rx_action) 515 entry->action = rx_action; 516 } 517 518 static void npc_config_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, 519 int blkaddr, int index, u8 intf, 520 struct mcam_entry *entry, bool enable) 521 { 522 int bank = npc_get_bank(mcam, index); 523 int kw = 0, actbank, actindex; 524 u8 tx_intf_mask = ~intf & 0x3; 525 u8 tx_intf = intf; 526 u64 cam0, cam1; 527 528 actbank = bank; /* Save bank id, to set action later on */ 529 actindex = index; 530 index &= (mcam->banksize - 1); 531 532 /* Disable before mcam entry update */ 533 npc_enable_mcam_entry(rvu, mcam, blkaddr, actindex, false); 534 535 /* Clear mcam entry to avoid writes being suppressed by NPC */ 536 npc_clear_mcam_entry(rvu, mcam, blkaddr, actindex); 537 538 /* CAM1 takes the comparison value and 539 * CAM0 specifies match for a bit in key being '0' or '1' or 'dontcare'. 540 * CAM1<n> = 0 & CAM0<n> = 1 => match if key<n> = 0 541 * CAM1<n> = 1 & CAM0<n> = 0 => match if key<n> = 1 542 * CAM1<n> = 0 & CAM0<n> = 0 => always match i.e dontcare. 543 */ 544 for (; bank < (actbank + mcam->banks_per_entry); bank++, kw = kw + 2) { 545 /* Interface should be set in all banks */ 546 if (is_npc_intf_tx(intf)) { 547 /* Last bit must be set and rest don't care 548 * for TX interfaces 549 */ 550 tx_intf_mask = 0x1; 551 tx_intf = intf & tx_intf_mask; 552 tx_intf_mask = ~tx_intf & tx_intf_mask; 553 } 554 555 rvu_write64(rvu, blkaddr, 556 NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 1), 557 tx_intf); 558 rvu_write64(rvu, blkaddr, 559 NPC_AF_MCAMEX_BANKX_CAMX_INTF(index, bank, 0), 560 tx_intf_mask); 561 562 /* Set the match key */ 563 npc_get_keyword(entry, kw, &cam0, &cam1); 564 rvu_write64(rvu, blkaddr, 565 NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 1), cam1); 566 rvu_write64(rvu, blkaddr, 567 NPC_AF_MCAMEX_BANKX_CAMX_W0(index, bank, 0), cam0); 568 569 npc_get_keyword(entry, kw + 1, &cam0, &cam1); 570 rvu_write64(rvu, blkaddr, 571 NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 1), cam1); 572 rvu_write64(rvu, blkaddr, 573 NPC_AF_MCAMEX_BANKX_CAMX_W1(index, bank, 0), cam0); 574 } 575 576 /* PF installing VF rule */ 577 if (is_npc_intf_rx(intf) && actindex < mcam->bmap_entries) 578 npc_fixup_vf_rule(rvu, mcam, blkaddr, actindex, entry, &enable); 579 580 /* Set 'action' */ 581 rvu_write64(rvu, blkaddr, 582 NPC_AF_MCAMEX_BANKX_ACTION(index, actbank), entry->action); 583 584 /* Set TAG 'action' */ 585 rvu_write64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_TAG_ACT(index, actbank), 586 entry->vtag_action); 587 588 /* Enable the entry */ 589 if (enable) 590 npc_enable_mcam_entry(rvu, mcam, blkaddr, actindex, true); 591 } 592 593 void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, 594 int blkaddr, u16 src, 595 struct mcam_entry *entry, u8 *intf, u8 *ena) 596 { 597 int sbank = npc_get_bank(mcam, src); 598 int bank, kw = 0; 599 u64 cam0, cam1; 600 601 src &= (mcam->banksize - 1); 602 bank = sbank; 603 604 for (; bank < (sbank + mcam->banks_per_entry); bank++, kw = kw + 2) { 605 cam1 = rvu_read64(rvu, blkaddr, 606 NPC_AF_MCAMEX_BANKX_CAMX_W0(src, bank, 1)); 607 cam0 = rvu_read64(rvu, blkaddr, 608 NPC_AF_MCAMEX_BANKX_CAMX_W0(src, bank, 0)); 609 npc_fill_entryword(entry, kw, cam0, cam1); 610 611 cam1 = rvu_read64(rvu, blkaddr, 612 NPC_AF_MCAMEX_BANKX_CAMX_W1(src, bank, 1)); 613 cam0 = rvu_read64(rvu, blkaddr, 614 NPC_AF_MCAMEX_BANKX_CAMX_W1(src, bank, 0)); 615 npc_fill_entryword(entry, kw + 1, cam0, cam1); 616 } 617 618 entry->action = rvu_read64(rvu, blkaddr, 619 NPC_AF_MCAMEX_BANKX_ACTION(src, sbank)); 620 entry->vtag_action = 621 rvu_read64(rvu, blkaddr, 622 NPC_AF_MCAMEX_BANKX_TAG_ACT(src, sbank)); 623 *intf = rvu_read64(rvu, blkaddr, 624 NPC_AF_MCAMEX_BANKX_CAMX_INTF(src, sbank, 1)) & 3; 625 *ena = rvu_read64(rvu, blkaddr, 626 NPC_AF_MCAMEX_BANKX_CFG(src, sbank)) & 1; 627 } 628 629 static int npc_copy_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam, 630 int blkaddr, u16 src, u16 dest) 631 { 632 int dbank = npc_get_bank(mcam, dest); 633 int sbank = npc_get_bank(mcam, src); 634 u64 cfg, sreg, dreg; 635 int bank, i; 636 637 if (is_cn20k(rvu->pdev)) 638 return npc_cn20k_copy_mcam_entry(rvu, blkaddr, src, dest); 639 640 src &= (mcam->banksize - 1); 641 dest &= (mcam->banksize - 1); 642 643 /* Copy INTF's, W0's, W1's CAM0 and CAM1 configuration */ 644 for (bank = 0; bank < mcam->banks_per_entry; bank++) { 645 sreg = NPC_AF_MCAMEX_BANKX_CAMX_INTF(src, sbank + bank, 0); 646 dreg = NPC_AF_MCAMEX_BANKX_CAMX_INTF(dest, dbank + bank, 0); 647 for (i = 0; i < 6; i++) { 648 cfg = rvu_read64(rvu, blkaddr, sreg + (i * 8)); 649 rvu_write64(rvu, blkaddr, dreg + (i * 8), cfg); 650 } 651 } 652 653 /* Copy action */ 654 cfg = rvu_read64(rvu, blkaddr, 655 NPC_AF_MCAMEX_BANKX_ACTION(src, sbank)); 656 rvu_write64(rvu, blkaddr, 657 NPC_AF_MCAMEX_BANKX_ACTION(dest, dbank), cfg); 658 659 /* Copy TAG action */ 660 cfg = rvu_read64(rvu, blkaddr, 661 NPC_AF_MCAMEX_BANKX_TAG_ACT(src, sbank)); 662 rvu_write64(rvu, blkaddr, 663 NPC_AF_MCAMEX_BANKX_TAG_ACT(dest, dbank), cfg); 664 665 /* Enable or disable */ 666 cfg = rvu_read64(rvu, blkaddr, 667 NPC_AF_MCAMEX_BANKX_CFG(src, sbank)); 668 rvu_write64(rvu, blkaddr, 669 NPC_AF_MCAMEX_BANKX_CFG(dest, dbank), cfg); 670 return 0; 671 } 672 673 u64 npc_get_mcam_action(struct rvu *rvu, struct npc_mcam *mcam, 674 int blkaddr, int index) 675 { 676 int bank = npc_get_bank(mcam, index); 677 u64 reg; 678 679 index &= (mcam->banksize - 1); 680 681 if (is_cn20k(rvu->pdev)) 682 reg = NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, bank, 0); 683 else 684 reg = NPC_AF_MCAMEX_BANKX_ACTION(index, bank); 685 return rvu_read64(rvu, blkaddr, reg); 686 } 687 688 void npc_set_mcam_action(struct rvu *rvu, struct npc_mcam *mcam, 689 int blkaddr, int index, u64 cfg) 690 { 691 int bank = npc_get_bank(mcam, index); 692 u64 reg; 693 694 index &= (mcam->banksize - 1); 695 696 if (is_cn20k(rvu->pdev)) 697 reg = NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, bank, 0); 698 else 699 reg = NPC_AF_MCAMEX_BANKX_ACTION(index, bank); 700 701 return rvu_write64(rvu, blkaddr, reg, cfg); 702 } 703 704 u32 rvu_get_cpt_chan_mask(struct rvu *rvu) 705 { 706 /* For cn10k the upper two bits of the channel number are 707 * cpt channel number. with masking out these bits in the 708 * mcam entry, same entry used for NIX will allow packets 709 * received from cpt for parsing. 710 */ 711 if (!is_rvu_otx2(rvu)) 712 return NIX_CHAN_CPT_X2P_MASK; 713 else 714 return 0xFFFu; 715 } 716 717 void rvu_npc_install_ucast_entry(struct rvu *rvu, u16 pcifunc, 718 int nixlf, u64 chan, u8 *mac_addr) 719 { 720 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); 721 struct npc_install_flow_req req = { 0 }; 722 struct npc_install_flow_rsp rsp = { 0 }; 723 struct npc_mcam *mcam = &rvu->hw->mcam; 724 struct nix_rx_action action = { 0 }; 725 int blkaddr, index; 726 727 /* AF's and SDP VFs work in promiscuous mode */ 728 if (is_lbk_vf(rvu, pcifunc) || is_sdp_vf(rvu, pcifunc)) 729 return; 730 731 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 732 if (blkaddr < 0) 733 return; 734 735 /* Ucast rule should not be installed if DMAC 736 * extraction is not supported by the profile. 737 */ 738 if (!npc_is_feature_supported(rvu, BIT_ULL(NPC_DMAC), pfvf->nix_rx_intf)) 739 return; 740 741 index = npc_get_nixlf_mcam_index(mcam, pcifunc, 742 nixlf, NIXLF_UCAST_ENTRY); 743 if (index < 0) { 744 dev_err(rvu->dev, 745 "%s: Error to get ucast entry for pcifunc=%#x\n", 746 __func__, pcifunc); 747 return; 748 } 749 750 /* Don't change the action if entry is already enabled 751 * Otherwise RSS action may get overwritten. 752 */ 753 if (is_mcam_entry_enabled(rvu, mcam, blkaddr, index)) { 754 *(u64 *)&action = npc_get_mcam_action(rvu, mcam, 755 blkaddr, index); 756 } else { 757 action.op = NIX_RX_ACTIONOP_UCAST; 758 action.pf_func = pcifunc; 759 } 760 761 req.default_rule = 1; 762 ether_addr_copy(req.packet.dmac, mac_addr); 763 eth_broadcast_addr((u8 *)&req.mask.dmac); 764 req.features = BIT_ULL(NPC_DMAC); 765 req.channel = chan; 766 req.chan_mask = rvu_get_cpt_chan_mask(rvu); 767 req.intf = pfvf->nix_rx_intf; 768 req.op = action.op; 769 req.hdr.pcifunc = 0; /* AF is requester */ 770 req.vf = action.pf_func; 771 req.index = action.index; 772 req.match_id = action.match_id; 773 req.flow_key_alg = action.flow_key_alg; 774 775 if (is_cn20k(rvu->pdev)) 776 req.hw_prio = pfvf->hw_prio; 777 778 rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); 779 } 780 781 void rvu_npc_install_promisc_entry(struct rvu *rvu, u16 pcifunc, 782 int nixlf, u64 chan, u8 chan_cnt) 783 { 784 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); 785 struct npc_install_flow_req req = { 0 }; 786 struct npc_install_flow_rsp rsp = { 0 }; 787 struct npc_mcam *mcam = &rvu->hw->mcam; 788 struct rvu_hwinfo *hw = rvu->hw; 789 int blkaddr, ucast_idx, index; 790 struct nix_rx_action action = { 0 }; 791 u64 relaxed_mask; 792 u8 flow_key_alg; 793 794 if (!hw->cap.nix_rx_multicast && is_cgx_vf(rvu, pcifunc)) 795 return; 796 797 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 798 if (blkaddr < 0) 799 return; 800 801 index = npc_get_nixlf_mcam_index(mcam, pcifunc, 802 nixlf, NIXLF_PROMISC_ENTRY); 803 804 /* In cn20k, default indexes are installed only for CGX mapped 805 * and lbk interfaces 806 */ 807 if (is_cgx_vf(rvu, pcifunc)) 808 index = npc_get_nixlf_mcam_index(mcam, 809 pcifunc & ~RVU_PFVF_FUNC_MASK, 810 nixlf, NIXLF_PROMISC_ENTRY); 811 812 if (index < 0) { 813 dev_err(rvu->dev, 814 "%s: Error to get promisc entry for pcifunc=%#x\n", 815 __func__, pcifunc); 816 return; 817 } 818 819 /* If the corresponding PF's ucast action is RSS, 820 * use the same action for promisc also 821 * Please note that for lbk(s) "index" and "ucast_idx" 822 * will be same. 823 */ 824 if (is_lbk_vf(rvu, pcifunc)) 825 ucast_idx = index; 826 else 827 ucast_idx = npc_get_nixlf_mcam_index(mcam, pcifunc, 828 nixlf, NIXLF_UCAST_ENTRY); 829 if (ucast_idx < 0) { 830 dev_err(rvu->dev, 831 "%s: Error to get ucast/promisc entry for pcifunc=%#x\n", 832 __func__, pcifunc); 833 return; 834 } 835 836 if (is_mcam_entry_enabled(rvu, mcam, blkaddr, ucast_idx)) 837 *(u64 *)&action = npc_get_mcam_action(rvu, mcam, 838 blkaddr, ucast_idx); 839 840 if (action.op != NIX_RX_ACTIONOP_RSS) { 841 *(u64 *)&action = 0; 842 action.op = NIX_RX_ACTIONOP_UCAST; 843 } 844 845 flow_key_alg = action.flow_key_alg; 846 847 /* RX_ACTION set to MCAST for CGX PF's */ 848 if (hw->cap.nix_rx_multicast && pfvf->use_mce_list && 849 is_pf_cgxmapped(rvu, rvu_get_pf(rvu->pdev, pcifunc))) { 850 *(u64 *)&action = 0; 851 action.op = NIX_RX_ACTIONOP_MCAST; 852 pfvf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK); 853 action.index = pfvf->promisc_mce_idx; 854 } 855 856 /* For cn10k the upper two bits of the channel number are 857 * cpt channel number. with masking out these bits in the 858 * mcam entry, same entry used for NIX will allow packets 859 * received from cpt for parsing. 860 */ 861 req.chan_mask = rvu_get_cpt_chan_mask(rvu); 862 863 if (chan_cnt > 1) { 864 if (!is_power_of_2(chan_cnt)) { 865 dev_err(rvu->dev, 866 "%s: channel count more than 1, must be power of 2\n", __func__); 867 return; 868 } 869 relaxed_mask = GENMASK_ULL(BITS_PER_LONG_LONG - 1, 870 ilog2(chan_cnt)); 871 req.chan_mask &= relaxed_mask; 872 } 873 874 req.channel = chan; 875 req.intf = pfvf->nix_rx_intf; 876 req.entry = index; 877 req.op = action.op; 878 req.hdr.pcifunc = 0; /* AF is requester */ 879 req.vf = pcifunc; 880 req.index = action.index; 881 req.match_id = action.match_id; 882 req.flow_key_alg = flow_key_alg; 883 884 if (is_cn20k(rvu->pdev)) 885 req.hw_prio = pfvf->hw_prio; 886 887 rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); 888 } 889 890 void rvu_npc_enable_promisc_entry(struct rvu *rvu, u16 pcifunc, 891 int nixlf, bool enable) 892 { 893 struct npc_mcam *mcam = &rvu->hw->mcam; 894 int blkaddr, index; 895 896 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 897 if (blkaddr < 0) 898 return; 899 900 /* Get 'pcifunc' of PF device */ 901 pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK; 902 903 index = npc_get_nixlf_mcam_index(mcam, pcifunc, 904 nixlf, NIXLF_PROMISC_ENTRY); 905 906 if (index < 0) { 907 dev_err(rvu->dev, 908 "%s: Error to get promisc entry for pcifunc=%#x\n", 909 __func__, pcifunc); 910 return; 911 } 912 913 npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable); 914 } 915 916 void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc, 917 int nixlf, u64 chan) 918 { 919 struct rvu_pfvf *pfvf; 920 struct npc_install_flow_req req = { 0 }; 921 struct npc_install_flow_rsp rsp = { 0 }; 922 struct npc_mcam *mcam = &rvu->hw->mcam; 923 struct rvu_hwinfo *hw = rvu->hw; 924 int blkaddr, index; 925 926 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 927 if (blkaddr < 0) 928 return; 929 930 /* Skip LBK VFs */ 931 if (is_lbk_vf(rvu, pcifunc)) 932 return; 933 934 /* If pkt replication is not supported, 935 * then only PF is allowed to add a bcast match entry. 936 */ 937 if (!hw->cap.nix_rx_multicast && is_vf(pcifunc)) 938 return; 939 940 /* Get 'pcifunc' of PF device */ 941 pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK; 942 pfvf = rvu_get_pfvf(rvu, pcifunc); 943 944 /* Bcast rule should not be installed if both DMAC 945 * and LXMB extraction is not supported by the profile. 946 */ 947 if (!npc_is_feature_supported(rvu, BIT_ULL(NPC_DMAC), pfvf->nix_rx_intf) && 948 !npc_is_feature_supported(rvu, BIT_ULL(NPC_LXMB), pfvf->nix_rx_intf)) 949 return; 950 951 index = npc_get_nixlf_mcam_index(mcam, pcifunc, 952 nixlf, NIXLF_BCAST_ENTRY); 953 if (index < 0) { 954 dev_err(rvu->dev, 955 "%s: Error to get bcast entry for pcifunc=%#x\n", 956 __func__, pcifunc); 957 return; 958 } 959 960 if (!hw->cap.nix_rx_multicast) { 961 /* Early silicon doesn't support pkt replication, 962 * so install entry with UCAST action, so that PF 963 * receives all broadcast packets. 964 */ 965 req.op = NIX_RX_ACTIONOP_UCAST; 966 } else { 967 req.op = NIX_RX_ACTIONOP_MCAST; 968 req.index = pfvf->bcast_mce_idx; 969 } 970 971 eth_broadcast_addr((u8 *)&req.packet.dmac); 972 eth_broadcast_addr((u8 *)&req.mask.dmac); 973 req.features = BIT_ULL(NPC_DMAC); 974 req.channel = chan; 975 req.chan_mask = 0xFFFU; 976 req.intf = pfvf->nix_rx_intf; 977 req.entry = index; 978 req.hdr.pcifunc = 0; /* AF is requester */ 979 req.vf = pcifunc; 980 981 if (is_cn20k(rvu->pdev)) 982 req.hw_prio = pfvf->hw_prio; 983 984 rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); 985 } 986 987 void rvu_npc_install_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf, 988 u64 chan) 989 { 990 struct npc_install_flow_req req = { 0 }; 991 struct npc_install_flow_rsp rsp = { 0 }; 992 struct npc_mcam *mcam = &rvu->hw->mcam; 993 struct rvu_hwinfo *hw = rvu->hw; 994 int blkaddr, ucast_idx, index; 995 u8 mac_addr[ETH_ALEN] = { 0 }; 996 struct nix_rx_action action = { 0 }; 997 struct rvu_pfvf *pfvf; 998 u8 flow_key_alg; 999 u16 vf_func; 1000 1001 /* Only CGX PF/VF can add allmulticast entry */ 1002 if (is_lbk_vf(rvu, pcifunc) || is_sdp_vf(rvu, pcifunc)) 1003 return; 1004 1005 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 1006 if (blkaddr < 0) 1007 return; 1008 1009 /* Get 'pcifunc' of PF device */ 1010 vf_func = pcifunc & RVU_PFVF_FUNC_MASK; 1011 pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK; 1012 pfvf = rvu_get_pfvf(rvu, pcifunc); 1013 1014 /* Mcast rule should not be installed if both DMAC 1015 * and LXMB extraction is not supported by the profile. 1016 */ 1017 if (!npc_is_feature_supported(rvu, BIT_ULL(NPC_DMAC), pfvf->nix_rx_intf) && 1018 !npc_is_feature_supported(rvu, BIT_ULL(NPC_LXMB), pfvf->nix_rx_intf)) 1019 return; 1020 1021 index = npc_get_nixlf_mcam_index(mcam, pcifunc, 1022 nixlf, NIXLF_ALLMULTI_ENTRY); 1023 if (index < 0) { 1024 dev_err(rvu->dev, 1025 "%s: Error to get mcast entry for pcifunc=%#x\n", 1026 __func__, pcifunc); 1027 return; 1028 } 1029 1030 /* If the corresponding PF's ucast action is RSS, 1031 * use the same action for multicast entry also 1032 */ 1033 ucast_idx = npc_get_nixlf_mcam_index(mcam, pcifunc, 1034 nixlf, NIXLF_UCAST_ENTRY); 1035 if (ucast_idx < 0) { 1036 dev_err(rvu->dev, 1037 "%s: Error to get ucast entry for pcifunc=%#x\n", 1038 __func__, pcifunc); 1039 return; 1040 } 1041 1042 if (is_mcam_entry_enabled(rvu, mcam, blkaddr, ucast_idx)) 1043 *(u64 *)&action = npc_get_mcam_action(rvu, mcam, 1044 blkaddr, ucast_idx); 1045 1046 flow_key_alg = action.flow_key_alg; 1047 if (action.op != NIX_RX_ACTIONOP_RSS) { 1048 *(u64 *)&action = 0; 1049 action.op = NIX_RX_ACTIONOP_UCAST; 1050 action.pf_func = pcifunc; 1051 } 1052 1053 /* RX_ACTION set to MCAST for CGX PF's */ 1054 if (hw->cap.nix_rx_multicast && pfvf->use_mce_list) { 1055 *(u64 *)&action = 0; 1056 action.op = NIX_RX_ACTIONOP_MCAST; 1057 action.index = pfvf->mcast_mce_idx; 1058 } 1059 1060 mac_addr[0] = 0x01; /* LSB bit of 1st byte in DMAC */ 1061 ether_addr_copy(req.packet.dmac, mac_addr); 1062 ether_addr_copy(req.mask.dmac, mac_addr); 1063 req.features = BIT_ULL(NPC_DMAC); 1064 1065 req.chan_mask = rvu_get_cpt_chan_mask(rvu); 1066 req.channel = chan; 1067 req.intf = pfvf->nix_rx_intf; 1068 req.entry = index; 1069 req.op = action.op; 1070 req.hdr.pcifunc = 0; /* AF is requester */ 1071 req.vf = pcifunc | vf_func; 1072 req.index = action.index; 1073 req.match_id = action.match_id; 1074 req.flow_key_alg = flow_key_alg; 1075 1076 if (is_cn20k(rvu->pdev)) 1077 req.hw_prio = pfvf->hw_prio; 1078 1079 rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); 1080 } 1081 1082 void rvu_npc_enable_allmulti_entry(struct rvu *rvu, u16 pcifunc, int nixlf, 1083 bool enable) 1084 { 1085 struct npc_mcam *mcam = &rvu->hw->mcam; 1086 int blkaddr, index; 1087 1088 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 1089 if (blkaddr < 0) 1090 return; 1091 1092 /* Get 'pcifunc' of PF device */ 1093 pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK; 1094 1095 index = npc_get_nixlf_mcam_index(mcam, pcifunc, nixlf, 1096 NIXLF_ALLMULTI_ENTRY); 1097 if (index < 0) { 1098 dev_err(rvu->dev, 1099 "%s: Error to get mcast entry for pcifunc=%#x\n", 1100 __func__, pcifunc); 1101 return; 1102 } 1103 1104 npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable); 1105 } 1106 1107 static void npc_update_vf_flow_entry(struct rvu *rvu, struct npc_mcam *mcam, 1108 int blkaddr, u16 pcifunc, u64 rx_action) 1109 { 1110 int actindex, index, bank, entry; 1111 struct rvu_npc_mcam_rule *rule; 1112 bool enable, update; 1113 1114 if (!(pcifunc & RVU_PFVF_FUNC_MASK)) 1115 return; 1116 1117 mutex_lock(&mcam->lock); 1118 for (index = 0; index < mcam->bmap_entries; index++) { 1119 if (mcam->entry2target_pffunc[index] != pcifunc) 1120 continue; 1121 update = true; 1122 /* update not needed for the rules added via ntuple filters */ 1123 list_for_each_entry(rule, &mcam->mcam_rules, list) { 1124 if (rule->entry == index) 1125 update = false; 1126 } 1127 if (!update) 1128 continue; 1129 bank = npc_get_bank(mcam, index); 1130 actindex = index; 1131 entry = index & (mcam->banksize - 1); 1132 1133 /* read vf flow entry enable status */ 1134 enable = is_mcam_entry_enabled(rvu, mcam, blkaddr, 1135 actindex); 1136 /* disable before mcam entry update */ 1137 npc_enable_mcam_entry(rvu, mcam, blkaddr, actindex, 1138 false); 1139 1140 /* update 'action' */ 1141 if (is_cn20k(rvu->pdev)) 1142 rvu_write64(rvu, blkaddr, 1143 NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(entry, 1144 bank, 1145 0), 1146 rx_action); 1147 else 1148 rvu_write64(rvu, blkaddr, 1149 NPC_AF_MCAMEX_BANKX_ACTION(entry, bank), 1150 rx_action); 1151 1152 if (enable) 1153 npc_enable_mcam_entry(rvu, mcam, blkaddr, 1154 actindex, true); 1155 } 1156 mutex_unlock(&mcam->lock); 1157 } 1158 1159 static void npc_update_rx_action_with_alg_idx(struct rvu *rvu, struct nix_rx_action action, 1160 struct rvu_pfvf *pfvf, int mcam_index, int blkaddr, 1161 int alg_idx) 1162 1163 { 1164 struct npc_mcam *mcam = &rvu->hw->mcam; 1165 struct rvu_hwinfo *hw = rvu->hw; 1166 int bank, op_rss; 1167 u64 reg; 1168 1169 if (!is_mcam_entry_enabled(rvu, mcam, blkaddr, mcam_index)) 1170 return; 1171 1172 op_rss = (!hw->cap.nix_rx_multicast || !pfvf->use_mce_list); 1173 1174 bank = npc_get_bank(mcam, mcam_index); 1175 mcam_index &= (mcam->banksize - 1); 1176 1177 if (is_cn20k(rvu->pdev)) 1178 reg = NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(mcam_index, 1179 bank, 0); 1180 else 1181 reg = NPC_AF_MCAMEX_BANKX_ACTION(mcam_index, bank); 1182 1183 /* If Rx action is MCAST update only RSS algorithm index */ 1184 if (!op_rss) { 1185 *(u64 *)&action = rvu_read64(rvu, blkaddr, reg); 1186 1187 action.flow_key_alg = alg_idx; 1188 } 1189 rvu_write64(rvu, blkaddr, reg, *(u64 *)&action); 1190 } 1191 1192 void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, 1193 int group, int alg_idx, int mcam_index) 1194 { 1195 struct npc_mcam *mcam = &rvu->hw->mcam; 1196 struct nix_rx_action action; 1197 int blkaddr, index, bank; 1198 struct rvu_pfvf *pfvf; 1199 u64 reg; 1200 1201 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 1202 if (blkaddr < 0) 1203 return; 1204 1205 /* Check if this is for reserved default entry */ 1206 if (mcam_index < 0) { 1207 if (group != DEFAULT_RSS_CONTEXT_GROUP) 1208 return; 1209 index = npc_get_nixlf_mcam_index(mcam, pcifunc, 1210 nixlf, NIXLF_UCAST_ENTRY); 1211 } else { 1212 /* TODO: validate this mcam index */ 1213 index = mcam_index; 1214 } 1215 1216 if (index < 0 || index >= mcam->total_entries) { 1217 dev_err(rvu->dev, 1218 "%s: Invalid mcam index, pcifunc=%#x\n", 1219 __func__, pcifunc); 1220 return; 1221 } 1222 1223 bank = npc_get_bank(mcam, index); 1224 index &= (mcam->banksize - 1); 1225 1226 if (is_cn20k(rvu->pdev)) 1227 reg = NPC_AF_CN20K_MCAMEX_BANKX_ACTIONX_EXT(index, bank, 0); 1228 else 1229 reg = NPC_AF_MCAMEX_BANKX_ACTION(index, bank); 1230 1231 *(u64 *)&action = rvu_read64(rvu, blkaddr, reg); 1232 /* Ignore if no action was set earlier */ 1233 if (!*(u64 *)&action) 1234 return; 1235 1236 action.op = NIX_RX_ACTIONOP_RSS; 1237 action.pf_func = pcifunc; 1238 action.index = group; 1239 action.flow_key_alg = alg_idx; 1240 1241 rvu_write64(rvu, blkaddr, reg, *(u64 *)&action); 1242 /* update the VF flow rule action with the VF default entry action */ 1243 if (mcam_index < 0) 1244 npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, 1245 *(u64 *)&action); 1246 1247 /* update the action change in default rule */ 1248 pfvf = rvu_get_pfvf(rvu, pcifunc); 1249 if (pfvf->def_ucast_rule) 1250 pfvf->def_ucast_rule->rx_action = action; 1251 1252 if (mcam_index < 0) { 1253 /* update the VF flow rule action with the VF default 1254 * entry action 1255 */ 1256 npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, 1257 *(u64 *)&action); 1258 1259 index = npc_get_nixlf_mcam_index(mcam, pcifunc, 1260 nixlf, NIXLF_PROMISC_ENTRY); 1261 1262 /* If PF's promiscuous entry is enabled, 1263 * Set RSS action for that entry as well 1264 */ 1265 if (index >= 0) 1266 npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, 1267 blkaddr, alg_idx); 1268 1269 index = npc_get_nixlf_mcam_index(mcam, pcifunc, 1270 nixlf, NIXLF_ALLMULTI_ENTRY); 1271 /* If PF's allmulti entry is enabled, 1272 * Set RSS action for that entry as well 1273 */ 1274 if (index >= 0) 1275 npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, 1276 blkaddr, alg_idx); 1277 } 1278 } 1279 1280 void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, 1281 int nixlf, int type, bool enable) 1282 { 1283 struct npc_mcam *mcam = &rvu->hw->mcam; 1284 struct rvu_hwinfo *hw = rvu->hw; 1285 struct nix_mce_list *mce_list; 1286 int index, blkaddr, mce_idx; 1287 struct rvu_pfvf *pfvf; 1288 1289 /* multicast pkt replication is not enabled for AF's VFs & SDP links */ 1290 if (is_lbk_vf(rvu, pcifunc) || is_sdp_pfvf(rvu, pcifunc)) 1291 return; 1292 1293 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 1294 if (blkaddr < 0) 1295 return; 1296 1297 index = npc_get_nixlf_mcam_index(mcam, pcifunc & ~RVU_PFVF_FUNC_MASK, 1298 nixlf, type); 1299 if (index < 0) { 1300 dev_err(rvu->dev, 1301 "%s: Error to get entry for pcifunc=%#x, type=%u\n", 1302 __func__, pcifunc, type); 1303 return; 1304 } 1305 1306 /* disable MCAM entry when packet replication is not supported by hw */ 1307 if (!hw->cap.nix_rx_multicast && !is_vf(pcifunc)) { 1308 npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable); 1309 return; 1310 } 1311 1312 /* return incase mce list is not enabled */ 1313 pfvf = rvu_get_pfvf(rvu, pcifunc & ~RVU_PFVF_FUNC_MASK); 1314 if (hw->cap.nix_rx_multicast && is_vf(pcifunc) && 1315 type != NIXLF_BCAST_ENTRY && !pfvf->use_mce_list) 1316 return; 1317 1318 nix_get_mce_list(rvu, pcifunc, type, &mce_list, &mce_idx); 1319 1320 nix_update_mce_list(rvu, pcifunc, mce_list, 1321 mce_idx, index, enable); 1322 if (enable) 1323 npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable); 1324 } 1325 1326 static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc, 1327 int nixlf, bool enable) 1328 { 1329 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); 1330 struct npc_mcam *mcam = &rvu->hw->mcam; 1331 int index, blkaddr; 1332 1333 /* only CGX or LBK interfaces have default entries */ 1334 if (is_cn20k(rvu->pdev) && !npc_is_cgx_or_lbk(rvu, pcifunc)) 1335 return; 1336 1337 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 1338 if (blkaddr < 0) 1339 return; 1340 1341 /* Ucast MCAM match entry of this PF/VF */ 1342 if (npc_is_feature_supported(rvu, BIT_ULL(NPC_DMAC), 1343 pfvf->nix_rx_intf)) { 1344 index = npc_get_nixlf_mcam_index(mcam, pcifunc, 1345 nixlf, NIXLF_UCAST_ENTRY); 1346 if (index < 0) { 1347 dev_err(rvu->dev, 1348 "%s: Error to get ucast entry for pcifunc=%#x\n", 1349 __func__, pcifunc); 1350 return; 1351 } 1352 npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable); 1353 } 1354 1355 /* Nothing to do for VFs, on platforms where pkt replication 1356 * is not supported 1357 */ 1358 if ((pcifunc & RVU_PFVF_FUNC_MASK) && !rvu->hw->cap.nix_rx_multicast) 1359 return; 1360 1361 /* add/delete pf_func to broadcast MCE list */ 1362 npc_enadis_default_mce_entry(rvu, pcifunc, nixlf, 1363 NIXLF_BCAST_ENTRY, enable); 1364 } 1365 1366 void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf) 1367 { 1368 if (nixlf < 0) 1369 return; 1370 1371 npc_enadis_default_entries(rvu, pcifunc, nixlf, false); 1372 1373 /* Delete multicast and promisc MCAM entries */ 1374 npc_enadis_default_mce_entry(rvu, pcifunc, nixlf, 1375 NIXLF_ALLMULTI_ENTRY, false); 1376 npc_enadis_default_mce_entry(rvu, pcifunc, nixlf, 1377 NIXLF_PROMISC_ENTRY, false); 1378 } 1379 1380 bool rvu_npc_enable_mcam_by_entry_index(struct rvu *rvu, int entry, int intf, bool enable) 1381 { 1382 int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 1383 struct npc_mcam *mcam = &rvu->hw->mcam; 1384 struct rvu_npc_mcam_rule *rule, *tmp; 1385 1386 mutex_lock(&mcam->lock); 1387 1388 list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) { 1389 if (rule->intf != intf) 1390 continue; 1391 1392 if (rule->entry != entry) 1393 continue; 1394 1395 rule->enable = enable; 1396 mutex_unlock(&mcam->lock); 1397 1398 npc_enable_mcam_entry(rvu, mcam, blkaddr, 1399 entry, enable); 1400 1401 return true; 1402 } 1403 1404 mutex_unlock(&mcam->lock); 1405 return false; 1406 } 1407 1408 void rvu_npc_enable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf) 1409 { 1410 if (nixlf < 0) 1411 return; 1412 1413 /* Enables only broadcast match entry. Promisc/Allmulti are enabled 1414 * in set_rx_mode mbox handler. 1415 */ 1416 npc_enadis_default_entries(rvu, pcifunc, nixlf, true); 1417 } 1418 1419 void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf) 1420 { 1421 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); 1422 struct npc_mcam *mcam = &rvu->hw->mcam; 1423 struct rvu_npc_mcam_rule *rule, *tmp; 1424 int blkaddr; 1425 1426 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 1427 if (blkaddr < 0) 1428 return; 1429 1430 mutex_lock(&mcam->lock); 1431 1432 /* Disable MCAM entries directing traffic to this 'pcifunc' */ 1433 list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) { 1434 if (is_npc_intf_rx(rule->intf) && 1435 rule->rx_action.pf_func == pcifunc && 1436 rule->rx_action.op != NIX_RX_ACTIONOP_MCAST) { 1437 npc_enable_mcam_entry(rvu, mcam, blkaddr, 1438 rule->entry, false); 1439 rule->enable = false; 1440 /* Indicate that default rule is disabled */ 1441 if (rule->default_rule) { 1442 pfvf->def_ucast_rule = NULL; 1443 list_del(&rule->list); 1444 kfree(rule); 1445 } 1446 } 1447 } 1448 1449 mutex_unlock(&mcam->lock); 1450 1451 npc_mcam_disable_flows(rvu, pcifunc); 1452 1453 rvu_npc_disable_default_entries(rvu, pcifunc, nixlf); 1454 } 1455 1456 void rvu_npc_free_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf) 1457 { 1458 struct npc_mcam *mcam = &rvu->hw->mcam; 1459 struct rvu_npc_mcam_rule *rule, *tmp; 1460 int blkaddr; 1461 1462 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 1463 if (blkaddr < 0) 1464 return; 1465 1466 mutex_lock(&mcam->lock); 1467 1468 /* Free all MCAM entries owned by this 'pcifunc' */ 1469 npc_mcam_free_all_entries(rvu, mcam, blkaddr, pcifunc); 1470 1471 /* Free all MCAM counters owned by this 'pcifunc' */ 1472 npc_mcam_free_all_counters(rvu, mcam, pcifunc); 1473 1474 /* Delete MCAM entries owned by this 'pcifunc' */ 1475 list_for_each_entry_safe(rule, tmp, &mcam->mcam_rules, list) { 1476 if (rule->owner == pcifunc && !rule->default_rule) { 1477 list_del(&rule->list); 1478 kfree(rule); 1479 } 1480 } 1481 1482 mutex_unlock(&mcam->lock); 1483 1484 rvu_npc_disable_default_entries(rvu, pcifunc, nixlf); 1485 } 1486 1487 static void npc_program_mkex_rx(struct rvu *rvu, int blkaddr, 1488 struct npc_mcam_kex *mkex, u8 intf) 1489 { 1490 int lid, lt, ld, fl; 1491 1492 if (is_npc_intf_tx(intf)) 1493 return; 1494 1495 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(intf), 1496 mkex->keyx_cfg[NIX_INTF_RX]); 1497 1498 /* Program LDATA */ 1499 for (lid = 0; lid < NPC_MAX_LID; lid++) { 1500 for (lt = 0; lt < NPC_MAX_LT; lt++) { 1501 for (ld = 0; ld < NPC_MAX_LD; ld++) 1502 SET_KEX_LD(intf, lid, lt, ld, 1503 mkex->intf_lid_lt_ld[NIX_INTF_RX] 1504 [lid][lt][ld]); 1505 } 1506 } 1507 /* Program LFLAGS */ 1508 for (ld = 0; ld < NPC_MAX_LD; ld++) { 1509 for (fl = 0; fl < NPC_MAX_LFL; fl++) 1510 SET_KEX_LDFLAGS(intf, ld, fl, 1511 mkex->intf_ld_flags[NIX_INTF_RX] 1512 [ld][fl]); 1513 } 1514 } 1515 1516 static void npc_program_mkex_tx(struct rvu *rvu, int blkaddr, 1517 struct npc_mcam_kex *mkex, u8 intf) 1518 { 1519 int lid, lt, ld, fl; 1520 1521 if (is_npc_intf_rx(intf)) 1522 return; 1523 1524 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(intf), 1525 mkex->keyx_cfg[NIX_INTF_TX]); 1526 1527 /* Program LDATA */ 1528 for (lid = 0; lid < NPC_MAX_LID; lid++) { 1529 for (lt = 0; lt < NPC_MAX_LT; lt++) { 1530 for (ld = 0; ld < NPC_MAX_LD; ld++) 1531 SET_KEX_LD(intf, lid, lt, ld, 1532 mkex->intf_lid_lt_ld[NIX_INTF_TX] 1533 [lid][lt][ld]); 1534 } 1535 } 1536 /* Program LFLAGS */ 1537 for (ld = 0; ld < NPC_MAX_LD; ld++) { 1538 for (fl = 0; fl < NPC_MAX_LFL; fl++) 1539 SET_KEX_LDFLAGS(intf, ld, fl, 1540 mkex->intf_ld_flags[NIX_INTF_TX] 1541 [ld][fl]); 1542 } 1543 } 1544 1545 static void npc_program_mkex_profile(struct rvu *rvu, int blkaddr, 1546 struct npc_mcam_kex *mkex) 1547 { 1548 struct rvu_hwinfo *hw = rvu->hw; 1549 u8 intf; 1550 int ld; 1551 1552 for (ld = 0; ld < NPC_MAX_LD; ld++) 1553 rvu_write64(rvu, blkaddr, NPC_AF_KEX_LDATAX_FLAGS_CFG(ld), 1554 mkex->kex_ld_flags[ld]); 1555 1556 for (intf = 0; intf < hw->npc_intfs; intf++) { 1557 npc_program_mkex_rx(rvu, blkaddr, mkex, intf); 1558 npc_program_mkex_tx(rvu, blkaddr, mkex, intf); 1559 } 1560 1561 /* Programme mkex hash profile */ 1562 npc_program_mkex_hash(rvu, blkaddr); 1563 } 1564 1565 int npc_fwdb_prfl_img_map(struct rvu *rvu, void __iomem **prfl_img_addr, 1566 u64 *size) 1567 { 1568 u64 prfl_addr, prfl_sz; 1569 1570 if (!rvu->fwdata) 1571 return -EINVAL; 1572 1573 prfl_addr = rvu->fwdata->mcam_addr; 1574 prfl_sz = rvu->fwdata->mcam_sz; 1575 1576 if (!prfl_addr || !prfl_sz) 1577 return -EINVAL; 1578 1579 *prfl_img_addr = ioremap_wc(prfl_addr, prfl_sz); 1580 if (!(*prfl_img_addr)) 1581 return -ENOMEM; 1582 1583 *size = prfl_sz; 1584 1585 return 0; 1586 } 1587 1588 /* strtoull of "mkexprof" with base:36 */ 1589 #define MKEX_END_SIGN 0xdeadbeef 1590 1591 static void npc_load_mkex_profile(struct rvu *rvu, int blkaddr, 1592 const char *mkex_profile) 1593 { 1594 struct device *dev = &rvu->pdev->dev; 1595 struct npc_mcam_kex *mcam_kex; 1596 void __iomem *mkex_prfl_addr = NULL; 1597 u64 prfl_sz; 1598 int ret; 1599 1600 /* If user not selected mkex profile */ 1601 if (rvu->kpu_fwdata_sz || 1602 !strncmp(mkex_profile, def_pfl_name, MKEX_NAME_LEN)) 1603 goto program_mkex; 1604 1605 /* Setting up the mapping for mkex profile image */ 1606 ret = npc_fwdb_prfl_img_map(rvu, &mkex_prfl_addr, &prfl_sz); 1607 if (ret < 0) 1608 goto program_mkex; 1609 1610 mcam_kex = (struct npc_mcam_kex __force *)mkex_prfl_addr; 1611 1612 while (((s64)prfl_sz > 0) && (mcam_kex->mkex_sign != MKEX_END_SIGN)) { 1613 /* Compare with mkex mod_param name string */ 1614 if (mcam_kex->mkex_sign == MKEX_SIGN && 1615 !strncmp(mcam_kex->name, mkex_profile, MKEX_NAME_LEN)) { 1616 /* Due to an errata (35786) in A0/B0 pass silicon, 1617 * parse nibble enable configuration has to be 1618 * identical for both Rx and Tx interfaces. 1619 */ 1620 if (!is_rvu_96xx_B0(rvu) || 1621 mcam_kex->keyx_cfg[NIX_INTF_RX] == mcam_kex->keyx_cfg[NIX_INTF_TX]) 1622 rvu->kpu.mcam_kex_prfl.mkex = mcam_kex; 1623 goto program_mkex; 1624 } 1625 1626 mcam_kex++; 1627 prfl_sz -= sizeof(struct npc_mcam_kex); 1628 } 1629 dev_warn(dev, "Failed to load requested profile: %s\n", mkex_profile); 1630 1631 program_mkex: 1632 dev_info(rvu->dev, "Using %s mkex profile\n", 1633 rvu->kpu.mcam_kex_prfl.mkex->name); 1634 /* Program selected mkex profile */ 1635 npc_program_mkex_profile(rvu, blkaddr, rvu->kpu.mcam_kex_prfl.mkex); 1636 if (mkex_prfl_addr) 1637 iounmap(mkex_prfl_addr); 1638 } 1639 1640 void npc_config_kpuaction(struct rvu *rvu, int blkaddr, 1641 const struct npc_kpu_profile_action *kpuaction, 1642 int kpu, int entry, bool pkind) 1643 { 1644 struct npc_kpu_action0 action0 = {0}; 1645 struct npc_kpu_action1 action1 = {0}; 1646 u64 reg; 1647 1648 action1.errlev = kpuaction->errlev; 1649 action1.errcode = kpuaction->errcode; 1650 action1.dp0_offset = kpuaction->dp0_offset; 1651 action1.dp1_offset = kpuaction->dp1_offset; 1652 action1.dp2_offset = kpuaction->dp2_offset; 1653 1654 if (pkind) 1655 reg = NPC_AF_PKINDX_ACTION1(entry); 1656 else 1657 reg = NPC_AF_KPUX_ENTRYX_ACTION1(kpu, entry); 1658 1659 rvu_write64(rvu, blkaddr, reg, *(u64 *)&action1); 1660 1661 action0.byp_count = kpuaction->bypass_count; 1662 action0.capture_ena = kpuaction->cap_ena; 1663 action0.parse_done = kpuaction->parse_done; 1664 action0.next_state = kpuaction->next_state; 1665 action0.capture_lid = kpuaction->lid; 1666 action0.capture_ltype = kpuaction->ltype; 1667 action0.capture_flags = kpuaction->flags; 1668 action0.ptr_advance = kpuaction->ptr_advance; 1669 action0.var_len_offset = kpuaction->offset; 1670 action0.var_len_mask = kpuaction->mask; 1671 action0.var_len_right = kpuaction->right; 1672 action0.var_len_shift = kpuaction->shift; 1673 1674 if (pkind) 1675 reg = NPC_AF_PKINDX_ACTION0(entry); 1676 else 1677 reg = NPC_AF_KPUX_ENTRYX_ACTION0(kpu, entry); 1678 1679 rvu_write64(rvu, blkaddr, reg, *(u64 *)&action0); 1680 } 1681 1682 static void npc_config_kpucam(struct rvu *rvu, int blkaddr, 1683 const struct npc_kpu_profile_cam *kpucam, 1684 int kpu, int entry) 1685 { 1686 struct npc_kpu_cam cam0 = {0}; 1687 struct npc_kpu_cam cam1 = {0}; 1688 1689 cam1.state = kpucam->state & kpucam->state_mask; 1690 cam1.dp0_data = kpucam->dp0 & kpucam->dp0_mask; 1691 cam1.dp1_data = kpucam->dp1 & kpucam->dp1_mask; 1692 cam1.dp2_data = kpucam->dp2 & kpucam->dp2_mask; 1693 1694 cam0.state = ~kpucam->state & kpucam->state_mask; 1695 cam0.dp0_data = ~kpucam->dp0 & kpucam->dp0_mask; 1696 cam0.dp1_data = ~kpucam->dp1 & kpucam->dp1_mask; 1697 cam0.dp2_data = ~kpucam->dp2 & kpucam->dp2_mask; 1698 1699 rvu_write64(rvu, blkaddr, 1700 NPC_AF_KPUX_ENTRYX_CAMX(kpu, entry, 0), *(u64 *)&cam0); 1701 rvu_write64(rvu, blkaddr, 1702 NPC_AF_KPUX_ENTRYX_CAMX(kpu, entry, 1), *(u64 *)&cam1); 1703 } 1704 1705 u64 npc_enable_mask(int count) 1706 { 1707 return (((count) < 64) ? ~(BIT_ULL(count) - 1) : (0x00ULL)); 1708 } 1709 1710 static void npc_program_kpu_profile(struct rvu *rvu, int blkaddr, int kpu, 1711 const struct npc_kpu_profile *profile) 1712 { 1713 int entry, num_entries, max_entries; 1714 u64 entry_mask; 1715 1716 if (profile->cam_entries != profile->action_entries) { 1717 dev_err(rvu->dev, 1718 "KPU%d: CAM and action entries [%d != %d] not equal\n", 1719 kpu, profile->cam_entries, profile->action_entries); 1720 } 1721 1722 max_entries = rvu->hw->npc_kpu_entries; 1723 1724 /* Program CAM match entries for previous KPU extracted data */ 1725 num_entries = min_t(int, profile->cam_entries, max_entries); 1726 for (entry = 0; entry < num_entries; entry++) 1727 npc_config_kpucam(rvu, blkaddr, 1728 &profile->cam[entry], kpu, entry); 1729 1730 /* Program this KPU's actions */ 1731 num_entries = min_t(int, profile->action_entries, max_entries); 1732 for (entry = 0; entry < num_entries; entry++) 1733 npc_config_kpuaction(rvu, blkaddr, &profile->action[entry], 1734 kpu, entry, false); 1735 1736 /* Enable all programmed entries */ 1737 num_entries = min_t(int, profile->action_entries, profile->cam_entries); 1738 entry_mask = npc_enable_mask(num_entries); 1739 /* Disable first KPU_MAX_CST_ENT entries for built-in profile */ 1740 if (!rvu->kpu.custom) 1741 entry_mask |= GENMASK_ULL(KPU_MAX_CST_ENT - 1, 0); 1742 rvu_write64(rvu, blkaddr, 1743 NPC_AF_KPUX_ENTRY_DISX(kpu, 0), entry_mask); 1744 if (num_entries > 64) { 1745 rvu_write64(rvu, blkaddr, 1746 NPC_AF_KPUX_ENTRY_DISX(kpu, 1), 1747 npc_enable_mask(num_entries - 64)); 1748 } 1749 1750 /* Enable this KPU */ 1751 rvu_write64(rvu, blkaddr, NPC_AF_KPUX_CFG(kpu), 0x01); 1752 } 1753 1754 static void npc_prepare_default_kpu(struct rvu *rvu, 1755 struct npc_kpu_profile_adapter *profile) 1756 { 1757 profile->custom = 0; 1758 profile->name = def_pfl_name; 1759 profile->version = NPC_KPU_PROFILE_VER; 1760 profile->ikpu = ikpu_action_entries; 1761 profile->pkinds = ARRAY_SIZE(ikpu_action_entries); 1762 profile->kpu = npc_kpu_profiles; 1763 profile->kpus = ARRAY_SIZE(npc_kpu_profiles); 1764 profile->lt_def = &npc_lt_defaults; 1765 profile->mkex_hash = &npc_mkex_hash_default; 1766 1767 if (!is_cn20k(rvu->pdev)) { 1768 profile->mcam_kex_prfl.mkex = &npc_mkex_default; 1769 return; 1770 } 1771 1772 profile->mcam_kex_prfl.mkex_extr = npc_mkex_extr_default_get(); 1773 ikpu_action_entries[NPC_RX_CPT_HDR_PKIND].offset = 6; 1774 ikpu_action_entries[NPC_RX_CPT_HDR_PKIND].mask = 0xe0; 1775 ikpu_action_entries[NPC_RX_CPT_HDR_PKIND].shift = 0x5; 1776 ikpu_action_entries[NPC_RX_CPT_HDR_PKIND].right = 0x1; 1777 1778 npc_cn20k_update_action_entries_n_flags(rvu, profile); 1779 } 1780 1781 static int npc_apply_custom_kpu(struct rvu *rvu, 1782 struct npc_kpu_profile_adapter *profile) 1783 { 1784 size_t hdr_sz = sizeof(struct npc_kpu_profile_fwdata), offset = 0; 1785 struct npc_kpu_profile_action *action; 1786 struct npc_kpu_profile_fwdata *fw; 1787 struct npc_kpu_profile_cam *cam; 1788 struct npc_kpu_fwdata *fw_kpu; 1789 int entries; 1790 u16 kpu, entry; 1791 1792 if (is_cn20k(rvu->pdev)) 1793 return npc_cn20k_apply_custom_kpu(rvu, profile); 1794 1795 fw = rvu->kpu_fwdata; 1796 1797 if (rvu->kpu_fwdata_sz < hdr_sz) { 1798 dev_warn(rvu->dev, "Invalid KPU profile size\n"); 1799 return -EINVAL; 1800 } 1801 if (le64_to_cpu(fw->signature) != KPU_SIGN) { 1802 dev_warn(rvu->dev, "Invalid KPU profile signature %llx\n", 1803 fw->signature); 1804 return -EINVAL; 1805 } 1806 /* Verify if the using known profile structure */ 1807 if (NPC_KPU_VER_MAJ(profile->version) > 1808 NPC_KPU_VER_MAJ(NPC_KPU_PROFILE_VER)) { 1809 dev_warn(rvu->dev, "Not supported Major version: %d > %d\n", 1810 NPC_KPU_VER_MAJ(profile->version), 1811 NPC_KPU_VER_MAJ(NPC_KPU_PROFILE_VER)); 1812 return -EINVAL; 1813 } 1814 /* Verify if profile is aligned with the required kernel changes */ 1815 if (NPC_KPU_VER_MIN(profile->version) < 1816 NPC_KPU_VER_MIN(NPC_KPU_PROFILE_VER)) { 1817 dev_warn(rvu->dev, 1818 "Invalid KPU profile version: %d.%d.%d expected version <= %d.%d.%d\n", 1819 NPC_KPU_VER_MAJ(profile->version), 1820 NPC_KPU_VER_MIN(profile->version), 1821 NPC_KPU_VER_PATCH(profile->version), 1822 NPC_KPU_VER_MAJ(NPC_KPU_PROFILE_VER), 1823 NPC_KPU_VER_MIN(NPC_KPU_PROFILE_VER), 1824 NPC_KPU_VER_PATCH(NPC_KPU_PROFILE_VER)); 1825 return -EINVAL; 1826 } 1827 /* Verify if profile fits the HW */ 1828 if (fw->kpus > profile->kpus) { 1829 dev_warn(rvu->dev, "Not enough KPUs: %d > %ld\n", fw->kpus, 1830 profile->kpus); 1831 return -EINVAL; 1832 } 1833 1834 profile->custom = 1; 1835 profile->name = fw->name; 1836 profile->version = le64_to_cpu(fw->version); 1837 profile->mcam_kex_prfl.mkex = &fw->mkex; 1838 profile->lt_def = &fw->lt_def; 1839 1840 for (kpu = 0; kpu < fw->kpus; kpu++) { 1841 fw_kpu = (struct npc_kpu_fwdata *)(fw->data + offset); 1842 if (fw_kpu->entries > KPU_MAX_CST_ENT) 1843 dev_warn(rvu->dev, 1844 "Too many custom entries on KPU%d: %d > %d\n", 1845 kpu, fw_kpu->entries, KPU_MAX_CST_ENT); 1846 entries = min(fw_kpu->entries, KPU_MAX_CST_ENT); 1847 cam = (struct npc_kpu_profile_cam *)fw_kpu->data; 1848 offset += sizeof(*fw_kpu) + fw_kpu->entries * sizeof(*cam); 1849 action = (struct npc_kpu_profile_action *)(fw->data + offset); 1850 offset += fw_kpu->entries * sizeof(*action); 1851 if (rvu->kpu_fwdata_sz < hdr_sz + offset) { 1852 dev_warn(rvu->dev, 1853 "Profile size mismatch on KPU%i parsing.\n", 1854 kpu + 1); 1855 return -EINVAL; 1856 } 1857 for (entry = 0; entry < entries; entry++) { 1858 profile->kpu[kpu].cam[entry] = cam[entry]; 1859 profile->kpu[kpu].action[entry] = action[entry]; 1860 } 1861 } 1862 1863 return 0; 1864 } 1865 1866 static int npc_load_kpu_prfl_img(struct rvu *rvu, void __iomem *prfl_addr, 1867 u64 prfl_sz, const char *kpu_profile) 1868 { 1869 struct npc_kpu_profile_fwdata *kpu_data = NULL; 1870 int rc = -EINVAL; 1871 1872 kpu_data = (struct npc_kpu_profile_fwdata __force *)prfl_addr; 1873 if (le64_to_cpu(kpu_data->signature) == KPU_SIGN && 1874 !strncmp(kpu_data->name, kpu_profile, KPU_NAME_LEN)) { 1875 dev_info(rvu->dev, "Loading KPU profile from firmware db: %s\n", 1876 kpu_profile); 1877 rvu->kpu_fwdata = kpu_data; 1878 rvu->kpu_fwdata_sz = prfl_sz; 1879 rvu->kpu_prfl_addr = prfl_addr; 1880 rc = 0; 1881 } 1882 1883 return rc; 1884 } 1885 1886 static int npc_fwdb_detect_load_prfl_img(struct rvu *rvu, uint64_t prfl_sz, 1887 const char *kpu_profile) 1888 { 1889 struct npc_coalesced_kpu_prfl *img_data = NULL; 1890 int i = 0, rc = -EINVAL; 1891 void __iomem *kpu_prfl_addr; 1892 u32 offset; 1893 1894 img_data = (struct npc_coalesced_kpu_prfl __force *)rvu->kpu_prfl_addr; 1895 if (le64_to_cpu(img_data->signature) == KPU_SIGN && 1896 !strncmp(img_data->name, kpu_profile, KPU_NAME_LEN)) { 1897 /* Loaded profile is a single KPU profile. */ 1898 rc = npc_load_kpu_prfl_img(rvu, rvu->kpu_prfl_addr, 1899 prfl_sz, kpu_profile); 1900 goto done; 1901 } 1902 1903 /* Loaded profile is coalesced image, offset of first KPU profile.*/ 1904 offset = offsetof(struct npc_coalesced_kpu_prfl, prfl_sz) + 1905 (img_data->num_prfl * sizeof(uint16_t)); 1906 /* Check if mapped image is coalesced image. */ 1907 while (i < img_data->num_prfl) { 1908 /* Profile image offsets are rounded up to next 8 multiple.*/ 1909 offset = ALIGN_8B_CEIL(offset); 1910 kpu_prfl_addr = (void __iomem *)((uintptr_t)rvu->kpu_prfl_addr + 1911 offset); 1912 rc = npc_load_kpu_prfl_img(rvu, kpu_prfl_addr, 1913 img_data->prfl_sz[i], kpu_profile); 1914 if (!rc) 1915 break; 1916 /* Calculating offset of profile image based on profile size.*/ 1917 offset += img_data->prfl_sz[i]; 1918 i++; 1919 } 1920 done: 1921 return rc; 1922 } 1923 1924 static int npc_load_kpu_profile_fwdb(struct rvu *rvu, const char *kpu_profile) 1925 { 1926 int ret = -EINVAL; 1927 u64 prfl_sz; 1928 1929 /* Setting up the mapping for NPC profile image */ 1930 ret = npc_fwdb_prfl_img_map(rvu, &rvu->kpu_prfl_addr, &prfl_sz); 1931 if (ret < 0) 1932 goto done; 1933 1934 /* Detect if profile is coalesced or single KPU profile and load */ 1935 ret = npc_fwdb_detect_load_prfl_img(rvu, prfl_sz, kpu_profile); 1936 if (ret == 0) 1937 goto done; 1938 1939 /* Cleaning up if KPU profile image from fwdata is not valid. */ 1940 if (rvu->kpu_prfl_addr) { 1941 iounmap(rvu->kpu_prfl_addr); 1942 rvu->kpu_prfl_addr = NULL; 1943 rvu->kpu_fwdata_sz = 0; 1944 rvu->kpu_fwdata = NULL; 1945 } 1946 1947 done: 1948 return ret; 1949 } 1950 1951 void npc_load_kpu_profile(struct rvu *rvu) 1952 { 1953 struct npc_kpu_profile_adapter *profile = &rvu->kpu; 1954 const char *kpu_profile = rvu->kpu_pfl_name; 1955 const struct firmware *fw = NULL; 1956 bool retry_fwdb = false; 1957 1958 /* If user not specified profile customization */ 1959 if (!strncmp(kpu_profile, def_pfl_name, KPU_NAME_LEN)) 1960 goto revert_to_default; 1961 /* First prepare default KPU, then we'll customize top entries. */ 1962 npc_prepare_default_kpu(rvu, profile); 1963 1964 /* Order of preceedence for load loading NPC profile (high to low) 1965 * Firmware binary in filesystem. 1966 * Firmware database method. 1967 * Default KPU profile. 1968 */ 1969 if (!request_firmware_direct(&fw, kpu_profile, rvu->dev)) { 1970 dev_info(rvu->dev, "Loading KPU profile from firmware: %s\n", 1971 kpu_profile); 1972 rvu->kpu_fwdata = kzalloc(fw->size, GFP_KERNEL); 1973 if (rvu->kpu_fwdata) { 1974 memcpy(rvu->kpu_fwdata, fw->data, fw->size); 1975 rvu->kpu_fwdata_sz = fw->size; 1976 } 1977 release_firmware(fw); 1978 retry_fwdb = true; 1979 goto program_kpu; 1980 } 1981 1982 load_image_fwdb: 1983 /* Loading the KPU profile using firmware database */ 1984 if (npc_load_kpu_profile_fwdb(rvu, kpu_profile)) 1985 goto revert_to_default; 1986 1987 program_kpu: 1988 /* Apply profile customization if firmware was loaded. */ 1989 if (!rvu->kpu_fwdata_sz || npc_apply_custom_kpu(rvu, profile)) { 1990 /* If image from firmware filesystem fails to load or invalid 1991 * retry with firmware database method. 1992 */ 1993 if (rvu->kpu_fwdata || rvu->kpu_fwdata_sz) { 1994 /* Loading image from firmware database failed. */ 1995 if (rvu->kpu_prfl_addr) { 1996 iounmap(rvu->kpu_prfl_addr); 1997 rvu->kpu_prfl_addr = NULL; 1998 } else { 1999 kfree(rvu->kpu_fwdata); 2000 } 2001 rvu->kpu_fwdata = NULL; 2002 rvu->kpu_fwdata_sz = 0; 2003 if (retry_fwdb) { 2004 retry_fwdb = false; 2005 goto load_image_fwdb; 2006 } 2007 } 2008 2009 dev_warn(rvu->dev, 2010 "Can't load KPU profile %s. Using default.\n", 2011 kpu_profile); 2012 kfree(rvu->kpu_fwdata); 2013 rvu->kpu_fwdata = NULL; 2014 goto revert_to_default; 2015 } 2016 2017 dev_info(rvu->dev, "Using custom profile '%s', version %d.%d.%d\n", 2018 profile->name, NPC_KPU_VER_MAJ(profile->version), 2019 NPC_KPU_VER_MIN(profile->version), 2020 NPC_KPU_VER_PATCH(profile->version)); 2021 2022 return; 2023 2024 revert_to_default: 2025 npc_prepare_default_kpu(rvu, profile); 2026 } 2027 2028 static void npc_parser_profile_init(struct rvu *rvu, int blkaddr) 2029 { 2030 struct rvu_hwinfo *hw = rvu->hw; 2031 int num_pkinds, num_kpus, idx; 2032 2033 /* Disable all KPUs and their entries */ 2034 for (idx = 0; idx < hw->npc_kpus; idx++) { 2035 rvu_write64(rvu, blkaddr, 2036 NPC_AF_KPUX_ENTRY_DISX(idx, 0), ~0ULL); 2037 rvu_write64(rvu, blkaddr, 2038 NPC_AF_KPUX_ENTRY_DISX(idx, 1), ~0ULL); 2039 rvu_write64(rvu, blkaddr, NPC_AF_KPUX_CFG(idx), 0x00); 2040 } 2041 2042 /* Load and customize KPU profile. */ 2043 npc_load_kpu_profile(rvu); 2044 2045 /* First program IKPU profile i.e PKIND configs. 2046 * Check HW max count to avoid configuring junk or 2047 * writing to unsupported CSR addresses. 2048 */ 2049 num_pkinds = rvu->kpu.pkinds; 2050 num_pkinds = min_t(int, hw->npc_pkinds, num_pkinds); 2051 2052 for (idx = 0; idx < num_pkinds; idx++) 2053 npc_config_kpuaction(rvu, blkaddr, &rvu->kpu.ikpu[idx], 0, idx, true); 2054 2055 /* Program KPU CAM and Action profiles */ 2056 num_kpus = rvu->kpu.kpus; 2057 num_kpus = min_t(int, hw->npc_kpus, num_kpus); 2058 2059 for (idx = 0; idx < num_kpus; idx++) 2060 npc_program_kpu_profile(rvu, blkaddr, idx, &rvu->kpu.kpu[idx]); 2061 } 2062 2063 void npc_mcam_rsrcs_deinit(struct rvu *rvu) 2064 { 2065 struct npc_mcam *mcam = &rvu->hw->mcam; 2066 2067 bitmap_free(mcam->bmap); 2068 bitmap_free(mcam->bmap_reverse); 2069 kfree(mcam->entry2pfvf_map); 2070 kfree(mcam->cntr2pfvf_map); 2071 kfree(mcam->entry2cntr_map); 2072 kfree(mcam->cntr_refcnt); 2073 kfree(mcam->entry2target_pffunc); 2074 kfree(mcam->counters.bmap); 2075 } 2076 2077 int npc_mcam_rsrcs_init(struct rvu *rvu, int blkaddr) 2078 { 2079 int nixlf_count = rvu_get_nixlf_count(rvu); 2080 struct npc_mcam *mcam = &rvu->hw->mcam; 2081 int rsvd, err; 2082 u16 index; 2083 int cntr; 2084 u64 cfg; 2085 2086 cfg = (rvu_read64(rvu, blkaddr, 2087 NPC_AF_INTFX_KEX_CFG(0)) >> 32) & 0x07; 2088 mcam->keysize = cfg; 2089 2090 /* Number of banks combined per MCAM entry */ 2091 if (is_cn20k(rvu->pdev)) { 2092 /* In cn20k, x2 entries is allowed for x4 profile. 2093 * set total_entries as 8192 * 2 and key size as x2. 2094 */ 2095 mcam->total_entries = mcam->banks * mcam->banksize; 2096 if (cfg == NPC_MCAM_KEY_X2) 2097 mcam->banks_per_entry = 1; 2098 else 2099 mcam->banks_per_entry = 2; 2100 2101 rsvd = 0; 2102 } else { 2103 mcam->total_entries = (mcam->banks / BIT_ULL(cfg)) * 2104 mcam->banksize; 2105 2106 if (cfg == NPC_MCAM_KEY_X4) 2107 mcam->banks_per_entry = 4; 2108 else if (cfg == NPC_MCAM_KEY_X2) 2109 mcam->banks_per_entry = 2; 2110 else 2111 mcam->banks_per_entry = 1; 2112 2113 /* Reserve one MCAM entry for each of the NIX LF to 2114 * guarantee space to install default matching DMAC rule. 2115 * Also reserve 2 MCAM entries for each PF for default 2116 * channel based matching or 'bcast & promisc' matching to 2117 * support BCAST and PROMISC modes of operation for PFs. 2118 * PF0 is excluded. 2119 */ 2120 rsvd = (nixlf_count * RSVD_MCAM_ENTRIES_PER_NIXLF) + 2121 ((rvu->hw->total_pfs - 1) * RSVD_MCAM_ENTRIES_PER_PF); 2122 if (mcam->total_entries <= rsvd) { 2123 dev_warn(rvu->dev, 2124 "Insufficient NPC MCAM size %d for pkt I/O, exiting\n", 2125 mcam->total_entries); 2126 return -ENOMEM; 2127 } 2128 } 2129 2130 mcam->bmap_entries = mcam->total_entries - rsvd; 2131 /* cn20k does not need offsets to alloc mcam entries */ 2132 if (!is_cn20k(rvu->pdev)) { 2133 mcam->nixlf_offset = mcam->bmap_entries; 2134 mcam->pf_offset = mcam->nixlf_offset + nixlf_count; 2135 } 2136 2137 /* Allocate bitmaps for managing MCAM entries */ 2138 mcam->bmap = bitmap_zalloc(mcam->bmap_entries, GFP_KERNEL); 2139 if (!mcam->bmap) 2140 return -ENOMEM; 2141 2142 mcam->bmap_reverse = bitmap_zalloc(mcam->bmap_entries, GFP_KERNEL); 2143 if (!mcam->bmap_reverse) 2144 goto free_bmap; 2145 2146 mcam->bmap_fcnt = mcam->bmap_entries; 2147 2148 /* Alloc memory for saving entry to RVU PFFUNC allocation mapping */ 2149 mcam->entry2pfvf_map = kcalloc(mcam->bmap_entries, sizeof(u16), 2150 GFP_KERNEL); 2151 2152 if (!mcam->entry2pfvf_map) 2153 goto free_bmap_reverse; 2154 2155 /* Reserve 1/8th of MCAM entries at the bottom for low priority 2156 * allocations and another 1/8th at the top for high priority 2157 * allocations. 2158 */ 2159 if (!is_cn20k(rvu->pdev)) { 2160 mcam->lprio_count = mcam->bmap_entries / 8; 2161 if (mcam->lprio_count > BITS_PER_LONG) 2162 mcam->lprio_count = round_down(mcam->lprio_count, 2163 BITS_PER_LONG); 2164 mcam->lprio_start = mcam->bmap_entries - mcam->lprio_count; 2165 mcam->hprio_count = mcam->lprio_count; 2166 mcam->hprio_end = mcam->hprio_count; 2167 } 2168 2169 /* Allocate bitmap for managing MCAM counters and memory 2170 * for saving counter to RVU PFFUNC allocation mapping. 2171 */ 2172 err = rvu_alloc_bitmap(&mcam->counters); 2173 if (err) 2174 goto free_entry_map; 2175 2176 mcam->cntr2pfvf_map = kcalloc(mcam->counters.max, sizeof(u16), 2177 GFP_KERNEL); 2178 if (!mcam->cntr2pfvf_map) 2179 goto free_cntr_bmap; 2180 2181 /* Alloc memory for MCAM entry to counter mapping and for tracking 2182 * counter's reference count. 2183 */ 2184 mcam->entry2cntr_map = kcalloc(mcam->bmap_entries, sizeof(u16), 2185 GFP_KERNEL); 2186 if (!mcam->entry2cntr_map) 2187 goto free_cntr_map; 2188 2189 mcam->cntr_refcnt = kcalloc(mcam->counters.max, sizeof(u16), 2190 GFP_KERNEL); 2191 if (!mcam->cntr_refcnt) 2192 goto free_entry_cntr_map; 2193 2194 /* Alloc memory for saving target device of mcam rule */ 2195 mcam->entry2target_pffunc = kcalloc(mcam->total_entries, 2196 sizeof(u16), GFP_KERNEL); 2197 if (!mcam->entry2target_pffunc) 2198 goto free_cntr_refcnt; 2199 2200 for (index = 0; index < mcam->bmap_entries; index++) { 2201 mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP; 2202 mcam->entry2cntr_map[index] = NPC_MCAM_INVALID_MAP; 2203 } 2204 2205 for (cntr = 0; cntr < mcam->counters.max; cntr++) 2206 mcam->cntr2pfvf_map[cntr] = NPC_MCAM_INVALID_MAP; 2207 2208 mutex_init(&mcam->lock); 2209 2210 return 0; 2211 2212 free_cntr_refcnt: 2213 kfree(mcam->cntr_refcnt); 2214 free_entry_cntr_map: 2215 kfree(mcam->entry2cntr_map); 2216 free_cntr_map: 2217 kfree(mcam->cntr2pfvf_map); 2218 free_cntr_bmap: 2219 kfree(mcam->counters.bmap); 2220 free_entry_map: 2221 kfree(mcam->entry2pfvf_map); 2222 free_bmap_reverse: 2223 bitmap_free(mcam->bmap_reverse); 2224 free_bmap: 2225 bitmap_free(mcam->bmap); 2226 2227 return -ENOMEM; 2228 } 2229 2230 static void rvu_npc_hw_init(struct rvu *rvu, int blkaddr) 2231 { 2232 struct npc_pkind *pkind = &rvu->hw->pkind; 2233 struct npc_mcam *mcam = &rvu->hw->mcam; 2234 struct rvu_hwinfo *hw = rvu->hw; 2235 u64 npc_const, npc_const1; 2236 u64 npc_const2 = 0; 2237 2238 npc_const = rvu_read64(rvu, blkaddr, NPC_AF_CONST); 2239 npc_const1 = rvu_read64(rvu, blkaddr, NPC_AF_CONST1); 2240 if (npc_const1 & BIT_ULL(63)) 2241 npc_const2 = rvu_read64(rvu, blkaddr, NPC_AF_CONST2); 2242 2243 pkind->rsrc.max = NPC_UNRESERVED_PKIND_COUNT; 2244 hw->npc_pkinds = (npc_const1 >> 12) & 0xFFULL; 2245 hw->npc_kpu_entries = npc_const1 & 0xFFFULL; 2246 hw->npc_kpus = (npc_const >> 8) & 0x1FULL; 2247 /* For Cn20k silicon, check if enhanced parser 2248 * is present, then set the NUM_KPMS = NUM_KPUS / 2 and 2249 * number of LDATA extractors per KEX. 2250 */ 2251 if (is_cn20k(rvu->pdev)) { 2252 if (!(npc_const1 & BIT_ULL(62))) { 2253 WARN(1, "Enhanced parser is not supported\n"); 2254 return; 2255 } 2256 hw->npc_kpms = hw->npc_kpus / 2; 2257 hw->npc_kex_extr = (npc_const1 >> 36) & 0x3FULL; 2258 } 2259 2260 hw->npc_intfs = npc_const & 0xFULL; 2261 hw->npc_counters = (npc_const >> 48) & 0xFFFFULL; 2262 2263 mcam->banks = (npc_const >> 44) & 0xFULL; 2264 mcam->banksize = (npc_const >> 28) & 0xFFFFULL; 2265 hw->npc_stat_ena = BIT_ULL(9); 2266 /* Extended set */ 2267 if (npc_const2) { 2268 hw->npc_ext_set = true; 2269 /* 96xx supports only match_stats and npc_counters 2270 * reflected in NPC_AF_CONST reg. 2271 * STAT_SEL and ENA are at [0:8] and 9 bit positions. 2272 * 98xx has both match_stat and ext and npc_counter 2273 * reflected in NPC_AF_CONST2 2274 * STAT_SEL_EXT added at [12:14] bit position. 2275 * cn10k supports only ext and hence npc_counters in 2276 * NPC_AF_CONST is 0 and npc_counters reflected in NPC_AF_CONST2. 2277 * STAT_SEL bitpos incremented from [0:8] to [0:11] and ENA bit moved to 63 2278 */ 2279 if (!hw->npc_counters) 2280 hw->npc_stat_ena = BIT_ULL(63); 2281 hw->npc_counters = (npc_const2 >> 16) & 0xFFFFULL; 2282 mcam->banksize = npc_const2 & 0xFFFFULL; 2283 } 2284 2285 mcam->counters.max = hw->npc_counters; 2286 } 2287 2288 static void rvu_npc_setup_interfaces(struct rvu *rvu, int blkaddr) 2289 { 2290 struct npc_mcam_kex_extr *mkex_extr = rvu->kpu.mcam_kex_prfl.mkex_extr; 2291 struct npc_mcam_kex *mkex = rvu->kpu.mcam_kex_prfl.mkex; 2292 struct npc_mcam *mcam = &rvu->hw->mcam; 2293 struct rvu_hwinfo *hw = rvu->hw; 2294 u64 nibble_ena, rx_kex, tx_kex; 2295 u64 *keyx_cfg, reg; 2296 u8 intf; 2297 2298 if (is_cn20k(rvu->pdev)) { 2299 keyx_cfg = mkex_extr->keyx_cfg; 2300 } else { 2301 keyx_cfg = mkex->keyx_cfg; 2302 /* Reserve last counter for MCAM RX miss action which is set to 2303 * drop packet. This way we will know how many pkts didn't 2304 * match any MCAM entry. 2305 */ 2306 mcam->counters.max--; 2307 mcam->rx_miss_act_cntr = mcam->counters.max; 2308 } 2309 2310 rx_kex = keyx_cfg[NIX_INTF_RX]; 2311 tx_kex = keyx_cfg[NIX_INTF_TX]; 2312 2313 nibble_ena = FIELD_GET(NPC_PARSE_NIBBLE, rx_kex); 2314 2315 nibble_ena = rvu_npc_get_tx_nibble_cfg(rvu, nibble_ena); 2316 if (nibble_ena) { 2317 tx_kex &= ~NPC_PARSE_NIBBLE; 2318 tx_kex |= FIELD_PREP(NPC_PARSE_NIBBLE, nibble_ena); 2319 keyx_cfg[NIX_INTF_TX] = tx_kex; 2320 } 2321 2322 /* Configure RX interfaces */ 2323 for (intf = 0; intf < hw->npc_intfs; intf++) { 2324 if (is_npc_intf_tx(intf)) 2325 continue; 2326 2327 /* Set RX MCAM search key size. LA..LE (ltype only) + Channel */ 2328 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(intf), 2329 rx_kex); 2330 2331 if (is_cn20k(rvu->pdev)) 2332 reg = NPC_AF_INTFX_MISS_ACTX(intf, 0); 2333 else 2334 reg = NPC_AF_INTFX_MISS_ACT(intf); 2335 2336 /* If MCAM lookup doesn't result in a match, drop the received 2337 * packet. And map this action to a counter to count dropped 2338 * packets. 2339 */ 2340 rvu_write64(rvu, blkaddr, reg, NIX_RX_ACTIONOP_DROP); 2341 2342 if (is_cn20k(rvu->pdev)) 2343 continue; 2344 2345 /* NPC_AF_INTFX_MISS_STAT_ACT[14:12] - counter[11:9] 2346 * NPC_AF_INTFX_MISS_STAT_ACT[8:0] - counter[8:0] 2347 */ 2348 rvu_write64(rvu, blkaddr, 2349 NPC_AF_INTFX_MISS_STAT_ACT(intf), 2350 ((mcam->rx_miss_act_cntr >> 9) << 12) | 2351 hw->npc_stat_ena | mcam->rx_miss_act_cntr); 2352 } 2353 2354 /* Configure TX interfaces */ 2355 for (intf = 0; intf < hw->npc_intfs; intf++) { 2356 if (is_npc_intf_rx(intf)) 2357 continue; 2358 2359 /* Extract Ltypes LID_LA to LID_LE */ 2360 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(intf), 2361 tx_kex); 2362 2363 if (is_cn20k(rvu->pdev)) 2364 reg = NPC_AF_INTFX_MISS_ACTX(intf, 0); 2365 else 2366 reg = NPC_AF_INTFX_MISS_ACT(intf); 2367 2368 /* Set TX miss action to UCAST_DEFAULT i.e 2369 * transmit the packet on NIX LF SQ's default channel. 2370 */ 2371 rvu_write64(rvu, blkaddr, reg, NIX_TX_ACTIONOP_UCAST_DEFAULT); 2372 } 2373 } 2374 2375 int rvu_npc_init(struct rvu *rvu) 2376 { 2377 struct npc_kpu_profile_adapter *kpu = &rvu->kpu; 2378 struct npc_pkind *pkind = &rvu->hw->pkind; 2379 struct npc_mcam *mcam = &rvu->hw->mcam; 2380 int blkaddr, entry, bank, err; 2381 2382 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 2383 if (blkaddr < 0) { 2384 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__); 2385 return -ENODEV; 2386 } 2387 2388 rvu_npc_hw_init(rvu, blkaddr); 2389 2390 /* First disable all MCAM entries, to stop traffic towards NIXLFs */ 2391 for (bank = 0; bank < mcam->banks; bank++) { 2392 for (entry = 0; entry < mcam->banksize; entry++) 2393 rvu_write64(rvu, blkaddr, 2394 NPC_AF_MCAMEX_BANKX_CFG(entry, bank), 0); 2395 } 2396 2397 err = rvu_alloc_bitmap(&pkind->rsrc); 2398 if (err) 2399 return err; 2400 /* Reserve PKIND#0 for LBKs. Power reset value of LBK_CH_PKIND is '0', 2401 * no need to configure PKIND for all LBKs separately. 2402 */ 2403 rvu_alloc_rsrc(&pkind->rsrc); 2404 2405 /* Allocate mem for pkind to PF and channel mapping info */ 2406 pkind->pfchan_map = devm_kcalloc(rvu->dev, pkind->rsrc.max, 2407 sizeof(u32), GFP_KERNEL); 2408 if (!pkind->pfchan_map) 2409 return -ENOMEM; 2410 2411 /* Configure KPU profile */ 2412 if (is_cn20k(rvu->pdev)) 2413 npc_cn20k_parser_profile_init(rvu, blkaddr); 2414 else 2415 npc_parser_profile_init(rvu, blkaddr); 2416 2417 /* Config Outer L2, IPv4's NPC layer info */ 2418 rvu_write64(rvu, blkaddr, NPC_AF_PCK_DEF_OL2, 2419 (kpu->lt_def->pck_ol2.lid << 8) | (kpu->lt_def->pck_ol2.ltype_match << 4) | 2420 kpu->lt_def->pck_ol2.ltype_mask); 2421 rvu_write64(rvu, blkaddr, NPC_AF_PCK_DEF_OIP4, 2422 (kpu->lt_def->pck_oip4.lid << 8) | (kpu->lt_def->pck_oip4.ltype_match << 4) | 2423 kpu->lt_def->pck_oip4.ltype_mask); 2424 2425 /* Config Inner IPV4 NPC layer info */ 2426 rvu_write64(rvu, blkaddr, NPC_AF_PCK_DEF_IIP4, 2427 (kpu->lt_def->pck_iip4.lid << 8) | (kpu->lt_def->pck_iip4.ltype_match << 4) | 2428 kpu->lt_def->pck_iip4.ltype_mask); 2429 2430 /* Enable below for Rx pkts. 2431 * - Outer IPv4 header checksum validation. 2432 * - Detect outer L2 broadcast address and set NPC_RESULT_S[L2B]. 2433 * - Detect outer L2 multicast address and set NPC_RESULT_S[L2M]. 2434 * - Inner IPv4 header checksum validation. 2435 * - Set non zero checksum error code value 2436 */ 2437 rvu_write64(rvu, blkaddr, NPC_AF_PCK_CFG, 2438 rvu_read64(rvu, blkaddr, NPC_AF_PCK_CFG) | 2439 ((u64)NPC_EC_OIP4_CSUM << 32) | (NPC_EC_IIP4_CSUM << 24) | 2440 BIT_ULL(7) | BIT_ULL(6) | BIT_ULL(2) | BIT_ULL(1)); 2441 2442 rvu_npc_setup_interfaces(rvu, blkaddr); 2443 2444 npc_config_secret_key(rvu, blkaddr); 2445 /* Configure MKEX profile */ 2446 if (is_cn20k(rvu->pdev)) 2447 npc_cn20k_load_mkex_profile(rvu, blkaddr, rvu->mkex_pfl_name); 2448 else 2449 npc_load_mkex_profile(rvu, blkaddr, rvu->mkex_pfl_name); 2450 2451 err = npc_mcam_rsrcs_init(rvu, blkaddr); 2452 if (err) 2453 return err; 2454 2455 err = npc_flow_steering_init(rvu, blkaddr); 2456 if (err) { 2457 dev_err(rvu->dev, 2458 "Incorrect mkex profile loaded using default mkex\n"); 2459 if (is_cn20k(rvu->pdev)) 2460 npc_cn20k_load_mkex_profile(rvu, blkaddr, def_pfl_name); 2461 else 2462 npc_load_mkex_profile(rvu, blkaddr, def_pfl_name); 2463 } 2464 2465 if (is_cn20k(rvu->pdev)) 2466 return npc_cn20k_init(rvu); 2467 2468 return 0; 2469 } 2470 2471 void rvu_npc_freemem(struct rvu *rvu) 2472 { 2473 struct npc_pkind *pkind = &rvu->hw->pkind; 2474 struct npc_mcam *mcam = &rvu->hw->mcam; 2475 2476 kfree(pkind->rsrc.bmap); 2477 npc_mcam_rsrcs_deinit(rvu); 2478 if (rvu->kpu_prfl_addr) 2479 iounmap(rvu->kpu_prfl_addr); 2480 else 2481 kfree(rvu->kpu_fwdata); 2482 mutex_destroy(&mcam->lock); 2483 2484 if (is_cn20k(rvu->pdev)) 2485 npc_cn20k_deinit(rvu); 2486 } 2487 2488 void rvu_npc_get_mcam_entry_alloc_info(struct rvu *rvu, u16 pcifunc, 2489 int blkaddr, int *alloc_cnt, 2490 int *enable_cnt) 2491 { 2492 struct npc_mcam *mcam = &rvu->hw->mcam; 2493 int entry; 2494 2495 *alloc_cnt = 0; 2496 *enable_cnt = 0; 2497 2498 for (entry = 0; entry < mcam->bmap_entries; entry++) { 2499 if (mcam->entry2pfvf_map[entry] == pcifunc) { 2500 (*alloc_cnt)++; 2501 if (is_mcam_entry_enabled(rvu, mcam, blkaddr, entry)) 2502 (*enable_cnt)++; 2503 } 2504 } 2505 } 2506 2507 void rvu_npc_get_mcam_counter_alloc_info(struct rvu *rvu, u16 pcifunc, 2508 int blkaddr, int *alloc_cnt, 2509 int *enable_cnt) 2510 { 2511 struct npc_mcam *mcam = &rvu->hw->mcam; 2512 int cntr; 2513 2514 *alloc_cnt = 0; 2515 *enable_cnt = 0; 2516 2517 for (cntr = 0; cntr < mcam->counters.max; cntr++) { 2518 if (mcam->cntr2pfvf_map[cntr] == pcifunc) { 2519 (*alloc_cnt)++; 2520 if (mcam->cntr_refcnt[cntr]) 2521 (*enable_cnt)++; 2522 } 2523 } 2524 } 2525 2526 int npc_mcam_verify_entry(struct npc_mcam *mcam, 2527 u16 pcifunc, int entry) 2528 { 2529 /* verify AF installed entries */ 2530 if (is_pffunc_af(pcifunc)) 2531 return 0; 2532 /* Verify if entry is valid and if it is indeed 2533 * allocated to the requesting PFFUNC. 2534 */ 2535 if (entry >= mcam->bmap_entries) 2536 return NPC_MCAM_INVALID_REQ; 2537 2538 if (pcifunc != mcam->entry2pfvf_map[entry]) 2539 return NPC_MCAM_PERM_DENIED; 2540 2541 return 0; 2542 } 2543 2544 static int npc_mcam_verify_counter(struct npc_mcam *mcam, 2545 u16 pcifunc, int cntr) 2546 { 2547 /* Verify if counter is valid and if it is indeed 2548 * allocated to the requesting PFFUNC. 2549 */ 2550 if (cntr >= mcam->counters.max) 2551 return NPC_MCAM_INVALID_REQ; 2552 2553 if (pcifunc != mcam->cntr2pfvf_map[cntr]) 2554 return NPC_MCAM_PERM_DENIED; 2555 2556 return 0; 2557 } 2558 2559 static void npc_map_mcam_entry_and_cntr(struct rvu *rvu, struct npc_mcam *mcam, 2560 int blkaddr, u16 entry, u16 cntr) 2561 { 2562 u16 index = entry & (mcam->banksize - 1); 2563 u32 bank = npc_get_bank(mcam, entry); 2564 struct rvu_hwinfo *hw = rvu->hw; 2565 2566 /* Set mapping and increment counter's refcnt */ 2567 mcam->entry2cntr_map[entry] = cntr; 2568 mcam->cntr_refcnt[cntr]++; 2569 2570 if (is_cn20k(rvu->pdev)) 2571 return; 2572 2573 /* Enable stats */ 2574 rvu_write64(rvu, blkaddr, 2575 NPC_AF_MCAMEX_BANKX_STAT_ACT(index, bank), 2576 ((cntr >> 9) << 12) | hw->npc_stat_ena | cntr); 2577 } 2578 2579 static void npc_unmap_mcam_entry_and_cntr(struct rvu *rvu, 2580 struct npc_mcam *mcam, 2581 int blkaddr, u16 entry, u16 cntr) 2582 { 2583 u16 index = entry & (mcam->banksize - 1); 2584 u32 bank = npc_get_bank(mcam, entry); 2585 2586 /* Remove mapping and reduce counter's refcnt */ 2587 mcam->entry2cntr_map[entry] = NPC_MCAM_INVALID_MAP; 2588 mcam->cntr_refcnt[cntr]--; 2589 2590 if (is_cn20k(rvu->pdev)) 2591 return; 2592 2593 /* Disable stats */ 2594 rvu_write64(rvu, blkaddr, 2595 NPC_AF_MCAMEX_BANKX_STAT_ACT(index, bank), 0x00); 2596 } 2597 2598 /* Sets MCAM entry in bitmap as used. Update 2599 * reverse bitmap too. Should be called with 2600 * 'mcam->lock' held. 2601 */ 2602 void npc_mcam_set_bit(struct npc_mcam *mcam, u16 index) 2603 { 2604 u16 entry, rentry; 2605 2606 entry = index; 2607 rentry = mcam->bmap_entries - index - 1; 2608 2609 __set_bit(entry, mcam->bmap); 2610 __set_bit(rentry, mcam->bmap_reverse); 2611 mcam->bmap_fcnt--; 2612 } 2613 2614 /* Sets MCAM entry in bitmap as free. Update 2615 * reverse bitmap too. Should be called with 2616 * 'mcam->lock' held. 2617 */ 2618 void npc_mcam_clear_bit(struct npc_mcam *mcam, u16 index) 2619 { 2620 u16 entry, rentry; 2621 2622 entry = index; 2623 rentry = mcam->bmap_entries - index - 1; 2624 2625 __clear_bit(entry, mcam->bmap); 2626 __clear_bit(rentry, mcam->bmap_reverse); 2627 mcam->bmap_fcnt++; 2628 } 2629 2630 static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam, 2631 int blkaddr, u16 pcifunc) 2632 { 2633 u16 dft_idxs[NPC_DFT_RULE_MAX_ID] = {[0 ... NPC_DFT_RULE_MAX_ID - 1] = USHRT_MAX}; 2634 bool cn20k_dft_rl; 2635 u16 index, cntr; 2636 int rc; 2637 2638 npc_cn20k_dft_rules_idx_get(rvu, pcifunc, 2639 &dft_idxs[NPC_DFT_RULE_BCAST_ID], 2640 &dft_idxs[NPC_DFT_RULE_MCAST_ID], 2641 &dft_idxs[NPC_DFT_RULE_PROMISC_ID], 2642 &dft_idxs[NPC_DFT_RULE_UCAST_ID]); 2643 2644 /* Scan all MCAM entries and free the ones mapped to 'pcifunc' */ 2645 for (index = 0; index < mcam->bmap_entries; index++) { 2646 if (mcam->entry2pfvf_map[index] != pcifunc) 2647 continue; 2648 2649 cn20k_dft_rl = false; 2650 2651 if (is_cn20k(rvu->pdev)) { 2652 if (dft_idxs[NPC_DFT_RULE_BCAST_ID] == index || 2653 dft_idxs[NPC_DFT_RULE_MCAST_ID] == index || 2654 dft_idxs[NPC_DFT_RULE_PROMISC_ID] == index || 2655 dft_idxs[NPC_DFT_RULE_UCAST_ID] == index) { 2656 cn20k_dft_rl = true; 2657 } 2658 } 2659 2660 /* Disable the entry */ 2661 npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false); 2662 2663 if (!cn20k_dft_rl) { 2664 mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP; 2665 /* Free the entry in bitmap */ 2666 npc_mcam_clear_bit(mcam, index); 2667 mcam->entry2target_pffunc[index] = 0x0; 2668 } 2669 2670 /* Update entry2counter mapping */ 2671 cntr = mcam->entry2cntr_map[index]; 2672 if (cntr != NPC_MCAM_INVALID_MAP) 2673 npc_unmap_mcam_entry_and_cntr(rvu, mcam, 2674 blkaddr, index, 2675 cntr); 2676 2677 if (!is_cn20k(rvu->pdev) || cn20k_dft_rl) 2678 continue; 2679 2680 rc = npc_cn20k_idx_free(rvu, &index, 1); 2681 if (rc) 2682 dev_err(rvu->dev, 2683 "Failed to free mcam idx=%u pcifunc=%#x\n", 2684 index, pcifunc); 2685 } 2686 } 2687 2688 static void npc_mcam_free_all_counters(struct rvu *rvu, struct npc_mcam *mcam, 2689 u16 pcifunc) 2690 { 2691 u16 cntr; 2692 2693 /* Scan all MCAM counters and free the ones mapped to 'pcifunc' */ 2694 for (cntr = 0; cntr < mcam->counters.max; cntr++) { 2695 if (mcam->cntr2pfvf_map[cntr] == pcifunc) { 2696 mcam->cntr2pfvf_map[cntr] = NPC_MCAM_INVALID_MAP; 2697 mcam->cntr_refcnt[cntr] = 0; 2698 rvu_free_rsrc(&mcam->counters, cntr); 2699 /* This API is expected to be called after freeing 2700 * MCAM entries, which inturn will remove 2701 * 'entry to counter' mapping. 2702 * No need to do it again. 2703 */ 2704 } 2705 } 2706 } 2707 2708 /* Find area of contiguous free entries of size 'nr'. 2709 * If not found return max contiguous free entries available. 2710 */ 2711 static u16 npc_mcam_find_zero_area(unsigned long *map, u16 size, u16 start, 2712 u16 nr, u16 *max_area) 2713 { 2714 u16 max_area_start = 0; 2715 u16 index, next, end; 2716 2717 *max_area = 0; 2718 2719 again: 2720 index = find_next_zero_bit(map, size, start); 2721 if (index >= size) 2722 return max_area_start; 2723 2724 end = ((index + nr) >= size) ? size : index + nr; 2725 next = find_next_bit(map, end, index); 2726 if (*max_area < (next - index)) { 2727 *max_area = next - index; 2728 max_area_start = index; 2729 } 2730 2731 if (next < end) { 2732 start = next + 1; 2733 goto again; 2734 } 2735 2736 return max_area_start; 2737 } 2738 2739 /* Find number of free MCAM entries available 2740 * within range i.e in between 'start' and 'end'. 2741 */ 2742 static u16 npc_mcam_get_free_count(unsigned long *map, u16 start, u16 end) 2743 { 2744 u16 index, next; 2745 u16 fcnt = 0; 2746 2747 again: 2748 if (start >= end) 2749 return fcnt; 2750 2751 index = find_next_zero_bit(map, end, start); 2752 if (index >= end) 2753 return fcnt; 2754 2755 next = find_next_bit(map, end, index); 2756 if (next <= end) { 2757 fcnt += next - index; 2758 start = next + 1; 2759 goto again; 2760 } 2761 2762 fcnt += end - index; 2763 return fcnt; 2764 } 2765 2766 static void 2767 npc_get_mcam_search_range_priority(struct npc_mcam *mcam, 2768 struct npc_mcam_alloc_entry_req *req, 2769 u16 *start, u16 *end, bool *reverse) 2770 { 2771 u16 fcnt; 2772 2773 if (req->ref_prio == NPC_MCAM_HIGHER_PRIO) 2774 goto hprio; 2775 2776 /* For a low priority entry allocation 2777 * - If reference entry is not in hprio zone then 2778 * search range: ref_entry to end. 2779 * - If reference entry is in hprio zone and if 2780 * request can be accomodated in non-hprio zone then 2781 * search range: 'start of middle zone' to 'end' 2782 * - else search in reverse, so that less number of hprio 2783 * zone entries are allocated. 2784 */ 2785 2786 *reverse = false; 2787 *start = req->ref_entry + 1; 2788 *end = mcam->bmap_entries; 2789 2790 if (req->ref_entry >= mcam->hprio_end) 2791 return; 2792 2793 fcnt = npc_mcam_get_free_count(mcam->bmap, 2794 mcam->hprio_end, mcam->bmap_entries); 2795 if (fcnt > req->count) 2796 *start = mcam->hprio_end; 2797 else 2798 *reverse = true; 2799 return; 2800 2801 hprio: 2802 /* For a high priority entry allocation, search is always 2803 * in reverse to preserve hprio zone entries. 2804 * - If reference entry is not in lprio zone then 2805 * search range: 0 to ref_entry. 2806 * - If reference entry is in lprio zone and if 2807 * request can be accomodated in middle zone then 2808 * search range: 'hprio_end' to 'lprio_start' 2809 */ 2810 2811 *reverse = true; 2812 *start = 0; 2813 *end = req->ref_entry; 2814 2815 if (req->ref_entry <= mcam->lprio_start) 2816 return; 2817 2818 fcnt = npc_mcam_get_free_count(mcam->bmap, 2819 mcam->hprio_end, mcam->lprio_start); 2820 if (fcnt < req->count) 2821 return; 2822 *start = mcam->hprio_end; 2823 *end = mcam->lprio_start; 2824 } 2825 2826 static int npc_mcam_alloc_entries(struct npc_mcam *mcam, u16 pcifunc, 2827 struct npc_mcam_alloc_entry_req *req, 2828 struct npc_mcam_alloc_entry_rsp *rsp) 2829 { 2830 struct rvu_hwinfo *hw = container_of(mcam, struct rvu_hwinfo, mcam); 2831 u16 entry_list[NPC_MAX_NONCONTIG_ENTRIES]; 2832 u16 fcnt, hp_fcnt, lp_fcnt; 2833 struct rvu *rvu = hw->rvu; 2834 u16 start, end, index; 2835 int entry, next_start; 2836 bool reverse = false; 2837 unsigned long *bmap; 2838 int ret, limit = 0; 2839 u16 max_contig; 2840 2841 if (!is_cn20k(rvu->pdev)) 2842 goto not_cn20k; 2843 2844 /* Only x2 or x4 key types are accepted */ 2845 if (req->kw_type != NPC_MCAM_KEY_X2 && req->kw_type != NPC_MCAM_KEY_X4) 2846 return NPC_MCAM_INVALID_REQ; 2847 2848 /* The below table is being followed during allocation, 2849 * 2850 * 1. ref_entry == 0 && prio == HIGH && count == 1 : user wants to 2851 * allocate 0th index 2852 * 2. ref_entry == 0 && prio == HIGH && count > 1 : Invalid request 2853 * 3. ref_entry == 0 && prio == LOW && count >= 1 : limit = 0 2854 * 4. ref_entry != 0 && prio == HIGH && count >= 1 : limit = 0 2855 * 5. ref_entry != 0 && prio == LOW && count >=1 : limit = Max 2856 * (X2 2*8192, X4 8192) 2857 */ 2858 if (req->ref_entry && req->ref_prio == NPC_MCAM_LOWER_PRIO) { 2859 if (req->kw_type == NPC_MCAM_KEY_X2) 2860 limit = 2 * mcam->bmap_entries; 2861 else 2862 limit = mcam->bmap_entries; 2863 } 2864 2865 ret = npc_cn20k_ref_idx_alloc(rvu, pcifunc, req->kw_type, 2866 req->ref_prio, rsp->entry_list, 2867 req->ref_entry, limit, 2868 req->contig, req->count, !!req->virt); 2869 2870 if (ret) { 2871 rsp->count = 0; 2872 return NPC_MCAM_ALLOC_FAILED; 2873 } 2874 2875 rsp->count = req->count; 2876 if (req->contig) 2877 rsp->entry = rsp->entry_list[0]; 2878 2879 /* cn20k, entries allocation algorithm is different. 2880 * This common API updates some bitmap on usage etc, which 2881 * will be used by other functions. So update those for 2882 * cn20k as well. 2883 */ 2884 2885 mutex_lock(&mcam->lock); 2886 /* Mark the allocated entries as used and set nixlf mapping */ 2887 for (entry = 0; entry < rsp->count; entry++) { 2888 index = npc_cn20k_vidx2idx(rsp->entry_list[entry]); 2889 npc_mcam_set_bit(mcam, index); 2890 mcam->entry2pfvf_map[index] = pcifunc; 2891 mcam->entry2cntr_map[index] = NPC_MCAM_INVALID_MAP; 2892 } 2893 2894 /* cn20k, free count is provided thru different mbox message. 2895 * one counter to indicate free x2 slots and free x4 slots 2896 * does not provide any useful information to the user. 2897 */ 2898 rsp->free_count = -1; 2899 mutex_unlock(&mcam->lock); 2900 2901 return 0; 2902 2903 not_cn20k: 2904 mutex_lock(&mcam->lock); 2905 2906 /* Check if there are any free entries */ 2907 if (!mcam->bmap_fcnt) { 2908 mutex_unlock(&mcam->lock); 2909 return NPC_MCAM_ALLOC_FAILED; 2910 } 2911 2912 /* MCAM entries are divided into high priority, middle and 2913 * low priority zones. Idea is to not allocate top and lower 2914 * most entries as much as possible, this is to increase 2915 * probability of honouring priority allocation requests. 2916 * 2917 * Two bitmaps are used for mcam entry management, 2918 * mcam->bmap for forward search i.e '0 to mcam->bmap_entries'. 2919 * mcam->bmap_reverse for reverse search i.e 'mcam->bmap_entries to 0'. 2920 * 2921 * Reverse bitmap is used to allocate entries 2922 * - when a higher priority entry is requested 2923 * - when available free entries are less. 2924 * Lower priority ones out of avaialble free entries are always 2925 * chosen when 'high vs low' question arises. 2926 * 2927 * For a VF base MCAM match rule is set by its PF. And all the 2928 * further MCAM rules installed by VF on its own are 2929 * concatenated with the base rule set by its PF. Hence PF entries 2930 * should be at lower priority compared to VF entries. Otherwise 2931 * base rule is hit always and rules installed by VF will be of 2932 * no use. Hence if the request is from PF then allocate low 2933 * priority entries. 2934 */ 2935 if (!(pcifunc & RVU_PFVF_FUNC_MASK)) 2936 goto lprio_alloc; 2937 2938 /* Get the search range for priority allocation request */ 2939 if (req->ref_prio) { 2940 npc_get_mcam_search_range_priority(mcam, req, 2941 &start, &end, &reverse); 2942 goto alloc; 2943 } 2944 2945 /* Find out the search range for non-priority allocation request 2946 * 2947 * Get MCAM free entry count in middle zone. 2948 */ 2949 lp_fcnt = npc_mcam_get_free_count(mcam->bmap, 2950 mcam->lprio_start, 2951 mcam->bmap_entries); 2952 hp_fcnt = npc_mcam_get_free_count(mcam->bmap, 0, mcam->hprio_end); 2953 fcnt = mcam->bmap_fcnt - lp_fcnt - hp_fcnt; 2954 2955 /* Check if request can be accomodated in the middle zone */ 2956 if (fcnt > req->count) { 2957 start = mcam->hprio_end; 2958 end = mcam->lprio_start; 2959 } else if ((fcnt + (hp_fcnt / 2) + (lp_fcnt / 2)) > req->count) { 2960 /* Expand search zone from half of hprio zone to 2961 * half of lprio zone. 2962 */ 2963 start = mcam->hprio_end / 2; 2964 end = mcam->bmap_entries - (mcam->lprio_count / 2); 2965 reverse = true; 2966 } else { 2967 /* Not enough free entries, search all entries in reverse, 2968 * so that low priority ones will get used up. 2969 */ 2970 lprio_alloc: 2971 reverse = true; 2972 start = 0; 2973 end = mcam->bmap_entries; 2974 /* Ensure PF requests are always at bottom and if PF requests 2975 * for higher/lower priority entry wrt reference entry then 2976 * honour that criteria and start search for entries from bottom 2977 * and not in mid zone. 2978 */ 2979 if (!(pcifunc & RVU_PFVF_FUNC_MASK) && 2980 req->ref_prio == NPC_MCAM_HIGHER_PRIO) 2981 end = req->ref_entry; 2982 2983 if (!(pcifunc & RVU_PFVF_FUNC_MASK) && 2984 req->ref_prio == NPC_MCAM_LOWER_PRIO) 2985 start = req->ref_entry; 2986 } 2987 2988 alloc: 2989 if (reverse) { 2990 bmap = mcam->bmap_reverse; 2991 start = mcam->bmap_entries - start; 2992 end = mcam->bmap_entries - end; 2993 swap(start, end); 2994 } else { 2995 bmap = mcam->bmap; 2996 } 2997 2998 if (req->contig) { 2999 /* Allocate requested number of contiguous entries, if 3000 * unsuccessful find max contiguous entries available. 3001 */ 3002 index = npc_mcam_find_zero_area(bmap, end, start, 3003 req->count, &max_contig); 3004 rsp->count = max_contig; 3005 if (reverse) 3006 rsp->entry = mcam->bmap_entries - index - max_contig; 3007 else 3008 rsp->entry = index; 3009 } else { 3010 /* Allocate requested number of non-contiguous entries, 3011 * if unsuccessful allocate as many as possible. 3012 */ 3013 rsp->count = 0; 3014 next_start = start; 3015 for (entry = 0; entry < req->count; entry++) { 3016 index = find_next_zero_bit(bmap, end, next_start); 3017 if (index >= end) 3018 break; 3019 3020 next_start = start + (index - start) + 1; 3021 3022 /* Save the entry's index */ 3023 if (reverse) 3024 index = mcam->bmap_entries - index - 1; 3025 entry_list[entry] = index; 3026 rsp->count++; 3027 } 3028 } 3029 3030 /* If allocating requested no of entries is unsucessful, 3031 * expand the search range to full bitmap length and retry. 3032 */ 3033 if (!req->ref_prio && rsp->count < req->count && 3034 ((end - start) != mcam->bmap_entries)) { 3035 reverse = true; 3036 start = 0; 3037 end = mcam->bmap_entries; 3038 goto alloc; 3039 } 3040 3041 /* For priority entry allocation requests, if allocation is 3042 * failed then expand search to max possible range and retry. 3043 */ 3044 if (req->ref_prio && rsp->count < req->count) { 3045 if (req->ref_prio == NPC_MCAM_LOWER_PRIO && 3046 (start != (req->ref_entry + 1))) { 3047 start = req->ref_entry + 1; 3048 end = mcam->bmap_entries; 3049 reverse = false; 3050 goto alloc; 3051 } else if ((req->ref_prio == NPC_MCAM_HIGHER_PRIO) && 3052 ((end - start) != req->ref_entry)) { 3053 start = 0; 3054 end = req->ref_entry; 3055 reverse = true; 3056 goto alloc; 3057 } 3058 } 3059 3060 /* Copy MCAM entry indices into mbox response entry_list. 3061 * Requester always expects indices in ascending order, so 3062 * reverse the list if reverse bitmap is used for allocation. 3063 */ 3064 if (!req->contig && rsp->count) { 3065 index = 0; 3066 for (entry = rsp->count - 1; entry >= 0; entry--) { 3067 if (reverse) 3068 rsp->entry_list[index++] = entry_list[entry]; 3069 else 3070 rsp->entry_list[entry] = entry_list[entry]; 3071 } 3072 } 3073 3074 /* Mark the allocated entries as used and set nixlf mapping */ 3075 for (entry = 0; entry < rsp->count; entry++) { 3076 index = req->contig ? 3077 (rsp->entry + entry) : rsp->entry_list[entry]; 3078 npc_mcam_set_bit(mcam, index); 3079 mcam->entry2pfvf_map[index] = pcifunc; 3080 mcam->entry2cntr_map[index] = NPC_MCAM_INVALID_MAP; 3081 } 3082 3083 /* Update available free count in mbox response */ 3084 rsp->free_count = mcam->bmap_fcnt; 3085 3086 mutex_unlock(&mcam->lock); 3087 return 0; 3088 } 3089 3090 /* Marks bitmaps to reserved the mcam slot */ 3091 void npc_mcam_rsrcs_reserve(struct rvu *rvu, int blkaddr, int entry_idx) 3092 { 3093 struct npc_mcam *mcam = &rvu->hw->mcam; 3094 3095 npc_mcam_set_bit(mcam, entry_idx); 3096 } 3097 3098 int npc_config_cntr_default_entries(struct rvu *rvu, bool enable) 3099 { 3100 struct npc_mcam *mcam = &rvu->hw->mcam; 3101 struct npc_install_flow_rsp rsp; 3102 struct rvu_npc_mcam_rule *rule; 3103 int blkaddr; 3104 3105 /* Counter is set for each rule by default */ 3106 if (is_cn20k(rvu->pdev)) 3107 return -EINVAL; 3108 3109 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3110 if (blkaddr < 0) 3111 return -EINVAL; 3112 3113 mutex_lock(&mcam->lock); 3114 list_for_each_entry(rule, &mcam->mcam_rules, list) { 3115 if (!is_mcam_entry_enabled(rvu, mcam, blkaddr, rule->entry)) 3116 continue; 3117 if (!rule->default_rule) 3118 continue; 3119 if (enable && !rule->has_cntr) { /* Alloc and map new counter */ 3120 __rvu_mcam_add_counter_to_rule(rvu, rule->owner, 3121 rule, &rsp); 3122 if (rsp.counter < 0) { 3123 dev_err(rvu->dev, 3124 "%s: Failed to allocate cntr for default rule (err=%d)\n", 3125 __func__, rsp.counter); 3126 break; 3127 } 3128 npc_map_mcam_entry_and_cntr(rvu, mcam, blkaddr, 3129 rule->entry, rsp.counter); 3130 /* Reset counter before use */ 3131 rvu_write64(rvu, blkaddr, 3132 NPC_AF_MATCH_STATX(rule->cntr), 0x0); 3133 } 3134 3135 /* Free and unmap counter */ 3136 if (!enable && rule->has_cntr) 3137 __rvu_mcam_remove_counter_from_rule(rvu, rule->owner, 3138 rule); 3139 } 3140 mutex_unlock(&mcam->lock); 3141 3142 return 0; 3143 } 3144 3145 int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu *rvu, 3146 struct npc_mcam_alloc_entry_req *req, 3147 struct npc_mcam_alloc_entry_rsp *rsp) 3148 { 3149 struct npc_mcam *mcam = &rvu->hw->mcam; 3150 u16 pcifunc = req->hdr.pcifunc; 3151 int blkaddr; 3152 3153 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3154 if (blkaddr < 0) 3155 return NPC_MCAM_INVALID_REQ; 3156 3157 rsp->entry = NPC_MCAM_ENTRY_INVALID; 3158 rsp->free_count = 0; 3159 3160 /* Check if ref_entry is greater that the range 3161 * then set it to max value. 3162 */ 3163 if (req->ref_entry > mcam->bmap_entries) 3164 req->ref_entry = mcam->bmap_entries; 3165 3166 /* ref_entry can't be '0' if requested priority is high. 3167 * Can't be last entry if requested priority is low. 3168 */ 3169 if ((!req->ref_entry && req->ref_prio == NPC_MCAM_HIGHER_PRIO) || 3170 (req->ref_entry == mcam->bmap_entries && 3171 req->ref_prio == NPC_MCAM_LOWER_PRIO)) 3172 return NPC_MCAM_INVALID_REQ; 3173 3174 /* Since list of allocated indices needs to be sent to requester, 3175 * max number of non-contiguous entries per mbox msg is limited. 3176 */ 3177 if (!req->contig && req->count > NPC_MAX_NONCONTIG_ENTRIES) { 3178 dev_err(rvu->dev, 3179 "%s: %d Non-contiguous MCAM entries requested is more than max (%d) allowed\n", 3180 __func__, req->count, NPC_MAX_NONCONTIG_ENTRIES); 3181 return NPC_MCAM_INVALID_REQ; 3182 } 3183 3184 /* Alloc request from PFFUNC with no NIXLF attached should be denied */ 3185 if (!is_pffunc_af(pcifunc) && !is_nixlf_attached(rvu, pcifunc)) 3186 return NPC_MCAM_ALLOC_DENIED; 3187 3188 return npc_mcam_alloc_entries(mcam, pcifunc, req, rsp); 3189 } 3190 3191 int rvu_mbox_handler_npc_mcam_free_entry(struct rvu *rvu, 3192 struct npc_mcam_free_entry_req *req, 3193 struct msg_rsp *rsp) 3194 { 3195 struct npc_mcam *mcam = &rvu->hw->mcam; 3196 u16 pcifunc = req->hdr.pcifunc; 3197 int blkaddr, rc = 0; 3198 u16 cntr; 3199 3200 req->entry = npc_cn20k_vidx2idx(req->entry); 3201 3202 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3203 if (blkaddr < 0) 3204 return NPC_MCAM_INVALID_REQ; 3205 3206 /* Free request from PFFUNC with no NIXLF attached, ignore */ 3207 if (!is_pffunc_af(pcifunc) && !is_nixlf_attached(rvu, pcifunc)) 3208 return NPC_MCAM_INVALID_REQ; 3209 3210 mutex_lock(&mcam->lock); 3211 3212 if (req->all) 3213 goto free_all; 3214 3215 rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry); 3216 if (rc) 3217 goto exit; 3218 3219 mcam->entry2pfvf_map[req->entry] = NPC_MCAM_INVALID_MAP; 3220 mcam->entry2target_pffunc[req->entry] = 0x0; 3221 npc_mcam_clear_bit(mcam, req->entry); 3222 npc_enable_mcam_entry(rvu, mcam, blkaddr, req->entry, false); 3223 3224 /* Update entry2counter mapping */ 3225 cntr = mcam->entry2cntr_map[req->entry]; 3226 if (cntr != NPC_MCAM_INVALID_MAP) 3227 npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, 3228 req->entry, cntr); 3229 3230 if (is_cn20k(rvu->pdev)) { 3231 rc = npc_cn20k_idx_free(rvu, &req->entry, 1); 3232 if (rc) 3233 dev_err(rvu->dev, 3234 "Failed to free index=%u\n", 3235 req->entry); 3236 } 3237 3238 goto exit; 3239 3240 free_all: 3241 /* Free up all entries allocated to requesting PFFUNC */ 3242 npc_mcam_free_all_entries(rvu, mcam, blkaddr, pcifunc); 3243 exit: 3244 mutex_unlock(&mcam->lock); 3245 return rc; 3246 } 3247 3248 int rvu_mbox_handler_npc_mcam_read_entry(struct rvu *rvu, 3249 struct npc_mcam_read_entry_req *req, 3250 struct npc_mcam_read_entry_rsp *rsp) 3251 { 3252 struct npc_mcam *mcam = &rvu->hw->mcam; 3253 u16 pcifunc = req->hdr.pcifunc; 3254 int blkaddr, rc; 3255 3256 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3257 if (blkaddr < 0) 3258 return NPC_MCAM_INVALID_REQ; 3259 3260 mutex_lock(&mcam->lock); 3261 rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry); 3262 if (!rc) { 3263 npc_read_mcam_entry(rvu, mcam, blkaddr, req->entry, 3264 &rsp->entry_data, 3265 &rsp->intf, &rsp->enable); 3266 } 3267 3268 mutex_unlock(&mcam->lock); 3269 return rc; 3270 } 3271 3272 int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu, 3273 struct npc_mcam_write_entry_req *req, 3274 struct msg_rsp *rsp) 3275 { 3276 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc); 3277 struct npc_mcam *mcam = &rvu->hw->mcam; 3278 u16 pcifunc = req->hdr.pcifunc; 3279 int blkaddr, rc; 3280 u8 nix_intf; 3281 3282 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3283 if (blkaddr < 0) 3284 return NPC_MCAM_INVALID_REQ; 3285 3286 mutex_lock(&mcam->lock); 3287 rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry); 3288 if (rc) 3289 goto exit; 3290 3291 if (!is_cn20k(rvu->pdev)) { 3292 /* Verify counter in SoCs other than cn20k */ 3293 if (req->set_cntr && 3294 npc_mcam_verify_counter(mcam, pcifunc, req->cntr)) { 3295 rc = NPC_MCAM_INVALID_REQ; 3296 goto exit; 3297 } 3298 } 3299 3300 if (!is_npc_interface_valid(rvu, req->intf)) { 3301 rc = NPC_MCAM_INVALID_REQ; 3302 goto exit; 3303 } 3304 3305 if (is_npc_intf_tx(req->intf)) 3306 nix_intf = pfvf->nix_tx_intf; 3307 else 3308 nix_intf = pfvf->nix_rx_intf; 3309 3310 /* For AF installed rules, the nix_intf should be set to target NIX */ 3311 if (is_pffunc_af(req->hdr.pcifunc)) 3312 nix_intf = req->intf; 3313 3314 npc_config_mcam_entry(rvu, mcam, blkaddr, req->entry, nix_intf, 3315 &req->entry_data, req->enable_entry); 3316 3317 if (req->set_cntr) 3318 npc_map_mcam_entry_and_cntr(rvu, mcam, blkaddr, 3319 req->entry, req->cntr); 3320 3321 rc = 0; 3322 exit: 3323 mutex_unlock(&mcam->lock); 3324 return rc; 3325 } 3326 3327 int rvu_mbox_handler_npc_mcam_ena_entry(struct rvu *rvu, 3328 struct npc_mcam_ena_dis_entry_req *req, 3329 struct msg_rsp *rsp) 3330 { 3331 struct npc_mcam *mcam = &rvu->hw->mcam; 3332 u16 pcifunc = req->hdr.pcifunc; 3333 int blkaddr, rc; 3334 3335 req->entry = npc_cn20k_vidx2idx(req->entry); 3336 3337 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3338 if (blkaddr < 0) 3339 return NPC_MCAM_INVALID_REQ; 3340 3341 mutex_lock(&mcam->lock); 3342 rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry); 3343 mutex_unlock(&mcam->lock); 3344 if (rc) 3345 return rc; 3346 3347 npc_enable_mcam_entry(rvu, mcam, blkaddr, req->entry, true); 3348 3349 return 0; 3350 } 3351 3352 int rvu_mbox_handler_npc_mcam_dis_entry(struct rvu *rvu, 3353 struct npc_mcam_ena_dis_entry_req *req, 3354 struct msg_rsp *rsp) 3355 { 3356 struct npc_mcam *mcam = &rvu->hw->mcam; 3357 u16 pcifunc = req->hdr.pcifunc; 3358 int blkaddr, rc; 3359 3360 req->entry = npc_cn20k_vidx2idx(req->entry); 3361 3362 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3363 if (blkaddr < 0) 3364 return NPC_MCAM_INVALID_REQ; 3365 3366 mutex_lock(&mcam->lock); 3367 rc = npc_mcam_verify_entry(mcam, pcifunc, req->entry); 3368 mutex_unlock(&mcam->lock); 3369 if (rc) 3370 return rc; 3371 3372 npc_enable_mcam_entry(rvu, mcam, blkaddr, req->entry, false); 3373 3374 return 0; 3375 } 3376 3377 int rvu_mbox_handler_npc_mcam_shift_entry(struct rvu *rvu, 3378 struct npc_mcam_shift_entry_req *req, 3379 struct npc_mcam_shift_entry_rsp *rsp) 3380 { 3381 struct npc_mcam *mcam = &rvu->hw->mcam; 3382 u16 pcifunc = req->hdr.pcifunc; 3383 u16 old_entry, new_entry; 3384 int blkaddr, rc = 0; 3385 u16 index, cntr; 3386 3387 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3388 if (blkaddr < 0) 3389 return NPC_MCAM_INVALID_REQ; 3390 3391 if (req->shift_count > NPC_MCAM_MAX_SHIFTS) 3392 return NPC_MCAM_INVALID_REQ; 3393 3394 mutex_lock(&mcam->lock); 3395 for (index = 0; index < req->shift_count; index++) { 3396 old_entry = npc_cn20k_vidx2idx(req->curr_entry[index]); 3397 new_entry = npc_cn20k_vidx2idx(req->new_entry[index]); 3398 3399 /* Check if both old and new entries are valid and 3400 * does belong to this PFFUNC or not. 3401 */ 3402 rc = npc_mcam_verify_entry(mcam, pcifunc, old_entry); 3403 if (rc) 3404 break; 3405 3406 rc = npc_mcam_verify_entry(mcam, pcifunc, new_entry); 3407 if (rc) 3408 break; 3409 3410 /* new_entry should not have a counter mapped */ 3411 if (mcam->entry2cntr_map[new_entry] != NPC_MCAM_INVALID_MAP) { 3412 rc = NPC_MCAM_PERM_DENIED; 3413 break; 3414 } 3415 3416 /* Disable the new_entry */ 3417 npc_enable_mcam_entry(rvu, mcam, blkaddr, new_entry, false); 3418 3419 /* Copy rule from old entry to new entry */ 3420 if (npc_copy_mcam_entry(rvu, mcam, blkaddr, old_entry, new_entry)) { 3421 rc = NPC_MCAM_INVALID_REQ; 3422 break; 3423 } 3424 3425 /* Copy counter mapping, if any */ 3426 cntr = mcam->entry2cntr_map[old_entry]; 3427 if (cntr != NPC_MCAM_INVALID_MAP) { 3428 npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, 3429 old_entry, cntr); 3430 npc_map_mcam_entry_and_cntr(rvu, mcam, blkaddr, 3431 new_entry, cntr); 3432 } 3433 3434 /* Enable new_entry and disable old_entry */ 3435 npc_enable_mcam_entry(rvu, mcam, blkaddr, new_entry, true); 3436 npc_enable_mcam_entry(rvu, mcam, blkaddr, old_entry, false); 3437 } 3438 3439 /* If shift has failed then report the failed index */ 3440 if (index != req->shift_count) { 3441 if (!rc) 3442 rc = NPC_MCAM_PERM_DENIED; 3443 rsp->failed_entry_idx = index; 3444 } 3445 3446 mutex_unlock(&mcam->lock); 3447 return rc; 3448 } 3449 3450 static int __npc_mcam_alloc_counter(struct rvu *rvu, 3451 struct npc_mcam_alloc_counter_req *req, 3452 struct npc_mcam_alloc_counter_rsp *rsp) 3453 { 3454 struct npc_mcam *mcam = &rvu->hw->mcam; 3455 u16 pcifunc = req->hdr.pcifunc; 3456 u16 max_contig, cntr; 3457 int blkaddr, index; 3458 3459 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3460 if (blkaddr < 0) 3461 return NPC_MCAM_INVALID_REQ; 3462 3463 /* If the request is from a PFFUNC with no NIXLF attached, ignore */ 3464 if (!is_pffunc_af(pcifunc) && !is_nixlf_attached(rvu, pcifunc)) 3465 return NPC_MCAM_INVALID_REQ; 3466 3467 /* Since list of allocated counter IDs needs to be sent to requester, 3468 * max number of non-contiguous counters per mbox msg is limited. 3469 */ 3470 if (!req->contig && req->count > NPC_MAX_NONCONTIG_COUNTERS) 3471 return NPC_MCAM_INVALID_REQ; 3472 3473 /* Check if unused counters are available or not */ 3474 if (!rvu_rsrc_free_count(&mcam->counters)) { 3475 return NPC_MCAM_ALLOC_FAILED; 3476 } 3477 3478 rsp->count = 0; 3479 3480 if (req->contig) { 3481 /* Allocate requested number of contiguous counters, if 3482 * unsuccessful find max contiguous entries available. 3483 */ 3484 index = npc_mcam_find_zero_area(mcam->counters.bmap, 3485 mcam->counters.max, 0, 3486 req->count, &max_contig); 3487 rsp->count = max_contig; 3488 rsp->cntr = index; 3489 for (cntr = index; cntr < (index + max_contig); cntr++) { 3490 __set_bit(cntr, mcam->counters.bmap); 3491 mcam->cntr2pfvf_map[cntr] = pcifunc; 3492 } 3493 } else { 3494 /* Allocate requested number of non-contiguous counters, 3495 * if unsuccessful allocate as many as possible. 3496 */ 3497 for (cntr = 0; cntr < req->count; cntr++) { 3498 index = rvu_alloc_rsrc(&mcam->counters); 3499 if (index < 0) 3500 break; 3501 rsp->cntr_list[cntr] = index; 3502 rsp->count++; 3503 mcam->cntr2pfvf_map[index] = pcifunc; 3504 } 3505 } 3506 3507 return 0; 3508 } 3509 3510 int rvu_mbox_handler_npc_mcam_alloc_counter(struct rvu *rvu, 3511 struct npc_mcam_alloc_counter_req *req, 3512 struct npc_mcam_alloc_counter_rsp *rsp) 3513 { 3514 struct npc_mcam *mcam = &rvu->hw->mcam; 3515 int err; 3516 3517 /* Counter is not supported for CN20K */ 3518 if (is_cn20k(rvu->pdev)) 3519 return NPC_MCAM_INVALID_REQ; 3520 3521 mutex_lock(&mcam->lock); 3522 3523 err = __npc_mcam_alloc_counter(rvu, req, rsp); 3524 3525 mutex_unlock(&mcam->lock); 3526 return err; 3527 } 3528 3529 static int __npc_mcam_free_counter(struct rvu *rvu, 3530 struct npc_mcam_oper_counter_req *req, 3531 struct msg_rsp *rsp) 3532 { 3533 struct npc_mcam *mcam = &rvu->hw->mcam; 3534 u16 index, entry = 0; 3535 int blkaddr, err; 3536 3537 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3538 if (blkaddr < 0) 3539 return NPC_MCAM_INVALID_REQ; 3540 3541 err = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr); 3542 if (err) { 3543 return err; 3544 } 3545 3546 /* Mark counter as free/unused */ 3547 mcam->cntr2pfvf_map[req->cntr] = NPC_MCAM_INVALID_MAP; 3548 rvu_free_rsrc(&mcam->counters, req->cntr); 3549 3550 /* Disable all MCAM entry's stats which are using this counter */ 3551 while (entry < mcam->bmap_entries) { 3552 if (!mcam->cntr_refcnt[req->cntr]) 3553 break; 3554 3555 index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); 3556 if (index >= mcam->bmap_entries) 3557 break; 3558 entry = index + 1; 3559 if (mcam->entry2cntr_map[index] != req->cntr) 3560 continue; 3561 3562 npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, 3563 index, req->cntr); 3564 } 3565 3566 return 0; 3567 } 3568 3569 int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu, 3570 struct npc_mcam_oper_counter_req *req, struct msg_rsp *rsp) 3571 { 3572 struct npc_mcam *mcam = &rvu->hw->mcam; 3573 int err; 3574 3575 /* Counter is not supported for CN20K */ 3576 if (is_cn20k(rvu->pdev)) 3577 return NPC_MCAM_INVALID_REQ; 3578 3579 mutex_lock(&mcam->lock); 3580 3581 err = __npc_mcam_free_counter(rvu, req, rsp); 3582 3583 mutex_unlock(&mcam->lock); 3584 3585 return err; 3586 } 3587 3588 void __rvu_mcam_remove_counter_from_rule(struct rvu *rvu, u16 pcifunc, 3589 struct rvu_npc_mcam_rule *rule) 3590 { 3591 struct npc_mcam_oper_counter_req free_req = { 0 }; 3592 struct msg_rsp free_rsp; 3593 3594 if (!rule->has_cntr) 3595 return; 3596 3597 free_req.hdr.pcifunc = pcifunc; 3598 free_req.cntr = rule->cntr; 3599 3600 __npc_mcam_free_counter(rvu, &free_req, &free_rsp); 3601 rule->has_cntr = false; 3602 } 3603 3604 void __rvu_mcam_add_counter_to_rule(struct rvu *rvu, u16 pcifunc, 3605 struct rvu_npc_mcam_rule *rule, 3606 struct npc_install_flow_rsp *rsp) 3607 { 3608 struct npc_mcam_alloc_counter_req cntr_req = { 0 }; 3609 struct npc_mcam_alloc_counter_rsp cntr_rsp = { 0 }; 3610 int err; 3611 3612 cntr_req.hdr.pcifunc = pcifunc; 3613 cntr_req.contig = true; 3614 cntr_req.count = 1; 3615 3616 /* we try to allocate a counter to track the stats of this 3617 * rule. If counter could not be allocated then proceed 3618 * without counter because counters are limited than entries. 3619 */ 3620 err = __npc_mcam_alloc_counter(rvu, &cntr_req, &cntr_rsp); 3621 if (!err && cntr_rsp.count) { 3622 rule->cntr = cntr_rsp.cntr; 3623 rule->has_cntr = true; 3624 rsp->counter = rule->cntr; 3625 } else { 3626 rsp->counter = err; 3627 } 3628 } 3629 3630 int rvu_mbox_handler_npc_mcam_unmap_counter(struct rvu *rvu, 3631 struct npc_mcam_unmap_counter_req *req, struct msg_rsp *rsp) 3632 { 3633 struct npc_mcam *mcam = &rvu->hw->mcam; 3634 u16 index, entry = 0; 3635 int blkaddr, rc; 3636 3637 /* Counter is not supported for CN20K */ 3638 if (is_cn20k(rvu->pdev)) 3639 return NPC_MCAM_INVALID_REQ; 3640 3641 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3642 if (blkaddr < 0) 3643 return NPC_MCAM_INVALID_REQ; 3644 3645 mutex_lock(&mcam->lock); 3646 rc = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr); 3647 if (rc) 3648 goto exit; 3649 3650 /* Unmap the MCAM entry and counter */ 3651 if (!req->all) { 3652 rc = npc_mcam_verify_entry(mcam, req->hdr.pcifunc, req->entry); 3653 if (rc) 3654 goto exit; 3655 npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, 3656 req->entry, req->cntr); 3657 goto exit; 3658 } 3659 3660 /* Disable all MCAM entry's stats which are using this counter */ 3661 while (entry < mcam->bmap_entries) { 3662 if (!mcam->cntr_refcnt[req->cntr]) 3663 break; 3664 3665 index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); 3666 if (index >= mcam->bmap_entries) 3667 break; 3668 entry = index + 1; 3669 3670 if (mcam->entry2cntr_map[index] != req->cntr) 3671 continue; 3672 3673 npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, 3674 index, req->cntr); 3675 } 3676 exit: 3677 mutex_unlock(&mcam->lock); 3678 return rc; 3679 } 3680 3681 int rvu_mbox_handler_npc_mcam_clear_counter(struct rvu *rvu, 3682 struct npc_mcam_oper_counter_req *req, struct msg_rsp *rsp) 3683 { 3684 struct npc_mcam *mcam = &rvu->hw->mcam; 3685 int blkaddr, err, index, bank; 3686 3687 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3688 if (blkaddr < 0) 3689 return NPC_MCAM_INVALID_REQ; 3690 3691 /* For cn20k, npc mcam index is passed as cntr, as each 3692 * mcam entry has corresponding counter. 3693 */ 3694 if (is_cn20k(rvu->pdev)) { 3695 index = req->cntr & (mcam->banksize - 1); 3696 bank = npc_get_bank(mcam, req->cntr); 3697 rvu_write64(rvu, blkaddr, 3698 NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index, bank), 0); 3699 return 0; 3700 } 3701 3702 mutex_lock(&mcam->lock); 3703 err = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr); 3704 mutex_unlock(&mcam->lock); 3705 if (err) 3706 return err; 3707 3708 rvu_write64(rvu, blkaddr, NPC_AF_MATCH_STATX(req->cntr), 0x00); 3709 3710 return 0; 3711 } 3712 3713 int rvu_mbox_handler_npc_mcam_counter_stats(struct rvu *rvu, 3714 struct npc_mcam_oper_counter_req *req, 3715 struct npc_mcam_oper_counter_rsp *rsp) 3716 { 3717 struct npc_mcam *mcam = &rvu->hw->mcam; 3718 int blkaddr, err, index, bank; 3719 u64 regval; 3720 3721 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3722 if (blkaddr < 0) 3723 return NPC_MCAM_INVALID_REQ; 3724 3725 /* In CN20K, mcam index is passed cntr. Each cn20k mcam entry 3726 * has its own counter. No need to verify the counter index. 3727 */ 3728 if (is_cn20k(rvu->pdev)) { 3729 index = req->cntr & (mcam->banksize - 1); 3730 bank = npc_get_bank(mcam, req->cntr); 3731 regval = rvu_read64(rvu, blkaddr, 3732 NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index, 3733 bank)); 3734 rsp->stat = regval; 3735 return 0; 3736 } 3737 3738 mutex_lock(&mcam->lock); 3739 err = npc_mcam_verify_counter(mcam, req->hdr.pcifunc, req->cntr); 3740 mutex_unlock(&mcam->lock); 3741 if (err) 3742 return err; 3743 3744 rsp->stat = rvu_read64(rvu, blkaddr, NPC_AF_MATCH_STATX(req->cntr)); 3745 rsp->stat &= BIT_ULL(48) - 1; 3746 3747 return 0; 3748 } 3749 3750 int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(struct rvu *rvu, 3751 struct npc_mcam_alloc_and_write_entry_req *req, 3752 struct npc_mcam_alloc_and_write_entry_rsp *rsp) 3753 { 3754 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc); 3755 struct npc_mcam_alloc_counter_req cntr_req; 3756 struct npc_mcam_alloc_counter_rsp cntr_rsp; 3757 struct npc_mcam_alloc_entry_req entry_req; 3758 struct npc_mcam_alloc_entry_rsp entry_rsp; 3759 struct npc_mcam *mcam = &rvu->hw->mcam; 3760 u16 entry = NPC_MCAM_ENTRY_INVALID; 3761 u16 cntr = NPC_MCAM_ENTRY_INVALID; 3762 int blkaddr, rc; 3763 u8 nix_intf; 3764 3765 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3766 if (blkaddr < 0) 3767 return NPC_MCAM_INVALID_REQ; 3768 3769 if (!is_npc_interface_valid(rvu, req->intf)) 3770 return NPC_MCAM_INVALID_REQ; 3771 3772 /* Try to allocate a MCAM entry */ 3773 entry_req.hdr.pcifunc = req->hdr.pcifunc; 3774 entry_req.contig = true; 3775 entry_req.ref_prio = req->ref_prio; 3776 entry_req.ref_entry = req->ref_entry; 3777 entry_req.count = 1; 3778 3779 rc = rvu_mbox_handler_npc_mcam_alloc_entry(rvu, 3780 &entry_req, &entry_rsp); 3781 if (rc) 3782 return rc; 3783 3784 if (!entry_rsp.count) 3785 return NPC_MCAM_ALLOC_FAILED; 3786 3787 entry = entry_rsp.entry; 3788 3789 if (!req->alloc_cntr) 3790 goto write_entry; 3791 3792 /* Now allocate counter */ 3793 cntr_req.hdr.pcifunc = req->hdr.pcifunc; 3794 cntr_req.contig = true; 3795 cntr_req.count = 1; 3796 3797 rc = rvu_mbox_handler_npc_mcam_alloc_counter(rvu, &cntr_req, &cntr_rsp); 3798 if (rc) { 3799 /* Free allocated MCAM entry */ 3800 mutex_lock(&mcam->lock); 3801 mcam->entry2pfvf_map[entry] = NPC_MCAM_INVALID_MAP; 3802 npc_mcam_clear_bit(mcam, entry); 3803 mutex_unlock(&mcam->lock); 3804 return rc; 3805 } 3806 3807 cntr = cntr_rsp.cntr; 3808 3809 write_entry: 3810 mutex_lock(&mcam->lock); 3811 3812 if (is_npc_intf_tx(req->intf)) 3813 nix_intf = pfvf->nix_tx_intf; 3814 else 3815 nix_intf = pfvf->nix_rx_intf; 3816 3817 npc_config_mcam_entry(rvu, mcam, blkaddr, entry, nix_intf, 3818 &req->entry_data, req->enable_entry); 3819 3820 if (req->alloc_cntr) 3821 npc_map_mcam_entry_and_cntr(rvu, mcam, blkaddr, entry, cntr); 3822 mutex_unlock(&mcam->lock); 3823 3824 rsp->entry = entry; 3825 rsp->cntr = cntr; 3826 3827 return 0; 3828 } 3829 3830 #define GET_KEX_CFG(intf) \ 3831 rvu_read64(rvu, BLKADDR_NPC, NPC_AF_INTFX_KEX_CFG(intf)) 3832 3833 #define GET_KEX_FLAGS(ld) \ 3834 rvu_read64(rvu, BLKADDR_NPC, NPC_AF_KEX_LDATAX_FLAGS_CFG(ld)) 3835 3836 #define GET_KEX_LD(intf, lid, lt, ld) \ 3837 rvu_read64(rvu, BLKADDR_NPC, \ 3838 NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, lid, lt, ld)) 3839 3840 #define GET_KEX_LDFLAGS(intf, ld, fl) \ 3841 rvu_read64(rvu, BLKADDR_NPC, \ 3842 NPC_AF_INTFX_LDATAX_FLAGSX_CFG(intf, ld, fl)) 3843 3844 int rvu_mbox_handler_npc_get_kex_cfg(struct rvu *rvu, struct msg_req *req, 3845 struct npc_get_kex_cfg_rsp *rsp) 3846 { 3847 int lid, lt, ld, fl; 3848 3849 rsp->rx_keyx_cfg = GET_KEX_CFG(NIX_INTF_RX); 3850 rsp->tx_keyx_cfg = GET_KEX_CFG(NIX_INTF_TX); 3851 for (lid = 0; lid < NPC_MAX_LID; lid++) { 3852 for (lt = 0; lt < NPC_MAX_LT; lt++) { 3853 for (ld = 0; ld < NPC_MAX_LD; ld++) { 3854 rsp->intf_lid_lt_ld[NIX_INTF_RX][lid][lt][ld] = 3855 GET_KEX_LD(NIX_INTF_RX, lid, lt, ld); 3856 rsp->intf_lid_lt_ld[NIX_INTF_TX][lid][lt][ld] = 3857 GET_KEX_LD(NIX_INTF_TX, lid, lt, ld); 3858 } 3859 } 3860 } 3861 for (ld = 0; ld < NPC_MAX_LD; ld++) 3862 rsp->kex_ld_flags[ld] = GET_KEX_FLAGS(ld); 3863 3864 for (ld = 0; ld < NPC_MAX_LD; ld++) { 3865 for (fl = 0; fl < NPC_MAX_LFL; fl++) { 3866 rsp->intf_ld_flags[NIX_INTF_RX][ld][fl] = 3867 GET_KEX_LDFLAGS(NIX_INTF_RX, ld, fl); 3868 rsp->intf_ld_flags[NIX_INTF_TX][ld][fl] = 3869 GET_KEX_LDFLAGS(NIX_INTF_TX, ld, fl); 3870 } 3871 } 3872 memcpy(rsp->mkex_pfl_name, rvu->mkex_pfl_name, MKEX_NAME_LEN); 3873 return 0; 3874 } 3875 3876 static int 3877 npc_set_var_len_offset_pkind(struct rvu *rvu, u16 pcifunc, u64 pkind, 3878 u8 var_len_off, u8 var_len_off_mask, u8 shift_dir) 3879 { 3880 struct npc_kpu_action0 *act0; 3881 u8 shift_count = 0; 3882 int blkaddr; 3883 u64 val; 3884 3885 if (!var_len_off_mask) 3886 return -EINVAL; 3887 3888 if (var_len_off_mask != 0xff) { 3889 if (shift_dir) 3890 shift_count = __ffs(var_len_off_mask); 3891 else 3892 shift_count = (8 - __fls(var_len_off_mask)); 3893 } 3894 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, pcifunc); 3895 if (blkaddr < 0) { 3896 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__); 3897 return -EINVAL; 3898 } 3899 val = rvu_read64(rvu, blkaddr, NPC_AF_PKINDX_ACTION0(pkind)); 3900 act0 = (struct npc_kpu_action0 *)&val; 3901 act0->var_len_shift = shift_count; 3902 act0->var_len_right = shift_dir; 3903 act0->var_len_mask = var_len_off_mask; 3904 act0->var_len_offset = var_len_off; 3905 rvu_write64(rvu, blkaddr, NPC_AF_PKINDX_ACTION0(pkind), val); 3906 return 0; 3907 } 3908 3909 int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir, 3910 u64 pkind, u8 var_len_off, u8 var_len_off_mask, 3911 u8 shift_dir) 3912 3913 { 3914 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); 3915 int blkaddr, nixlf, rc, intf_mode; 3916 int pf = rvu_get_pf(rvu->pdev, pcifunc); 3917 u64 rxpkind, txpkind; 3918 u8 cgx_id, lmac_id; 3919 3920 /* use default pkind to disable edsa/higig */ 3921 rxpkind = rvu_npc_get_pkind(rvu, pf); 3922 txpkind = NPC_TX_DEF_PKIND; 3923 intf_mode = NPC_INTF_MODE_DEF; 3924 3925 if (mode & OTX2_PRIV_FLAGS_CUSTOM) { 3926 if (pkind == NPC_RX_CUSTOM_PRE_L2_PKIND) { 3927 rc = npc_set_var_len_offset_pkind(rvu, pcifunc, pkind, 3928 var_len_off, 3929 var_len_off_mask, 3930 shift_dir); 3931 if (rc) 3932 return rc; 3933 } 3934 rxpkind = pkind; 3935 txpkind = pkind; 3936 } 3937 3938 if (dir & PKIND_RX) { 3939 /* rx pkind set req valid only for cgx mapped PFs */ 3940 if (!is_cgx_config_permitted(rvu, pcifunc)) 3941 return 0; 3942 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id); 3943 3944 rc = cgx_set_pkind(rvu_cgx_pdata(cgx_id, rvu), lmac_id, 3945 rxpkind); 3946 if (rc) 3947 return rc; 3948 } 3949 3950 if (dir & PKIND_TX) { 3951 /* Tx pkind set request valid if PCIFUNC has NIXLF attached */ 3952 rc = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr); 3953 if (rc) 3954 return rc; 3955 3956 rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf), 3957 txpkind); 3958 } 3959 3960 pfvf->intf_mode = intf_mode; 3961 return 0; 3962 } 3963 3964 int rvu_mbox_handler_npc_set_pkind(struct rvu *rvu, struct npc_set_pkind *req, 3965 struct msg_rsp *rsp) 3966 { 3967 return rvu_npc_set_parse_mode(rvu, req->hdr.pcifunc, req->mode, 3968 req->dir, req->pkind, req->var_len_off, 3969 req->var_len_off_mask, req->shift_dir); 3970 } 3971 3972 int rvu_mbox_handler_npc_read_base_steer_rule(struct rvu *rvu, 3973 struct msg_req *req, 3974 struct npc_mcam_read_base_rule_rsp *rsp) 3975 { 3976 struct npc_mcam *mcam = &rvu->hw->mcam; 3977 int index, blkaddr, nixlf, rc = 0; 3978 u16 pcifunc = req->hdr.pcifunc; 3979 struct rvu_pfvf *pfvf; 3980 u8 intf, enable; 3981 3982 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 3983 if (blkaddr < 0) 3984 return NPC_MCAM_INVALID_REQ; 3985 3986 /* Return the channel number in case of PF */ 3987 if (!(pcifunc & RVU_PFVF_FUNC_MASK)) { 3988 pfvf = rvu_get_pfvf(rvu, pcifunc); 3989 rsp->entry.kw[0] = pfvf->rx_chan_base; 3990 rsp->entry.kw_mask[0] = 0xFFFULL; 3991 goto out; 3992 } 3993 3994 /* Find the pkt steering rule installed by PF to this VF */ 3995 mutex_lock(&mcam->lock); 3996 for (index = 0; index < mcam->bmap_entries; index++) { 3997 if (mcam->entry2target_pffunc[index] == pcifunc) 3998 goto read_entry; 3999 } 4000 4001 rc = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL); 4002 if (rc < 0) { 4003 mutex_unlock(&mcam->lock); 4004 goto out; 4005 } 4006 /* Read the default ucast entry if there is no pkt steering rule */ 4007 index = npc_get_nixlf_mcam_index(mcam, pcifunc, nixlf, 4008 NIXLF_UCAST_ENTRY); 4009 if (index < 0) { 4010 mutex_unlock(&mcam->lock); 4011 rc = NIX_AF_ERR_AF_LF_INVALID; 4012 goto out; 4013 } 4014 4015 read_entry: 4016 /* Read the mcam entry */ 4017 npc_read_mcam_entry(rvu, mcam, blkaddr, index, &rsp->entry, &intf, 4018 &enable); 4019 mutex_unlock(&mcam->lock); 4020 out: 4021 return rc; 4022 } 4023 4024 int rvu_mbox_handler_npc_mcam_entry_stats(struct rvu *rvu, 4025 struct npc_mcam_get_stats_req *req, 4026 struct npc_mcam_get_stats_rsp *rsp) 4027 { 4028 struct npc_mcam *mcam = &rvu->hw->mcam; 4029 u16 index, cntr; 4030 int blkaddr; 4031 u64 regval; 4032 u32 bank; 4033 4034 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 4035 if (blkaddr < 0) 4036 return NPC_MCAM_INVALID_REQ; 4037 4038 req->entry = npc_cn20k_vidx2idx(req->entry); 4039 4040 index = req->entry & (mcam->banksize - 1); 4041 bank = npc_get_bank(mcam, req->entry); 4042 4043 mutex_lock(&mcam->lock); 4044 4045 if (is_cn20k(rvu->pdev)) { 4046 regval = rvu_read64(rvu, blkaddr, 4047 NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index, 4048 bank)); 4049 rsp->stat_ena = 1; 4050 rsp->stat = regval; 4051 mutex_unlock(&mcam->lock); 4052 return 0; 4053 } 4054 4055 /* read MCAM entry STAT_ACT register */ 4056 regval = rvu_read64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_STAT_ACT(index, 4057 bank)); 4058 4059 if (!(regval & rvu->hw->npc_stat_ena)) { 4060 rsp->stat_ena = 0; 4061 mutex_unlock(&mcam->lock); 4062 return 0; 4063 } 4064 4065 cntr = regval & 0x1FF; 4066 4067 rsp->stat_ena = 1; 4068 rsp->stat = rvu_read64(rvu, blkaddr, NPC_AF_MATCH_STATX(cntr)); 4069 rsp->stat &= BIT_ULL(48) - 1; 4070 4071 mutex_unlock(&mcam->lock); 4072 4073 return 0; 4074 } 4075 4076 void rvu_npc_clear_ucast_entry(struct rvu *rvu, int pcifunc, int nixlf) 4077 { 4078 struct npc_mcam *mcam = &rvu->hw->mcam; 4079 struct rvu_npc_mcam_rule *rule; 4080 int ucast_idx, blkaddr; 4081 4082 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 4083 if (blkaddr < 0) 4084 return; 4085 4086 ucast_idx = npc_get_nixlf_mcam_index(mcam, pcifunc, 4087 nixlf, NIXLF_UCAST_ENTRY); 4088 if (ucast_idx < 0) { 4089 dev_err(rvu->dev, 4090 "%s: Error to get ucast entry for pcifunc=%#x\n", 4091 __func__, pcifunc); 4092 return; 4093 } 4094 4095 npc_enable_mcam_entry(rvu, mcam, blkaddr, ucast_idx, false); 4096 4097 npc_set_mcam_action(rvu, mcam, blkaddr, ucast_idx, 0); 4098 4099 npc_clear_mcam_entry(rvu, mcam, blkaddr, ucast_idx); 4100 4101 mutex_lock(&mcam->lock); 4102 list_for_each_entry(rule, &mcam->mcam_rules, list) { 4103 if (rule->entry == ucast_idx) { 4104 list_del(&rule->list); 4105 kfree(rule); 4106 break; 4107 } 4108 } 4109 mutex_unlock(&mcam->lock); 4110 } 4111