0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/bitfield.h>
0009 #include <linux/module.h>
0010 #include <linux/pci.h>
0011 #include <linux/firmware.h>
0012 #include <linux/stddef.h>
0013 #include <linux/debugfs.h>
0014
0015 #include "rvu_struct.h"
0016 #include "rvu_reg.h"
0017 #include "rvu.h"
0018 #include "npc.h"
0019 #include "cgx.h"
0020 #include "rvu_npc_fs.h"
0021 #include "rvu_npc_hash.h"
0022
0023 static u64 rvu_npc_wide_extract(const u64 input[], size_t start_bit,
0024 size_t width_bits)
0025 {
0026 const u64 mask = ~(u64)((~(__uint128_t)0) << width_bits);
0027 const size_t msb = start_bit + width_bits - 1;
0028 const size_t lword = start_bit >> 6;
0029 const size_t uword = msb >> 6;
0030 size_t lbits;
0031 u64 hi, lo;
0032
0033 if (lword == uword)
0034 return (input[lword] >> (start_bit & 63)) & mask;
0035
0036 lbits = 64 - (start_bit & 63);
0037 hi = input[uword];
0038 lo = (input[lword] >> (start_bit & 63));
0039 return ((hi << lbits) | lo) & mask;
0040 }
0041
0042 static void rvu_npc_lshift_key(u64 *key, size_t key_bit_len)
0043 {
0044 u64 prev_orig_word = 0;
0045 u64 cur_orig_word = 0;
0046 size_t extra = key_bit_len % 64;
0047 size_t max_idx = key_bit_len / 64;
0048 size_t i;
0049
0050 if (extra)
0051 max_idx++;
0052
0053 for (i = 0; i < max_idx; i++) {
0054 cur_orig_word = key[i];
0055 key[i] = key[i] << 1;
0056 key[i] |= ((prev_orig_word >> 63) & 0x1);
0057 prev_orig_word = cur_orig_word;
0058 }
0059 }
0060
0061 static u32 rvu_npc_toeplitz_hash(const u64 *data, u64 *key, size_t data_bit_len,
0062 size_t key_bit_len)
0063 {
0064 u32 hash_out = 0;
0065 u64 temp_data = 0;
0066 int i;
0067
0068 for (i = data_bit_len - 1; i >= 0; i--) {
0069 temp_data = (data[i / 64]);
0070 temp_data = temp_data >> (i % 64);
0071 temp_data &= 0x1;
0072 if (temp_data)
0073 hash_out ^= (u32)(rvu_npc_wide_extract(key, key_bit_len - 32, 32));
0074
0075 rvu_npc_lshift_key(key, key_bit_len);
0076 }
0077
0078 return hash_out;
0079 }
0080
0081 u32 npc_field_hash_calc(u64 *ldata, struct npc_mcam_kex_hash *mkex_hash,
0082 u64 *secret_key, u8 intf, u8 hash_idx)
0083 {
0084 u64 hash_key[3];
0085 u64 data_padded[2];
0086 u32 field_hash;
0087
0088 hash_key[0] = secret_key[1] << 31;
0089 hash_key[0] |= secret_key[2];
0090 hash_key[1] = secret_key[1] >> 33;
0091 hash_key[1] |= secret_key[0] << 31;
0092 hash_key[2] = secret_key[0] >> 33;
0093
0094 data_padded[0] = mkex_hash->hash_mask[intf][hash_idx][0] & ldata[0];
0095 data_padded[1] = mkex_hash->hash_mask[intf][hash_idx][1] & ldata[1];
0096 field_hash = rvu_npc_toeplitz_hash(data_padded, hash_key, 128, 159);
0097
0098 field_hash &= mkex_hash->hash_ctrl[intf][hash_idx] >> 32;
0099 field_hash |= mkex_hash->hash_ctrl[intf][hash_idx];
0100 return field_hash;
0101 }
0102
0103 static u64 npc_update_use_hash(int lt, int ld)
0104 {
0105 u64 cfg = 0;
0106
0107 switch (lt) {
0108 case NPC_LT_LC_IP6:
0109
0110
0111
0112 cfg = KEX_LD_CFG_USE_HASH(0x1, 0x03,
0113 ld ? 0x8 : 0x18,
0114 0x1, 0x0, 0x10);
0115 break;
0116 }
0117
0118 return cfg;
0119 }
0120
0121 static void npc_program_mkex_hash_rx(struct rvu *rvu, int blkaddr,
0122 u8 intf)
0123 {
0124 struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
0125 int lid, lt, ld, hash_cnt = 0;
0126
0127 if (is_npc_intf_tx(intf))
0128 return;
0129
0130
0131 for (lid = 0; lid < NPC_MAX_LID; lid++) {
0132 for (lt = 0; lt < NPC_MAX_LT; lt++) {
0133 for (ld = 0; ld < NPC_MAX_LD; ld++) {
0134 if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
0135 u64 cfg = npc_update_use_hash(lt, ld);
0136
0137 hash_cnt++;
0138 if (hash_cnt == NPC_MAX_HASH)
0139 return;
0140
0141
0142 SET_KEX_LD(intf, lid, lt, ld, cfg);
0143
0144 SET_KEX_LD_HASH(intf, ld,
0145 mkex_hash->hash[intf][ld]);
0146 SET_KEX_LD_HASH_MASK(intf, ld, 0,
0147 mkex_hash->hash_mask[intf][ld][0]);
0148 SET_KEX_LD_HASH_MASK(intf, ld, 1,
0149 mkex_hash->hash_mask[intf][ld][1]);
0150 SET_KEX_LD_HASH_CTRL(intf, ld,
0151 mkex_hash->hash_ctrl[intf][ld]);
0152 }
0153 }
0154 }
0155 }
0156 }
0157
0158 static void npc_program_mkex_hash_tx(struct rvu *rvu, int blkaddr,
0159 u8 intf)
0160 {
0161 struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
0162 int lid, lt, ld, hash_cnt = 0;
0163
0164 if (is_npc_intf_rx(intf))
0165 return;
0166
0167
0168 for (lid = 0; lid < NPC_MAX_LID; lid++) {
0169 for (lt = 0; lt < NPC_MAX_LT; lt++) {
0170 for (ld = 0; ld < NPC_MAX_LD; ld++)
0171 if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
0172 u64 cfg = npc_update_use_hash(lt, ld);
0173
0174 hash_cnt++;
0175 if (hash_cnt == NPC_MAX_HASH)
0176 return;
0177
0178
0179 SET_KEX_LD(intf, lid, lt, ld, cfg);
0180
0181 SET_KEX_LD_HASH(intf, ld,
0182 mkex_hash->hash[intf][ld]);
0183 SET_KEX_LD_HASH_MASK(intf, ld, 0,
0184 mkex_hash->hash_mask[intf][ld][0]);
0185 SET_KEX_LD_HASH_MASK(intf, ld, 1,
0186 mkex_hash->hash_mask[intf][ld][1]);
0187 SET_KEX_LD_HASH_CTRL(intf, ld,
0188 mkex_hash->hash_ctrl[intf][ld]);
0189 hash_cnt++;
0190 if (hash_cnt == NPC_MAX_HASH)
0191 return;
0192 }
0193 }
0194 }
0195 }
0196
0197 void npc_config_secret_key(struct rvu *rvu, int blkaddr)
0198 {
0199 struct hw_cap *hwcap = &rvu->hw->cap;
0200 struct rvu_hwinfo *hw = rvu->hw;
0201 u8 intf;
0202
0203 if (!hwcap->npc_hash_extract) {
0204 dev_info(rvu->dev, "HW does not support secret key configuration\n");
0205 return;
0206 }
0207
0208 for (intf = 0; intf < hw->npc_intfs; intf++) {
0209 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY0(intf),
0210 RVU_NPC_HASH_SECRET_KEY0);
0211 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf),
0212 RVU_NPC_HASH_SECRET_KEY1);
0213 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf),
0214 RVU_NPC_HASH_SECRET_KEY2);
0215 }
0216 }
0217
0218 void npc_program_mkex_hash(struct rvu *rvu, int blkaddr)
0219 {
0220 struct hw_cap *hwcap = &rvu->hw->cap;
0221 struct rvu_hwinfo *hw = rvu->hw;
0222 u8 intf;
0223
0224 if (!hwcap->npc_hash_extract) {
0225 dev_dbg(rvu->dev, "Field hash extract feature is not supported\n");
0226 return;
0227 }
0228
0229 for (intf = 0; intf < hw->npc_intfs; intf++) {
0230 npc_program_mkex_hash_rx(rvu, blkaddr, intf);
0231 npc_program_mkex_hash_tx(rvu, blkaddr, intf);
0232 }
0233 }
0234
0235 void npc_update_field_hash(struct rvu *rvu, u8 intf,
0236 struct mcam_entry *entry,
0237 int blkaddr,
0238 u64 features,
0239 struct flow_msg *pkt,
0240 struct flow_msg *mask,
0241 struct flow_msg *opkt,
0242 struct flow_msg *omask)
0243 {
0244 struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
0245 struct npc_get_secret_key_req req;
0246 struct npc_get_secret_key_rsp rsp;
0247 u64 ldata[2], cfg;
0248 u32 field_hash;
0249 u8 hash_idx;
0250
0251 if (!rvu->hw->cap.npc_hash_extract) {
0252 dev_dbg(rvu->dev, "%s: Field hash extract feature is not supported\n", __func__);
0253 return;
0254 }
0255
0256 req.intf = intf;
0257 rvu_mbox_handler_npc_get_secret_key(rvu, &req, &rsp);
0258
0259 for (hash_idx = 0; hash_idx < NPC_MAX_HASH; hash_idx++) {
0260 cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_HASHX_CFG(intf, hash_idx));
0261 if ((cfg & BIT_ULL(11)) && (cfg & BIT_ULL(12))) {
0262 u8 lid = (cfg & GENMASK_ULL(10, 8)) >> 8;
0263 u8 ltype = (cfg & GENMASK_ULL(7, 4)) >> 4;
0264 u8 ltype_mask = cfg & GENMASK_ULL(3, 0);
0265
0266 if (mkex_hash->lid_lt_ld_hash_en[intf][lid][ltype][hash_idx]) {
0267 switch (ltype & ltype_mask) {
0268
0269
0270
0271
0272 case NPC_LT_LC_IP6:
0273 if (features & BIT_ULL(NPC_SIP_IPV6)) {
0274 u32 src_ip[IPV6_WORDS];
0275
0276 be32_to_cpu_array(src_ip, pkt->ip6src, IPV6_WORDS);
0277 ldata[0] = (u64)src_ip[0] << 32 | src_ip[1];
0278 ldata[1] = (u64)src_ip[2] << 32 | src_ip[3];
0279 field_hash = npc_field_hash_calc(ldata,
0280 mkex_hash,
0281 rsp.secret_key,
0282 intf,
0283 hash_idx);
0284 npc_update_entry(rvu, NPC_SIP_IPV6, entry,
0285 field_hash, 0, 32, 0, intf);
0286 memcpy(&opkt->ip6src, &pkt->ip6src,
0287 sizeof(pkt->ip6src));
0288 memcpy(&omask->ip6src, &mask->ip6src,
0289 sizeof(mask->ip6src));
0290 break;
0291 }
0292
0293 if (features & BIT_ULL(NPC_DIP_IPV6)) {
0294 u32 dst_ip[IPV6_WORDS];
0295
0296 be32_to_cpu_array(dst_ip, pkt->ip6dst, IPV6_WORDS);
0297 ldata[0] = (u64)dst_ip[0] << 32 | dst_ip[1];
0298 ldata[1] = (u64)dst_ip[2] << 32 | dst_ip[3];
0299 field_hash = npc_field_hash_calc(ldata,
0300 mkex_hash,
0301 rsp.secret_key,
0302 intf,
0303 hash_idx);
0304 npc_update_entry(rvu, NPC_DIP_IPV6, entry,
0305 field_hash, 0, 32, 0, intf);
0306 memcpy(&opkt->ip6dst, &pkt->ip6dst,
0307 sizeof(pkt->ip6dst));
0308 memcpy(&omask->ip6dst, &mask->ip6dst,
0309 sizeof(mask->ip6dst));
0310 }
0311 break;
0312 }
0313 }
0314 }
0315 }
0316 }
0317
0318 int rvu_mbox_handler_npc_get_secret_key(struct rvu *rvu,
0319 struct npc_get_secret_key_req *req,
0320 struct npc_get_secret_key_rsp *rsp)
0321 {
0322 u64 *secret_key = rsp->secret_key;
0323 u8 intf = req->intf;
0324 int blkaddr;
0325
0326 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
0327 if (blkaddr < 0) {
0328 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
0329 return -EINVAL;
0330 }
0331
0332 secret_key[0] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY0(intf));
0333 secret_key[1] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf));
0334 secret_key[2] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf));
0335
0336 return 0;
0337 }
0338
0339
0340
0341
0342
0343
0344 static u64 rvu_npc_exact_mac2u64(u8 *mac_addr)
0345 {
0346 u64 mac = 0;
0347 int index;
0348
0349 for (index = ETH_ALEN - 1; index >= 0; index--)
0350 mac |= ((u64)*mac_addr++) << (8 * index);
0351
0352 return mac;
0353 }
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363 static u64 rvu_exact_prepare_mdata(u8 *mac, u16 chan, u16 ctype, u64 mask)
0364 {
0365 u64 ldata = rvu_npc_exact_mac2u64(mac);
0366
0367
0368
0369
0370 ldata |= ((u64)chan << 48);
0371 ldata |= ((u64)ctype << 60);
0372 ldata &= mask;
0373 ldata = ldata << 2;
0374
0375 return ldata;
0376 }
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388 static u32 rvu_exact_calculate_hash(struct rvu *rvu, u16 chan, u16 ctype, u8 *mac,
0389 u64 mask, u32 table_depth)
0390 {
0391 struct npc_exact_table *table = rvu->hw->table;
0392 u64 hash_key[2];
0393 u64 key_in[2];
0394 u64 ldata;
0395 u32 hash;
0396
0397 key_in[0] = RVU_NPC_HASH_SECRET_KEY0;
0398 key_in[1] = RVU_NPC_HASH_SECRET_KEY2;
0399
0400 hash_key[0] = key_in[0] << 31;
0401 hash_key[0] |= key_in[1];
0402 hash_key[1] = key_in[0] >> 33;
0403
0404 ldata = rvu_exact_prepare_mdata(mac, chan, ctype, mask);
0405
0406 dev_dbg(rvu->dev, "%s: ldata=0x%llx hash_key0=0x%llx hash_key2=0x%llx\n", __func__,
0407 ldata, hash_key[1], hash_key[0]);
0408 hash = rvu_npc_toeplitz_hash(&ldata, (u64 *)hash_key, 64, 95);
0409
0410 hash &= table->mem_table.hash_mask;
0411 hash += table->mem_table.hash_offset;
0412 dev_dbg(rvu->dev, "%s: hash=%x\n", __func__, hash);
0413
0414 return hash;
0415 }
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427 static int rvu_npc_exact_alloc_mem_table_entry(struct rvu *rvu, u8 *way,
0428 u32 *index, unsigned int hash)
0429 {
0430 struct npc_exact_table *table;
0431 int depth, i;
0432
0433 table = rvu->hw->table;
0434 depth = table->mem_table.depth;
0435
0436
0437 mutex_lock(&table->lock);
0438 for (i = 0; i < table->mem_table.ways; i++) {
0439 if (test_bit(hash + i * depth, table->mem_table.bmap))
0440 continue;
0441
0442 set_bit(hash + i * depth, table->mem_table.bmap);
0443 mutex_unlock(&table->lock);
0444
0445 dev_dbg(rvu->dev, "%s: mem table entry alloc success (way=%d index=%d)\n",
0446 __func__, i, hash);
0447
0448 *way = i;
0449 *index = hash;
0450 return 0;
0451 }
0452 mutex_unlock(&table->lock);
0453
0454 dev_dbg(rvu->dev, "%s: No space in 4 way exact way, weight=%u\n", __func__,
0455 bitmap_weight(table->mem_table.bmap, table->mem_table.depth));
0456 return -ENOSPC;
0457 }
0458
0459
0460
0461
0462
0463
0464 static void rvu_npc_exact_free_id(struct rvu *rvu, u32 seq_id)
0465 {
0466 struct npc_exact_table *table;
0467
0468 table = rvu->hw->table;
0469 mutex_lock(&table->lock);
0470 clear_bit(seq_id, table->id_bmap);
0471 mutex_unlock(&table->lock);
0472 dev_dbg(rvu->dev, "%s: freed id %d\n", __func__, seq_id);
0473 }
0474
0475
0476
0477
0478
0479
0480
0481 static bool rvu_npc_exact_alloc_id(struct rvu *rvu, u32 *seq_id)
0482 {
0483 struct npc_exact_table *table;
0484 u32 idx;
0485
0486 table = rvu->hw->table;
0487
0488 mutex_lock(&table->lock);
0489 idx = find_first_zero_bit(table->id_bmap, table->tot_ids);
0490 if (idx == table->tot_ids) {
0491 mutex_unlock(&table->lock);
0492 dev_err(rvu->dev, "%s: No space in id bitmap (%d)\n",
0493 __func__, bitmap_weight(table->id_bmap, table->tot_ids));
0494
0495 return false;
0496 }
0497
0498
0499 set_bit(idx, table->id_bmap);
0500 mutex_unlock(&table->lock);
0501
0502 *seq_id = idx;
0503 dev_dbg(rvu->dev, "%s: Allocated id (%d)\n", __func__, *seq_id);
0504
0505 return true;
0506 }
0507
0508
0509
0510
0511
0512
0513
0514 static int rvu_npc_exact_alloc_cam_table_entry(struct rvu *rvu, int *index)
0515 {
0516 struct npc_exact_table *table;
0517 u32 idx;
0518
0519 table = rvu->hw->table;
0520
0521 mutex_lock(&table->lock);
0522 idx = find_first_zero_bit(table->cam_table.bmap, table->cam_table.depth);
0523 if (idx == table->cam_table.depth) {
0524 mutex_unlock(&table->lock);
0525 dev_info(rvu->dev, "%s: No space in exact cam table, weight=%u\n", __func__,
0526 bitmap_weight(table->cam_table.bmap, table->cam_table.depth));
0527 return -ENOSPC;
0528 }
0529
0530
0531 set_bit(idx, table->cam_table.bmap);
0532 mutex_unlock(&table->lock);
0533
0534 *index = idx;
0535 dev_dbg(rvu->dev, "%s: cam table entry alloc success (index=%d)\n",
0536 __func__, idx);
0537 return 0;
0538 }
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549 static u64 rvu_exact_prepare_table_entry(struct rvu *rvu, bool enable,
0550 u8 ctype, u16 chan, u8 *mac_addr)
0551
0552 {
0553 u64 ldata = rvu_npc_exact_mac2u64(mac_addr);
0554
0555
0556 u64 mdata = FIELD_PREP(GENMASK_ULL(63, 63), enable ? 1 : 0);
0557
0558
0559 mdata |= FIELD_PREP(GENMASK_ULL(61, 60), ctype);
0560
0561
0562 mdata |= FIELD_PREP(GENMASK_ULL(59, 48), chan);
0563
0564
0565 mdata |= FIELD_PREP(GENMASK_ULL(47, 0), ldata);
0566
0567 return mdata;
0568 }
0569
0570
0571
0572
0573
0574 static void rvu_exact_config_secret_key(struct rvu *rvu)
0575 {
0576 int blkaddr;
0577
0578 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
0579 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET0(NIX_INTF_RX),
0580 RVU_NPC_HASH_SECRET_KEY0);
0581
0582 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET1(NIX_INTF_RX),
0583 RVU_NPC_HASH_SECRET_KEY1);
0584
0585 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET2(NIX_INTF_RX),
0586 RVU_NPC_HASH_SECRET_KEY2);
0587 }
0588
0589
0590
0591
0592
0593 static void rvu_exact_config_search_key(struct rvu *rvu)
0594 {
0595 int blkaddr;
0596 u64 reg_val;
0597
0598 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
0599
0600
0601 reg_val = FIELD_PREP(GENMASK_ULL(39, 32), 0);
0602
0603
0604 reg_val |= FIELD_PREP(GENMASK_ULL(18, 16), ETH_ALEN - 1);
0605
0606
0607 reg_val |= FIELD_PREP(GENMASK_ULL(11, 11), 1);
0608 reg_val |= FIELD_PREP(GENMASK_ULL(10, 8), NPC_LID_LA);
0609
0610
0611
0612
0613 reg_val |= FIELD_PREP(GENMASK_ULL(12, 12), 0);
0614
0615
0616 reg_val |= FIELD_PREP(GENMASK_ULL(7, 4), 0);
0617
0618
0619 reg_val |= FIELD_PREP(GENMASK_ULL(3, 0), 0);
0620
0621 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_CFG(NIX_INTF_RX), reg_val);
0622 }
0623
0624
0625
0626
0627
0628
0629
0630
0631 static void rvu_exact_config_result_ctrl(struct rvu *rvu, uint32_t depth)
0632 {
0633 int blkaddr;
0634 u64 reg = 0;
0635
0636 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
0637
0638
0639 rvu->hw->table->mem_table.hash_mask = (depth - 1);
0640 reg |= FIELD_PREP(GENMASK_ULL(42, 32), (depth - 1));
0641
0642
0643 rvu->hw->table->mem_table.hash_offset = 0;
0644 reg |= FIELD_PREP(GENMASK_ULL(10, 0), 0);
0645
0646
0647 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_RESULT_CTL(NIX_INTF_RX), reg);
0648
0649 }
0650
0651
0652
0653
0654
0655 static void rvu_exact_config_table_mask(struct rvu *rvu)
0656 {
0657 int blkaddr;
0658 u64 mask = 0;
0659
0660 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
0661
0662
0663 mask |= FIELD_PREP(GENMASK_ULL(61, 60), 0);
0664
0665
0666 mask |= GENMASK_ULL(59, 48);
0667
0668
0669 mask |= GENMASK_ULL(47, 0);
0670
0671
0672 rvu->hw->table->mem_table.mask = mask;
0673
0674
0675 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_MASK(NIX_INTF_RX), mask);
0676 }
0677
0678
0679
0680
0681
0682
0683 u32 rvu_npc_exact_get_max_entries(struct rvu *rvu)
0684 {
0685 struct npc_exact_table *table;
0686
0687 table = rvu->hw->table;
0688 return table->tot_ids;
0689 }
0690
0691
0692
0693
0694
0695
0696 bool rvu_npc_exact_has_match_table(struct rvu *rvu)
0697 {
0698 return rvu->hw->cap.npc_exact_match_enabled;
0699 }
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709 static struct npc_exact_table_entry *
0710 __rvu_npc_exact_find_entry_by_seq_id(struct rvu *rvu, u32 seq_id)
0711 {
0712 struct npc_exact_table *table = rvu->hw->table;
0713 struct npc_exact_table_entry *entry = NULL;
0714 struct list_head *lhead;
0715
0716 lhead = &table->lhead_gbl;
0717
0718
0719 list_for_each_entry(entry, lhead, glist) {
0720 if (entry->seq_id != seq_id)
0721 continue;
0722
0723 return entry;
0724 }
0725
0726 return NULL;
0727 }
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746 static int rvu_npc_exact_add_to_list(struct rvu *rvu, enum npc_exact_opc_type opc_type, u8 ways,
0747 u32 index, u8 cgx_id, u8 lmac_id, u8 *mac_addr, u16 chan,
0748 u8 ctype, u32 *seq_id, bool cmd, u32 mcam_idx, u16 pcifunc)
0749 {
0750 struct npc_exact_table_entry *entry, *tmp, *iter;
0751 struct npc_exact_table *table = rvu->hw->table;
0752 struct list_head *lhead, *pprev;
0753
0754 WARN_ON(ways >= NPC_EXACT_TBL_MAX_WAYS);
0755
0756 if (!rvu_npc_exact_alloc_id(rvu, seq_id)) {
0757 dev_err(rvu->dev, "%s: Generate seq id failed\n", __func__);
0758 return -EFAULT;
0759 }
0760
0761 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
0762 if (!entry) {
0763 rvu_npc_exact_free_id(rvu, *seq_id);
0764 dev_err(rvu->dev, "%s: Memory allocation failed\n", __func__);
0765 return -ENOMEM;
0766 }
0767
0768 mutex_lock(&table->lock);
0769 switch (opc_type) {
0770 case NPC_EXACT_OPC_CAM:
0771 lhead = &table->lhead_cam_tbl_entry;
0772 table->cam_tbl_entry_cnt++;
0773 break;
0774
0775 case NPC_EXACT_OPC_MEM:
0776 lhead = &table->lhead_mem_tbl_entry[ways];
0777 table->mem_tbl_entry_cnt++;
0778 break;
0779
0780 default:
0781 mutex_unlock(&table->lock);
0782 kfree(entry);
0783 rvu_npc_exact_free_id(rvu, *seq_id);
0784
0785 dev_err(rvu->dev, "%s: Unknown opc type%d\n", __func__, opc_type);
0786 return -EINVAL;
0787 }
0788
0789
0790 INIT_LIST_HEAD(&entry->glist);
0791 list_add_tail(&entry->glist, &table->lhead_gbl);
0792 INIT_LIST_HEAD(&entry->list);
0793 entry->index = index;
0794 entry->ways = ways;
0795 entry->opc_type = opc_type;
0796
0797 entry->pcifunc = pcifunc;
0798
0799 ether_addr_copy(entry->mac, mac_addr);
0800 entry->chan = chan;
0801 entry->ctype = ctype;
0802 entry->cgx_id = cgx_id;
0803 entry->lmac_id = lmac_id;
0804
0805 entry->seq_id = *seq_id;
0806
0807 entry->mcam_idx = mcam_idx;
0808 entry->cmd = cmd;
0809
0810 pprev = lhead;
0811
0812
0813 list_for_each_entry_safe(iter, tmp, lhead, list) {
0814 if (index < iter->index)
0815 break;
0816
0817 pprev = &iter->list;
0818 }
0819
0820
0821 list_add(&entry->list, pprev);
0822 mutex_unlock(&table->lock);
0823 return 0;
0824 }
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834 static void rvu_npc_exact_mem_table_write(struct rvu *rvu, int blkaddr, u8 ways,
0835 u32 index, u64 mdata)
0836 {
0837 rvu_write64(rvu, blkaddr, NPC_AF_EXACT_MEM_ENTRY(ways, index), mdata);
0838 }
0839
0840
0841
0842
0843
0844
0845
0846
0847 static void rvu_npc_exact_cam_table_write(struct rvu *rvu, int blkaddr,
0848 u32 index, u64 mdata)
0849 {
0850 rvu_write64(rvu, blkaddr, NPC_AF_EXACT_CAM_ENTRY(index), mdata);
0851 }
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861 static int rvu_npc_exact_dealloc_table_entry(struct rvu *rvu, enum npc_exact_opc_type opc_type,
0862 u8 ways, u32 index)
0863 {
0864 int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
0865 struct npc_exact_table *table;
0866 u8 null_dmac[6] = { 0 };
0867 int depth;
0868
0869
0870 u64 null_mdata = rvu_exact_prepare_table_entry(rvu, false, 0, 0, null_dmac);
0871
0872 table = rvu->hw->table;
0873 depth = table->mem_table.depth;
0874
0875 mutex_lock(&table->lock);
0876
0877 switch (opc_type) {
0878 case NPC_EXACT_OPC_CAM:
0879
0880
0881 if (!test_bit(index, table->cam_table.bmap)) {
0882 mutex_unlock(&table->lock);
0883 dev_err(rvu->dev, "%s: Trying to free an unused entry ways=%d index=%d\n",
0884 __func__, ways, index);
0885 return -EINVAL;
0886 }
0887
0888 rvu_npc_exact_cam_table_write(rvu, blkaddr, index, null_mdata);
0889 clear_bit(index, table->cam_table.bmap);
0890 break;
0891
0892 case NPC_EXACT_OPC_MEM:
0893
0894
0895 if (!test_bit(index + ways * depth, table->mem_table.bmap)) {
0896 mutex_unlock(&table->lock);
0897 dev_err(rvu->dev, "%s: Trying to free an unused entry index=%d\n",
0898 __func__, index);
0899 return -EINVAL;
0900 }
0901
0902 rvu_npc_exact_mem_table_write(rvu, blkaddr, ways, index, null_mdata);
0903 clear_bit(index + ways * depth, table->mem_table.bmap);
0904 break;
0905
0906 default:
0907 mutex_unlock(&table->lock);
0908 dev_err(rvu->dev, "%s: invalid opc type %d", __func__, opc_type);
0909 return -ENOSPC;
0910 }
0911
0912 mutex_unlock(&table->lock);
0913
0914 dev_dbg(rvu->dev, "%s: Successfully deleted entry (index=%d, ways=%d opc_type=%d\n",
0915 __func__, index, ways, opc_type);
0916
0917 return 0;
0918 }
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935 static int rvu_npc_exact_alloc_table_entry(struct rvu *rvu, char *mac, u16 chan, u8 ctype,
0936 u32 *index, u8 *ways, enum npc_exact_opc_type *opc_type)
0937 {
0938 struct npc_exact_table *table;
0939 unsigned int hash;
0940 int err;
0941
0942 table = rvu->hw->table;
0943
0944
0945 hash = rvu_exact_calculate_hash(rvu, chan, ctype, mac, table->mem_table.mask,
0946 table->mem_table.depth);
0947 err = rvu_npc_exact_alloc_mem_table_entry(rvu, ways, index, hash);
0948 if (!err) {
0949 *opc_type = NPC_EXACT_OPC_MEM;
0950 dev_dbg(rvu->dev, "%s: inserted in 4 ways hash table ways=%d, index=%d\n",
0951 __func__, *ways, *index);
0952 return 0;
0953 }
0954
0955 dev_dbg(rvu->dev, "%s: failed to insert in 4 ways hash table\n", __func__);
0956
0957
0958 *ways = 0;
0959 err = rvu_npc_exact_alloc_cam_table_entry(rvu, index);
0960 if (!err) {
0961 *opc_type = NPC_EXACT_OPC_CAM;
0962 dev_dbg(rvu->dev, "%s: inserted in fully associative hash table index=%u\n",
0963 __func__, *index);
0964 return 0;
0965 }
0966
0967 dev_err(rvu->dev, "%s: failed to insert in fully associative hash table\n", __func__);
0968 return -ENOSPC;
0969 }
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980 static bool rvu_npc_exact_save_drop_rule_chan_and_mask(struct rvu *rvu, int drop_mcam_idx,
0981 u64 chan_val, u64 chan_mask, u16 pcifunc)
0982 {
0983 struct npc_exact_table *table;
0984 int i;
0985
0986 table = rvu->hw->table;
0987
0988 for (i = 0; i < NPC_MCAM_DROP_RULE_MAX; i++) {
0989 if (!table->drop_rule_map[i].valid)
0990 break;
0991
0992 if (table->drop_rule_map[i].chan_val != (u16)chan_val)
0993 continue;
0994
0995 if (table->drop_rule_map[i].chan_mask != (u16)chan_mask)
0996 continue;
0997
0998 return false;
0999 }
1000
1001 if (i == NPC_MCAM_DROP_RULE_MAX)
1002 return false;
1003
1004 table->drop_rule_map[i].drop_rule_idx = drop_mcam_idx;
1005 table->drop_rule_map[i].chan_val = (u16)chan_val;
1006 table->drop_rule_map[i].chan_mask = (u16)chan_mask;
1007 table->drop_rule_map[i].pcifunc = pcifunc;
1008 table->drop_rule_map[i].valid = true;
1009 return true;
1010 }
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022 static bool rvu_npc_exact_calc_drop_rule_chan_and_mask(struct rvu *rvu, u8 intf_type,
1023 u8 cgx_id, u8 lmac_id,
1024 u64 *val, u64 *mask)
1025 {
1026 u16 chan_val, chan_mask;
1027
1028
1029 if (intf_type != NIX_INTF_TYPE_CGX)
1030 return false;
1031
1032 chan_val = rvu_nix_chan_cgx(rvu, cgx_id, lmac_id, 0);
1033 chan_mask = 0xfff;
1034
1035 if (val)
1036 *val = chan_val;
1037
1038 if (mask)
1039 *mask = chan_mask;
1040
1041 return true;
1042 }
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053 u16 rvu_npc_exact_drop_rule_to_pcifunc(struct rvu *rvu, u32 drop_rule_idx)
1054 {
1055 struct npc_exact_table *table;
1056 int i;
1057
1058 table = rvu->hw->table;
1059
1060 for (i = 0; i < NPC_MCAM_DROP_RULE_MAX; i++) {
1061 if (!table->drop_rule_map[i].valid)
1062 break;
1063
1064 if (table->drop_rule_map[i].drop_rule_idx != drop_rule_idx)
1065 continue;
1066
1067 return table->drop_rule_map[i].pcifunc;
1068 }
1069
1070 dev_err(rvu->dev, "%s: drop mcam rule index (%d) >= NPC_MCAM_DROP_RULE_MAX\n",
1071 __func__, drop_rule_idx);
1072 return -1;
1073 }
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087 static bool rvu_npc_exact_get_drop_rule_info(struct rvu *rvu, u8 intf_type, u8 cgx_id,
1088 u8 lmac_id, u32 *drop_mcam_idx, u64 *val,
1089 u64 *mask, u16 *pcifunc)
1090 {
1091 struct npc_exact_table *table;
1092 u64 chan_val, chan_mask;
1093 bool rc;
1094 int i;
1095
1096 table = rvu->hw->table;
1097
1098 if (intf_type != NIX_INTF_TYPE_CGX) {
1099 dev_err(rvu->dev, "%s: No drop rule for LBK/SDP mode\n", __func__);
1100 return false;
1101 }
1102
1103 rc = rvu_npc_exact_calc_drop_rule_chan_and_mask(rvu, intf_type, cgx_id,
1104 lmac_id, &chan_val, &chan_mask);
1105 if (!rc)
1106 return false;
1107
1108 for (i = 0; i < NPC_MCAM_DROP_RULE_MAX; i++) {
1109 if (!table->drop_rule_map[i].valid)
1110 break;
1111
1112 if (table->drop_rule_map[i].chan_val != (u16)chan_val)
1113 continue;
1114
1115 if (val)
1116 *val = table->drop_rule_map[i].chan_val;
1117 if (mask)
1118 *mask = table->drop_rule_map[i].chan_mask;
1119 if (pcifunc)
1120 *pcifunc = table->drop_rule_map[i].pcifunc;
1121
1122 *drop_mcam_idx = i;
1123 return true;
1124 }
1125
1126 if (i == NPC_MCAM_DROP_RULE_MAX) {
1127 dev_err(rvu->dev, "%s: drop mcam rule index (%d) >= NPC_MCAM_DROP_RULE_MAX\n",
1128 __func__, *drop_mcam_idx);
1129 return false;
1130 }
1131
1132 dev_err(rvu->dev, "%s: Could not retrieve for cgx=%d, lmac=%d\n",
1133 __func__, cgx_id, lmac_id);
1134 return false;
1135 }
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149 static u16 __rvu_npc_exact_cmd_rules_cnt_update(struct rvu *rvu, int drop_mcam_idx,
1150 int val, bool *enable_or_disable_cam)
1151 {
1152 struct npc_exact_table *table;
1153 u16 *cnt, old_cnt;
1154 bool promisc;
1155
1156 table = rvu->hw->table;
1157 promisc = table->promisc_mode[drop_mcam_idx];
1158
1159 cnt = &table->cnt_cmd_rules[drop_mcam_idx];
1160 old_cnt = *cnt;
1161
1162 *cnt += val;
1163
1164 if (!enable_or_disable_cam)
1165 goto done;
1166
1167 *enable_or_disable_cam = false;
1168
1169 if (promisc)
1170 goto done;
1171
1172
1173 if (!*cnt && val < 0) {
1174 *enable_or_disable_cam = true;
1175 goto done;
1176 }
1177
1178
1179 if (!old_cnt && val > 0) {
1180 *enable_or_disable_cam = true;
1181 goto done;
1182 }
1183
1184 done:
1185 return *cnt;
1186 }
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197 static int rvu_npc_exact_del_table_entry_by_id(struct rvu *rvu, u32 seq_id)
1198 {
1199 struct npc_exact_table_entry *entry = NULL;
1200 struct npc_exact_table *table;
1201 bool disable_cam = false;
1202 u32 drop_mcam_idx = -1;
1203 int *cnt;
1204 bool rc;
1205
1206 table = rvu->hw->table;
1207
1208 mutex_lock(&table->lock);
1209
1210
1211 entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, seq_id);
1212 if (!entry) {
1213 dev_dbg(rvu->dev, "%s: failed to find entry for id=%d\n", __func__, seq_id);
1214 mutex_unlock(&table->lock);
1215 return -ENODATA;
1216 }
1217
1218 cnt = (entry->opc_type == NPC_EXACT_OPC_CAM) ? &table->cam_tbl_entry_cnt :
1219 &table->mem_tbl_entry_cnt;
1220
1221
1222 list_del_init(&entry->list);
1223 list_del_init(&entry->glist);
1224
1225 (*cnt)--;
1226
1227 rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, entry->cgx_id,
1228 entry->lmac_id, &drop_mcam_idx, NULL, NULL, NULL);
1229 if (!rc) {
1230 dev_dbg(rvu->dev, "%s: failed to retrieve drop info for id=0x%x\n",
1231 __func__, seq_id);
1232 mutex_unlock(&table->lock);
1233 return -ENODATA;
1234 }
1235
1236 if (entry->cmd)
1237 __rvu_npc_exact_cmd_rules_cnt_update(rvu, drop_mcam_idx, -1, &disable_cam);
1238
1239
1240 if (disable_cam) {
1241 rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, false);
1242 dev_dbg(rvu->dev, "%s: Disabling mcam idx %d\n",
1243 __func__, drop_mcam_idx);
1244 }
1245
1246 mutex_unlock(&table->lock);
1247
1248 rvu_npc_exact_dealloc_table_entry(rvu, entry->opc_type, entry->ways, entry->index);
1249
1250 rvu_npc_exact_free_id(rvu, seq_id);
1251
1252 dev_dbg(rvu->dev, "%s: delete entry success for id=0x%x, mca=%pM\n",
1253 __func__, seq_id, entry->mac);
1254 kfree(entry);
1255
1256 return 0;
1257 }
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276 static int rvu_npc_exact_add_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_id, u8 *mac,
1277 u16 chan, u8 ctype, u32 *seq_id, bool cmd,
1278 u32 mcam_idx, u16 pcifunc)
1279 {
1280 int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1281 enum npc_exact_opc_type opc_type;
1282 bool enable_cam = false;
1283 u32 drop_mcam_idx;
1284 u32 index;
1285 u64 mdata;
1286 bool rc;
1287 int err;
1288 u8 ways;
1289
1290 ctype = 0;
1291
1292 err = rvu_npc_exact_alloc_table_entry(rvu, mac, chan, ctype, &index, &ways, &opc_type);
1293 if (err) {
1294 dev_err(rvu->dev, "%s: Could not alloc in exact match table\n", __func__);
1295 return err;
1296 }
1297
1298
1299 mdata = rvu_exact_prepare_table_entry(rvu, true, ctype, chan, mac);
1300
1301 if (opc_type == NPC_EXACT_OPC_CAM)
1302 rvu_npc_exact_cam_table_write(rvu, blkaddr, index, mdata);
1303 else
1304 rvu_npc_exact_mem_table_write(rvu, blkaddr, ways, index, mdata);
1305
1306
1307 err = rvu_npc_exact_add_to_list(rvu, opc_type, ways, index, cgx_id, lmac_id,
1308 mac, chan, ctype, seq_id, cmd, mcam_idx, pcifunc);
1309 if (err) {
1310 rvu_npc_exact_dealloc_table_entry(rvu, opc_type, ways, index);
1311 dev_err(rvu->dev, "%s: could not add to exact match table\n", __func__);
1312 return err;
1313 }
1314
1315 rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, cgx_id, lmac_id,
1316 &drop_mcam_idx, NULL, NULL, NULL);
1317 if (!rc) {
1318 rvu_npc_exact_dealloc_table_entry(rvu, opc_type, ways, index);
1319 dev_dbg(rvu->dev, "%s: failed to get drop rule info cgx=%d lmac=%d\n",
1320 __func__, cgx_id, lmac_id);
1321 return -EINVAL;
1322 }
1323
1324 if (cmd)
1325 __rvu_npc_exact_cmd_rules_cnt_update(rvu, drop_mcam_idx, 1, &enable_cam);
1326
1327
1328 if (enable_cam) {
1329 rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, true);
1330 dev_dbg(rvu->dev, "%s: Enabling mcam idx %d\n",
1331 __func__, drop_mcam_idx);
1332 }
1333
1334 dev_dbg(rvu->dev,
1335 "%s: Successfully added entry (index=%d, dmac=%pM, ways=%d opc_type=%d\n",
1336 __func__, index, mac, ways, opc_type);
1337
1338 return 0;
1339 }
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354 static int rvu_npc_exact_update_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_id,
1355 u8 *old_mac, u8 *new_mac, u32 *seq_id)
1356 {
1357 int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1358 struct npc_exact_table_entry *entry;
1359 struct npc_exact_table *table;
1360 u32 hash_index;
1361 u64 mdata;
1362
1363 table = rvu->hw->table;
1364
1365 mutex_lock(&table->lock);
1366
1367
1368 entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, *seq_id);
1369 if (!entry) {
1370 mutex_unlock(&table->lock);
1371 dev_dbg(rvu->dev,
1372 "%s: failed to find entry for cgx_id=%d lmac_id=%d old_mac=%pM\n",
1373 __func__, cgx_id, lmac_id, old_mac);
1374 return -ENODATA;
1375 }
1376
1377
1378
1379
1380 if (entry->opc_type == NPC_EXACT_OPC_MEM) {
1381 hash_index = rvu_exact_calculate_hash(rvu, entry->chan, entry->ctype,
1382 new_mac, table->mem_table.mask,
1383 table->mem_table.depth);
1384 if (hash_index != entry->index) {
1385 dev_dbg(rvu->dev,
1386 "%s: Update failed due to index mismatch(new=0x%x, old=%x)\n",
1387 __func__, hash_index, entry->index);
1388 mutex_unlock(&table->lock);
1389 return -EINVAL;
1390 }
1391 }
1392
1393 mdata = rvu_exact_prepare_table_entry(rvu, true, entry->ctype, entry->chan, new_mac);
1394
1395 if (entry->opc_type == NPC_EXACT_OPC_MEM)
1396 rvu_npc_exact_mem_table_write(rvu, blkaddr, entry->ways, entry->index, mdata);
1397 else
1398 rvu_npc_exact_cam_table_write(rvu, blkaddr, entry->index, mdata);
1399
1400
1401 ether_addr_copy(entry->mac, new_mac);
1402 *seq_id = entry->seq_id;
1403
1404 dev_dbg(rvu->dev,
1405 "%s: Successfully updated entry (index=%d, dmac=%pM, ways=%d opc_type=%d\n",
1406 __func__, entry->index, entry->mac, entry->ways, entry->opc_type);
1407
1408 dev_dbg(rvu->dev, "%s: Successfully updated entry (old mac=%pM new_mac=%pM\n",
1409 __func__, old_mac, new_mac);
1410
1411 mutex_unlock(&table->lock);
1412 return 0;
1413 }
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425 int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc)
1426 {
1427 struct npc_exact_table *table;
1428 int pf = rvu_get_pf(pcifunc);
1429 u8 cgx_id, lmac_id;
1430 u32 drop_mcam_idx;
1431 bool *promisc;
1432 bool rc;
1433 u32 cnt;
1434
1435 table = rvu->hw->table;
1436
1437 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1438 rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, cgx_id, lmac_id,
1439 &drop_mcam_idx, NULL, NULL, NULL);
1440 if (!rc) {
1441 dev_dbg(rvu->dev, "%s: failed to get drop rule info cgx=%d lmac=%d\n",
1442 __func__, cgx_id, lmac_id);
1443 return -EINVAL;
1444 }
1445
1446 mutex_lock(&table->lock);
1447 promisc = &table->promisc_mode[drop_mcam_idx];
1448
1449 if (!*promisc) {
1450 mutex_unlock(&table->lock);
1451 dev_dbg(rvu->dev, "%s: Err Already promisc mode disabled (cgx=%d lmac=%d)\n",
1452 __func__, cgx_id, lmac_id);
1453 return LMAC_AF_ERR_INVALID_PARAM;
1454 }
1455 *promisc = false;
1456 cnt = __rvu_npc_exact_cmd_rules_cnt_update(rvu, drop_mcam_idx, 0, NULL);
1457 mutex_unlock(&table->lock);
1458
1459
1460 if (!cnt)
1461 rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, false);
1462 else
1463 rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, !*promisc);
1464
1465 dev_dbg(rvu->dev, "%s: disabled promisc mode (cgx=%d lmac=%d, cnt=%d)\n",
1466 __func__, cgx_id, lmac_id, cnt);
1467 return 0;
1468 }
1469
1470
1471
1472
1473
1474
1475
1476 int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc)
1477 {
1478 struct npc_exact_table *table;
1479 int pf = rvu_get_pf(pcifunc);
1480 u8 cgx_id, lmac_id;
1481 u32 drop_mcam_idx;
1482 bool *promisc;
1483 bool rc;
1484 u32 cnt;
1485
1486 table = rvu->hw->table;
1487
1488 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1489 rc = rvu_npc_exact_get_drop_rule_info(rvu, NIX_INTF_TYPE_CGX, cgx_id, lmac_id,
1490 &drop_mcam_idx, NULL, NULL, NULL);
1491 if (!rc) {
1492 dev_dbg(rvu->dev, "%s: failed to get drop rule info cgx=%d lmac=%d\n",
1493 __func__, cgx_id, lmac_id);
1494 return -EINVAL;
1495 }
1496
1497 mutex_lock(&table->lock);
1498 promisc = &table->promisc_mode[drop_mcam_idx];
1499
1500 if (*promisc) {
1501 mutex_unlock(&table->lock);
1502 dev_dbg(rvu->dev, "%s: Already in promisc mode (cgx=%d lmac=%d)\n",
1503 __func__, cgx_id, lmac_id);
1504 return LMAC_AF_ERR_INVALID_PARAM;
1505 }
1506 *promisc = true;
1507 cnt = __rvu_npc_exact_cmd_rules_cnt_update(rvu, drop_mcam_idx, 0, NULL);
1508 mutex_unlock(&table->lock);
1509
1510
1511 if (!cnt)
1512 rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, false);
1513 else
1514 rvu_npc_enable_mcam_by_entry_index(rvu, drop_mcam_idx, NIX_INTF_RX, !*promisc);
1515
1516 dev_dbg(rvu->dev, "%s: Enabled promisc mode (cgx=%d lmac=%d cnt=%d)\n",
1517 __func__, cgx_id, lmac_id, cnt);
1518 return 0;
1519 }
1520
1521
1522
1523
1524
1525
1526
1527
1528 int rvu_npc_exact_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req,
1529 struct msg_rsp *rsp)
1530 {
1531 int pf = rvu_get_pf(req->hdr.pcifunc);
1532 u32 seq_id = req->index;
1533 struct rvu_pfvf *pfvf;
1534 u8 cgx_id, lmac_id;
1535 int rc;
1536
1537 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1538
1539 pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
1540
1541 rc = rvu_npc_exact_del_table_entry_by_id(rvu, seq_id);
1542 if (rc) {
1543
1544 dev_err(rvu->dev, "%s MAC (%pM) del PF=%d failed\n", __func__, pfvf->mac_addr, pf);
1545 return 0;
1546 }
1547
1548 dev_dbg(rvu->dev, "%s MAC (%pM) del PF=%d success (seq_id=%u)\n",
1549 __func__, pfvf->mac_addr, pf, seq_id);
1550 return 0;
1551 }
1552
1553
1554
1555
1556
1557
1558
1559
1560 int rvu_npc_exact_mac_addr_update(struct rvu *rvu,
1561 struct cgx_mac_addr_update_req *req,
1562 struct cgx_mac_addr_update_rsp *rsp)
1563 {
1564 int pf = rvu_get_pf(req->hdr.pcifunc);
1565 struct npc_exact_table_entry *entry;
1566 struct npc_exact_table *table;
1567 struct rvu_pfvf *pfvf;
1568 u32 seq_id, mcam_idx;
1569 u8 old_mac[ETH_ALEN];
1570 u8 cgx_id, lmac_id;
1571 int rc;
1572
1573 if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
1574 return LMAC_AF_ERR_PERM_DENIED;
1575
1576 dev_dbg(rvu->dev, "%s: Update request for seq_id=%d, mac=%pM\n",
1577 __func__, req->index, req->mac_addr);
1578
1579 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1580
1581 pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
1582
1583 table = rvu->hw->table;
1584
1585 mutex_lock(&table->lock);
1586
1587
1588 entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, req->index);
1589 if (!entry) {
1590 dev_err(rvu->dev, "%s: failed to find entry for id=0x%x\n", __func__, req->index);
1591 mutex_unlock(&table->lock);
1592 return LMAC_AF_ERR_EXACT_MATCH_TBL_LOOK_UP_FAILED;
1593 }
1594 ether_addr_copy(old_mac, entry->mac);
1595 seq_id = entry->seq_id;
1596 mcam_idx = entry->mcam_idx;
1597 mutex_unlock(&table->lock);
1598
1599 rc = rvu_npc_exact_update_table_entry(rvu, cgx_id, lmac_id, old_mac,
1600 req->mac_addr, &seq_id);
1601 if (!rc) {
1602 rsp->index = seq_id;
1603 dev_dbg(rvu->dev, "%s mac:%pM (pfvf:%pM default:%pM) update to PF=%d success\n",
1604 __func__, req->mac_addr, pfvf->mac_addr, pfvf->default_mac, pf);
1605 ether_addr_copy(pfvf->mac_addr, req->mac_addr);
1606 return 0;
1607 }
1608
1609
1610 rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
1611 if (rc) {
1612
1613 dev_dbg(rvu->dev, "%s MAC (%pM) del PF=%d failed\n", __func__,
1614 pfvf->mac_addr, pf);
1615 }
1616
1617 rc = rvu_npc_exact_add_table_entry(rvu, cgx_id, lmac_id, req->mac_addr,
1618 pfvf->rx_chan_base, 0, &seq_id, true,
1619 mcam_idx, req->hdr.pcifunc);
1620 if (rc) {
1621 dev_err(rvu->dev, "%s MAC (%pM) add PF=%d failed\n", __func__,
1622 req->mac_addr, pf);
1623 return LMAC_AF_ERR_EXACT_MATCH_TBL_ADD_FAILED;
1624 }
1625
1626 rsp->index = seq_id;
1627 dev_dbg(rvu->dev,
1628 "%s MAC (new:%pM, old=%pM default:%pM) del and add to PF=%d success (seq_id=%u)\n",
1629 __func__, req->mac_addr, pfvf->mac_addr, pfvf->default_mac, pf, seq_id);
1630
1631 ether_addr_copy(pfvf->mac_addr, req->mac_addr);
1632 return 0;
1633 }
1634
1635
1636
1637
1638
1639
1640
1641
1642 int rvu_npc_exact_mac_addr_add(struct rvu *rvu,
1643 struct cgx_mac_addr_add_req *req,
1644 struct cgx_mac_addr_add_rsp *rsp)
1645 {
1646 int pf = rvu_get_pf(req->hdr.pcifunc);
1647 struct rvu_pfvf *pfvf;
1648 u8 cgx_id, lmac_id;
1649 int rc = 0;
1650 u32 seq_id;
1651
1652 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1653 pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
1654
1655 rc = rvu_npc_exact_add_table_entry(rvu, cgx_id, lmac_id, req->mac_addr,
1656 pfvf->rx_chan_base, 0, &seq_id,
1657 true, -1, req->hdr.pcifunc);
1658
1659 if (!rc) {
1660 rsp->index = seq_id;
1661 dev_dbg(rvu->dev, "%s MAC (%pM) add to PF=%d success (seq_id=%u)\n",
1662 __func__, req->mac_addr, pf, seq_id);
1663 return 0;
1664 }
1665
1666 dev_err(rvu->dev, "%s MAC (%pM) add to PF=%d failed\n", __func__,
1667 req->mac_addr, pf);
1668 return LMAC_AF_ERR_EXACT_MATCH_TBL_ADD_FAILED;
1669 }
1670
1671
1672
1673
1674
1675
1676
1677
1678 int rvu_npc_exact_mac_addr_del(struct rvu *rvu,
1679 struct cgx_mac_addr_del_req *req,
1680 struct msg_rsp *rsp)
1681 {
1682 int pf = rvu_get_pf(req->hdr.pcifunc);
1683 int rc;
1684
1685 rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
1686 if (!rc) {
1687 dev_dbg(rvu->dev, "%s del to PF=%d success (seq_id=%u)\n",
1688 __func__, pf, req->index);
1689 return 0;
1690 }
1691
1692 dev_err(rvu->dev, "%s del to PF=%d failed (seq_id=%u)\n",
1693 __func__, pf, req->index);
1694 return LMAC_AF_ERR_EXACT_MATCH_TBL_DEL_FAILED;
1695 }
1696
1697
1698
1699
1700
1701
1702
1703
1704 int rvu_npc_exact_mac_addr_set(struct rvu *rvu, struct cgx_mac_addr_set_or_get *req,
1705 struct cgx_mac_addr_set_or_get *rsp)
1706 {
1707 int pf = rvu_get_pf(req->hdr.pcifunc);
1708 u32 seq_id = req->index;
1709 struct rvu_pfvf *pfvf;
1710 u8 cgx_id, lmac_id;
1711 u32 mcam_idx = -1;
1712 int rc, nixlf;
1713
1714 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
1715
1716 pfvf = &rvu->pf[pf];
1717
1718
1719
1720
1721 rc = rvu_npc_exact_update_table_entry(rvu, cgx_id, lmac_id, pfvf->mac_addr,
1722 req->mac_addr, &seq_id);
1723 if (!rc) {
1724 rsp->index = seq_id;
1725 ether_addr_copy(pfvf->mac_addr, req->mac_addr);
1726 ether_addr_copy(rsp->mac_addr, req->mac_addr);
1727 dev_dbg(rvu->dev, "%s MAC (%pM) update to PF=%d success\n",
1728 __func__, req->mac_addr, pf);
1729 return 0;
1730 }
1731
1732
1733 rc = rvu_npc_exact_del_table_entry_by_id(rvu, req->index);
1734 if (rc) {
1735 dev_dbg(rvu->dev, "%s MAC (%pM) del PF=%d failed\n",
1736 __func__, pfvf->mac_addr, pf);
1737 }
1738
1739
1740 rc = nix_get_nixlf(rvu, req->hdr.pcifunc, &nixlf, NULL);
1741 if (!rc) {
1742 mcam_idx = npc_get_nixlf_mcam_index(&rvu->hw->mcam, req->hdr.pcifunc,
1743 nixlf, NIXLF_UCAST_ENTRY);
1744 }
1745
1746 rc = rvu_npc_exact_add_table_entry(rvu, cgx_id, lmac_id, req->mac_addr,
1747 pfvf->rx_chan_base, 0, &seq_id,
1748 true, mcam_idx, req->hdr.pcifunc);
1749 if (rc) {
1750 dev_err(rvu->dev, "%s MAC (%pM) add PF=%d failed\n",
1751 __func__, req->mac_addr, pf);
1752 return LMAC_AF_ERR_EXACT_MATCH_TBL_ADD_FAILED;
1753 }
1754
1755 rsp->index = seq_id;
1756 ether_addr_copy(rsp->mac_addr, req->mac_addr);
1757 ether_addr_copy(pfvf->mac_addr, req->mac_addr);
1758 dev_dbg(rvu->dev,
1759 "%s MAC (%pM) del and add to PF=%d success (seq_id=%u)\n",
1760 __func__, req->mac_addr, pf, seq_id);
1761 return 0;
1762 }
1763
1764
1765
1766
1767
1768
1769 bool rvu_npc_exact_can_disable_feature(struct rvu *rvu)
1770 {
1771 struct npc_exact_table *table = rvu->hw->table;
1772 bool empty;
1773
1774 if (!rvu->hw->cap.npc_exact_match_enabled)
1775 return false;
1776
1777 mutex_lock(&table->lock);
1778 empty = list_empty(&table->lhead_gbl);
1779 mutex_unlock(&table->lock);
1780
1781 return empty;
1782 }
1783
1784
1785
1786
1787
1788 void rvu_npc_exact_disable_feature(struct rvu *rvu)
1789 {
1790 rvu->hw->cap.npc_exact_match_enabled = false;
1791 }
1792
1793
1794
1795
1796
1797
1798 void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc)
1799 {
1800 struct npc_exact_table *table = rvu->hw->table;
1801 struct npc_exact_table_entry *tmp, *iter;
1802 u32 seq_id;
1803
1804 mutex_lock(&table->lock);
1805 list_for_each_entry_safe(iter, tmp, &table->lhead_gbl, glist) {
1806 if (pcifunc != iter->pcifunc)
1807 continue;
1808
1809 seq_id = iter->seq_id;
1810 dev_dbg(rvu->dev, "%s: resetting pcifun=%d seq_id=%u\n", __func__,
1811 pcifunc, seq_id);
1812
1813 mutex_unlock(&table->lock);
1814 rvu_npc_exact_del_table_entry_by_id(rvu, seq_id);
1815 mutex_lock(&table->lock);
1816 }
1817 mutex_unlock(&table->lock);
1818 }
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828 int rvu_npc_exact_init(struct rvu *rvu)
1829 {
1830 u64 bcast_mcast_val, bcast_mcast_mask;
1831 struct npc_exact_table *table;
1832 u64 exact_val, exact_mask;
1833 u64 chan_val, chan_mask;
1834 u8 cgx_id, lmac_id;
1835 u32 *drop_mcam_idx;
1836 u16 max_lmac_cnt;
1837 u64 npc_const3;
1838 int table_size;
1839 int blkaddr;
1840 u16 pcifunc;
1841 int err, i;
1842 u64 cfg;
1843 bool rc;
1844
1845
1846
1847
1848 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1849 if (blkaddr < 0) {
1850 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
1851 return -EINVAL;
1852 }
1853
1854
1855 npc_const3 = rvu_read64(rvu, blkaddr, NPC_AF_CONST3);
1856 if (!(npc_const3 & BIT_ULL(62))) {
1857 dev_info(rvu->dev, "%s: No support for exact match support\n",
1858 __func__);
1859 return 0;
1860 }
1861
1862
1863 cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX));
1864 if (!(cfg & NPC_EXACT_NIBBLE_HIT)) {
1865 dev_info(rvu->dev, "%s: NPC exact match nibble not enabled in KEX profile\n",
1866 __func__);
1867 return 0;
1868 }
1869
1870
1871 rvu->hw->cap.npc_exact_match_enabled = true;
1872
1873 table = kmalloc(sizeof(*table), GFP_KERNEL);
1874 if (!table)
1875 return -ENOMEM;
1876
1877 dev_dbg(rvu->dev, "%s: Memory allocation for table success\n", __func__);
1878 memset(table, 0, sizeof(*table));
1879 rvu->hw->table = table;
1880
1881
1882 table->mem_table.depth = FIELD_GET(GENMASK_ULL(31, 24), npc_const3);
1883 table->mem_table.ways = FIELD_GET(GENMASK_ULL(19, 16), npc_const3);
1884 table->cam_table.depth = FIELD_GET(GENMASK_ULL(15, 0), npc_const3);
1885
1886 dev_dbg(rvu->dev, "%s: NPC exact match 4way_2k table(ways=%d, depth=%d)\n",
1887 __func__, table->mem_table.ways, table->cam_table.depth);
1888
1889
1890
1891
1892 if ((table->mem_table.depth & (table->mem_table.depth - 1)) != 0) {
1893 dev_err(rvu->dev,
1894 "%s: NPC exact match 4way_2k table depth(%d) is not square of 2\n",
1895 __func__, table->mem_table.depth);
1896 return -EINVAL;
1897 }
1898
1899 table_size = table->mem_table.depth * table->mem_table.ways;
1900
1901
1902 table->mem_table.bmap = devm_kcalloc(rvu->dev, BITS_TO_LONGS(table_size),
1903 sizeof(long), GFP_KERNEL);
1904 if (!table->mem_table.bmap)
1905 return -ENOMEM;
1906
1907 dev_dbg(rvu->dev, "%s: Allocated bitmap for 4way 2K entry table\n", __func__);
1908
1909
1910 table->cam_table.bmap = devm_kcalloc(rvu->dev, 1, sizeof(long), GFP_KERNEL);
1911
1912 if (!table->cam_table.bmap)
1913 return -ENOMEM;
1914
1915 dev_dbg(rvu->dev, "%s: Allocated bitmap for 32 entry cam\n", __func__);
1916
1917 table->tot_ids = (table->mem_table.depth * table->mem_table.ways) + table->cam_table.depth;
1918 table->id_bmap = devm_kcalloc(rvu->dev, BITS_TO_LONGS(table->tot_ids),
1919 table->tot_ids, GFP_KERNEL);
1920
1921 if (!table->id_bmap)
1922 return -ENOMEM;
1923
1924 dev_dbg(rvu->dev, "%s: Allocated bitmap for id map (total=%d)\n",
1925 __func__, table->tot_ids);
1926
1927
1928
1929
1930
1931 for (i = 0; i < NPC_EXACT_TBL_MAX_WAYS; i++)
1932 INIT_LIST_HEAD(&table->lhead_mem_tbl_entry[i]);
1933
1934 INIT_LIST_HEAD(&table->lhead_cam_tbl_entry);
1935 INIT_LIST_HEAD(&table->lhead_gbl);
1936
1937 mutex_init(&table->lock);
1938
1939 rvu_exact_config_secret_key(rvu);
1940 rvu_exact_config_search_key(rvu);
1941
1942 rvu_exact_config_table_mask(rvu);
1943 rvu_exact_config_result_ctrl(rvu, table->mem_table.depth);
1944
1945
1946
1947
1948 exact_val = !NPC_EXACT_RESULT_HIT;
1949 exact_mask = NPC_EXACT_RESULT_HIT;
1950
1951
1952
1953
1954 bcast_mcast_val = 0b0000;
1955 bcast_mcast_mask = 0b0011;
1956
1957
1958 drop_mcam_idx = &table->num_drop_rules;
1959
1960 max_lmac_cnt = rvu->cgx_cnt_max * MAX_LMAC_PER_CGX + PF_CGXMAP_BASE;
1961 for (i = PF_CGXMAP_BASE; i < max_lmac_cnt; i++) {
1962 if (rvu->pf2cgxlmac_map[i] == 0xFF)
1963 continue;
1964
1965 rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[i], &cgx_id, &lmac_id);
1966
1967 rc = rvu_npc_exact_calc_drop_rule_chan_and_mask(rvu, NIX_INTF_TYPE_CGX, cgx_id,
1968 lmac_id, &chan_val, &chan_mask);
1969 if (!rc) {
1970 dev_err(rvu->dev,
1971 "%s: failed, info chan_val=0x%llx chan_mask=0x%llx rule_id=%d\n",
1972 __func__, chan_val, chan_mask, *drop_mcam_idx);
1973 return -EINVAL;
1974 }
1975
1976
1977 pcifunc = RVU_PFFUNC(i, 0);
1978
1979 dev_dbg(rvu->dev,
1980 "%s:Drop rule cgx=%d lmac=%d chan(val=0x%llx, mask=0x%llx\n",
1981 __func__, cgx_id, lmac_id, chan_val, chan_mask);
1982
1983 rc = rvu_npc_exact_save_drop_rule_chan_and_mask(rvu, table->num_drop_rules,
1984 chan_val, chan_mask, pcifunc);
1985 if (!rc) {
1986 dev_err(rvu->dev,
1987 "%s: failed to set drop info for cgx=%d, lmac=%d, chan=%llx\n",
1988 __func__, cgx_id, lmac_id, chan_val);
1989 return -EINVAL;
1990 }
1991
1992 err = npc_install_mcam_drop_rule(rvu, *drop_mcam_idx,
1993 &table->counter_idx[*drop_mcam_idx],
1994 chan_val, chan_mask,
1995 exact_val, exact_mask,
1996 bcast_mcast_val, bcast_mcast_mask);
1997 if (err) {
1998 dev_err(rvu->dev,
1999 "failed to configure drop rule (cgx=%d lmac=%d)\n",
2000 cgx_id, lmac_id);
2001 return err;
2002 }
2003
2004 (*drop_mcam_idx)++;
2005 }
2006
2007 dev_info(rvu->dev, "initialized exact match table successfully\n");
2008 return 0;
2009 }