From patchwork Wed Sep 8 08:37:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 98298 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id BA982A0C56; Wed, 8 Sep 2021 10:38:17 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7EAEC411E1; Wed, 8 Sep 2021 10:37:00 +0200 (CEST) Received: from smtpbgau1.qq.com (smtpbgau1.qq.com [54.206.16.166]) by mails.dpdk.org (Postfix) with ESMTP id 3E822411DC for ; Wed, 8 Sep 2021 10:36:56 +0200 (CEST) X-QQ-mid: bizesmtp47t1631090210thv83uoe Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by esmtp6.qq.com (ESMTP) with id ; Wed, 08 Sep 2021 16:36:49 +0800 (CST) X-QQ-SSF: 01400000002000E0G000B00A0000000 X-QQ-FEAT: r/cTxDoDoiGYKx6n32Xd3z36w0VmcjwGOG5SO2NuExKmVO1HIIzo32GDwyqsi 3pO0QdyRkfC6XfEAN09wgosBAqrNhWaDnlqg/fn2RfJVcIerHXoD8afmdRtK+1Y+552YbYU DWnSLOpp/9Y0ND2Fov2xVqEAxuV3RkaeBm2Jo7SVb/2O+togsUh7xoItrzYAshr4bKf2vVn TttJCPNrNttvqdLBUutfgBtvJzIw9eUwY8Yp6lnI8/Vs8ARHKXlod7ur/+Xxvk6NYSeU68I J+XDNsrIp/VgHkEdaU6YhjtEHGe7LoT5jc7I0DLk/ywd8TuOMLAMYbA9q6Qnts5J33G0Kgq 4xDUsYli2bhM0qUdAyPsSKHB4JL4tYf5fAdED/L X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu Date: Wed, 8 Sep 2021 16:37:42 +0800 Message-Id: <20210908083758.312055-17-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210908083758.312055-1-jiawenwu@trustnetic.com> References: <20210908083758.312055-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign7 X-QQ-Bgrelay: 1 Subject: [dpdk-dev] [PATCH 16/32] net/ngbe: support VLAN filter X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Support to filter of a VLAN tag identifier. Signed-off-by: Jiawen Wu --- doc/guides/nics/features/ngbe.ini | 1 + doc/guides/nics/ngbe.rst | 2 +- drivers/net/ngbe/base/ngbe_dummy.h | 5 ++ drivers/net/ngbe/base/ngbe_hw.c | 29 +++++++ drivers/net/ngbe/base/ngbe_hw.h | 2 + drivers/net/ngbe/base/ngbe_type.h | 3 + drivers/net/ngbe/ngbe_ethdev.c | 128 +++++++++++++++++++++++++++++ 7 files changed, 169 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/features/ngbe.ini b/doc/guides/nics/features/ngbe.ini index 4b22dc683a..265edba361 100644 --- a/doc/guides/nics/features/ngbe.ini +++ b/doc/guides/nics/features/ngbe.ini @@ -17,6 +17,7 @@ Promiscuous mode = Y Allmulticast mode = Y Unicast MAC filter = Y Multicast MAC filter = Y +VLAN filter = Y CRC offload = P VLAN offload = P QinQ offload = P diff --git a/doc/guides/nics/ngbe.rst b/doc/guides/nics/ngbe.rst index 4d01c27064..3683862fd1 100644 --- a/doc/guides/nics/ngbe.rst +++ b/doc/guides/nics/ngbe.rst @@ -11,7 +11,7 @@ for Wangxun 1 Gigabit Ethernet NICs. Features -------- -- MAC filtering +- MAC/VLAN filtering - Packet type information - Checksum offload - VLAN/QinQ stripping and inserting diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index fe2d53f312..7814fd6226 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -132,6 +132,10 @@ static inline s32 ngbe_mac_update_mc_addr_list_dummy(struct ngbe_hw *TUP0, { return NGBE_ERR_OPS_DUMMY; } +static inline s32 ngbe_mac_clear_vfta_dummy(struct ngbe_hw *TUP0) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_mac_init_thermal_ssth_dummy(struct ngbe_hw *TUP0) { return NGBE_ERR_OPS_DUMMY; @@ -209,6 +213,7 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) hw->mac.clear_vmdq = ngbe_mac_clear_vmdq_dummy; hw->mac.init_rx_addrs = ngbe_mac_init_rx_addrs_dummy; hw->mac.update_mc_addr_list = ngbe_mac_update_mc_addr_list_dummy; + hw->mac.clear_vfta = ngbe_mac_clear_vfta_dummy; hw->mac.init_thermal_sensor_thresh = ngbe_mac_init_thermal_ssth_dummy; hw->mac.check_overtemp = ngbe_mac_check_overtemp_dummy; hw->phy.identify = ngbe_phy_identify_dummy; diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index 897baf179d..ce0867575a 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -19,6 +19,9 @@ s32 ngbe_start_hw(struct ngbe_hw *hw) { DEBUGFUNC("ngbe_start_hw"); + /* Clear the VLAN filter table */ + hw->mac.clear_vfta(hw); + /* Clear statistics registers */ hw->mac.clear_hw_cntrs(hw); @@ -910,6 +913,30 @@ s32 ngbe_init_uta_tables(struct ngbe_hw *hw) return 0; } +/** + * ngbe_clear_vfta - Clear VLAN filter table + * @hw: pointer to hardware structure + * + * Clears the VLAN filer table, and the VMDq index associated with the filter + **/ +s32 ngbe_clear_vfta(struct ngbe_hw *hw) +{ + u32 offset; + + DEBUGFUNC("ngbe_clear_vfta"); + + for (offset = 0; offset < hw->mac.vft_size; offset++) + wr32(hw, NGBE_VLANTBL(offset), 0); + + for (offset = 0; offset < NGBE_NUM_POOL; offset++) { + wr32(hw, NGBE_PSRVLANIDX, offset); + wr32(hw, NGBE_PSRVLAN, 0); + wr32(hw, NGBE_PSRVLANPLM(0), 0); + } + + return 0; +} + /** * ngbe_check_mac_link_em - Determine link and speed status * @hw: pointer to hardware structure @@ -1238,6 +1265,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) mac->update_mc_addr_list = ngbe_update_mc_addr_list; mac->set_vmdq = ngbe_set_vmdq; mac->clear_vmdq = ngbe_clear_vmdq; + mac->clear_vfta = ngbe_clear_vfta; /* Link */ mac->get_link_capabilities = ngbe_get_link_capabilities_em; @@ -1254,6 +1282,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) rom->validate_checksum = ngbe_validate_eeprom_checksum_em; mac->mcft_size = NGBE_EM_MC_TBL_SIZE; + mac->vft_size = NGBE_EM_VFT_TBL_SIZE; mac->num_rar_entries = NGBE_EM_RAR_ENTRIES; mac->max_rx_queues = NGBE_EM_MAX_RX_QUEUES; mac->max_tx_queues = NGBE_EM_MAX_TX_QUEUES; diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index f06baa4395..a27bd3e650 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -12,6 +12,7 @@ #define NGBE_EM_MAX_RX_QUEUES 8 #define NGBE_EM_RAR_ENTRIES 32 #define NGBE_EM_MC_TBL_SIZE 32 +#define NGBE_EM_VFT_TBL_SIZE 128 s32 ngbe_init_hw(struct ngbe_hw *hw); s32 ngbe_start_hw(struct ngbe_hw *hw); @@ -48,6 +49,7 @@ void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask); s32 ngbe_set_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq); s32 ngbe_clear_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq); s32 ngbe_init_uta_tables(struct ngbe_hw *hw); +s32 ngbe_clear_vfta(struct ngbe_hw *hw); s32 ngbe_init_thermal_sensor_thresh(struct ngbe_hw *hw); s32 ngbe_mac_check_overtemp(struct ngbe_hw *hw); diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 3e62dde707..5a88d38e84 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -10,6 +10,7 @@ #define NGBE_FRAME_SIZE_MAX (9728) /* Maximum frame size, +FCS */ #define NGBE_FRAME_SIZE_DFT (1522) /* Default frame size, +FCS */ +#define NGBE_NUM_POOL (32) #define NGBE_MAX_QP (8) #define NGBE_MAX_UTA 128 @@ -252,6 +253,7 @@ struct ngbe_mac_info { s32 (*update_mc_addr_list)(struct ngbe_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, ngbe_mc_addr_itr func, bool clear); + s32 (*clear_vfta)(struct ngbe_hw *hw); /* Manageability interface */ s32 (*init_thermal_sensor_thresh)(struct ngbe_hw *hw); @@ -264,6 +266,7 @@ struct ngbe_mac_info { u32 mta_shadow[NGBE_MAX_MTA]; s32 mc_filter_type; u32 mcft_size; + u32 vft_size; u32 num_rar_entries; u32 max_tx_queues; u32 max_rx_queues; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index d076ba8036..acc018c811 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -492,6 +492,131 @@ static struct rte_pci_driver rte_ngbe_pmd = { .remove = eth_ngbe_pci_remove, }; +static int +ngbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct ngbe_vfta *shadow_vfta = NGBE_DEV_VFTA(dev); + uint32_t vfta; + uint32_t vid_idx; + uint32_t vid_bit; + + vid_idx = (uint32_t)((vlan_id >> 5) & 0x7F); + vid_bit = (uint32_t)(1 << (vlan_id & 0x1F)); + vfta = rd32(hw, NGBE_VLANTBL(vid_idx)); + if (on) + vfta |= vid_bit; + else + vfta &= ~vid_bit; + wr32(hw, NGBE_VLANTBL(vid_idx), vfta); + + /* update local VFTA copy */ + shadow_vfta->vfta[vid_idx] = vfta; + + return 0; +} + +static void +ngbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + struct ngbe_rx_queue *rxq; + bool restart; + uint32_t rxcfg, rxbal, rxbah; + + if (on) + ngbe_vlan_hw_strip_enable(dev, queue); + else + ngbe_vlan_hw_strip_disable(dev, queue); + + rxq = dev->data->rx_queues[queue]; + rxbal = rd32(hw, NGBE_RXBAL(rxq->reg_idx)); + rxbah = rd32(hw, NGBE_RXBAH(rxq->reg_idx)); + rxcfg = rd32(hw, NGBE_RXCFG(rxq->reg_idx)); + if (rxq->offloads & DEV_RX_OFFLOAD_VLAN_STRIP) { + restart = (rxcfg & NGBE_RXCFG_ENA) && + !(rxcfg & NGBE_RXCFG_VLAN); + rxcfg |= NGBE_RXCFG_VLAN; + } else { + restart = (rxcfg & NGBE_RXCFG_ENA) && + (rxcfg & NGBE_RXCFG_VLAN); + rxcfg &= ~NGBE_RXCFG_VLAN; + } + rxcfg &= ~NGBE_RXCFG_ENA; + + if (restart) { + /* set vlan strip for ring */ + ngbe_dev_rx_queue_stop(dev, queue); + wr32(hw, NGBE_RXBAL(rxq->reg_idx), rxbal); + wr32(hw, NGBE_RXBAH(rxq->reg_idx), rxbah); + wr32(hw, NGBE_RXCFG(rxq->reg_idx), rxcfg); + ngbe_dev_rx_queue_start(dev, queue); + } +} + +static int +ngbe_vlan_tpid_set(struct rte_eth_dev *dev, + enum rte_vlan_type vlan_type, + uint16_t tpid) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + int ret = 0; + uint32_t portctrl, vlan_ext, qinq; + + portctrl = rd32(hw, NGBE_PORTCTL); + + vlan_ext = (portctrl & NGBE_PORTCTL_VLANEXT); + qinq = vlan_ext && (portctrl & NGBE_PORTCTL_QINQ); + switch (vlan_type) { + case ETH_VLAN_TYPE_INNER: + if (vlan_ext) { + wr32m(hw, NGBE_VLANCTL, + NGBE_VLANCTL_TPID_MASK, + NGBE_VLANCTL_TPID(tpid)); + wr32m(hw, NGBE_DMATXCTRL, + NGBE_DMATXCTRL_TPID_MASK, + NGBE_DMATXCTRL_TPID(tpid)); + } else { + ret = -ENOTSUP; + PMD_DRV_LOG(ERR, + "Inner type is not supported by single VLAN"); + } + + if (qinq) { + wr32m(hw, NGBE_TAGTPID(0), + NGBE_TAGTPID_LSB_MASK, + NGBE_TAGTPID_LSB(tpid)); + } + break; + case ETH_VLAN_TYPE_OUTER: + if (vlan_ext) { + /* Only the high 16-bits is valid */ + wr32m(hw, NGBE_EXTAG, + NGBE_EXTAG_VLAN_MASK, + NGBE_EXTAG_VLAN(tpid)); + } else { + wr32m(hw, NGBE_VLANCTL, + NGBE_VLANCTL_TPID_MASK, + NGBE_VLANCTL_TPID(tpid)); + wr32m(hw, NGBE_DMATXCTRL, + NGBE_DMATXCTRL_TPID_MASK, + NGBE_DMATXCTRL_TPID(tpid)); + } + + if (qinq) { + wr32m(hw, NGBE_TAGTPID(0), + NGBE_TAGTPID_MSB_MASK, + NGBE_TAGTPID_MSB(tpid)); + } + break; + default: + PMD_DRV_LOG(ERR, "Unsupported VLAN type %d", vlan_type); + return -EINVAL; + } + + return ret; +} + void ngbe_vlan_hw_filter_disable(struct rte_eth_dev *dev) { @@ -2411,7 +2536,10 @@ static const struct eth_dev_ops ngbe_eth_dev_ops = { .queue_stats_mapping_set = ngbe_dev_queue_stats_mapping_set, .fw_version_get = ngbe_fw_version_get, .mtu_set = ngbe_dev_mtu_set, + .vlan_filter_set = ngbe_vlan_filter_set, + .vlan_tpid_set = ngbe_vlan_tpid_set, .vlan_offload_set = ngbe_vlan_offload_set, + .vlan_strip_queue_set = ngbe_vlan_strip_queue_set, .rx_queue_start = ngbe_dev_rx_queue_start, .rx_queue_stop = ngbe_dev_rx_queue_stop, .tx_queue_start = ngbe_dev_tx_queue_start,