lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Sun, 17 Nov 2019 21:44:25 +0530 From: sunil.kovvuri@...il.com To: netdev@...r.kernel.org Cc: davem@...emloft.net, Kiran Kumar K <kirankumark@...vell.com>, Subbaraya Sundeep <sbhatta@...vell.com>, Sunil Goutham <sgoutham@...vell.com> Subject: [PATCH 14/15] octeontx2-af: NPC Tx parsed data key extraction profile From: Kiran Kumar K <kirankumark@...vell.com> This patch enables Tx side parsing by configuring the pkind 63 in tx_parse_cfg and add default ldata profile for tx. Unlike Ingress parsing where CHAN field represents the port where the pkt is received, for a transmitted pkt, NIX HW adds a header which will have PF_FUNC, SQ idx information, which if extracted to NPC parse key can be used to do egress side filtering/forwarding. This patch configures HW to extract this header info into parse key. Signed-off-by: Kiran Kumar K <kirankumark@...vell.com> Signed-off-by: Subbaraya Sundeep <sbhatta@...vell.com> Signed-off-by: Sunil Goutham <sgoutham@...vell.com> --- .../net/ethernet/marvell/octeontx2/af/rvu_nix.c | 6 + .../net/ethernet/marvell/octeontx2/af/rvu_npc.c | 235 ++++++++++++++++----- 2 files changed, 191 insertions(+), 50 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c index f1201e0..07f0f4b 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c @@ -58,6 +58,8 @@ enum nix_makr_fmt_indexes { NIX_MARK_CFG_MAX, }; +#define NIX_TX_PKIND 63ULL + /* For now considering MC resources needed for broadcast * pkt replication only. i.e 256 HWVFs + 12 PFs. */ @@ -1110,6 +1112,10 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu, /* Config Rx pkt length, csum checks and apad enable / disable */ rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_CFG(nixlf), req->rx_cfg); + /* Configure pkind for TX parse config, 63 from npc_profile */ + cfg = NIX_TX_PKIND; + rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf), cfg); + intf = is_afvf(pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX; err = nix_interface_init(rvu, pcifunc, intf, nixlf); if (err) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c index cf61796..d1aab99 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c @@ -29,12 +29,33 @@ #define NPC_PARSE_RESULT_DMAC_OFFSET 8 #define NPC_KEX_CHAN_MASK 0xFFFULL +#define NPC_KEX_PF_FUNC_MASK 0xFFFFULL static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr, u16 pcifunc); static void npc_mcam_free_all_counters(struct rvu *rvu, struct npc_mcam *mcam, u16 pcifunc); +static int npc_mcam_verify_pf_func(struct rvu *rvu, + struct mcam_entry *entry_data, + u8 intf, u16 pcifunc) +{ + u16 pf_func, pf_func_mask; + + if (intf == NIX_INTF_RX) + return 0; + + pf_func_mask = (entry_data->kw_mask[0] >> 32) & + NPC_KEX_PF_FUNC_MASK; + pf_func = (entry_data->kw[0] >> 32) & NPC_KEX_PF_FUNC_MASK; + + pf_func = htons(pf_func); + if (pf_func_mask != NPC_KEX_PF_FUNC_MASK || pf_func != pcifunc) + return -EINVAL; + + return 0; +} + static int npc_mcam_verify_channel(struct rvu *rvu, u16 pcifunc, u8 intf, u16 channel) { @@ -720,37 +741,78 @@ void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf) (((bytesm1) << 16) | ((hdr_ofs) << 8) | ((ena) << 7) | \ ((flags_ena) << 6) | ((key_ofs) & 0x3F)) -static void npc_config_ldata_extract(struct rvu *rvu, int blkaddr) +static void npc_config_tx_ldata_extract(struct rvu *rvu, int blkaddr) { - struct npc_mcam *mcam = &rvu->hw->mcam; - int lid, ltype; - int lid_count; u64 cfg; - cfg = rvu_read64(rvu, blkaddr, NPC_AF_CONST); - lid_count = (cfg >> 4) & 0xF; + /* Default TX MCAM KEX profile */ + /* Layer A: Ethernet: */ - /* First clear any existing config i.e - * disable LDATA and FLAGS extraction. - */ - for (lid = 0; lid < lid_count; lid++) { - for (ltype = 0; ltype < 16; ltype++) { - SET_KEX_LD(NIX_INTF_RX, lid, ltype, 0, 0ULL); - SET_KEX_LD(NIX_INTF_RX, lid, ltype, 1, 0ULL); - SET_KEX_LD(NIX_INTF_TX, lid, ltype, 0, 0ULL); - SET_KEX_LD(NIX_INTF_TX, lid, ltype, 1, 0ULL); + /* PF_FUNC: 2B , KW0 [47:32] */ + cfg = KEX_LD_CFG(0x01, 0x0, 0x1, 0x0, 0x4); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LA, NPC_LT_LA_IH_NIX_ETHER, 0, cfg); - SET_KEX_LDFLAGS(NIX_INTF_RX, 0, ltype, 0ULL); - SET_KEX_LDFLAGS(NIX_INTF_RX, 1, ltype, 0ULL); - SET_KEX_LDFLAGS(NIX_INTF_TX, 0, ltype, 0ULL); - SET_KEX_LDFLAGS(NIX_INTF_TX, 1, ltype, 0ULL); - } - } + /* PF_FUNC incase of higig2 */ + cfg = KEX_LD_CFG(0x01, 0x0, 0x1, 0x0, 0x4); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LA, NPC_LT_LA_IH_NIX_HIGIG2_ETHER, 0, + cfg); - if (mcam->keysize != NPC_MCAM_KEY_X2) - return; + /* Layer B: Single VLAN (CTAG) */ + /* CTAG VLAN[2..3] KW0[63:48] */ + cfg = KEX_LD_CFG(0x01, 0x2, 0x1, 0x0, 0x6); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LB, NPC_LT_LB_CTAG, 0, cfg); + + /* CTAG VLAN[2..3] KW1[15:0] */ + cfg = KEX_LD_CFG(0x01, 0x4, 0x1, 0x0, 0x8); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LB, NPC_LT_LB_CTAG, 1, cfg); + + /* Layer B: Stacked VLAN (STAG|QinQ) */ + /* Outer VLAN: 2 bytes, KW0[63:48] */ + cfg = KEX_LD_CFG(0x01, 0x2, 0x1, 0x0, 0x6); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 0, cfg); + + /* Outer VLAN: 2 Bytes, KW1[15:0] */ + cfg = KEX_LD_CFG(0x01, 0x8, 0x1, 0x0, 0x8); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 1, cfg); + + /* DMAC: 6 bytes, KW1[63:16] */ + cfg = KEX_LD_CFG(0x05, 0x8, 0x1, 0x0, 0xa); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LA, NPC_LT_LA_IH_NIX_ETHER, 1, cfg); + + /* clasification in higig2 header */ + cfg = KEX_LD_CFG(0x01, 0x10, 0x1, 0x0, 0xa); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LA, NPC_LT_LA_IH_NIX_HIGIG2_ETHER, 1, + cfg); + + /* Layer C: IPv4 */ + /* SIP+DIP: 8 bytes, KW2[63:0] */ + cfg = KEX_LD_CFG(0x07, 0xc, 0x1, 0x0, 0x10); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LC, NPC_LT_LC_IP, 0, cfg); + + /* Layer D:UDP */ + /* SPORT: 2 bytes, KW3[15:0] */ + cfg = KEX_LD_CFG(0x1, 0x0, 0x1, 0x0, 0x18); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LD, NPC_LT_LD_UDP, 0, cfg); + + /* DPORT: 2 bytes, KW3[31:16] */ + cfg = KEX_LD_CFG(0x1, 0x2, 0x1, 0x0, 0x1a); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LD, NPC_LT_LD_UDP, 1, cfg); + + /* Layer D:TCP */ + /* SPORT: 2 bytes, KW3[15:0] */ + cfg = KEX_LD_CFG(0x1, 0x0, 0x1, 0x0, 0x18); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LD, NPC_LT_LD_TCP, 0, cfg); + + /* DPORT: 2 bytes, KW3[31:16] */ + cfg = KEX_LD_CFG(0x1, 0x2, 0x1, 0x0, 0x1a); + SET_KEX_LD(NIX_INTF_TX, NPC_LID_LD, NPC_LT_LD_TCP, 1, cfg); +} + +static void npc_config_rx_ldata_extract(struct rvu *rvu, int blkaddr) +{ + u64 cfg; - /* Default MCAM KEX profile */ + /* Default RX MCAM KEX profile */ /* Layer A: Ethernet: */ /* DMAC: 6 bytes, KW1[47:0] */ @@ -761,21 +823,34 @@ static void npc_config_ldata_extract(struct rvu *rvu, int blkaddr) cfg = KEX_LD_CFG(0x01, 0xc, 0x1, 0x0, 0x4); SET_KEX_LD(NIX_INTF_RX, NPC_LID_LA, NPC_LT_LA_ETHER, 1, cfg); + /* Classification in higig2 header */ + cfg = KEX_LD_CFG(0x01, 0x8, 0x1, 0x0, NPC_PARSE_RESULT_DMAC_OFFSET); + SET_KEX_LD(NIX_INTF_RX, NPC_LID_LA, NPC_LT_LA_HIGIG2_ETHER, 0, cfg); + + /* Vid in higig2 header */ + cfg = KEX_LD_CFG(0x01, 0xc, 0x1, 0x0, NPC_PARSE_RESULT_DMAC_OFFSET + 2); + SET_KEX_LD(NIX_INTF_RX, NPC_LID_LA, NPC_LT_LA_HIGIG2_ETHER, 1, cfg); + /* Layer B: Single VLAN (CTAG) */ /* CTAG VLAN[2..3] + Ethertype, 4 bytes, KW0[63:32] */ - cfg = KEX_LD_CFG(0x03, 0x0, 0x1, 0x0, 0x4); + cfg = KEX_LD_CFG(0x03, 0x2, 0x1, 0x0, 0x4); SET_KEX_LD(NIX_INTF_RX, NPC_LID_LB, NPC_LT_LB_CTAG, 0, cfg); /* Layer B: Stacked VLAN (STAG|QinQ) */ - /* CTAG VLAN[2..3] + Ethertype, 4 bytes, KW0[63:32] */ - cfg = KEX_LD_CFG(0x03, 0x4, 0x1, 0x0, 0x4); + /* Outer VLAN: 2 bytes, KW0[63:48] */ + cfg = KEX_LD_CFG(0x01, 0x2, 0x1, 0x0, 0x6); SET_KEX_LD(NIX_INTF_RX, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 0, cfg); + /* Ethertype: 2 bytes, KW0[47:32] */ + cfg = KEX_LD_CFG(0x01, 0x8, 0x1, 0x0, 0x4); + SET_KEX_LD(NIX_INTF_RX, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 1, cfg); + /* Layer C: IPv4 */ /* SIP+DIP: 8 bytes, KW2[63:0] */ cfg = KEX_LD_CFG(0x07, 0xc, 0x1, 0x0, 0x10); SET_KEX_LD(NIX_INTF_RX, NPC_LID_LC, NPC_LT_LC_IP, 0, cfg); /* TOS: 1 byte, KW1[63:56] */ + cfg = KEX_LD_CFG(0x0, 0x1, 0x1, 0x0, 0xf); SET_KEX_LD(NIX_INTF_RX, NPC_LID_LC, NPC_LT_LC_IP, 1, cfg); @@ -783,6 +858,7 @@ static void npc_config_ldata_extract(struct rvu *rvu, int blkaddr) /* SPORT: 2 bytes, KW3[15:0] */ cfg = KEX_LD_CFG(0x1, 0x0, 0x1, 0x0, 0x18); SET_KEX_LD(NIX_INTF_RX, NPC_LID_LD, NPC_LT_LD_UDP, 0, cfg); + /* DPORT: 2 bytes, KW3[31:16] */ cfg = KEX_LD_CFG(0x1, 0x2, 0x1, 0x0, 0x1a); SET_KEX_LD(NIX_INTF_RX, NPC_LID_LD, NPC_LT_LD_UDP, 1, cfg); @@ -791,11 +867,49 @@ static void npc_config_ldata_extract(struct rvu *rvu, int blkaddr) /* SPORT: 2 bytes, KW3[15:0] */ cfg = KEX_LD_CFG(0x1, 0x0, 0x1, 0x0, 0x18); SET_KEX_LD(NIX_INTF_RX, NPC_LID_LD, NPC_LT_LD_TCP, 0, cfg); + /* DPORT: 2 bytes, KW3[31:16] */ cfg = KEX_LD_CFG(0x1, 0x2, 0x1, 0x0, 0x1a); SET_KEX_LD(NIX_INTF_RX, NPC_LID_LD, NPC_LT_LD_TCP, 1, cfg); } +static void npc_config_ldata_extract(struct rvu *rvu, int blkaddr) +{ + int lid, ltype; + int lid_count; + u64 cfg; + + cfg = rvu_read64(rvu, blkaddr, NPC_AF_CONST); + lid_count = (cfg >> 4) & 0xF; + + /* First clear any existing config i.e + * disable LDATA and FLAGS extraction. + */ + for (lid = 0; lid < lid_count; lid++) { + for (ltype = 0; ltype < 16; ltype++) { + SET_KEX_LD(NIX_INTF_RX, lid, ltype, 0, 0ULL); + SET_KEX_LD(NIX_INTF_RX, lid, ltype, 1, 0ULL); + SET_KEX_LD(NIX_INTF_TX, lid, ltype, 0, 0ULL); + SET_KEX_LD(NIX_INTF_TX, lid, ltype, 1, 0ULL); + + SET_KEX_LDFLAGS(NIX_INTF_RX, 0, ltype, 0ULL); + SET_KEX_LDFLAGS(NIX_INTF_RX, 1, ltype, 0ULL); + SET_KEX_LDFLAGS(NIX_INTF_TX, 0, ltype, 0ULL); + SET_KEX_LDFLAGS(NIX_INTF_TX, 1, ltype, 0ULL); + } + } + + cfg = (rvu_read64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(0)) >> 32) & 0x07; + /* Default profile works with key size NPC_MCAM_KEY_X2 */ + if (cfg != NPC_MCAM_KEY_X2) + return; + + /* Config RX ldata extract */ + npc_config_rx_ldata_extract(rvu, blkaddr); + /* Config TX ldata extract */ + npc_config_tx_ldata_extract(rvu, blkaddr); +} + static void npc_program_mkex_profile(struct rvu *rvu, int blkaddr, struct npc_mcam_kex *mkex) { @@ -837,6 +951,20 @@ static void npc_program_mkex_profile(struct rvu *rvu, int blkaddr, } } +static bool is_parse_nibble_config_valid(struct rvu *rvu, + struct npc_mcam_kex *mcam_kex) +{ + if (!is_rvu_96xx_B0(rvu)) + return true; + + /* Due to a HW issue in above silicon versions, parse nibble enable + * configuration has to be identical for both Rx and Tx interfaces. + */ + if (mcam_kex->keyx_cfg[NIX_INTF_RX] != mcam_kex->keyx_cfg[NIX_INTF_TX]) + return false; + return true; +} + /* strtoull of "mkexprof" with base:36 */ #define MKEX_SIGN 0x19bbfdbd15f #define MKEX_END_SIGN 0xdeadbeef @@ -854,8 +982,10 @@ static void npc_load_mkex_profile(struct rvu *rvu, int blkaddr) if (!strncmp(mkex_profile, "default", MKEX_NAME_LEN)) goto load_default; - if (cgx_get_mkex_prfl_info(&prfl_addr, &prfl_sz)) + if (!rvu->fwdata) goto load_default; + prfl_addr = rvu->fwdata->mcam_addr; + prfl_sz = rvu->fwdata->mcam_sz; if (!prfl_addr || !prfl_sz) goto load_default; @@ -870,13 +1000,7 @@ static void npc_load_mkex_profile(struct rvu *rvu, int blkaddr) /* Compare with mkex mod_param name string */ if (mcam_kex->mkex_sign == MKEX_SIGN && !strncmp(mcam_kex->name, mkex_profile, MKEX_NAME_LEN)) { - /* Due to an errata (35786) in A0/B0 pass silicon, - * parse nibble enable configuration has to be - * identical for both Rx and Tx interfaces. - */ - if (is_rvu_96xx_B0(rvu) && - mcam_kex->keyx_cfg[NIX_INTF_RX] != - mcam_kex->keyx_cfg[NIX_INTF_TX]) + if (!is_parse_nibble_config_valid(rvu, mcam_kex)) goto load_default; /* Program selected mkex profile */ @@ -1219,36 +1343,36 @@ int rvu_npc_init(struct rvu *rvu) /* Enable below for Rx pkts. * - Outer IPv4 header checksum validation. - * - Detect outer L2 broadcast address and set NPC_RESULT_S[L2M]. + * - Detect outer L2 broadcast address and set NPC_RESULT_S[L2B]. + * - Detect outer L2 multicast address and set NPC_RESULT_S[L2M]. * - Inner IPv4 header checksum validation. * - Set non zero checksum error code value */ rvu_write64(rvu, blkaddr, NPC_AF_PCK_CFG, rvu_read64(rvu, blkaddr, NPC_AF_PCK_CFG) | - BIT_ULL(32) | BIT_ULL(24) | BIT_ULL(6) | - BIT_ULL(2) | BIT_ULL(1)); + ((u64)NPC_EC_OIP4_CSUM << 32) | (NPC_EC_IIP4_CSUM << 24) | + BIT_ULL(7) | BIT_ULL(6) | BIT_ULL(2) | BIT_ULL(1)); /* Set RX and TX side MCAM search key size. - * LA..LD (ltype only) + Channel + * LA..LE (ltype only) + Channel */ - nibble_ena = 0x49247; + nibble_ena = 0x249207; rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_RX), ((keyz & 0x3) << 32) | nibble_ena); - /* Due to an errata (35786) in A0 pass silicon, parse nibble enable - * configuration has to be identical for both Rx and Tx interfaces. - */ + + /* Extract Ltypes LID_LA to LID_LE */ if (!is_rvu_96xx_B0(rvu)) - nibble_ena = (1ULL << 19) - 1; + nibble_ena = 0x249200; rvu_write64(rvu, blkaddr, NPC_AF_INTFX_KEX_CFG(NIX_INTF_TX), ((keyz & 0x3) << 32) | nibble_ena); + /* Configure MKEX profile */ + npc_load_mkex_profile(rvu, blkaddr); + err = npc_mcam_rsrcs_init(rvu, blkaddr); if (err) return err; - /* Configure MKEX profile */ - npc_load_mkex_profile(rvu, blkaddr); - /* Set TX miss action to UCAST_DEFAULT i.e * transmit the packet on NIX LF SQ's default channel. */ @@ -1262,7 +1386,6 @@ int rvu_npc_init(struct rvu *rvu) NIX_RX_ACTIONOP_DROP); rvu_write64(rvu, blkaddr, NPC_AF_INTFX_MISS_STAT_ACT(NIX_INTF_RX), BIT_ULL(9) | mcam->rx_miss_act_cntr); - return 0; } @@ -1869,6 +1992,12 @@ int rvu_mbox_handler_npc_mcam_write_entry(struct rvu *rvu, goto exit; } + if (npc_mcam_verify_pf_func(rvu, &req->entry_data, req->intf, + pcifunc)) { + rc = NPC_MCAM_INVALID_REQ; + goto exit; + } + npc_config_mcam_entry(rvu, mcam, blkaddr, req->entry, req->intf, &req->entry_data, req->enable_entry); @@ -2091,10 +2220,11 @@ int rvu_mbox_handler_npc_mcam_free_counter(struct rvu *rvu, index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); if (index >= mcam->bmap_entries) break; + entry = index + 1; + if (mcam->entry2cntr_map[index] != req->cntr) continue; - entry = index + 1; npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, index, req->cntr); } @@ -2137,10 +2267,11 @@ int rvu_mbox_handler_npc_mcam_unmap_counter(struct rvu *rvu, index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); if (index >= mcam->bmap_entries) break; + entry = index + 1; + if (mcam->entry2cntr_map[index] != req->cntr) continue; - entry = index + 1; npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, index, req->cntr); } @@ -2221,6 +2352,10 @@ int rvu_mbox_handler_npc_mcam_alloc_and_write_entry(struct rvu *rvu, if (npc_mcam_verify_channel(rvu, req->hdr.pcifunc, req->intf, channel)) return NPC_MCAM_INVALID_REQ; + if (npc_mcam_verify_pf_func(rvu, &req->entry_data, req->intf, + req->hdr.pcifunc)) + return NPC_MCAM_INVALID_REQ; + /* Try to allocate a MCAM entry */ entry_req.hdr.pcifunc = req->hdr.pcifunc; entry_req.contig = true; -- 2.7.4
Powered by blists - more mailing lists