@@ -482,6 +482,7 @@ struct npc_set_pkind {
#define OTX2_PRIV_FLAGS_DEFAULT BIT_ULL(0)
#define OTX2_PRIV_FLAGS_EDSA BIT_ULL(1)
#define OTX2_PRIV_FLAGS_HIGIG BIT_ULL(2)
+#define OTX2_PRIV_FLAGS_FDSA BIT_ULL(3)
#define OTX2_PRIV_FLAGS_CUSTOM BIT_ULL(63)
u64 mode;
#define PKIND_TX BIT_ULL(0)
@@ -179,6 +179,7 @@ enum key_fields {
NPC_DPORT_UDP,
NPC_SPORT_SCTP,
NPC_DPORT_SCTP,
+ NPC_FDSA_VAL,
NPC_HEADER_FIELDS_MAX,
NPC_CHAN = NPC_HEADER_FIELDS_MAX, /* Valid when Rx */
NPC_PF_FUNC, /* Valid when Tx */
@@ -208,6 +209,13 @@ enum key_fields {
NPC_KEY_FIELDS_MAX,
};
+enum npc_interface_type {
+ NPC_INTF_MODE_DEF,
+ NPC_INTF_MODE_EDSA,
+ NPC_INTF_MODE_HIGIG,
+ NPC_INTF_MODE_FDSA,
+};
+
struct npc_kpu_profile_cam {
u8 state;
u8 state_mask;
@@ -239,6 +239,7 @@ struct rvu_pfvf {
u8 nix_blkaddr; /* BLKADDR_NIX0/1 assigned to this PF */
u8 nix_rx_intf; /* NIX0_RX/NIX1_RX interface to NPC */
u8 nix_tx_intf; /* NIX0_TX/NIX1_TX interface to NPC */
+ int intf_mode;
};
struct nix_txsch {
@@ -2002,7 +2002,8 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s,
seq_printf(s, "mask 0x%x\n", ntohs(rule->mask.etype));
break;
case NPC_OUTER_VID:
- seq_printf(s, "0x%x ", ntohs(rule->packet.vlan_tci));
+ case NPC_FDSA_VAL:
+ seq_printf(s, "%d ", ntohs(rule->packet.vlan_tci));
seq_printf(s, "mask 0x%x\n",
ntohs(rule->mask.vlan_tci));
break;
@@ -1217,6 +1217,11 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
rvu_write64(rvu, blkaddr,
NIX_AF_LFX_RX_VTAG_TYPEX(nixlf, NIX_AF_LFX_RX_VTAG_TYPE7),
VTAGSIZE_T4 | VTAG_STRIP);
+ /* Configure RX VTAG Type 6 (strip) for fdsa */
+ rvu_write64(rvu, blkaddr,
+ NIX_AF_LFX_RX_VTAG_TYPEX(nixlf, NIX_AF_LFX_RX_VTAG_TYPE6),
+ VTAGSIZE_T4 | VTAG_STRIP | VTAG_CAPTURE);
+
goto exit;
@@ -2016,8 +2021,8 @@ static int nix_rx_vtag_cfg(struct rvu *rvu, int nixlf, int blkaddr,
req->vtag_size > VTAGSIZE_T8)
return -EINVAL;
- /* RX VTAG Type 7 reserved for vf vlan */
- if (req->rx.vtag_type == NIX_AF_LFX_RX_VTAG_TYPE7)
+ /* RX VTAG Type 7,6 are reserved for vf vlan& FDSA tag strip */
+ if (req->rx.vtag_type >= NIX_AF_LFX_RX_VTAG_TYPE6)
return NIX_AF_ERR_RX_VTAG_INUSE;
if (req->rx.capture_vtag)
@@ -2849,18 +2849,24 @@ int rvu_mbox_handler_npc_mcam_entry_stats(struct rvu *rvu,
int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
u64 pkind)
{
+ struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+ int blkaddr, nixlf, rc, intf_mode;
int pf = rvu_get_pf(pcifunc);
bool enable_higig2 = false;
- int blkaddr, nixlf, rc;
u64 rxpkind, txpkind;
u8 cgx_id, lmac_id;
/* use default pkind to disable edsa/higig */
rxpkind = rvu_npc_get_pkind(rvu, pf);
txpkind = NPC_TX_DEF_PKIND;
+ intf_mode = NPC_INTF_MODE_DEF;
if (mode & OTX2_PRIV_FLAGS_EDSA) {
rxpkind = NPC_RX_EDSA_PKIND;
+ intf_mode = NPC_INTF_MODE_EDSA;
+ } else if (mode & OTX2_PRIV_FLAGS_FDSA) {
+ rxpkind = NPC_RX_EDSA_PKIND;
+ intf_mode = NPC_INTF_MODE_FDSA;
} else if (mode & OTX2_PRIV_FLAGS_HIGIG) {
/* Silicon does not support enabling higig in time stamp mode */
if (rvu_nix_is_ptp_tx_enabled(rvu, pcifunc))
@@ -2872,6 +2878,7 @@ int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
rxpkind = NPC_RX_HIGIG_PKIND;
txpkind = NPC_TX_HIGIG_PKIND;
+ intf_mode = NPC_INTF_MODE_HIGIG;
enable_higig2 = true;
} else if (mode & OTX2_PRIV_FLAGS_CUSTOM) {
rxpkind = pkind;
@@ -2903,6 +2910,7 @@ int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
if (enable_higig2 ^ rvu_cgx_is_higig2_enabled(rvu, pf))
rvu_cgx_enadis_higig2(rvu, pf, enable_higig2);
+ pfvf->intf_mode = intf_mode;
return 0;
}
@@ -39,6 +39,7 @@ static const char * const npc_flow_names[] = {
[NPC_DPORT_UDP] = "udp destination port",
[NPC_SPORT_SCTP] = "sctp source port",
[NPC_DPORT_SCTP] = "sctp destination port",
+ [NPC_FDSA_VAL] = "FDSA tag value ",
[NPC_UNKNOWN] = "unknown",
};
@@ -445,6 +446,7 @@ do { \
NPC_SCAN_HDR(NPC_ETYPE_TAG2, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 8, 2);
NPC_SCAN_HDR(NPC_VLAN_TAG1, NPC_LID_LB, NPC_LT_LB_CTAG, 2, 2);
NPC_SCAN_HDR(NPC_VLAN_TAG2, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 2, 2);
+ NPC_SCAN_HDR(NPC_FDSA_VAL, NPC_LID_LB, NPC_LT_LB_FDSA, 1, 1);
NPC_SCAN_HDR(NPC_DMAC, NPC_LID_LA, la_ltype, la_start, 6);
NPC_SCAN_HDR(NPC_SMAC, NPC_LID_LA, la_ltype, la_start, 6);
/* PF_FUNC is 2 bytes at 0th byte of NPC_LT_LA_IH_NIX_ETHER */
@@ -492,9 +494,12 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf)
*features |= BIT_ULL(NPC_IPPROTO_ESP);
/* for vlan corresponding layer type should be in the key */
- if (*features & BIT_ULL(NPC_OUTER_VID))
- if (!npc_check_field(rvu, blkaddr, NPC_LB, intf))
+ if (*features & BIT_ULL(NPC_OUTER_VID) ||
+ *features & BIT_ULL(NPC_FDSA_VAL))
+ if (!npc_check_field(rvu, blkaddr, NPC_LB, intf)) {
*features &= ~BIT_ULL(NPC_OUTER_VID);
+ *features &= ~BIT_ULL(NPC_FDSA_VAL);
+ }
}
/* Scan key extraction profile and record how fields of our interest
@@ -786,6 +791,9 @@ static void npc_update_flow(struct rvu *rvu, struct mcam_entry *entry,
npc_update_entry(rvu, NPC_LB, entry,
NPC_LT_LB_STAG_QINQ | NPC_LT_LB_CTAG, 0,
NPC_LT_LB_STAG_QINQ & NPC_LT_LB_CTAG, 0, intf);
+ if (features & BIT_ULL(NPC_FDSA_VAL))
+ npc_update_entry(rvu, NPC_LB, entry, NPC_LT_LB_FDSA,
+ 0, ~0ULL, 0, intf);
/* For AH, LTYPE should be present in entry */
if (features & BIT_ULL(NPC_IPPROTO_AH))
@@ -830,6 +838,8 @@ do { \
NPC_WRITE_FLOW(NPC_OUTER_VID, vlan_tci, ntohs(pkt->vlan_tci), 0,
ntohs(mask->vlan_tci), 0);
+ NPC_WRITE_FLOW(NPC_FDSA_VAL, vlan_tci, ntohs(pkt->vlan_tci), 0,
+ ntohs(mask->vlan_tci), 0);
npc_update_ipv6_flow(rvu, entry, features, pkt, mask, output, intf);
}