From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-lb0-f175.google.com (mail-lb0-f175.google.com [209.85.217.175]) by dpdk.org (Postfix) with ESMTP id BA5E8688F for ; Wed, 4 Jun 2014 17:19:52 +0200 (CEST) Received: by mail-lb0-f175.google.com with SMTP id l4so4409152lbv.20 for ; Wed, 04 Jun 2014 08:20:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=2pbFcekqruev9dYBqywWV8/ugqCtmJPHU8DUpUxOc1I=; b=BkIdncwQWB/lN5qzpO+CtIK22boG2HEY7VPrwG2uMcUXvSDqV+b9PWDz5SR/1En1Q5 7WHpI9BOOTdUzq//glKpMnJ0OgyNJ1jh8D09675l9WkTn/5fz4meuM5Xt5JjhQ2fAvkq o6GMrSWEZXhzQWr4T63NC3VTkLuW2YS2N4Bag8Gu7k1/eBmT4adYVQ25j30Ug6UMvlLi 2QVbRGdYhdz+OknLwJPOmEJZGpgYU6orMZfllP5DEueK/pTdDwpP7xBM7hVnZ1iXcZl4 Eh5ntoy6DCOZd/Gj55Ggr5nrFYRWgmG4PoOgAEClEDt9fzwFACdm/KtUIeqZ5xPMcNu6 Vycw== X-Received: by 10.152.45.37 with SMTP id j5mr14865363lam.58.1401895205701; Wed, 04 Jun 2014 08:20:05 -0700 (PDT) Received: from hst119.rambler.ru (offcarp-nat.rambler.ru. [81.19.64.46]) by mx.google.com with ESMTPSA id b6sm2419863laa.20.2014.06.04.08.20.04 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 04 Jun 2014 08:20:05 -0700 (PDT) From: Vladimir Medvedkin To: dev@dpdk.org Date: Wed, 4 Jun 2014 11:18:41 -0400 Message-Id: <1401895122-7895-3-git-send-email-medvedkinv@gmail.com> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1401895122-7895-1-git-send-email-medvedkinv@gmail.com> References: <1401895122-7895-1-git-send-email-medvedkinv@gmail.com> Subject: [dpdk-dev] [PATCH v2 2/3] ixgbe: Add syn queue filter for ixgbe 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: Wed, 04 Jun 2014 15:19:53 -0000 This patch adds ability to route TCP packets according to SYN flag presence to certain queue. Signed-off-by: Vladimir Medvedkin --- lib/librte_ether/rte_ethdev.c | 66 +++++++++++++++++++++++++++++++++ lib/librte_ether/rte_ethdev.h | 63 +++++++++++++++++++++++++++++++ lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h | 6 +++ lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 57 +++++++++++++++++++++++++++- 4 files changed, 191 insertions(+), 1 deletion(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index ad19817..4e25e59 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1195,6 +1195,72 @@ rte_eth_dev_get_vlan_offload(uint8_t port_id) } int +rte_eth_dev_synq_add_filter(uint8_t port_id, struct rte_eth_synq_filter *filter) +{ + struct rte_eth_dev *dev; + struct rte_eth_dev_info info; + + rte_eth_dev_info_get(port_id, &info); + + if (port_id >= nb_ports) { + PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id); + return (-ENODEV); + } + + dev = &rte_eth_devices[port_id]; + + if (filter == NULL) { + PMD_DEBUG_TRACE("Invalid filter pointer\n"); + return (-EINVAL); + } + + if (filter->rx_queue >= info.max_rx_queues) { + PMD_DEBUG_TRACE("Invalid RX queue_id=%d\n", filter->rx_queue); + return (-EINVAL); + } + + FUNC_PTR_OR_ERR_RET(*dev->dev_ops->synq_add_filter, -ENOTSUP); + return (*dev->dev_ops->synq_add_filter)(dev, filter); +} + +int +rte_eth_dev_synq_get_filter(uint8_t port_id, struct rte_eth_synq_filter *filter) +{ + struct rte_eth_dev *dev; + + if (port_id >= nb_ports) { + PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id); + return (-ENODEV); + } + + dev = &rte_eth_devices[port_id]; + + if (filter == NULL) { + PMD_DEBUG_TRACE("Invalid filter pointer\n"); + return (-EINVAL); + } + + FUNC_PTR_OR_ERR_RET(*dev->dev_ops->synq_add_filter, -ENOTSUP); + return (*dev->dev_ops->synq_get_filter)(dev, filter); +} + +int +rte_eth_dev_synq_del_filter(uint8_t port_id) +{ + struct rte_eth_dev *dev; + + if (port_id >= nb_ports) { + PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id); + return (-ENODEV); + } + + dev = &rte_eth_devices[port_id]; + + FUNC_PTR_OR_ERR_RET(*dev->dev_ops->synq_add_filter, -ENOTSUP); + return (*dev->dev_ops->synq_del_filter)(dev); +} + +int rte_eth_dev_l2_etype_add_filter(uint8_t port_id, uint8_t filter_id, struct rte_eth_l2etype_filter *filter) { struct rte_eth_dev *dev; diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 0e6326e..6b90aed 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -562,6 +562,14 @@ struct rte_eth_pfc_conf { }; /** + * A structure used to configure SYN Packet queue Filters + */ +struct rte_eth_synq_filter { + uint8_t rx_queue; + uint8_t synq_first; /**< Defines the priority between SYNQF and 5-tuple filter. */ +}; + +/** * A structure used to configure L2 Ethertype Filters */ struct rte_eth_l2etype_filter { @@ -926,6 +934,15 @@ typedef uint16_t (*eth_tx_burst_t)(void *txq, uint16_t nb_pkts); /**< @internal Send output packets on a transmit queue of an Ethernet device. */ +typedef int (*synq_add_filter_t)(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter); +/**< @internal Setup SYN Packer queue filter */ + +typedef int (*synq_get_filter_t)(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter); +/**< @internal Get SYN Packer queue filter */ + +typedef int (*synq_del_filter_t)(struct rte_eth_dev *dev); +/**< @internal Delete SYN Packer queue filter */ + typedef int (*l2_etype_add_filter_t)(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter); /**< @internal Setup a new L2 Ethertype filter */ @@ -1144,6 +1161,12 @@ struct eth_dev_ops { eth_set_vf_tx_t set_vf_tx; /**< enable/disable a VF transmit */ eth_set_vf_vlan_filter_t set_vf_vlan_filter; /**< Set VF VLAN filter */ + /** Setup a SYN Packet queue filter. */ + synq_add_filter_t synq_add_filter; + /** Get a SYN Packet queue filter. */ + synq_get_filter_t synq_get_filter; + /** Delete a SYN Packet queue filter. */ + synq_del_filter_t synq_del_filter; /** Setup a L2 Ethertype filter. */ l2_etype_add_filter_t l2_etype_add_filter; /** Get a L2 Ethertype filter. */ @@ -2139,6 +2162,46 @@ rte_eth_tx_burst(uint8_t port_id, uint16_t queue_id, #endif /** + * Setup SYN Packet queue filter + * @param port_id + * The port identifier of the Ethernet device. + * @param filter + * The pointer to the synq filter structure. + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support SYN Packet queue filters. + * - (-ENODEV) if *port_id* invalid. + * - (-EINVAL) if *filter* invalid. +*/ +int rte_eth_dev_synq_add_filter(uint8_t port_id, struct rte_eth_synq_filter *filter); + +/** + * Get SYN Packet queue filter + * @param port_id + * The port identifier of the Ethernet device. + * @param filter + * The pointer to the synq filter structure. + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support SYN Packet queue filters. + * - (-ENODEV) if *port_id* invalid. + * - (-ENOENT) if SYN Packet filter inactive + * - (-EINVAL) if *filter* pointer is NULL +*/ +int rte_eth_dev_synq_get_filter(uint8_t port_id, struct rte_eth_synq_filter *filter); + +/** + * Clear SYN Packet queue filter + * @param port_id + * The port identifier of the Ethernet device. + * @return + * - (0) if successful. + * - (-ENOTSUP) if hardware doesn't support SYN Packet queue filters. + * - (-ENODEV) if *port_id* invalid. +*/ +int rte_eth_dev_synq_del_filter(uint8_t port_id); + +/** * Setup L2 Ethertype queue filter * @param port_id * The port identifier of the Ethernet device. diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h index 28653d5..8f911ff 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h @@ -1529,6 +1529,12 @@ enum { #define IXGBE_IVAR_ALLOC_VAL 0x80 /* Interrupt Allocation valid */ +/* SYN Packet Queue Filter */ +#define IXGBE_SYNQF_EN 0x00000001 +#define IXGBE_SYNQF_RX_QUEUE 0x000000FE +#define IXGBE_SYNQF_SHIFT 1 +#define IXGBE_SYNQF_SYN_FIRST (1 << 31) /* bit 31 */ + /* ETYPE Queue Filter/Select Bit Masks */ #define IXGBE_MAX_ETQF_FILTERS 8 #define IXGBE_ETQF_FCOE 0x08000000 /* bit 27 */ diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c index 2db6fe5..6e4ab9d 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c @@ -146,7 +146,9 @@ static void ixgbe_add_rar(struct rte_eth_dev *dev, struct ether_addr *mac_addr, uint32_t index, uint32_t pool); static void ixgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index); static void ixgbe_dcb_init(struct ixgbe_hw *hw,struct ixgbe_dcb_config *dcb_config); - +static int ixgbe_synq_add_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter); +static int ixgbe_synq_get_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter); +static int ixgbe_synq_del_filter(struct rte_eth_dev *dev); static int ixgbe_l2_etype_add_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter); static int ixgbe_l2_etype_get_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter); static int ixgbe_l2_etype_del_filter(struct rte_eth_dev *dev, uint8_t filter_id); @@ -283,6 +285,9 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = { .set_vf_rx = ixgbe_set_pool_rx, .set_vf_tx = ixgbe_set_pool_tx, .set_vf_vlan_filter = ixgbe_set_pool_vlan_filter, + .synq_add_filter = ixgbe_synq_add_filter, + .synq_get_filter = ixgbe_synq_get_filter, + .synq_del_filter = ixgbe_synq_del_filter, .l2_etype_add_filter = ixgbe_l2_etype_add_filter, .l2_etype_get_filter = ixgbe_l2_etype_get_filter, .l2_etype_del_filter = ixgbe_l2_etype_del_filter, @@ -3069,6 +3074,56 @@ ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id) } static int +ixgbe_synq_add_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter) +{ + struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t synqf = 0; + + if (hw->mac.type != ixgbe_mac_82599EB) + return (-ENOSYS); + + synqf = IXGBE_SYNQF_EN; + synqf |= filter->rx_queue << IXGBE_SYNQF_SHIFT; + + if (filter->synq_first) + synqf |= IXGBE_SYNQF_SYN_FIRST; + + IXGBE_WRITE_REG(hw, IXGBE_SYNQF, synqf); + return 0; +} + +static int +ixgbe_synq_get_filter(struct rte_eth_dev *dev, struct rte_eth_synq_filter *filter) +{ + 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); + + if (!(synqf & IXGBE_SYNQF_EN)) + return (-ENOENT); + + filter->rx_queue = (synqf & IXGBE_SYNQF_RX_QUEUE) >> IXGBE_SYNQF_SHIFT; + filter->synq_first = synqf & IXGBE_SYNQF_SYN_FIRST; + return 0; +} + +static int +ixgbe_synq_del_filter(struct rte_eth_dev *dev) +{ + struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + if (hw->mac.type != ixgbe_mac_82599EB) + return (-ENOSYS); + + IXGBE_WRITE_REG(hw, IXGBE_SYNQF, 0); + return 0; +} + +static int ixgbe_l2_etype_add_filter(struct rte_eth_dev *dev, uint8_t filter_id, struct rte_eth_l2etype_filter *filter) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); -- 1.8.3.2