From patchwork Fri Jun 2 06:36:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhao1, Wei" X-Patchwork-Id: 25021 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 [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 5F47B7D27; Fri, 2 Jun 2017 08:45:44 +0200 (CEST) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 9333F7D18 for ; Fri, 2 Jun 2017 08:45:38 +0200 (CEST) Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga104.jf.intel.com with ESMTP; 01 Jun 2017 23:45:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.39,283,1493708400"; d="scan'208";a="110013433" Received: from dpdk1.bj.intel.com ([172.16.182.84]) by fmsmga006.fm.intel.com with ESMTP; 01 Jun 2017 23:45:33 -0700 From: Wei Zhao To: dev@dpdk.org Cc: wenzhuo.lu@intel.com, Wei Zhao Date: Fri, 2 Jun 2017 14:36:24 +0800 Message-Id: <1496385391-12445-5-git-send-email-wei.zhao1@intel.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1496385391-12445-1-git-send-email-wei.zhao1@intel.com> References: <1495523581-56027-1-git-send-email-wei.zhao1@intel.com> <1496385391-12445-1-git-send-email-wei.zhao1@intel.com> Subject: [dpdk-dev] [PATCH v2 04/11] net/e1000: restore flex type filter 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" Add support for restoring flex type filter in SW. Signed-off-by: Wei Zhao Acked-by: Wenzhuo Lu --- drivers/net/e1000/igb_ethdev.c | 189 ++++++++++++++++++++++++++--------------- 1 file changed, 122 insertions(+), 67 deletions(-) diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index b2346b3..b1988ac 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -786,6 +786,22 @@ static int igb_ntuple_filter_uninit(struct rte_eth_dev *eth_dev) return 0; } +/* Remove all flex filters of the device */ +static int igb_flex_filter_uninit(struct rte_eth_dev *eth_dev) +{ + struct e1000_filter_info *filter_info = + E1000_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private); + struct e1000_flex_filter *p_flex; + + while ((p_flex = TAILQ_FIRST(&filter_info->flex_list))) { + TAILQ_REMOVE(&filter_info->flex_list, p_flex, entries); + rte_free(p_flex); + } + filter_info->flex_mask = 0; + + return 0; +} + static int eth_igb_dev_init(struct rte_eth_dev *eth_dev) { @@ -1004,6 +1020,9 @@ eth_igb_dev_uninit(struct rte_eth_dev *eth_dev) /* remove all ntuple filters of the device */ igb_ntuple_filter_uninit(eth_dev); + /* remove all flex filters of the device */ + igb_flex_filter_uninit(eth_dev); + return 0; } @@ -1506,11 +1525,8 @@ static void eth_igb_stop(struct rte_eth_dev *dev) { struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); - struct e1000_filter_info *filter_info = - E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private); struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); struct rte_eth_link link; - struct e1000_flex_filter *p_flex; struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; igb_intr_disable(hw); @@ -1539,13 +1555,6 @@ eth_igb_stop(struct rte_eth_dev *dev) memset(&link, 0, sizeof(link)); rte_igb_dev_atomic_write_link_status(dev, &link); - /* Remove all flex filters of the device */ - while ((p_flex = TAILQ_FIRST(&filter_info->flex_list))) { - TAILQ_REMOVE(&filter_info->flex_list, p_flex, entries); - rte_free(p_flex); - } - filter_info->flex_mask = 0; - if (!rte_intr_allow_others(intr_handle)) /* resume to the default handler */ rte_intr_callback_register(intr_handle, @@ -3910,6 +3919,45 @@ igb_remove_2tuple_filter(struct rte_eth_dev *dev, return 0; } +/* inject a igb flex filter to HW */ +static inline void +igb_inject_flex_filter(struct rte_eth_dev *dev, + struct e1000_flex_filter *filter) +{ + struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t wufc, queueing; + uint32_t reg_off; + uint8_t i, j = 0; + + wufc = E1000_READ_REG(hw, E1000_WUFC); + if (filter->index < E1000_MAX_FHFT) + reg_off = E1000_FHFT(filter->index); + else + reg_off = E1000_FHFT_EXT(filter->index - E1000_MAX_FHFT); + + E1000_WRITE_REG(hw, E1000_WUFC, wufc | E1000_WUFC_FLEX_HQ | + (E1000_WUFC_FLX0 << filter->index)); + queueing = filter->filter_info.len | + (filter->queue << E1000_FHFT_QUEUEING_QUEUE_SHIFT) | + (filter->filter_info.priority << + E1000_FHFT_QUEUEING_PRIO_SHIFT); + E1000_WRITE_REG(hw, reg_off + E1000_FHFT_QUEUEING_OFFSET, + queueing); + + for (i = 0; i < E1000_FLEX_FILTERS_MASK_SIZE; i++) { + E1000_WRITE_REG(hw, reg_off, + filter->filter_info.dwords[j]); + reg_off += sizeof(uint32_t); + E1000_WRITE_REG(hw, reg_off, + filter->filter_info.dwords[++j]); + reg_off += sizeof(uint32_t); + E1000_WRITE_REG(hw, reg_off, + (uint32_t)filter->filter_info.mask[i]); + reg_off += sizeof(uint32_t) * 2; + ++j; + } +} + static inline struct e1000_flex_filter * eth_igb_flex_filter_lookup(struct e1000_flex_filter_list *filter_list, struct e1000_flex_filter_info *key) @@ -3925,18 +3973,48 @@ eth_igb_flex_filter_lookup(struct e1000_flex_filter_list *filter_list, return NULL; } -static int +/* remove a flex byte filter + * @param + * dev: Pointer to struct rte_eth_dev. + * filter: the pointer of the filter will be removed. + */ +static void +igb_remove_flex_filter(struct rte_eth_dev *dev, + struct e1000_flex_filter *filter) +{ + struct e1000_filter_info *filter_info = + E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private); + struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t wufc, i; + uint32_t reg_off; + + wufc = E1000_READ_REG(hw, E1000_WUFC); + if (filter->index < E1000_MAX_FHFT) + reg_off = E1000_FHFT(filter->index); + else + reg_off = E1000_FHFT_EXT(filter->index - E1000_MAX_FHFT); + + for (i = 0; i < E1000_FHFT_SIZE_IN_DWD; i++) + E1000_WRITE_REG(hw, reg_off + i * sizeof(uint32_t), 0); + + E1000_WRITE_REG(hw, E1000_WUFC, wufc & + (~(E1000_WUFC_FLX0 << filter->index))); + + filter_info->flex_mask &= ~(1 << filter->index); + TAILQ_REMOVE(&filter_info->flex_list, filter, entries); + rte_free(filter); +} + +int eth_igb_add_del_flex_filter(struct rte_eth_dev *dev, struct rte_eth_flex_filter *filter, bool add) { - struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct e1000_filter_info *filter_info = E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private); struct e1000_flex_filter *flex_filter, *it; - uint32_t wufc, queueing, mask; - uint32_t reg_off; - uint8_t shift, i, j = 0; + uint32_t mask; + uint8_t shift, i; flex_filter = rte_zmalloc("e1000_flex_filter", sizeof(struct e1000_flex_filter), 0); @@ -3956,15 +4034,20 @@ eth_igb_add_del_flex_filter(struct rte_eth_dev *dev, flex_filter->filter_info.mask[i] = mask; } - wufc = E1000_READ_REG(hw, E1000_WUFC); + it = eth_igb_flex_filter_lookup(&filter_info->flex_list, + &flex_filter->filter_info); + if (it == NULL && !add) { + PMD_DRV_LOG(ERR, "filter doesn't exist."); + rte_free(flex_filter); + return -ENOENT; + } + if (it != NULL && add) { + PMD_DRV_LOG(ERR, "filter exists."); + rte_free(flex_filter); + return -EEXIST; + } if (add) { - if (eth_igb_flex_filter_lookup(&filter_info->flex_list, - &flex_filter->filter_info) != NULL) { - PMD_DRV_LOG(ERR, "filter exists."); - rte_free(flex_filter); - return -EEXIST; - } flex_filter->queue = filter->queue; /* * look for an unused flex filter index @@ -3986,52 +4069,10 @@ eth_igb_add_del_flex_filter(struct rte_eth_dev *dev, return -ENOSYS; } - if (flex_filter->index < E1000_MAX_FHFT) - reg_off = E1000_FHFT(flex_filter->index); - else - reg_off = E1000_FHFT_EXT(flex_filter->index - E1000_MAX_FHFT); - - E1000_WRITE_REG(hw, E1000_WUFC, wufc | E1000_WUFC_FLEX_HQ | - (E1000_WUFC_FLX0 << flex_filter->index)); - queueing = filter->len | - (filter->queue << E1000_FHFT_QUEUEING_QUEUE_SHIFT) | - (filter->priority << E1000_FHFT_QUEUEING_PRIO_SHIFT); - E1000_WRITE_REG(hw, reg_off + E1000_FHFT_QUEUEING_OFFSET, - queueing); - for (i = 0; i < E1000_FLEX_FILTERS_MASK_SIZE; i++) { - E1000_WRITE_REG(hw, reg_off, - flex_filter->filter_info.dwords[j]); - reg_off += sizeof(uint32_t); - E1000_WRITE_REG(hw, reg_off, - flex_filter->filter_info.dwords[++j]); - reg_off += sizeof(uint32_t); - E1000_WRITE_REG(hw, reg_off, - (uint32_t)flex_filter->filter_info.mask[i]); - reg_off += sizeof(uint32_t) * 2; - ++j; - } - } else { - it = eth_igb_flex_filter_lookup(&filter_info->flex_list, - &flex_filter->filter_info); - if (it == NULL) { - PMD_DRV_LOG(ERR, "filter doesn't exist."); - rte_free(flex_filter); - return -ENOENT; - } + igb_inject_flex_filter(dev, flex_filter); - if (it->index < E1000_MAX_FHFT) - reg_off = E1000_FHFT(it->index); - else - reg_off = E1000_FHFT_EXT(it->index - E1000_MAX_FHFT); - - for (i = 0; i < E1000_FHFT_SIZE_IN_DWD; i++) - E1000_WRITE_REG(hw, reg_off + i * sizeof(uint32_t), 0); - E1000_WRITE_REG(hw, E1000_WUFC, wufc & - (~(E1000_WUFC_FLX0 << it->index))); - - filter_info->flex_mask &= ~(1 << it->index); - TAILQ_REMOVE(&filter_info->flex_list, it, entries); - rte_free(it); + } else { + igb_remove_flex_filter(dev, it); rte_free(flex_filter); } @@ -5533,6 +5574,19 @@ igb_ethertype_filter_restore(struct rte_eth_dev *dev) } } +/* restore flex byte filter */ +static inline void +igb_flex_filter_restore(struct rte_eth_dev *dev) +{ + struct e1000_filter_info *filter_info = + E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private); + struct e1000_flex_filter *flex_filter; + + TAILQ_FOREACH(flex_filter, &filter_info->flex_list, entries) { + igb_inject_flex_filter(dev, flex_filter); + } +} + /* restore all types filter */ static int igb_filter_restore(struct rte_eth_dev *dev) @@ -5540,6 +5594,7 @@ igb_filter_restore(struct rte_eth_dev *dev) igb_ntuple_filter_restore(dev); igb_ethertype_filter_restore(dev); igb_syn_filter_restore(dev); + igb_flex_filter_restore(dev); return 0; }