From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [143.182.124.21]) by dpdk.org (Postfix) with ESMTP id ECD7C2E8A for ; Tue, 20 May 2014 06:05:49 +0200 (CEST) Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 19 May 2014 21:05:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.98,871,1392192000"; d="scan'208";a="434281412" Received: from shilc102.sh.intel.com ([10.239.39.44]) by azsmga001.ch.intel.com with ESMTP; 19 May 2014 20:53:52 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shilc102.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id s4K3rlKZ006602; Tue, 20 May 2014 11:53:49 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id s4K3rhkE018798; Tue, 20 May 2014 11:53:45 +0800 Received: (from wujingji@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id s4K3rhQ8018794; Tue, 20 May 2014 11:53:43 +0800 From: Jingjing Wu To: dev@dpdk.org Date: Tue, 20 May 2014 11:53:28 +0800 Message-Id: <1400558009-18667-4-git-send-email-jingjing.wu@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1400558009-18667-1-git-send-email-jingjing.wu@intel.com> References: <1400558009-18667-1-git-send-email-jingjing.wu@intel.com> Subject: [dpdk-dev] [PATCH 3/4][PMD][GENERIC_FILTER]add ixgbe NIC filters of generic filter feature X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 May 2014 04:05:50 -0000 This patch adds following ixgbe NIC filters implement for intel NIC 82599 syn filter, ethertype filter, 5tuple filter Signed-off-by: jingjing.wu --- lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 365 ++++++++++++++++++++++++++++++++++++ lib/librte_pmd_ixgbe/ixgbe_ethdev.h | 33 ++++ 2 files changed, 398 insertions(+) diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c index 89ab4aa..49ff0d1 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c @@ -181,6 +181,22 @@ static int ixgbe_mirror_rule_set(struct rte_eth_dev *dev, static int ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id); +static int ixgbe_set_syn_filter(struct rte_eth_dev *dev, + struct rte_syn_filter *filter, uint8_t rx_queue); +static int ixgbe_get_syn_filter(struct rte_eth_dev *dev, + struct rte_syn_filter *filter, uint8_t *rx_queue); +static int ixgbe_add_ethertype_filter(struct rte_eth_dev *dev, uint16_t index, + struct rte_ethertype_filter *filter, uint8_t rx_queue); +static int ixgbe_remove_ethertype_filter(struct rte_eth_dev *dev, uint16_t index); +static int ixgbe_get_ethertype_filter(struct rte_eth_dev *dev, uint16_t index, + struct rte_ethertype_filter *filter, uint8_t *rx_queue); +static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index, + struct rte_5tuple_filter *filter, uint8_t rx_queue); +static int ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev, + uint16_t index); +static int ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index, + struct rte_5tuple_filter *filter, uint8_t *rx_queue); + /* * Define VF Stats MACRO for Non "cleared on read" register */ @@ -300,6 +316,14 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = { .bypass_ver_show = ixgbe_bypass_ver_show, .bypass_wd_reset = ixgbe_bypass_wd_reset, #endif /* RTE_NIC_BYPASS */ + .set_syn_filter = ixgbe_set_syn_filter, + .get_syn_filter = ixgbe_get_syn_filter, + .add_ethertype_filter = ixgbe_add_ethertype_filter, + .remove_ethertype_filter = ixgbe_remove_ethertype_filter, + .get_ethertype_filter = ixgbe_get_ethertype_filter, + .add_5tuple_filter = ixgbe_add_5tuple_filter, + .remove_5tuple_filter = ixgbe_remove_5tuple_filter, + .get_5tuple_filter = ixgbe_get_5tuple_filter, }; /* @@ -3060,3 +3084,344 @@ ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id) return 0; } + +/* + * set the syn filter + * + * @param + * dev: Pointer to struct rte_eth_dev. + * syn: 1 means enable, 0 means disable. + * rx_queue: the queue id the filter assigned to + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ixgbe_set_syn_filter(struct rte_eth_dev *dev, + struct rte_syn_filter *filter, uint8_t rx_queue) +{ + struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t synqf; + + if (hw->mac.type != ixgbe_mac_82599EB) + return -ENOSYS; + + if (rx_queue >= IXGBE_MAX_RX_QUEUE_NUM) + return (-EINVAL); + + synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF); + + if (filter->enable) + synqf = (uint32_t)(((rx_queue << IXGBE_SYN_FILTER_QUEUE_SHIFT) & + IXGBE_SYN_FILTER_QUEUE) | IXGBE_SYN_FILTER_ENABLE); + else + synqf &= ~(IXGBE_SYN_FILTER_QUEUE | IXGBE_SYN_FILTER_ENABLE); + + + if (filter->hig_pri) + synqf |= IXGBE_SYN_FILTER_SYNQFP; + else + synqf &= ~IXGBE_SYN_FILTER_SYNQFP; + + IXGBE_WRITE_REG(hw, IXGBE_SYNQF, synqf); + + return 0; +} + +/* + * get the syn filter's info + * + * @param + * dev: Pointer to struct rte_eth_dev. + * *syn: pointer to syn value (1 means enable, 0 means disable). + * *rx_queue: pointer to the queue id the filter assigned to + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ixgbe_get_syn_filter(struct rte_eth_dev *dev, + struct rte_syn_filter *filter, uint8_t *rx_queue) + +{ + struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t synqf; + + if (hw->mac.type != ixgbe_mac_82599EB) + return -ENOSYS; + + synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF); + filter->enable = (synqf & IXGBE_SYN_FILTER_ENABLE) ? 1 : 0; + filter->hig_pri = (synqf & IXGBE_SYN_FILTER_SYNQFP) ? 1 : 0; + *rx_queue = (uint8_t)((synqf & IXGBE_SYN_FILTER_QUEUE)>> 1); + + return 0; +} + +/* + * add an ethertype filter + * + * @param + * dev: Pointer to struct rte_eth_dev. + * index: the index the filter allocates + * filter: ponter to the filter that will be added + * rx_queue: the queue id the filter assigned to + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ixgbe_add_ethertype_filter(struct rte_eth_dev *dev, + uint16_t index, struct rte_ethertype_filter *filter, + uint8_t rx_queue) +{ + struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t etqf, etqs = 0; + + if (hw->mac.type != ixgbe_mac_82599EB) + return -ENOSYS; + + if (index >= IXGBE_MAX_ETQF_FILTERS || rx_queue >= IXGBE_MAX_RX_QUEUE_NUM) + return (-EINVAL); + + etqf = IXGBE_READ_REG(hw, IXGBE_ETQF(index)); + if (etqf & IXGBE_ETQF_FILTER_EN) + return (-EINVAL); /** filter index is in use*/ + + etqf = 0; + etqf |= IXGBE_ETQF_FILTER_EN; + etqf |= (uint32_t)filter->ethertype; + + if (filter->priority_en){ + if (filter->priority > IXGBE_ETQF_MAX_PRI) + return (-EINVAL); + etqf |= (uint32_t)((filter->priority << IXGBE_ETQF_SHIFT ) & IXGBE_ETQF_UP); + etqf |= IXGBE_ETQF_UP_EN; + } + etqs |= (uint32_t)((rx_queue << IXGBE_ETQS_RX_QUEUE_SHIFT) & IXGBE_ETQS_RX_QUEUE); + etqs |= IXGBE_ETQS_QUEUE_EN; + + IXGBE_WRITE_REG(hw, IXGBE_ETQF(index), etqf); + IXGBE_WRITE_REG(hw, IXGBE_ETQS(index), etqs); + + return 0; +} + +/* + * remove an ethertype filter + * + * @param + * dev: Pointer to struct rte_eth_dev. + * index: the index the filter allocates + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ixgbe_remove_ethertype_filter(struct rte_eth_dev *dev, + uint16_t index) +{ + struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if (hw->mac.type != ixgbe_mac_82599EB) + return -ENOSYS; + + if (index >= IXGBE_MAX_ETQF_FILTERS) + return (-EINVAL); + + IXGBE_WRITE_REG(hw, IXGBE_ETQF(index), 0); + IXGBE_WRITE_REG(hw, IXGBE_ETQS(index), 0); + + return 0; +} + +/* + * gets an ethertype filter + * + * @param + * dev: Pointer to struct rte_eth_dev. + * index: the index the filter allocates + * filter: ponter to the filter that will be gotten + * *rx_queue: the ponited of the queue id the filter assigned to + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ixgbe_get_ethertype_filter(struct rte_eth_dev *dev, + uint16_t index, struct rte_ethertype_filter *filter, + uint8_t *rx_queue) +{ + struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t etqf, etqs; + + if (hw->mac.type != ixgbe_mac_82599EB) + return -ENOSYS; + + if (index >= IXGBE_MAX_ETQF_FILTERS) + return (-EINVAL); + + etqf = IXGBE_READ_REG(hw, IXGBE_ETQF(index)); + etqs = IXGBE_READ_REG(hw, IXGBE_ETQS(index)); + if (etqf & IXGBE_ETQF_FILTER_EN){ + filter->ethertype = etqf & IXGBE_ETQF_ETHERTYPE; + filter->priority_en = (etqf & IXGBE_ETQF_UP_EN)? 1 : 0; + if (filter->priority_en) + filter->priority = (etqf & IXGBE_ETQF_UP) >> 16; + *rx_queue = (etqs & IXGBE_ETQS_RX_QUEUE) >> IXGBE_ETQS_RX_QUEUE_SHIFT; + return 0; + } + + return (-ENOENT); +} + +/* + * add a 5tuple filter + * + * @param + * dev: Pointer to struct rte_eth_dev. + * index: the index the filter allocates + * filter: ponter to the filter that will be added + * rx_queue: the queue id the filter assigned to + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index, + struct rte_5tuple_filter *filter, uint8_t rx_queue) +{ + struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t ftqf, sdpqf = 0; + uint32_t l34timir = 0; + + if (hw->mac.type != ixgbe_mac_82599EB) + return -ENOSYS; + + if (index >= IXGBE_MAX_FTQF_FILTERS || rx_queue >= IXGBE_MAX_RX_QUEUE_NUM || + filter->priority > IXGBE_5TUPLE_MAX_PRI || + filter->priority < IXGBE_5TUPLE_MIN_PRI) + return (-EINVAL); /** filter index is out of range*/ + + ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index)); + if (ftqf & IXGBR_FTQF_ENABLE) + return (-EINVAL); /** filter index is in use*/ + ftqf = 0; + + sdpqf = (uint32_t)(filter->dst_port << IXGBE_SDQPF_DSTPORT_SHIFT); + sdpqf = sdpqf |(filter->src_port & IXGBE_SDQPF_SRCPORT); + + ftqf |= (uint32_t)(filter->l4type & IXGBR_FTQF_PROTOCOL); + ftqf |= (uint32_t)((filter->priority << IXGBR_FTQF_PRIORITY_SHIFT) & IXGBR_FTQF_PRIORITY); + if (filter->src_ip_mask == 1) /** 1b means not compare*/ + ftqf |= IXGBR_FTQF_SRCIP_MASK; + if (filter->dst_ip_mask == 1) + ftqf |= IXGBR_FTQF_DSTIP_MASK; + if (filter->src_port_mask == 1) + ftqf |= IXGBR_FTQF_SRCPORT_MASK; + if (filter->dst_port_mask == 1) + ftqf |= IXGBR_FTQF_DSTPORT_MASK; + if (filter->l4type_mask == 1) + ftqf |= IXGBR_FTQF_L4TYPE_MASK; + ftqf |= IXGBR_FTQF_POOL_MASK; + ftqf |= IXGBR_FTQF_ENABLE; + + IXGBE_WRITE_REG(hw, IXGBE_DAQF(index), filter->dst_ip); + IXGBE_WRITE_REG(hw, IXGBE_SAQF(index), filter->src_ip); + IXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), sdpqf); + IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), ftqf); + + l34timir |= IXGBE_L34T_IMIR_RESERVE ; + l34timir |= (uint32_t)(rx_queue << IXGBE_L34T_IMIR_QUEUE_SHIFT); + IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), l34timir); + + return 0; +} + +/* + * remove a 5tuple filter + * + * @param + * dev: Pointer to struct rte_eth_dev. + * index: the index the filter allocates + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev, + uint16_t index) +{ + struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if (hw->mac.type != ixgbe_mac_82599EB) + return -ENOSYS; + + if (index >= IXGBE_MAX_FTQF_FILTERS) + return (-EINVAL); /** filter index is out of range*/ + + IXGBE_WRITE_REG(hw, IXGBE_DAQF(index), 0); + IXGBE_WRITE_REG(hw, IXGBE_SAQF(index), 0); + IXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), 0); + IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), 0); + IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), 0); + IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), 0); + return 0; + +} + +/* + * get a 5tuple filter + * + * @param + * dev: Pointer to struct rte_eth_dev. + * index: the index the filter allocates + * filter: ponter to the filter that returns + * *rx_queue: pointer of the queue id the filter assigned to + * + * @return + * - On success, zero. + * - On failure, a negative value. + */ +static int +ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index, + struct rte_5tuple_filter *filter, uint8_t *rx_queue) +{ + struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t sdpqf, ftqf, l34timir; + + if (hw->mac.type != ixgbe_mac_82599EB) + return -ENOSYS; + + if (index >= IXGBE_MAX_FTQF_FILTERS) + return (-EINVAL); /** filter index is out of range*/ + + ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index)); + if (ftqf & IXGBR_FTQF_ENABLE){ + filter->l4type = (enum rte_filter_l4type)(ftqf & IXGBR_FTQF_PROTOCOL); + filter->priority = (ftqf & IXGBR_FTQF_PRIORITY) >> IXGBR_FTQF_PRIORITY_SHIFT; + filter->src_ip_mask = (ftqf & IXGBR_FTQF_SRCIP_MASK) ? 1 : 0; + filter->dst_ip_mask = (ftqf & IXGBR_FTQF_DSTIP_MASK) ? 1 : 0; + filter->src_port_mask = (ftqf & IXGBR_FTQF_SRCPORT_MASK) ? 1 : 0; + filter->dst_port_mask = (ftqf & IXGBR_FTQF_DSTPORT_MASK) ? 1 : 0; + filter->l4type_mask = (ftqf & IXGBR_FTQF_L4TYPE_MASK) ? 1 : 0; + + sdpqf = IXGBE_READ_REG(hw, IXGBE_SDPQF(index)); + filter->dst_port = (sdpqf & IXGBE_SDQPF_DSTPORT) >> IXGBE_SDQPF_DSTPORT_SHIFT; + filter->src_port = sdpqf & IXGBE_SDQPF_SRCPORT; + filter->dst_ip = IXGBE_READ_REG(hw, IXGBE_DAQF(index)); + filter->src_ip = IXGBE_READ_REG(hw, IXGBE_SAQF(index)); + + l34timir = IXGBE_READ_REG(hw, IXGBE_L34T_IMIR(index)); + *rx_queue = (l34timir & IXGBE_L34T_IMIR_QUEUE) >> IXGBE_L34T_IMIR_QUEUE_SHIFT; + return 0; + } + return (-ENOENT); +} diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h index 9d7e93f..7c6139b 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h @@ -67,6 +67,39 @@ #define IXGBE_LPBK_82599_NONE 0x0 /* Default value. Loopback is disabled. */ #define IXGBE_LPBK_82599_TX_RX 0x1 /* Tx->Rx loopback operation is enabled. */ +#define IXGBE_SYN_FILTER_ENABLE 0x00000001 /** syn filter enable field*/ +#define IXGBE_SYN_FILTER_QUEUE 0x000000FE /** syn filter queue field*/ +#define IXGBE_SYN_FILTER_QUEUE_SHIFT 1 /** syn filter queue field shift*/ +#define IXGBE_SYN_FILTER_SYNQFP 0x80000000 /**syn filter SYNQFP*/ + +#define IXGBE_ETQF_UP 0x00070000 /** ethertype filter priority field*/ +#define IXGBE_ETQF_SHIFT 16 +#define IXGBE_ETQF_UP_EN 0x00080000 +#define IXGBE_ETQF_ETHERTYPE 0x0000FFFF /** ethertype filter ethertype field*/ +#define IXGBE_ETQF_MAX_PRI 7 + +#define IXGBE_SDQPF_DSTPORT 0xFFFF0000 /** dst port field */ +#define IXGBE_SDQPF_DSTPORT_SHIFT 16 /** dst port field shift*/ +#define IXGBE_SDQPF_SRCPORT 0x0000FFFF /** src port field */ +#define IXGBR_FTQF_PROTOCOL 0x00000003 /** protocol */ +#define IXGBR_FTQF_PRIORITY 0x0000001C /** priority */ +#define IXGBR_FTQF_PRIORITY_SHIFT 2 +#define IXGBR_FTQF_SRCIP_MASK 0x02000000 /** src IP mask */ +#define IXGBR_FTQF_DSTIP_MASK 0x04000000 /** dst IP mask */ +#define IXGBR_FTQF_SRCPORT_MASK 0x08000000 /** src port mask */ +#define IXGBR_FTQF_DSTPORT_MASK 0x10000000 /** dst port mask */ +#define IXGBR_FTQF_L4TYPE_MASK 0x20000000 /** protocol mask */ +#define IXGBR_FTQF_POOL_MASK 0x40000000 /** pool mask */ +#define IXGBR_FTQF_ENABLE 0x80000000 /** enable bit */ +#define IXGBR_FTQF_PRIORITY_DEFAULT 0x00000004 +#define IXGBE_L34T_IMIR_SIZE_BP 0x00001000 +#define IXGBE_L34T_IMIR_RESERVE 0x00080000 /** bit 13 to 19 must be set to 1000000b*/ +#define IXGBE_L34T_IMIR_LLI 0x00100000 +#define IXGBE_L34T_IMIR_QUEUE 0x0FE00000 +#define IXGBE_L34T_IMIR_QUEUE_SHIFT 21 +#define IXGBE_5TUPLE_MAX_PRI 7 +#define IXGBE_5TUPLE_MIN_PRI 1 + /* * Information about the fdir mode. */ -- 1.8.1.4