From patchwork Sun Jun 30 18:05:57 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: 55731 X-Patchwork-Delegate: jerinj@marvell.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 A3B9E1BC07; Sun, 30 Jun 2019 20:11:23 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by dpdk.org (Postfix) with ESMTP id 78F7A1BB21 for ; Sun, 30 Jun 2019 20:08: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 x5UI54D9015680; Sun, 30 Jun 2019 11:08: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=9KCarRjYSUSZl3y9rDpcRHWSRMstXNOxLwRv1Cg9r7o=; b=Ypvki5E6Z4Zn2+rB2tUpajZ2xg60g3gqj+32GKXV7jTCRxAon4YZxgwls0rIVuD7cqDF L0FqGWzMH9M8ptGKLT3z4YVDZXkq+SX8gALi2Hw/B4Agc4GPJac94GVVPxXpkMotcm3o LoFAwuwbJEQ6lwKxtcGqdBpXHZrhGo3A5XdhQmC3L6QRXuip4vHgKkldbIWpnhIajPNe daUxrAa5czPVNMISrsQJmdP2bEKaKE4cBgijBQIK8nhuXT68lINKCq1U0NngSMQFtRaK b9czuF8g/GAaFF3xuqOJnlqzH7U5o+zRmAmfun1fKYNsReJ4aXN1QSNhDMWdlU6pdrAr wg== Received: from sc-exch04.marvell.com ([199.233.58.184]) by mx0b-0016f401.pphosted.com with ESMTP id 2te7gm3yeg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Sun, 30 Jun 2019 11:08:51 -0700 Received: from SC-EXCH01.marvell.com (10.93.176.81) by SC-EXCH04.marvell.com (10.93.176.84) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Sun, 30 Jun 2019 11:08:49 -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, 30 Jun 2019 11:08:49 -0700 Received: from jerin-lab.marvell.com (jerin-lab.marvell.com [10.28.34.14]) by maili.marvell.com (Postfix) with ESMTP id A42763F703F; Sun, 30 Jun 2019 11:08:47 -0700 (PDT) From: To: , John McNamara , Marko Kovacevic , Jerin Jacob , "Nithin Dabilpuram" , Kiran Kumar K CC: Vivek Sharma Date: Sun, 30 Jun 2019 23:35:57 +0530 Message-ID: <20190630180609.36705-46-jerinj@marvell.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190630180609.36705-1-jerinj@marvell.com> References: <20190602152434.23996-1-jerinj@marvell.com> <20190630180609.36705-1-jerinj@marvell.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-06-30_08:, , signatures=0 Subject: [dpdk-dev] [PATCH v2 45/57] net/octeontx2: support VLAN filters 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 Support setting up VLAN filters so as to allow tagged packet's reception after VLAN HW Filter offload is enabled. Signed-off-by: Vivek Sharma --- doc/guides/nics/features/octeontx2.ini | 1 + doc/guides/nics/features/octeontx2_vec.ini | 1 + doc/guides/nics/features/octeontx2_vf.ini | 1 + doc/guides/nics/octeontx2.rst | 2 +- drivers/net/octeontx2/otx2_ethdev.c | 2 + drivers/net/octeontx2/otx2_ethdev.h | 4 + drivers/net/octeontx2/otx2_vlan.c | 149 ++++++++++++++++++++- 7 files changed, 157 insertions(+), 3 deletions(-) diff --git a/doc/guides/nics/features/octeontx2.ini b/doc/guides/nics/features/octeontx2.ini index ac4712b0c..37b802999 100644 --- a/doc/guides/nics/features/octeontx2.ini +++ b/doc/guides/nics/features/octeontx2.ini @@ -21,6 +21,7 @@ RSS hash = Y RSS key update = Y RSS reta update = Y Inner RSS = Y +VLAN filter = Y Flow control = Y Flow API = Y VLAN offload = Y diff --git a/doc/guides/nics/features/octeontx2_vec.ini b/doc/guides/nics/features/octeontx2_vec.ini index e54c1babe..ccedd1359 100644 --- a/doc/guides/nics/features/octeontx2_vec.ini +++ b/doc/guides/nics/features/octeontx2_vec.ini @@ -21,6 +21,7 @@ RSS hash = Y RSS key update = Y RSS reta update = Y Inner RSS = Y +VLAN filter = Y Flow control = Y Flow API = Y VLAN offload = Y diff --git a/doc/guides/nics/features/octeontx2_vf.ini b/doc/guides/nics/features/octeontx2_vf.ini index 769ab16ee..24df14717 100644 --- a/doc/guides/nics/features/octeontx2_vf.ini +++ b/doc/guides/nics/features/octeontx2_vf.ini @@ -17,6 +17,7 @@ RSS hash = Y RSS key update = Y RSS reta update = Y Inner RSS = Y +VLAN filter = Y Flow API = Y VLAN offload = Y QinQ offload = Y diff --git a/doc/guides/nics/octeontx2.rst b/doc/guides/nics/octeontx2.rst index a53b71a6d..d6082e508 100644 --- a/doc/guides/nics/octeontx2.rst +++ b/doc/guides/nics/octeontx2.rst @@ -22,7 +22,7 @@ Features of the OCTEON TX2 Ethdev PMD are: - Lock-free Tx queue - Multiple queues for TX and RX - Receiver Side Scaling (RSS) -- MAC filtering +- MAC/VLAN filtering - Generic flow API - VLAN/QinQ stripping and insertion - Port hardware statistics diff --git a/drivers/net/octeontx2/otx2_ethdev.c b/drivers/net/octeontx2/otx2_ethdev.c index 55a5cdc48..78cbd8811 100644 --- a/drivers/net/octeontx2/otx2_ethdev.c +++ b/drivers/net/octeontx2/otx2_ethdev.c @@ -1346,6 +1346,8 @@ static const struct eth_dev_ops otx2_eth_dev_ops = { .timesync_read_time = otx2_nix_timesync_read_time, .timesync_write_time = otx2_nix_timesync_write_time, .vlan_offload_set = otx2_nix_vlan_offload_set, + .vlan_filter_set = otx2_nix_vlan_filter_set, + .vlan_strip_queue_set = otx2_nix_vlan_strip_queue_set, }; static inline int diff --git a/drivers/net/octeontx2/otx2_ethdev.h b/drivers/net/octeontx2/otx2_ethdev.h index 50fd18b6e..996ddec47 100644 --- a/drivers/net/octeontx2/otx2_ethdev.h +++ b/drivers/net/octeontx2/otx2_ethdev.h @@ -450,6 +450,10 @@ int otx2_nix_vlan_offload_init(struct rte_eth_dev *eth_dev); int otx2_nix_vlan_fini(struct rte_eth_dev *eth_dev); int otx2_nix_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask); void otx2_nix_vlan_update_promisc(struct rte_eth_dev *eth_dev, int enable); +int otx2_nix_vlan_filter_set(struct rte_eth_dev *eth_dev, uint16_t vlan_id, + int on); +void otx2_nix_vlan_strip_queue_set(struct rte_eth_dev *dev, + uint16_t queue, int on); /* Lookup configuration */ void *otx2_nix_fastpath_lookup_mem_get(void); diff --git a/drivers/net/octeontx2/otx2_vlan.c b/drivers/net/octeontx2/otx2_vlan.c index 7cf4f3136..6216d6545 100644 --- a/drivers/net/octeontx2/otx2_vlan.c +++ b/drivers/net/octeontx2/otx2_vlan.c @@ -22,8 +22,8 @@ enum vtag_cfg_dir { }; static int -__rte_unused nix_vlan_mcam_enb_dis(struct otx2_eth_dev *dev, - uint32_t entry, const int enable) +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; @@ -460,6 +460,8 @@ nix_vlan_hw_filter(struct rte_eth_dev *eth_dev, const uint8_t enable, uint16_t vlan_id) { struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev); + struct otx2_vlan_info *vlan = &dev->vlan_info; + struct vlan_entry *entry; int rc = -EINVAL; if (!vlan_id && enable) { @@ -473,6 +475,24 @@ nix_vlan_hw_filter(struct rte_eth_dev *eth_dev, const uint8_t enable, return 0; } + /* Enable/disable existing vlan filter entries */ + TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) { + if (vlan_id) { + if (entry->vlan_id == vlan_id) { + rc = nix_vlan_mcam_enb_dis(dev, + entry->mcam_idx, + enable); + if (rc) + return rc; + } + } else { + rc = nix_vlan_mcam_enb_dis(dev, entry->mcam_idx, + enable); + if (rc) + return rc; + } + } + if (!vlan_id && !enable) { rc = nix_vlan_handle_default_rx_entry(eth_dev, false, true, enable); @@ -487,6 +507,85 @@ nix_vlan_hw_filter(struct rte_eth_dev *eth_dev, const uint8_t enable, return 0; } +/* Enable/disable vlan filtering for the given vlan_id */ +int +otx2_nix_vlan_filter_set(struct rte_eth_dev *eth_dev, uint16_t vlan_id, + int on) +{ + struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev); + struct otx2_vlan_info *vlan = &dev->vlan_info; + struct vlan_entry *entry; + int entry_exists = 0; + int rc = -EINVAL; + int mcam_idx; + + if (!vlan_id) { + otx2_err("Vlan Id can't be zero"); + return rc; + } + + if (!vlan->def_rx_mcam_idx) { + otx2_err("Vlan Filtering is disabled, enable it first"); + return rc; + } + + if (on) { + TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) { + if (entry->vlan_id == vlan_id) { + /* Vlan entry already exists */ + entry_exists = 1; + /* Mcam entry already allocated */ + if (entry->mcam_idx) { + rc = nix_vlan_hw_filter(eth_dev, on, + vlan_id); + return rc; + } + break; + } + } + + if (!entry_exists) { + entry = rte_zmalloc("otx2_nix_vlan_entry", + sizeof(struct vlan_entry), 0); + if (!entry) { + otx2_err("Failed to allocate memory"); + return -ENOMEM; + } + } + + /* Enables vlan_id & mac address based filtering */ + if (eth_dev->data->promiscuous) + mcam_idx = nix_vlan_mcam_config(eth_dev, vlan_id, + VLAN_ID_MATCH); + else + mcam_idx = nix_vlan_mcam_config(eth_dev, vlan_id, + VLAN_ID_MATCH | + MAC_ADDR_MATCH); + if (mcam_idx < 0) { + otx2_err("Failed to config vlan mcam"); + TAILQ_REMOVE(&vlan->fltr_tbl, entry, next); + rte_free(entry); + return mcam_idx; + } + + entry->mcam_idx = mcam_idx; + if (!entry_exists) { + entry->vlan_id = vlan_id; + TAILQ_INSERT_HEAD(&vlan->fltr_tbl, entry, next); + } + } else { + TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) { + if (entry->vlan_id == vlan_id) { + nix_vlan_mcam_free(dev, entry->mcam_idx); + TAILQ_REMOVE(&vlan->fltr_tbl, entry, next); + rte_free(entry); + break; + } + } + } + return 0; +} + /* Configure double vlan(qinq) on or off */ static int otx2_nix_config_double_vlan(struct rte_eth_dev *eth_dev, @@ -594,6 +693,13 @@ otx2_nix_vlan_offload_set(struct rte_eth_dev *eth_dev, int mask) return rc; } +void otx2_nix_vlan_strip_queue_set(__rte_unused struct rte_eth_dev *dev, + __rte_unused uint16_t queue, + __rte_unused int on) +{ + otx2_err("Not Supported"); +} + static int nix_vlan_rx_mkex_offset(uint64_t mask) { @@ -646,6 +752,27 @@ nix_vlan_get_mkex_info(struct otx2_eth_dev *dev) return 0; } +static void nix_vlan_reinstall_vlan_filters(struct rte_eth_dev *eth_dev) +{ + struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev); + struct vlan_entry *entry; + int rc; + + /* VLAN filters can't be set without setting filtern on */ + rc = nix_vlan_handle_default_rx_entry(eth_dev, false, true, true); + if (rc) { + otx2_err("Failed to reinstall vlan filters"); + return; + } + + TAILQ_FOREACH(entry, &dev->vlan_info.fltr_tbl, next) { + rc = otx2_nix_vlan_filter_set(eth_dev, entry->vlan_id, true); + if (rc) + otx2_err("Failed to reinstall filter for vlan:%d", + entry->vlan_id); + } +} + int otx2_nix_vlan_offload_init(struct rte_eth_dev *eth_dev) { @@ -661,6 +788,11 @@ otx2_nix_vlan_offload_init(struct rte_eth_dev *eth_dev) } TAILQ_INIT(&dev->vlan_info.fltr_tbl); + } else { + /* Reinstall all mcam entries now if filter offload is set */ + if (eth_dev->data->dev_conf.rxmode.offloads & + DEV_RX_OFFLOAD_VLAN_FILTER) + nix_vlan_reinstall_vlan_filters(eth_dev); } mask = @@ -679,8 +811,21 @@ otx2_nix_vlan_fini(struct rte_eth_dev *eth_dev) { struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev); struct otx2_vlan_info *vlan = &dev->vlan_info; + struct vlan_entry *entry; int rc; + TAILQ_FOREACH(entry, &vlan->fltr_tbl, next) { + if (!dev->configured) { + TAILQ_REMOVE(&vlan->fltr_tbl, entry, next); + rte_free(entry); + } else { + /* MCAM entries freed by flow_fini & lf_free on + * port stop. + */ + entry->mcam_idx = 0; + } + } + if (!dev->configured) { if (vlan->def_rx_mcam_idx) { rc = nix_vlan_mcam_free(dev, vlan->def_rx_mcam_idx);