From patchwork Sun Jun 2 15:24:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerin Jacob Kollanukkaran X-Patchwork-Id: 54087 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id B6D321BB47; Sun, 2 Jun 2019 17:26:54 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by dpdk.org (Postfix) with ESMTP id EEA651BBEE for ; Sun, 2 Jun 2019 17:26:52 +0200 (CEST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x52FLOCk021032; Sun, 2 Jun 2019 08:26:52 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0818; bh=xodww+tvfl7gKh1+d9KO9LYdPMLvKIq+XkxkVEOby3c=; b=vLXB/zMnWQG1nY3Rk23mGr2wi93WaMPW9ChwurWDmB3n2hwf/R1WfU0HhlFl4ODsQaeF rwCiHGzq3dCttcddr4QYGB4N4gjIH1v3GbXq3v+bvYnRAlyWuNWwx2SMwKjGL60gRYCa tOdlUTYmJA+kNx5sR4hUGopYanq0x14GWBUANVwcJPGgBdMr1+kUym3zWYomtDXGDE8T 81556ZmepHL8XnXlLjAIVqEu0/eg2DYr8zon1JXfprAxdvpPDLASdx6oqNXKhVAVr+8x chAkWjQGnq/FWFmgNEKAOjwX3KMeHa3chzRsGFeqKPDhguw4mMLC9lAQ/+yfUBYb0SUe VQ== Received: from sc-exch01.marvell.com ([199.233.58.181]) by mx0b-0016f401.pphosted.com with ESMTP id 2survk4997-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Sun, 02 Jun 2019 08:26:52 -0700 Received: from SC-EXCH01.marvell.com (10.93.176.81) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Sun, 2 Jun 2019 08:26:50 -0700 Received: from maili.marvell.com (10.93.176.43) by SC-EXCH01.marvell.com (10.93.176.81) with Microsoft SMTP Server id 15.0.1367.3 via Frontend Transport; Sun, 2 Jun 2019 08:26:50 -0700 Received: from jerin-lab.marvell.com (jerin-lab.marvell.com [10.28.34.14]) by maili.marvell.com (Postfix) with ESMTP id 2305C3F703F; Sun, 2 Jun 2019 08:26:48 -0700 (PDT) From: To: , Jerin Jacob , Nithin Dabilpuram , Kiran Kumar K CC: , Vivek Sharma Date: Sun, 2 Jun 2019 20:54:20 +0530 Message-ID: <20190602152434.23996-45-jerinj@marvell.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190602152434.23996-1-jerinj@marvell.com> References: <20190602152434.23996-1-jerinj@marvell.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-06-02_09:, , signatures=0 Subject: [dpdk-dev] [PATCH v1 44/58] net/octeontx2: implement VLAN utility functions X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Vivek Sharma Implement accessory functions needed for VLAN functionality. Introduce VLAN related structures as well. Maximum Vtag insertion size is controlled by SMQ configuration. This patch also configure SMQ for supporting upto double vtag insertion. Signed-off-by: Vivek Sharma --- drivers/net/octeontx2/Makefile | 1 + drivers/net/octeontx2/meson.build | 1 + drivers/net/octeontx2/otx2_ethdev.c | 10 ++ drivers/net/octeontx2/otx2_ethdev.h | 48 +++++++ drivers/net/octeontx2/otx2_tm.c | 5 +- drivers/net/octeontx2/otx2_vlan.c | 190 ++++++++++++++++++++++++++++ 6 files changed, 253 insertions(+), 2 deletions(-) create mode 100644 drivers/net/octeontx2/otx2_vlan.c diff --git a/drivers/net/octeontx2/Makefile b/drivers/net/octeontx2/Makefile index d651c8c50..b1cc6d83b 100644 --- a/drivers/net/octeontx2/Makefile +++ b/drivers/net/octeontx2/Makefile @@ -36,6 +36,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_OCTEONTX2_PMD) += \ otx2_ptp.c \ otx2_flow.c \ otx2_link.c \ + otx2_vlan.c \ otx2_stats.c \ otx2_lookup.c \ otx2_ethdev.c \ diff --git a/drivers/net/octeontx2/meson.build b/drivers/net/octeontx2/meson.build index a2c494bb4..d5f272c8b 100644 --- a/drivers/net/octeontx2/meson.build +++ b/drivers/net/octeontx2/meson.build @@ -9,6 +9,7 @@ sources = files( 'otx2_ptp.c', 'otx2_flow.c', 'otx2_link.c', + 'otx2_vlan.c', 'otx2_stats.c', 'otx2_lookup.c', 'otx2_ethdev.c', diff --git a/drivers/net/octeontx2/otx2_ethdev.c b/drivers/net/octeontx2/otx2_ethdev.c index bda5b4aa4..cfc22a2da 100644 --- a/drivers/net/octeontx2/otx2_ethdev.c +++ b/drivers/net/octeontx2/otx2_ethdev.c @@ -1079,6 +1079,7 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev) /* Free the resources allocated from the previous configure */ if (dev->configured == 1) { otx2_nix_rxchan_bpid_cfg(eth_dev, false); + otx2_nix_vlan_fini(eth_dev); otx2_flow_fini(dev); oxt2_nix_unregister_queue_irqs(eth_dev); nix_set_nop_rxtx_function(eth_dev); @@ -1126,6 +1127,12 @@ otx2_nix_configure(struct rte_eth_dev *eth_dev) goto free_nix_lf; } + rc = otx2_nix_vlan_offload_init(eth_dev); + if (rc) { + otx2_err("Failed to init vlan offload rc=%d", rc); + goto free_nix_lf; + } + /* Register queue IRQs */ rc = oxt2_nix_register_queue_irqs(eth_dev); if (rc) { @@ -1546,6 +1553,9 @@ otx2_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close) /* Disable nix bpid config */ otx2_nix_rxchan_bpid_cfg(eth_dev, false); + /* Disable vlan offloads */ + otx2_nix_vlan_fini(eth_dev); + /* Disable other rte_flow entries */ otx2_flow_fini(dev); diff --git a/drivers/net/octeontx2/otx2_ethdev.h b/drivers/net/octeontx2/otx2_ethdev.h index e9123641c..b54018ae0 100644 --- a/drivers/net/octeontx2/otx2_ethdev.h +++ b/drivers/net/octeontx2/otx2_ethdev.h @@ -40,6 +40,7 @@ /* Used for struct otx2_eth_dev::flags */ #define OTX2_LINK_CFG_IN_PROGRESS_F BIT_ULL(0) +#define NIX_MAX_VTAG_INS 2 #define VLAN_TAG_SIZE 4 #define NIX_HW_L2_OVERHEAD 22 /* ETH_HLEN+2*VLAN_HLEN */ @@ -163,6 +164,47 @@ struct otx2_fc_info { uint16_t bpid[NIX_MAX_CHAN]; }; +struct vlan_mkex_info { + struct npc_xtract_info la_xtract; + struct npc_xtract_info lb_xtract; + uint64_t lb_lt_offset; +}; + +struct vlan_entry { + uint32_t mcam_idx; + uint16_t vlan_id; + TAILQ_ENTRY(vlan_entry) next; +}; + +TAILQ_HEAD(otx2_vlan_filter_tbl, vlan_entry); + +struct otx2_vlan_info { + struct otx2_vlan_filter_tbl fltr_tbl; + /* MKEX layer info */ + struct mcam_entry def_tx_mcam_ent; + struct mcam_entry def_rx_mcam_ent; + struct vlan_mkex_info mkex; + /* Default mcam entry that matches vlan packets */ + uint32_t def_rx_mcam_idx; + uint32_t def_tx_mcam_idx; + /* MCAM entry that matches double vlan packets */ + uint32_t qinq_mcam_idx; + /* Indices of tx_vtag def registers */ + uint32_t outer_vlan_idx; + uint32_t inner_vlan_idx; + uint16_t outer_vlan_tpid; + uint16_t inner_vlan_tpid; + uint16_t pvid; + /* QinQ entry allocated before default one */ + uint8_t qinq_before_def; + uint8_t pvid_insert_on; + /* Rx vtag action type */ + uint8_t vtag_type_idx; + uint8_t filter_on; + uint8_t strip_on; + uint8_t qinq_on; +}; + struct otx2_eth_dev { OTX2_DEV; /* Base class */ MARKER otx2_eth_dev_data_start; @@ -222,6 +264,7 @@ struct otx2_eth_dev { struct rte_timecounter systime_tc; struct rte_timecounter rx_tstamp_tc; struct rte_timecounter tx_tstamp_tc; + struct otx2_vlan_info vlan_info; } __rte_cache_aligned; struct otx2_eth_txq { @@ -422,4 +465,9 @@ int otx2_nix_timesync_read_time(struct rte_eth_dev *eth_dev, struct timespec *ts); int otx2_eth_dev_ptp_info_update(struct otx2_dev *dev, bool ptp_en); +/* VLAN */ +int otx2_nix_vlan_offload_init(struct rte_eth_dev *eth_dev); +int otx2_nix_vlan_fini(struct rte_eth_dev *eth_dev); + + #endif /* __OTX2_ETHDEV_H__ */ diff --git a/drivers/net/octeontx2/otx2_tm.c b/drivers/net/octeontx2/otx2_tm.c index 4439389b8..246920695 100644 --- a/drivers/net/octeontx2/otx2_tm.c +++ b/drivers/net/octeontx2/otx2_tm.c @@ -359,7 +359,7 @@ populate_tm_registers(struct otx2_eth_dev *dev, /* Set xoff which will be cleared later */ *reg++ = NIX_AF_SMQX_CFG(schq); - *regval++ = BIT_ULL(50) | + *regval++ = BIT_ULL(50) | ((uint64_t)NIX_MAX_VTAG_INS << 36) | (NIX_MAX_HW_FRS << 8) | NIX_MIN_HW_FRS; req->num_regs++; *reg++ = NIX_AF_MDQX_PARENT(schq); @@ -688,7 +688,8 @@ nix_smq_xoff(struct otx2_eth_dev *dev, uint16_t smq, bool enable) req->reg[0] = NIX_AF_SMQX_CFG(smq); /* Unmodified fields */ - req->regval[0] = (NIX_MAX_HW_FRS << 8) | NIX_MIN_HW_FRS; + req->regval[0] = ((uint64_t)NIX_MAX_VTAG_INS << 36) | + (NIX_MAX_HW_FRS << 8) | NIX_MIN_HW_FRS; if (enable) req->regval[0] |= BIT_ULL(50) | BIT_ULL(49); diff --git a/drivers/net/octeontx2/otx2_vlan.c b/drivers/net/octeontx2/otx2_vlan.c new file mode 100644 index 000000000..b3136d2cf --- /dev/null +++ b/drivers/net/octeontx2/otx2_vlan.c @@ -0,0 +1,190 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2019 Marvell International Ltd. + */ + +#include +#include + +#include "otx2_ethdev.h" +#include "otx2_flow.h" + + +#define VLAN_ID_MATCH 0x1 +#define VTAG_F_MATCH 0x2 +#define MAC_ADDR_MATCH 0x4 +#define QINQ_F_MATCH 0x8 +#define VLAN_DROP 0x10 + +enum vtag_cfg_dir { + VTAG_TX, + VTAG_RX +}; + +static int +__rte_unused nix_vlan_mcam_enb_dis(struct otx2_eth_dev *dev, + uint32_t entry, const int enable) +{ + struct npc_mcam_ena_dis_entry_req *req; + struct otx2_mbox *mbox = dev->mbox; + int rc = -EINVAL; + + if (enable) + req = otx2_mbox_alloc_msg_npc_mcam_ena_entry(mbox); + else + req = otx2_mbox_alloc_msg_npc_mcam_dis_entry(mbox); + + req->entry = entry; + + rc = otx2_mbox_process_msg(mbox, NULL); + return rc; +} + +static int +__rte_unused nix_vlan_mcam_free(struct otx2_eth_dev *dev, uint32_t entry) +{ + struct npc_mcam_free_entry_req *req; + struct otx2_mbox *mbox = dev->mbox; + int rc = -EINVAL; + + req = otx2_mbox_alloc_msg_npc_mcam_free_entry(mbox); + req->entry = entry; + + rc = otx2_mbox_process_msg(mbox, NULL); + return rc; +} + +static int +__rte_unused nix_vlan_mcam_write(struct rte_eth_dev *eth_dev, uint16_t ent_idx, + struct mcam_entry *entry, uint8_t intf) +{ + struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev); + struct npc_mcam_write_entry_req *req; + struct otx2_mbox *mbox = dev->mbox; + struct msghdr *rsp; + int rc = -EINVAL; + + req = otx2_mbox_alloc_msg_npc_mcam_write_entry(mbox); + + req->entry = ent_idx; + req->intf = intf; + req->enable_entry = 1; + memcpy(&req->entry_data, entry, sizeof(struct mcam_entry)); + + rc = otx2_mbox_process_msg(mbox, (void *)&rsp); + return rc; +} + +static int +__rte_unused nix_vlan_mcam_alloc_and_write(struct rte_eth_dev *eth_dev, + struct mcam_entry *entry, + uint8_t intf, bool drop) +{ + struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev); + struct npc_mcam_alloc_and_write_entry_req *req; + struct npc_mcam_alloc_and_write_entry_rsp *rsp; + struct otx2_mbox *mbox = dev->mbox; + int rc = -EINVAL; + + req = otx2_mbox_alloc_msg_npc_mcam_alloc_and_write_entry(mbox); + + if (intf == NPC_MCAM_RX) { + if (!drop && dev->vlan_info.def_rx_mcam_idx) { + req->priority = NPC_MCAM_HIGHER_PRIO; + req->ref_entry = dev->vlan_info.def_rx_mcam_idx; + } else if (drop && dev->vlan_info.qinq_mcam_idx) { + req->priority = NPC_MCAM_LOWER_PRIO; + req->ref_entry = dev->vlan_info.qinq_mcam_idx; + } else { + req->priority = NPC_MCAM_ANY_PRIO; + req->ref_entry = 0; + } + } else { + req->priority = NPC_MCAM_ANY_PRIO; + req->ref_entry = 0; + } + + req->intf = intf; + req->enable_entry = 1; + memcpy(&req->entry_data, entry, sizeof(struct mcam_entry)); + + rc = otx2_mbox_process_msg(mbox, (void *)&rsp); + if (rc) + return rc; + + return rsp->entry; +} + +static int +nix_vlan_rx_mkex_offset(uint64_t mask) +{ + int nib_count = 0; + + while (mask) { + nib_count += mask & 1; + mask >>= 1; + } + + return nib_count * 4; +} + +static int +nix_vlan_get_mkex_info(struct otx2_eth_dev *dev) +{ + struct vlan_mkex_info *mkex = &dev->vlan_info.mkex; + struct otx2_npc_flow_info *npc = &dev->npc_flow; + struct npc_xtract_info *x_info = NULL; + uint64_t rx_keyx; + otx2_dxcfg_t *p; + int rc = -EINVAL; + + if (npc == NULL) { + otx2_err("Missing npc mkex configuration"); + return rc; + } + +#define NPC_KEX_CHAN_NIBBLE_ENA 0x7ULL +#define NPC_KEX_LB_LTYPE_NIBBLE_ENA 0x1000ULL +#define NPC_KEX_LB_LTYPE_NIBBLE_MASK 0xFFFULL + + rx_keyx = npc->keyx_supp_nmask[NPC_MCAM_RX]; + if ((rx_keyx & NPC_KEX_CHAN_NIBBLE_ENA) != NPC_KEX_CHAN_NIBBLE_ENA) + return rc; + + if ((rx_keyx & NPC_KEX_LB_LTYPE_NIBBLE_ENA) != + NPC_KEX_LB_LTYPE_NIBBLE_ENA) + return rc; + + mkex->lb_lt_offset = + nix_vlan_rx_mkex_offset(rx_keyx & NPC_KEX_LB_LTYPE_NIBBLE_MASK); + + p = &npc->prx_dxcfg; + x_info = &(*p)[NPC_MCAM_RX][NPC_LID_LA][NPC_LT_LA_ETHER].xtract[0]; + memcpy(&mkex->la_xtract, x_info, sizeof(struct npc_xtract_info)); + x_info = &(*p)[NPC_MCAM_RX][NPC_LID_LB][NPC_LT_LB_CTAG].xtract[0]; + memcpy(&mkex->lb_xtract, x_info, sizeof(struct npc_xtract_info)); + + return 0; +} + +int +otx2_nix_vlan_offload_init(struct rte_eth_dev *eth_dev) +{ + struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev); + int rc; + + /* Port initialized for first time or restarted */ + if (!dev->configured) { + rc = nix_vlan_get_mkex_info(dev); + if (rc) { + otx2_err("Failed to get vlan mkex info rc=%d", rc); + return rc; + } + } + return 0; +} + +int +otx2_nix_vlan_fini(__rte_unused struct rte_eth_dev *eth_dev) +{ + return 0; +}