|
10 | 10 | #include "rvu_reg.h"
|
11 | 11 | #include "rvu.h"
|
12 | 12 | #include "npc.h"
|
13 |
| -#include "rvu_npc_hash.h" |
14 | 13 | #include "rvu_npc_fs.h"
|
| 14 | +#include "rvu_npc_hash.h" |
15 | 15 |
|
16 | 16 | #define NPC_BYTESM GENMASK_ULL(19, 16)
|
17 | 17 | #define NPC_HDR_OFFSET GENMASK_ULL(15, 8)
|
@@ -297,6 +297,7 @@ static void npc_scan_parse_result(struct npc_mcam *mcam, u8 bit_number,
|
297 | 297 | default:
|
298 | 298 | return;
|
299 | 299 | }
|
| 300 | + |
300 | 301 | npc_set_kw_masks(mcam, type, nr_bits, kwi, offset, intf);
|
301 | 302 | }
|
302 | 303 |
|
@@ -860,6 +861,7 @@ do { \
|
860 | 861 | } while (0)
|
861 | 862 |
|
862 | 863 | NPC_WRITE_FLOW(NPC_DMAC, dmac, dmac_val, 0, dmac_mask, 0);
|
| 864 | + |
863 | 865 | NPC_WRITE_FLOW(NPC_SMAC, smac, smac_val, 0, smac_mask, 0);
|
864 | 866 | NPC_WRITE_FLOW(NPC_ETYPE, etype, ntohs(pkt->etype), 0,
|
865 | 867 | ntohs(mask->etype), 0);
|
@@ -891,8 +893,7 @@ do { \
|
891 | 893 | pkt, mask, opkt, omask);
|
892 | 894 | }
|
893 | 895 |
|
894 |
| -static struct rvu_npc_mcam_rule *rvu_mcam_find_rule(struct npc_mcam *mcam, |
895 |
| - u16 entry) |
| 896 | +static struct rvu_npc_mcam_rule *rvu_mcam_find_rule(struct npc_mcam *mcam, u16 entry) |
896 | 897 | {
|
897 | 898 | struct rvu_npc_mcam_rule *iter;
|
898 | 899 |
|
@@ -1058,8 +1059,9 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target,
|
1058 | 1059 | u16 owner = req->hdr.pcifunc;
|
1059 | 1060 | struct msg_rsp write_rsp;
|
1060 | 1061 | struct mcam_entry *entry;
|
1061 |
| - int entry_index, err; |
1062 | 1062 | bool new = false;
|
| 1063 | + u16 entry_index; |
| 1064 | + int err; |
1063 | 1065 |
|
1064 | 1066 | installed_features = req->features;
|
1065 | 1067 | features = req->features;
|
@@ -1460,3 +1462,98 @@ void npc_mcam_disable_flows(struct rvu *rvu, u16 target)
|
1460 | 1462 | }
|
1461 | 1463 | mutex_unlock(&mcam->lock);
|
1462 | 1464 | }
|
| 1465 | + |
| 1466 | +/* single drop on non hit rule starting from 0th index. This an extension |
| 1467 | + * to RPM mac filter to support more rules. |
| 1468 | + */ |
| 1469 | +int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx, |
| 1470 | + u64 chan_val, u64 chan_mask, u64 exact_val, u64 exact_mask, |
| 1471 | + u64 bcast_mcast_val, u64 bcast_mcast_mask) |
| 1472 | +{ |
| 1473 | + struct npc_mcam_alloc_counter_req cntr_req = { 0 }; |
| 1474 | + struct npc_mcam_alloc_counter_rsp cntr_rsp = { 0 }; |
| 1475 | + struct npc_mcam_write_entry_req req = { 0 }; |
| 1476 | + struct npc_mcam *mcam = &rvu->hw->mcam; |
| 1477 | + struct rvu_npc_mcam_rule *rule; |
| 1478 | + struct msg_rsp rsp; |
| 1479 | + bool enabled; |
| 1480 | + int blkaddr; |
| 1481 | + int err; |
| 1482 | + |
| 1483 | + blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); |
| 1484 | + if (blkaddr < 0) { |
| 1485 | + dev_err(rvu->dev, "%s: NPC block not implemented\n", __func__); |
| 1486 | + return -ENODEV; |
| 1487 | + } |
| 1488 | + |
| 1489 | + /* Bail out if no exact match support */ |
| 1490 | + if (!rvu_npc_exact_has_match_table(rvu)) { |
| 1491 | + dev_info(rvu->dev, "%s: No support for exact match feature\n", __func__); |
| 1492 | + return -EINVAL; |
| 1493 | + } |
| 1494 | + |
| 1495 | + /* If 0th entry is already used, return err */ |
| 1496 | + enabled = is_mcam_entry_enabled(rvu, mcam, blkaddr, mcam_idx); |
| 1497 | + if (enabled) { |
| 1498 | + dev_err(rvu->dev, "%s: failed to add single drop on non hit rule at %d th index\n", |
| 1499 | + __func__, mcam_idx); |
| 1500 | + return -EINVAL; |
| 1501 | + } |
| 1502 | + |
| 1503 | + /* Add this entry to mcam rules list */ |
| 1504 | + rule = kzalloc(sizeof(*rule), GFP_KERNEL); |
| 1505 | + if (!rule) |
| 1506 | + return -ENOMEM; |
| 1507 | + |
| 1508 | + /* Disable rule by default. Enable rule when first dmac filter is |
| 1509 | + * installed |
| 1510 | + */ |
| 1511 | + rule->enable = false; |
| 1512 | + rule->chan = chan_val; |
| 1513 | + rule->chan_mask = chan_mask; |
| 1514 | + rule->entry = mcam_idx; |
| 1515 | + rvu_mcam_add_rule(mcam, rule); |
| 1516 | + |
| 1517 | + /* Reserve slot 0 */ |
| 1518 | + npc_mcam_rsrcs_reserve(rvu, blkaddr, mcam_idx); |
| 1519 | + |
| 1520 | + /* Allocate counter for this single drop on non hit rule */ |
| 1521 | + cntr_req.hdr.pcifunc = 0; /* AF request */ |
| 1522 | + cntr_req.contig = true; |
| 1523 | + cntr_req.count = 1; |
| 1524 | + err = rvu_mbox_handler_npc_mcam_alloc_counter(rvu, &cntr_req, &cntr_rsp); |
| 1525 | + if (err) { |
| 1526 | + dev_err(rvu->dev, "%s: Err to allocate cntr for drop rule (err=%d)\n", |
| 1527 | + __func__, err); |
| 1528 | + return -EFAULT; |
| 1529 | + } |
| 1530 | + *counter_idx = cntr_rsp.cntr; |
| 1531 | + |
| 1532 | + /* Fill in fields for this mcam entry */ |
| 1533 | + npc_update_entry(rvu, NPC_EXACT_RESULT, &req.entry_data, exact_val, 0, |
| 1534 | + exact_mask, 0, NIX_INTF_RX); |
| 1535 | + npc_update_entry(rvu, NPC_CHAN, &req.entry_data, chan_val, 0, |
| 1536 | + chan_mask, 0, NIX_INTF_RX); |
| 1537 | + npc_update_entry(rvu, NPC_LXMB, &req.entry_data, bcast_mcast_val, 0, |
| 1538 | + bcast_mcast_mask, 0, NIX_INTF_RX); |
| 1539 | + |
| 1540 | + req.intf = NIX_INTF_RX; |
| 1541 | + req.set_cntr = true; |
| 1542 | + req.cntr = cntr_rsp.cntr; |
| 1543 | + req.entry = mcam_idx; |
| 1544 | + |
| 1545 | + err = rvu_mbox_handler_npc_mcam_write_entry(rvu, &req, &rsp); |
| 1546 | + if (err) { |
| 1547 | + dev_err(rvu->dev, "%s: Installation of single drop on non hit rule at %d failed\n", |
| 1548 | + __func__, mcam_idx); |
| 1549 | + return err; |
| 1550 | + } |
| 1551 | + |
| 1552 | + dev_err(rvu->dev, "%s: Installed single drop on non hit rule at %d, cntr=%d\n", |
| 1553 | + __func__, mcam_idx, req.cntr); |
| 1554 | + |
| 1555 | + /* disable entry at Bank 0, index 0 */ |
| 1556 | + npc_enable_mcam_entry(rvu, mcam, blkaddr, mcam_idx, false); |
| 1557 | + |
| 1558 | + return 0; |
| 1559 | +} |
0 commit comments