1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell RVU Admin Function driver
4 * Copyright (C) 2022 Marvell.
8 #include <linux/bitfield.h>
9 #include <linux/module.h>
10 #include <linux/pci.h>
11 #include <linux/firmware.h>
12 #include <linux/stddef.h>
13 #include <linux/debugfs.h>
14 #include <linux/bitfield.h>
16 #include "rvu_struct.h"
21 #include "rvu_npc_hash.h"
22 #include "rvu_npc_fs.h"
23 #include "rvu_npc_hash.h"
25 static u64 rvu_npc_wide_extract(const u64 input[], size_t start_bit,
28 const u64 mask = ~(u64)((~(__uint128_t)0) << width_bits);
29 const size_t msb = start_bit + width_bits - 1;
30 const size_t lword = start_bit >> 6;
31 const size_t uword = msb >> 6;
36 return (input[lword] >> (start_bit & 63)) & mask;
38 lbits = 64 - (start_bit & 63);
40 lo = (input[lword] >> (start_bit & 63));
41 return ((hi << lbits) | lo) & mask;
44 static void rvu_npc_lshift_key(u64 *key, size_t key_bit_len)
46 u64 prev_orig_word = 0;
47 u64 cur_orig_word = 0;
48 size_t extra = key_bit_len % 64;
49 size_t max_idx = key_bit_len / 64;
55 for (i = 0; i < max_idx; i++) {
56 cur_orig_word = key[i];
58 key[i] |= ((prev_orig_word >> 63) & 0x1);
59 prev_orig_word = cur_orig_word;
63 static u32 rvu_npc_toeplitz_hash(const u64 *data, u64 *key, size_t data_bit_len,
70 for (i = data_bit_len - 1; i >= 0; i--) {
71 temp_data = (data[i / 64]);
72 temp_data = temp_data >> (i % 64);
75 hash_out ^= (u32)(rvu_npc_wide_extract(key, key_bit_len - 32, 32));
77 rvu_npc_lshift_key(key, key_bit_len);
83 u32 npc_field_hash_calc(u64 *ldata, struct npc_mcam_kex_hash *mkex_hash,
84 u64 *secret_key, u8 intf, u8 hash_idx)
90 hash_key[0] = secret_key[1] << 31;
91 hash_key[0] |= secret_key[2];
92 hash_key[1] = secret_key[1] >> 33;
93 hash_key[1] |= secret_key[0] << 31;
94 hash_key[2] = secret_key[0] >> 33;
96 data_padded[0] = mkex_hash->hash_mask[intf][hash_idx][0] & ldata[0];
97 data_padded[1] = mkex_hash->hash_mask[intf][hash_idx][1] & ldata[1];
98 field_hash = rvu_npc_toeplitz_hash(data_padded, hash_key, 128, 159);
100 field_hash &= mkex_hash->hash_ctrl[intf][hash_idx] >> 32;
101 field_hash |= mkex_hash->hash_ctrl[intf][hash_idx];
105 static u64 npc_update_use_hash(int lt, int ld)
111 /* Update use_hash(bit-20) and bytesm1 (bit-16:19)
114 cfg = KEX_LD_CFG_USE_HASH(0x1, 0x03,
123 static void npc_program_mkex_hash_rx(struct rvu *rvu, int blkaddr,
126 struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
127 int lid, lt, ld, hash_cnt = 0;
129 if (is_npc_intf_tx(intf))
132 /* Program HASH_CFG */
133 for (lid = 0; lid < NPC_MAX_LID; lid++) {
134 for (lt = 0; lt < NPC_MAX_LT; lt++) {
135 for (ld = 0; ld < NPC_MAX_LD; ld++) {
136 if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
137 u64 cfg = npc_update_use_hash(lt, ld);
140 if (hash_cnt == NPC_MAX_HASH)
143 /* Set updated KEX configuration */
144 SET_KEX_LD(intf, lid, lt, ld, cfg);
145 /* Set HASH configuration */
146 SET_KEX_LD_HASH(intf, ld,
147 mkex_hash->hash[intf][ld]);
148 SET_KEX_LD_HASH_MASK(intf, ld, 0,
149 mkex_hash->hash_mask[intf][ld][0]);
150 SET_KEX_LD_HASH_MASK(intf, ld, 1,
151 mkex_hash->hash_mask[intf][ld][1]);
152 SET_KEX_LD_HASH_CTRL(intf, ld,
153 mkex_hash->hash_ctrl[intf][ld]);
160 static void npc_program_mkex_hash_tx(struct rvu *rvu, int blkaddr,
163 struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
164 int lid, lt, ld, hash_cnt = 0;
166 if (is_npc_intf_rx(intf))
169 /* Program HASH_CFG */
170 for (lid = 0; lid < NPC_MAX_LID; lid++) {
171 for (lt = 0; lt < NPC_MAX_LT; lt++) {
172 for (ld = 0; ld < NPC_MAX_LD; ld++)
173 if (mkex_hash->lid_lt_ld_hash_en[intf][lid][lt][ld]) {
174 u64 cfg = npc_update_use_hash(lt, ld);
177 if (hash_cnt == NPC_MAX_HASH)
180 /* Set updated KEX configuration */
181 SET_KEX_LD(intf, lid, lt, ld, cfg);
182 /* Set HASH configuration */
183 SET_KEX_LD_HASH(intf, ld,
184 mkex_hash->hash[intf][ld]);
185 SET_KEX_LD_HASH_MASK(intf, ld, 0,
186 mkex_hash->hash_mask[intf][ld][0]);
187 SET_KEX_LD_HASH_MASK(intf, ld, 1,
188 mkex_hash->hash_mask[intf][ld][1]);
189 SET_KEX_LD_HASH_CTRL(intf, ld,
190 mkex_hash->hash_ctrl[intf][ld]);
192 if (hash_cnt == NPC_MAX_HASH)
199 void npc_config_secret_key(struct rvu *rvu, int blkaddr)
201 struct hw_cap *hwcap = &rvu->hw->cap;
202 struct rvu_hwinfo *hw = rvu->hw;
205 if (!hwcap->npc_hash_extract) {
206 dev_info(rvu->dev, "HW does not support secret key configuration\n");
210 for (intf = 0; intf < hw->npc_intfs; intf++) {
211 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY0(intf),
212 RVU_NPC_HASH_SECRET_KEY0);
213 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf),
214 RVU_NPC_HASH_SECRET_KEY1);
215 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf),
216 RVU_NPC_HASH_SECRET_KEY2);
220 void npc_program_mkex_hash(struct rvu *rvu, int blkaddr)
222 struct hw_cap *hwcap = &rvu->hw->cap;
223 struct rvu_hwinfo *hw = rvu->hw;
226 if (!hwcap->npc_hash_extract) {
227 dev_dbg(rvu->dev, "Field hash extract feature is not supported\n");
231 for (intf = 0; intf < hw->npc_intfs; intf++) {
232 npc_program_mkex_hash_rx(rvu, blkaddr, intf);
233 npc_program_mkex_hash_tx(rvu, blkaddr, intf);
237 void npc_update_field_hash(struct rvu *rvu, u8 intf,
238 struct mcam_entry *entry,
241 struct flow_msg *pkt,
242 struct flow_msg *mask,
243 struct flow_msg *opkt,
244 struct flow_msg *omask)
246 struct npc_mcam_kex_hash *mkex_hash = rvu->kpu.mkex_hash;
247 struct npc_get_secret_key_req req;
248 struct npc_get_secret_key_rsp rsp;
253 if (!rvu->hw->cap.npc_hash_extract) {
254 dev_dbg(rvu->dev, "%s: Field hash extract feature is not supported\n", __func__);
259 rvu_mbox_handler_npc_get_secret_key(rvu, &req, &rsp);
261 for (hash_idx = 0; hash_idx < NPC_MAX_HASH; hash_idx++) {
262 cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_HASHX_CFG(intf, hash_idx));
263 if ((cfg & BIT_ULL(11)) && (cfg & BIT_ULL(12))) {
264 u8 lid = (cfg & GENMASK_ULL(10, 8)) >> 8;
265 u8 ltype = (cfg & GENMASK_ULL(7, 4)) >> 4;
266 u8 ltype_mask = cfg & GENMASK_ULL(3, 0);
268 if (mkex_hash->lid_lt_ld_hash_en[intf][lid][ltype][hash_idx]) {
269 switch (ltype & ltype_mask) {
270 /* If hash extract enabled is supported for IPv6 then
271 * 128 bit IPv6 source and destination addressed
272 * is hashed to 32 bit value.
275 if (features & BIT_ULL(NPC_SIP_IPV6)) {
276 u32 src_ip[IPV6_WORDS];
278 be32_to_cpu_array(src_ip, pkt->ip6src, IPV6_WORDS);
279 ldata[0] = (u64)src_ip[0] << 32 | src_ip[1];
280 ldata[1] = (u64)src_ip[2] << 32 | src_ip[3];
281 field_hash = npc_field_hash_calc(ldata,
286 npc_update_entry(rvu, NPC_SIP_IPV6, entry,
287 field_hash, 0, 32, 0, intf);
288 memcpy(&opkt->ip6src, &pkt->ip6src,
289 sizeof(pkt->ip6src));
290 memcpy(&omask->ip6src, &mask->ip6src,
291 sizeof(mask->ip6src));
295 if (features & BIT_ULL(NPC_DIP_IPV6)) {
296 u32 dst_ip[IPV6_WORDS];
298 be32_to_cpu_array(dst_ip, pkt->ip6dst, IPV6_WORDS);
299 ldata[0] = (u64)dst_ip[0] << 32 | dst_ip[1];
300 ldata[1] = (u64)dst_ip[2] << 32 | dst_ip[3];
301 field_hash = npc_field_hash_calc(ldata,
306 npc_update_entry(rvu, NPC_DIP_IPV6, entry,
307 field_hash, 0, 32, 0, intf);
308 memcpy(&opkt->ip6dst, &pkt->ip6dst,
309 sizeof(pkt->ip6dst));
310 memcpy(&omask->ip6dst, &mask->ip6dst,
311 sizeof(mask->ip6dst));
320 int rvu_mbox_handler_npc_get_secret_key(struct rvu *rvu,
321 struct npc_get_secret_key_req *req,
322 struct npc_get_secret_key_rsp *rsp)
324 u64 *secret_key = rsp->secret_key;
328 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
330 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
334 secret_key[0] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY0(intf));
335 secret_key[1] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY1(intf));
336 secret_key[2] = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_SECRET_KEY2(intf));
342 * rvu_npc_exact_mac2u64 - utility function to convert mac address to u64.
343 * @macaddr: MAC address.
344 * Returns mdata for exact match table.
346 static u64 rvu_npc_exact_mac2u64(u8 *mac_addr)
351 for (index = ETH_ALEN - 1; index >= 0; index--)
352 mac |= ((u64)*mac_addr++) << (8 * index);
358 * rvu_exact_prepare_mdata - Make mdata for mcam entry
360 * @chan: Channel number.
361 * @ctype: Channel Type.
364 static u64 rvu_exact_prepare_mdata(u8 *mac, u16 chan, u16 ctype, u64 mask)
366 u64 ldata = rvu_npc_exact_mac2u64(mac);
368 /* Please note that mask is 48bit which excludes chan and ctype.
369 * Increase mask bits if we need to include them as well.
371 ldata |= ((u64)chan << 48);
372 ldata |= ((u64)ctype << 60);
380 * rvu_exact_calculate_hash - calculate hash index to mem table.
381 * @rvu: resource virtualization unit.
382 * @chan: Channel number
383 * @ctype: Channel type.
386 * @table_depth: Depth of table.
388 u32 rvu_exact_calculate_hash(struct rvu *rvu, u16 chan, u16 ctype, u8 *mac,
389 u64 mask, u32 table_depth)
391 struct npc_exact_table *table = rvu->hw->table;
397 key_in[0] = RVU_NPC_HASH_SECRET_KEY0;
398 key_in[1] = RVU_NPC_HASH_SECRET_KEY2;
400 hash_key[0] = key_in[0] << 31;
401 hash_key[0] |= key_in[1];
402 hash_key[1] = key_in[0] >> 33;
404 ldata = rvu_exact_prepare_mdata(mac, chan, ctype, mask);
406 dev_dbg(rvu->dev, "%s: ldata=0x%llx hash_key0=0x%llx hash_key2=0x%llx\n", __func__,
407 ldata, hash_key[1], hash_key[0]);
408 hash = rvu_npc_toeplitz_hash(&ldata, (u64 *)hash_key, 64, 95);
410 hash &= table->mem_table.hash_mask;
411 hash += table->mem_table.hash_offset;
412 dev_dbg(rvu->dev, "%s: hash=%x\n", __func__, hash);
418 * rvu_npc_exact_alloc_mem_table_entry - find free entry in 4 way table.
419 * @rvu: resource virtualization unit.
420 * @way: Indicate way to table.
421 * @index: Hash index to 4 way table.
423 * Searches 4 way table using hash index. Returns 0 on success.
425 static int rvu_npc_exact_alloc_mem_table_entry(struct rvu *rvu, u8 *way,
426 u32 *index, unsigned int hash)
428 struct npc_exact_table *table;
431 table = rvu->hw->table;
432 depth = table->mem_table.depth;
434 /* Check all the 4 ways for a free slot. */
435 mutex_lock(&table->lock);
436 for (i = 0; i < table->mem_table.ways; i++) {
437 if (test_bit(hash + i * depth, table->mem_table.bmap))
440 set_bit(hash + i * depth, table->mem_table.bmap);
441 mutex_unlock(&table->lock);
443 dev_dbg(rvu->dev, "%s: mem table entry alloc success (way=%d index=%d)\n",
450 mutex_unlock(&table->lock);
452 dev_dbg(rvu->dev, "%s: No space in 4 way exact way, weight=%u\n", __func__,
453 bitmap_weight(table->mem_table.bmap, table->mem_table.depth));
458 * rvu_npc_exact_free_id - Free seq id from bitmat.
459 * @rvu: Resource virtualization unit.
460 * @seq_id: Sequence identifier to be freed.
462 static void rvu_npc_exact_free_id(struct rvu *rvu, u32 seq_id)
464 struct npc_exact_table *table;
466 table = rvu->hw->table;
467 mutex_lock(&table->lock);
468 clear_bit(seq_id, table->id_bmap);
469 mutex_unlock(&table->lock);
470 dev_dbg(rvu->dev, "%s: freed id %d\n", __func__, seq_id);
474 * rvu_npc_exact_alloc_id - Alloc seq id from bitmap.
475 * @rvu: Resource virtualization unit.
476 * @seq_id: Sequence identifier.
478 static bool rvu_npc_exact_alloc_id(struct rvu *rvu, u32 *seq_id)
480 struct npc_exact_table *table;
483 table = rvu->hw->table;
485 mutex_lock(&table->lock);
486 idx = find_first_zero_bit(table->id_bmap, table->tot_ids);
487 if (idx == table->tot_ids) {
488 mutex_unlock(&table->lock);
489 dev_err(rvu->dev, "%s: No space in id bitmap (%d)\n",
490 __func__, bitmap_weight(table->id_bmap, table->tot_ids));
495 /* Mark bit map to indicate that slot is used.*/
496 set_bit(idx, table->id_bmap);
497 mutex_unlock(&table->lock);
500 dev_dbg(rvu->dev, "%s: Allocated id (%d)\n", __func__, *seq_id);
506 * rvu_npc_exact_alloc_cam_table_entry - find free slot in fully associative table.
507 * @rvu: resource virtualization unit.
508 * @index: Index to exact CAM table.
510 static int rvu_npc_exact_alloc_cam_table_entry(struct rvu *rvu, int *index)
512 struct npc_exact_table *table;
515 table = rvu->hw->table;
517 mutex_lock(&table->lock);
518 idx = find_first_zero_bit(table->cam_table.bmap, table->cam_table.depth);
519 if (idx == table->cam_table.depth) {
520 mutex_unlock(&table->lock);
521 dev_info(rvu->dev, "%s: No space in exact cam table, weight=%u\n", __func__,
522 bitmap_weight(table->cam_table.bmap, table->cam_table.depth));
526 /* Mark bit map to indicate that slot is used.*/
527 set_bit(idx, table->cam_table.bmap);
528 mutex_unlock(&table->lock);
531 dev_dbg(rvu->dev, "%s: cam table entry alloc success (index=%d)\n",
537 * rvu_exact_prepare_table_entry - Data for exact match table entry.
538 * @rvu: Resource virtualization unit.
539 * @enable: Enable/Disable entry
540 * @ctype: Software defined channel type. Currently set as 0.
541 * @chan: Channel number.
542 * @mac_addr: Destination mac address.
543 * returns mdata for exact match table.
545 static u64 rvu_exact_prepare_table_entry(struct rvu *rvu, bool enable,
546 u8 ctype, u16 chan, u8 *mac_addr)
549 u64 ldata = rvu_npc_exact_mac2u64(mac_addr);
551 /* Enable or disable */
552 u64 mdata = FIELD_PREP(GENMASK_ULL(63, 63), !!enable);
555 mdata |= FIELD_PREP(GENMASK_ULL(61, 60), ctype);
558 mdata |= FIELD_PREP(GENMASK_ULL(59, 48), chan);
561 mdata |= FIELD_PREP(GENMASK_ULL(47, 0), ldata);
567 * rvu_exact_config_secret_key - Configure secret key.
568 * Returns mdata for exact match table.
570 static void rvu_exact_config_secret_key(struct rvu *rvu)
574 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
575 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET0(NIX_INTF_RX),
576 RVU_NPC_HASH_SECRET_KEY0);
578 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET1(NIX_INTF_RX),
579 RVU_NPC_HASH_SECRET_KEY1);
581 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_SECRET2(NIX_INTF_RX),
582 RVU_NPC_HASH_SECRET_KEY2);
586 * rvu_exact_config_search_key - Configure search key
587 * Returns mdata for exact match table.
589 static void rvu_exact_config_search_key(struct rvu *rvu)
594 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
597 reg_val = FIELD_PREP(GENMASK_ULL(39, 32), 0);
599 /* BYTESM1, number of bytes - 1 */
600 reg_val |= FIELD_PREP(GENMASK_ULL(18, 16), ETH_ALEN - 1);
602 /* Enable LID and set LID to NPC_LID_LA */
603 reg_val |= FIELD_PREP(GENMASK_ULL(11, 11), 1);
604 reg_val |= FIELD_PREP(GENMASK_ULL(10, 8), NPC_LID_LA);
606 /* Clear layer type based extraction */
609 reg_val |= FIELD_PREP(GENMASK_ULL(12, 12), 0);
611 /* Set LTYPE_MATCH to 0 */
612 reg_val |= FIELD_PREP(GENMASK_ULL(7, 4), 0);
614 /* Set LTYPE_MASK to 0 */
615 reg_val |= FIELD_PREP(GENMASK_ULL(3, 0), 0);
617 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_CFG(NIX_INTF_RX), reg_val);
621 * rvu_exact_config_result_ctrl - Set exact table hash control
622 * @rvu: Resource virtualization unit.
623 * @depth: Depth of Exact match table.
625 * Sets mask and offset for hash for mem table.
627 static void rvu_exact_config_result_ctrl(struct rvu *rvu, uint32_t depth)
632 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
634 /* Set mask. Note that depth is a power of 2 */
635 rvu->hw->table->mem_table.hash_mask = (depth - 1);
636 reg |= FIELD_PREP(GENMASK_ULL(42, 32), (depth - 1));
638 /* Set offset as 0 */
639 rvu->hw->table->mem_table.hash_offset = 0;
640 reg |= FIELD_PREP(GENMASK_ULL(10, 0), 0);
643 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_RESULT_CTL(NIX_INTF_RX), reg);
644 /* Store hash mask and offset for s/w algorithm */
648 * rvu_exact_config_table_mask - Set exact table mask.
649 * @rvu: Resource virtualization unit.
651 static void rvu_exact_config_table_mask(struct rvu *rvu)
656 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
658 /* Don't use Ctype */
659 mask |= FIELD_PREP(GENMASK_ULL(61, 60), 0);
662 mask |= GENMASK_ULL(59, 48);
665 mask |= GENMASK_ULL(47, 0);
667 /* Store mask for s/w hash calcualtion */
668 rvu->hw->table->mem_table.mask = mask;
670 /* Set mask for RX.*/
671 rvu_write64(rvu, blkaddr, NPC_AF_INTFX_EXACT_MASK(NIX_INTF_RX), mask);
675 * rvu_npc_exact_get_max_entries - Get total number of entries in table.
676 * @rvu: resource virtualization unit.
678 u32 rvu_npc_exact_get_max_entries(struct rvu *rvu)
680 struct npc_exact_table *table;
682 table = rvu->hw->table;
683 return table->tot_ids;
687 * rvu_npc_exact_has_match_table - Checks support for exact match.
688 * @rvu: resource virtualization unit.
691 bool rvu_npc_exact_has_match_table(struct rvu *rvu)
693 return rvu->hw->cap.npc_exact_match_enabled;
697 * __rvu_npc_exact_find_entry_by_seq_id - find entry by id
698 * @rvu: resource virtualization unit.
699 * @seq_id: Sequence identifier.
701 * Caller should acquire the lock.
703 static struct npc_exact_table_entry *
704 __rvu_npc_exact_find_entry_by_seq_id(struct rvu *rvu, u32 seq_id)
706 struct npc_exact_table *table = rvu->hw->table;
707 struct npc_exact_table_entry *entry = NULL;
708 struct list_head *lhead;
710 lhead = &table->lhead_gbl;
712 /* traverse to find the matching entry */
713 list_for_each_entry(entry, lhead, glist) {
714 if (entry->seq_id != seq_id)
724 * rvu_npc_exact_add_to_list - Add entry to list
725 * @rvu: resource virtualization unit.
726 * @opc_type: OPCODE to select MEM/CAM table.
727 * @ways: MEM table ways.
728 * @index: Index in MEM/CAM table.
729 * @cgx_id: CGX identifier.
730 * @lamc_id: LMAC identifier.
731 * @mac_addr: MAC address.
732 * @chan: Channel number.
733 * @ctype: Channel Type.
734 * @seq_id: Sequence identifier
735 * @cmd: True if function is called by ethtool cmd
736 * @mcam_idx: NPC mcam index of DMAC entry in NPC mcam.
737 * @pcifunc: pci function
739 static int rvu_npc_exact_add_to_list(struct rvu *rvu, enum npc_exact_opc_type opc_type, u8 ways,
740 u32 index, u8 cgx_id, u8 lmac_id, u8 *mac_addr, u16 chan,
741 u8 ctype, u32 *seq_id, bool cmd, u32 mcam_idx, u16 pcifunc)
743 struct npc_exact_table_entry *entry, *tmp, *iter;
744 struct npc_exact_table *table = rvu->hw->table;
745 struct list_head *lhead, *pprev;
747 WARN_ON(ways >= NPC_EXACT_TBL_MAX_WAYS);
749 if (!rvu_npc_exact_alloc_id(rvu, seq_id)) {
750 dev_err(rvu->dev, "%s: Generate seq id failed\n", __func__);
754 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
756 rvu_npc_exact_free_id(rvu, *seq_id);
757 dev_err(rvu->dev, "%s: Memory allocation failed\n", __func__);
761 mutex_lock(&table->lock);
763 case NPC_EXACT_OPC_CAM:
764 lhead = &table->lhead_cam_tbl_entry;
765 table->cam_tbl_entry_cnt++;
768 case NPC_EXACT_OPC_MEM:
769 lhead = &table->lhead_mem_tbl_entry[ways];
770 table->mem_tbl_entry_cnt++;
774 mutex_unlock(&table->lock);
776 rvu_npc_exact_free_id(rvu, *seq_id);
778 dev_err(rvu->dev, "%s: Unknown opc type%d\n", __func__, opc_type);
782 /* Add to global list */
783 INIT_LIST_HEAD(&entry->glist);
784 list_add_tail(&entry->glist, &table->lhead_gbl);
785 INIT_LIST_HEAD(&entry->list);
786 entry->index = index;
788 entry->opc_type = opc_type;
790 entry->pcifunc = pcifunc;
792 ether_addr_copy(entry->mac, mac_addr);
794 entry->ctype = ctype;
795 entry->cgx_id = cgx_id;
796 entry->lmac_id = lmac_id;
798 entry->seq_id = *seq_id;
800 entry->mcam_idx = mcam_idx;
805 /* Insert entry in ascending order of index */
806 list_for_each_entry_safe(iter, tmp, lhead, list) {
807 if (index < iter->index)
813 /* Add to each table list */
814 list_add(&entry->list, pprev);
815 mutex_unlock(&table->lock);
820 * rvu_npc_exact_mem_table_write - Wrapper for register write
821 * @rvu: resource virtualization unit.
822 * @blkaddr: Block address
823 * @ways: ways for MEM table.
824 * @index: Index in MEM
825 * @mdata: Meta data to be written to register.
827 static void rvu_npc_exact_mem_table_write(struct rvu *rvu, int blkaddr, u8 ways,
828 u32 index, u64 mdata)
830 rvu_write64(rvu, blkaddr, NPC_AF_EXACT_MEM_ENTRY(ways, index), mdata);
834 * rvu_npc_exact_cam_table_write - Wrapper for register write
835 * @rvu: resource virtualization unit.
836 * @blkaddr: Block address
837 * @index: Index in MEM
838 * @mdata: Meta data to be written to register.
840 static void rvu_npc_exact_cam_table_write(struct rvu *rvu, int blkaddr,
841 u32 index, u64 mdata)
843 rvu_write64(rvu, blkaddr, NPC_AF_EXACT_CAM_ENTRY(index), mdata);
847 * rvu_npc_exact_dealloc_table_entry - dealloc table entry
848 * @rvu: resource virtualization unit.
849 * @opc_type: OPCODE for selection of table(MEM or CAM)
850 * @ways: ways if opc_type is MEM table.
851 * @index: Index of MEM or CAM table.
853 static int rvu_npc_exact_dealloc_table_entry(struct rvu *rvu, enum npc_exact_opc_type opc_type,
856 int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
857 struct npc_exact_table *table;
858 u8 null_dmac[6] = { 0 };
861 /* Prepare entry with all fields set to zero */
862 u64 null_mdata = rvu_exact_prepare_table_entry(rvu, false, 0, 0, null_dmac);
864 table = rvu->hw->table;
865 depth = table->mem_table.depth;
867 mutex_lock(&table->lock);
870 case NPC_EXACT_OPC_CAM:
872 /* Check whether entry is used already */
873 if (!test_bit(index, table->cam_table.bmap)) {
874 mutex_unlock(&table->lock);
875 dev_err(rvu->dev, "%s: Trying to free an unused entry ways=%d index=%d\n",
876 __func__, ways, index);
880 rvu_npc_exact_cam_table_write(rvu, blkaddr, index, null_mdata);
881 clear_bit(index, table->cam_table.bmap);
884 case NPC_EXACT_OPC_MEM:
886 /* Check whether entry is used already */
887 if (!test_bit(index + ways * depth, table->mem_table.bmap)) {
888 mutex_unlock(&table->lock);
889 dev_err(rvu->dev, "%s: Trying to free an unused entry index=%d\n",
894 rvu_npc_exact_mem_table_write(rvu, blkaddr, ways, index, null_mdata);
895 clear_bit(index + ways * depth, table->mem_table.bmap);
899 mutex_unlock(&table->lock);
900 dev_err(rvu->dev, "%s: invalid opc type %d", __func__, opc_type);
904 mutex_unlock(&table->lock);
906 dev_dbg(rvu->dev, "%s: Successfully deleted entry (index=%d, ways=%d opc_type=%d\n",
907 __func__, index, ways, opc_type);
913 * rvu_npc_exact_alloc_table_entry - Allociate an entry
914 * @rvu: resource virtualization unit.
916 * @chan: Channel number.
917 * @ctype: Channel Type.
918 * @index: Index of MEM table or CAM table.
919 * @ways: Ways. Only valid for MEM table.
920 * @opc_type: OPCODE to select table (MEM or CAM)
922 * Try allocating a slot from MEM table. If all 4 ways
923 * slot are full for a hash index, check availability in
924 * 32-entry CAM table for allocation.
926 static int rvu_npc_exact_alloc_table_entry(struct rvu *rvu, char *mac, u16 chan, u8 ctype,
927 u32 *index, u8 *ways, enum npc_exact_opc_type *opc_type)
929 struct npc_exact_table *table;
933 table = rvu->hw->table;
935 /* Check in 4-ways mem entry for free slote */
936 hash = rvu_exact_calculate_hash(rvu, chan, ctype, mac, table->mem_table.mask,
937 table->mem_table.depth);
938 err = rvu_npc_exact_alloc_mem_table_entry(rvu, ways, index, hash);
940 *opc_type = NPC_EXACT_OPC_MEM;
941 dev_dbg(rvu->dev, "%s: inserted in 4 ways hash table ways=%d, index=%d\n",
942 __func__, *ways, *index);
946 dev_dbg(rvu->dev, "%s: failed to insert in 4 ways hash table\n", __func__);
948 /* wayss is 0 for cam table */
950 err = rvu_npc_exact_alloc_cam_table_entry(rvu, index);
952 *opc_type = NPC_EXACT_OPC_CAM;
953 dev_dbg(rvu->dev, "%s: inserted in fully associative hash table index=%u\n",
958 dev_err(rvu->dev, "%s: failed to insert in fully associative hash table\n", __func__);
963 * rvu_npc_exact_del_table_entry_by_id - Delete and free table entry.
964 * @rvu: resource virtualization unit.
965 * @seq_id: Sequence identifier of the entry.
967 * Deletes entry from linked lists and free up slot in HW MEM or CAM
970 int rvu_npc_exact_del_table_entry_by_id(struct rvu *rvu, u32 seq_id)
972 struct npc_exact_table_entry *entry = NULL;
973 struct npc_exact_table *table;
976 table = rvu->hw->table;
978 mutex_lock(&table->lock);
980 /* Lookup for entry which needs to be updated */
981 entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, seq_id);
983 dev_dbg(rvu->dev, "%s: failed to find entry for id=0x%x\n", __func__, seq_id);
984 mutex_unlock(&table->lock);
988 cnt = (entry->opc_type == NPC_EXACT_OPC_CAM) ? &table->cam_tbl_entry_cnt :
989 &table->mem_tbl_entry_cnt;
991 /* delete from lists */
992 list_del_init(&entry->list);
993 list_del_init(&entry->glist);
997 mutex_unlock(&table->lock);
999 rvu_npc_exact_dealloc_table_entry(rvu, entry->opc_type, entry->ways, entry->index);
1001 rvu_npc_exact_free_id(rvu, seq_id);
1003 dev_dbg(rvu->dev, "%s: delete entry success for id=0x%x, mca=%pM\n",
1004 __func__, seq_id, entry->mac);
1011 * rvu_npc_exact_add_table_entry - Adds a table entry
1012 * @rvu: resource virtualization unit.
1013 * @cgx_id: cgx identifier.
1014 * @lmac_id: lmac identifier.
1015 * @mac: MAC address.
1016 * @chan: Channel number.
1017 * @ctype: Channel Type.
1018 * @seq_id: Sequence number.
1019 * @cmd: Whether it is invoked by ethtool cmd.
1020 * @mcam_idx: NPC mcam index corresponding to MAC
1021 * @pcifunc: PCI func.
1023 * Creates a new exact match table entry in either CAM or
1026 int rvu_npc_exact_add_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_id, u8 *mac,
1027 u16 chan, u8 ctype, u32 *seq_id, bool cmd,
1028 u32 mcam_idx, u16 pcifunc)
1030 int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1031 enum npc_exact_opc_type opc_type;
1032 struct npc_exact_table *table;
1038 table = rvu->hw->table;
1042 err = rvu_npc_exact_alloc_table_entry(rvu, mac, chan, ctype, &index, &ways, &opc_type);
1044 dev_err(rvu->dev, "%s: Could not alloc in exact match table\n", __func__);
1048 /* Write mdata to table */
1049 mdata = rvu_exact_prepare_table_entry(rvu, true, ctype, chan, mac);
1051 if (opc_type == NPC_EXACT_OPC_CAM)
1052 rvu_npc_exact_cam_table_write(rvu, blkaddr, index, mdata);
1054 rvu_npc_exact_mem_table_write(rvu, blkaddr, ways, index, mdata);
1056 /* Insert entry to linked list */
1057 err = rvu_npc_exact_add_to_list(rvu, opc_type, ways, index, cgx_id, lmac_id,
1058 mac, chan, ctype, seq_id, cmd, mcam_idx, pcifunc);
1060 rvu_npc_exact_dealloc_table_entry(rvu, opc_type, ways, index);
1061 dev_err(rvu->dev, "%s: could not add to exact match table\n", __func__);
1066 "%s: Successfully added entry (index=%d, dmac=%pM, ways=%d opc_type=%d\n",
1067 __func__, index, mac, ways, opc_type);
1073 * rvu_npc_exact_update_table_entry - Update exact match table.
1074 * @rvu: resource virtualization unit.
1075 * @cgx_id: CGX identifier.
1076 * @lamc_id: LMAC identifier.
1077 * @old_mac: Existing MAC address entry.
1078 * @new_mac: New MAC address entry.
1079 * @seq_id: Sequence identifier of the entry.
1081 * Updates MAC address of an entry. If entry is in MEM table, new
1082 * hash value may not match with old one.
1084 int rvu_npc_exact_update_table_entry(struct rvu *rvu, u8 cgx_id, u8 lmac_id,
1085 u8 *old_mac, u8 *new_mac, u32 *seq_id)
1087 int blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1088 struct npc_exact_table_entry *entry;
1089 struct npc_exact_table *table;
1093 table = rvu->hw->table;
1095 mutex_lock(&table->lock);
1097 /* Lookup for entry which needs to be updated */
1098 entry = __rvu_npc_exact_find_entry_by_seq_id(rvu, *seq_id);
1100 mutex_unlock(&table->lock);
1102 "%s: failed to find entry for cgx_id=%d lmac_id=%d old_mac=%pM\n",
1103 __func__, cgx_id, lmac_id, old_mac);
1107 /* If entry is in mem table and new hash index is different than old
1108 * hash index, we cannot update the entry. Fail in these scenarios.
1110 if (entry->opc_type == NPC_EXACT_OPC_MEM) {
1111 hash_index = rvu_exact_calculate_hash(rvu, entry->chan, entry->ctype,
1112 new_mac, table->mem_table.mask,
1113 table->mem_table.depth);
1114 if (hash_index != entry->index) {
1116 "%s: Update failed due to index mismatch(new=0x%x, old=%x)\n",
1117 __func__, hash_index, entry->index);
1118 mutex_unlock(&table->lock);
1123 mdata = rvu_exact_prepare_table_entry(rvu, true, entry->ctype, entry->chan, new_mac);
1125 if (entry->opc_type == NPC_EXACT_OPC_MEM)
1126 rvu_npc_exact_mem_table_write(rvu, blkaddr, entry->ways, entry->index, mdata);
1128 rvu_npc_exact_cam_table_write(rvu, blkaddr, entry->index, mdata);
1130 /* Update entry fields */
1131 ether_addr_copy(entry->mac, new_mac);
1132 *seq_id = entry->seq_id;
1135 "%s: Successfully updated entry (index=%d, dmac=%pM, ways=%d opc_type=%d\n",
1136 __func__, hash_index, entry->mac, entry->ways, entry->opc_type);
1138 dev_dbg(rvu->dev, "%s: Successfully updated entry (old mac=%pM new_mac=%pM\n",
1139 __func__, old_mac, new_mac);
1141 mutex_unlock(&table->lock);
1146 * rvu_npc_exact_can_disable_feature - Check if feature can be disabled.
1147 * @rvu: resource virtualization unit.
1149 bool rvu_npc_exact_can_disable_feature(struct rvu *rvu)
1151 struct npc_exact_table *table = rvu->hw->table;
1154 if (!rvu->hw->cap.npc_exact_match_enabled)
1157 mutex_lock(&table->lock);
1158 empty = list_empty(&table->lhead_gbl);
1159 mutex_unlock(&table->lock);
1165 * rvu_npc_exact_disable_feature - Disable feature.
1166 * @rvu: resource virtualization unit.
1168 void rvu_npc_exact_disable_feature(struct rvu *rvu)
1170 rvu->hw->cap.npc_exact_match_enabled = false;
1174 * rvu_npc_exact_reset - Delete and free all entry which match pcifunc.
1175 * @rvu: resource virtualization unit.
1176 * @pcifunc: PCI func to match.
1178 void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc)
1180 struct npc_exact_table *table = rvu->hw->table;
1181 struct npc_exact_table_entry *tmp, *iter;
1184 mutex_lock(&table->lock);
1185 list_for_each_entry_safe(iter, tmp, &table->lhead_gbl, glist) {
1186 if (pcifunc != iter->pcifunc)
1189 seq_id = iter->seq_id;
1190 dev_dbg(rvu->dev, "%s: resetting pcifun=%d seq_id=%u\n", __func__,
1193 mutex_unlock(&table->lock);
1194 rvu_npc_exact_del_table_entry_by_id(rvu, seq_id);
1195 mutex_lock(&table->lock);
1197 mutex_unlock(&table->lock);
1201 * rvu_npc_exact_init - initialize exact match table
1202 * @rvu: resource virtualization unit.
1204 * Initialize HW and SW resources to manage 4way-2K table and fully
1205 * associative 32-entry mcam table.
1207 int rvu_npc_exact_init(struct rvu *rvu)
1209 struct npc_exact_table *table;
1216 /* Read NPC_AF_CONST3 and check for have exact
1217 * match functionality is present
1219 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1221 dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__);
1225 /* Check exact match feature is supported */
1226 npc_const3 = rvu_read64(rvu, blkaddr, NPC_AF_CONST3);
1227 if (!(npc_const3 & BIT_ULL(62))) {
1228 dev_info(rvu->dev, "%s: No support for exact match support\n",
1233 /* Check if kex profile has enabled EXACT match nibble */
1234 cfg = rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX));
1235 if (!(cfg & NPC_EXACT_NIBBLE_HIT)) {
1236 dev_info(rvu->dev, "%s: NPC exact match nibble not enabled in KEX profile\n",
1241 /* Set capability to true */
1242 rvu->hw->cap.npc_exact_match_enabled = true;
1244 table = kmalloc(sizeof(*table), GFP_KERNEL);
1248 dev_dbg(rvu->dev, "%s: Memory allocation for table success\n", __func__);
1249 memset(table, 0, sizeof(*table));
1250 rvu->hw->table = table;
1252 /* Read table size, ways and depth */
1253 table->mem_table.depth = FIELD_GET(GENMASK_ULL(31, 24), npc_const3);
1254 table->mem_table.ways = FIELD_GET(GENMASK_ULL(19, 16), npc_const3);
1255 table->cam_table.depth = FIELD_GET(GENMASK_ULL(15, 0), npc_const3);
1257 dev_dbg(rvu->dev, "%s: NPC exact match 4way_2k table(ways=%d, depth=%d)\n",
1258 __func__, table->mem_table.ways, table->cam_table.depth);
1260 /* Check if depth of table is not a sequre of 2
1261 * TODO: why _builtin_popcount() is not working ?
1263 if ((table->mem_table.depth & (table->mem_table.depth - 1)) != 0) {
1265 "%s: NPC exact match 4way_2k table depth(%d) is not square of 2\n",
1266 __func__, table->mem_table.depth);
1270 table_size = table->mem_table.depth * table->mem_table.ways;
1272 /* Allocate bitmap for 4way 2K table */
1273 table->mem_table.bmap = devm_kcalloc(rvu->dev, BITS_TO_LONGS(table_size),
1274 sizeof(long), GFP_KERNEL);
1275 if (!table->mem_table.bmap)
1278 dev_dbg(rvu->dev, "%s: Allocated bitmap for 4way 2K entry table\n", __func__);
1280 /* Allocate bitmap for 32 entry mcam */
1281 table->cam_table.bmap = devm_kcalloc(rvu->dev, 1, sizeof(long), GFP_KERNEL);
1283 if (!table->cam_table.bmap)
1286 dev_dbg(rvu->dev, "%s: Allocated bitmap for 32 entry cam\n", __func__);
1288 table->tot_ids = (table->mem_table.depth * table->mem_table.ways) + table->cam_table.depth;
1289 table->id_bmap = devm_kcalloc(rvu->dev, BITS_TO_LONGS(table->tot_ids),
1290 table->tot_ids, GFP_KERNEL);
1292 if (!table->id_bmap)
1295 dev_dbg(rvu->dev, "%s: Allocated bitmap for id map (total=%d)\n",
1296 __func__, table->tot_ids);
1298 /* Initialize list heads for npc_exact_table entries.
1299 * This entry is used by debugfs to show entries in
1300 * exact match table.
1302 for (i = 0; i < NPC_EXACT_TBL_MAX_WAYS; i++)
1303 INIT_LIST_HEAD(&table->lhead_mem_tbl_entry[i]);
1305 INIT_LIST_HEAD(&table->lhead_cam_tbl_entry);
1306 INIT_LIST_HEAD(&table->lhead_gbl);
1308 mutex_init(&table->lock);
1310 rvu_exact_config_secret_key(rvu);
1311 rvu_exact_config_search_key(rvu);
1313 rvu_exact_config_table_mask(rvu);
1314 rvu_exact_config_result_ctrl(rvu, table->mem_table.depth);
1316 dev_info(rvu->dev, "initialized exact match table successfully\n");