From patchwork Thu Jan 8 01:42:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: zzang X-Patchwork-Id: 2222 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 595775A08; Thu, 8 Jan 2015 02:43:41 +0100 (CET) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 3B96058DD for ; Thu, 8 Jan 2015 02:43:39 +0100 (CET) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 07 Jan 2015 17:41:10 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.07,718,1413270000"; d="scan'208";a="666159043" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by orsmga002.jf.intel.com with ESMTP; 07 Jan 2015 17:43:37 -0800 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id t081hZNJ017234; Thu, 8 Jan 2015 09:43:35 +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 t081hX8k024846; Thu, 8 Jan 2015 09:43:35 +0800 Received: (from zzang@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t081hWuO024841; Thu, 8 Jan 2015 09:43:32 +0800 From: zhida zang To: dev@dpdk.org Date: Thu, 8 Jan 2015 09:42:38 +0800 Message-Id: <1420681358-24809-1-git-send-email-zhida.zang@intel.com> X-Mailer: git-send-email 1.7.4.1 Subject: [dpdk-dev] [PATCH] ixgbe/igb: integrate syn filter to new API 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patch integrates syn filter to new API in ixgbe/igb driver. changes: ixgbe: remove old functions that deal with syn filter ixgbe: add new functions that deal with syn filter (fit for filter_ctrl API) e1000: remove old functions that deal with syn filter e1000: add new functions that deal with syn filter (fit for filter_ctrl API) testpmd: change the entry for syn filter in cmdline testpmd: change function call to get syn filter in config Signed-off-by: Zhida Zang --- app/test-pmd/cmdline.c | 179 ++++++++++++++++++++--------------- app/test-pmd/config.c | 10 +- lib/librte_ether/rte_eth_ctrl.h | 12 +++ lib/librte_pmd_e1000/igb_ethdev.c | 176 ++++++++++++++++++++-------------- lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 182 ++++++++++++++++++++---------------- 5 files changed, 331 insertions(+), 228 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 4c3fc76..820b3a6 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -665,13 +665,13 @@ static void cmd_help_long_parsed(void *parsed_result, "get_5tuple_filter (port_id) index (idx)\n" " get info of a 5tuple filter.\n\n" - "add_syn_filter (port_id) priority (high|low) queue (queue_id)" + "syn_filter add (port_id) priority (high|low) queue (queue_id)" " add syn filter.\n\n" - "remove_syn_filter (port_id)" + "syn_filter del (port_id)" " remove syn filter.\n\n" - "get_syn_filter (port_id) " + "syn_filter get (port_id) " " get syn filter info.\n\n" "add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)" @@ -7044,101 +7044,130 @@ cmdline_parse_inst_t cmd_get_ethertype_filter = { }, }; -/* *** set SYN filter *** */ -struct cmd_set_syn_filter_result { +/* *** Add/Del/Get syn filter *** */ +struct cmd_syn_filter_result { cmdline_fixed_string_t filter; + cmdline_fixed_string_t ops; uint8_t port_id; cmdline_fixed_string_t priority; cmdline_fixed_string_t high; cmdline_fixed_string_t queue; - uint16_t queue_id; + uint16_t queue_id; }; -static void -cmd_set_syn_filter_parsed(void *parsed_result, - __attribute__((unused)) struct cmdline *cl, - __attribute__((unused)) void *data) -{ - int ret = 0; - struct cmd_set_syn_filter_result *res = parsed_result; - struct rte_syn_filter filter; - - if (!strcmp(res->filter, "add_syn_filter")) { - if (!strcmp(res->high, "high")) - filter.hig_pri = 1; - else - filter.hig_pri = 0; - ret = rte_eth_dev_add_syn_filter(res->port_id, - &filter, res->queue_id); - } else if (!strcmp(res->filter, "remove_syn_filter")) - ret = rte_eth_dev_remove_syn_filter(res->port_id); - else if (!strcmp(res->filter, "get_syn_filter")) - get_syn_filter(res->port_id); - if (ret < 0) - printf("syn filter setting error: (%s)\n", strerror(-ret)); - -} -cmdline_parse_token_num_t cmd_syn_filter_portid = - TOKEN_NUM_INITIALIZER(struct cmd_set_syn_filter_result, - port_id, UINT8); +cmdline_parse_token_string_t cmd_syn_filter_filter = + TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result, + filter, "syn_filter"); +cmdline_parse_token_string_t cmd_syn_filter_add = + TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result, + ops, "add"); +cmdline_parse_token_string_t cmd_syn_filter_del = + TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result, + ops, "del"); +cmdline_parse_token_string_t cmd_syn_filter_get = + TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result, + ops, "get"); +cmdline_parse_token_num_t cmd_syn_filter_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_syn_filter_result, + port_id, UINT8); cmdline_parse_token_string_t cmd_syn_filter_priority = - TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result, + TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result, priority, "priority"); cmdline_parse_token_string_t cmd_syn_filter_high = - TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result, + TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result, high, "high#low"); cmdline_parse_token_string_t cmd_syn_filter_queue = - TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result, + TOKEN_STRING_INITIALIZER(struct cmd_syn_filter_result, queue, "queue"); cmdline_parse_token_num_t cmd_syn_filter_queue_id = - TOKEN_NUM_INITIALIZER(struct cmd_set_syn_filter_result, + TOKEN_NUM_INITIALIZER(struct cmd_syn_filter_result, queue_id, UINT16); -cmdline_parse_token_string_t cmd_syn_filter_add_filter = - TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result, - filter, "add_syn_filter"); -cmdline_parse_token_string_t cmd_syn_filter_remove_filter = - TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result, - filter, "remove_syn_filter"); +static void +cmd_syn_filter_parsed(void *parsed_result, struct cmdline *cl, + void *data); + cmdline_parse_inst_t cmd_add_syn_filter = { - .f = cmd_set_syn_filter_parsed, - .data = NULL, - .help_str = "add syn filter", - .tokens = { - (void *)&cmd_syn_filter_add_filter, - (void *)&cmd_syn_filter_portid, - (void *)&cmd_syn_filter_priority, - (void *)&cmd_syn_filter_high, - (void *)&cmd_syn_filter_queue, - (void *)&cmd_syn_filter_queue_id, - NULL, - }, + .f = cmd_syn_filter_parsed, + .data = (void *)&cmd_add_syn_filter, + .help_str = "add syn filter", + .tokens = { + (void *)&cmd_syn_filter_filter, + (void *)&cmd_syn_filter_add, + (void *)&cmd_syn_filter_port_id, + (void *)&cmd_syn_filter_priority, + (void *)&cmd_syn_filter_high, + (void *)&cmd_syn_filter_queue, + (void *)&cmd_syn_filter_queue_id, + NULL, + }, }; cmdline_parse_inst_t cmd_remove_syn_filter = { - .f = cmd_set_syn_filter_parsed, - .data = NULL, - .help_str = "remove syn filter", - .tokens = { - (void *)&cmd_syn_filter_remove_filter, - (void *)&cmd_syn_filter_portid, - NULL, - }, + .f = cmd_syn_filter_parsed, + .data = (void *)&cmd_remove_syn_filter, + .help_str = "remove syn filter", + .tokens = { + (void *)&cmd_syn_filter_filter, + (void *)&cmd_syn_filter_del, + (void *)&cmd_syn_filter_port_id, + NULL, + }, }; -cmdline_parse_token_string_t cmd_syn_filter_get_filter = - TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result, - filter, "get_syn_filter"); - cmdline_parse_inst_t cmd_get_syn_filter = { - .f = cmd_set_syn_filter_parsed, - .data = NULL, - .help_str = "get syn filter", - .tokens = { - (void *)&cmd_syn_filter_get_filter, - (void *)&cmd_syn_filter_portid, - NULL, - }, + .f = cmd_syn_filter_parsed, + .data = (void *)&cmd_get_syn_filter, + .help_str = "get syn filter", + .tokens = { + (void *)&cmd_syn_filter_filter, + (void *)&cmd_syn_filter_get, + (void *)&cmd_syn_filter_port_id, + NULL, + }, }; +static void +cmd_syn_filter_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_syn_filter_result *res = parsed_result; + struct rte_eth_syn_filter syn_filter; + int ret = 0; + + ret = rte_eth_dev_filter_supported(res->port_id, + RTE_ETH_FILTER_SYN); + if (ret < 0) { + printf("syn filter is not supported on port %u.\n", + res->port_id); + return; + } + + memset(&syn_filter, 0, sizeof(syn_filter)); + + if (!strcmp(res->ops, "add")) { + if (!strcmp(res->high, "high")) + syn_filter.hig_pri = 1; + else + syn_filter.hig_pri = 0; + + syn_filter.queue = res->queue_id; + ret = rte_eth_dev_filter_ctrl(res->port_id, + RTE_ETH_FILTER_SYN, + RTE_ETH_FILTER_ADD, + &syn_filter); + } else if (!strcmp(res->ops, "del")) + ret = rte_eth_dev_filter_ctrl(res->port_id, + RTE_ETH_FILTER_SYN, + RTE_ETH_FILTER_DELETE, + &syn_filter); + else + get_syn_filter(res->port_id); + + if (ret < 0) + printf("syn filter programming error: (%s)\n", + strerror(-ret)); +} + /* *** ADD/REMOVE A 2tuple FILTER *** */ struct cmd_2tuple_filter_result { cmdline_fixed_string_t filter; diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index b102b72..10278b3 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -2020,12 +2020,14 @@ get_ethertype_filter(uint8_t port_id, uint16_t index) void get_syn_filter(uint8_t port_id) { - struct rte_syn_filter filter; + struct rte_eth_syn_filter filter; int ret = 0; - uint16_t rx_queue; memset(&filter, 0, sizeof(filter)); - ret = rte_eth_dev_get_syn_filter(port_id, &filter, &rx_queue); + ret = rte_eth_dev_filter_ctrl(port_id, + RTE_ETH_FILTER_SYN, + RTE_ETH_FILTER_GET, + &filter); if (ret < 0) { if (ret == (-ENOENT)) @@ -2036,7 +2038,7 @@ get_syn_filter(uint8_t port_id) } printf("syn filter: priority: %s, queue: %d\n", filter.hig_pri ? "high" : "low", - rx_queue); + filter.queue); } void get_2tuple_filter(uint8_t port_id, uint16_t index) diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h index 8dd384d..14dc323 100644 --- a/lib/librte_ether/rte_eth_ctrl.h +++ b/lib/librte_ether/rte_eth_ctrl.h @@ -53,6 +53,7 @@ enum rte_filter_type { RTE_ETH_FILTER_NONE = 0, RTE_ETH_FILTER_MACVLAN, RTE_ETH_FILTER_TUNNEL, + RTE_ETH_FILTER_SYN, RTE_ETH_FILTER_MAX }; @@ -96,6 +97,17 @@ struct rte_eth_mac_filter { }; /** + * A structure used to define the sync filter entry + * to support RTE_ETH_FILTER_SYN with RTE_ETH_FILTER_ADD, + * RTE_ETH_FILTER_DELETE and RTE_ETH_FILTER_GET operations. + */ +struct rte_eth_syn_filter { + uint8_t hig_pri; /**< 1 means higher pri than 2tuple,5tuple, + and flex filter, 0 means lower pri.*/ + uint16_t queue; /**< Queue assigned to when match*/ +}; + +/** * Tunneled type. */ enum rte_eth_tunnel_type { diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c index c13ea05..caf0cdc 100644 --- a/lib/librte_pmd_e1000/igb_ethdev.c +++ b/lib/librte_pmd_e1000/igb_ethdev.c @@ -140,11 +140,18 @@ static int eth_igb_rss_reta_update(struct rte_eth_dev *dev, static int eth_igb_rss_reta_query(struct rte_eth_dev *dev, struct rte_eth_rss_reta *reta_conf); -static int eth_igb_add_syn_filter(struct rte_eth_dev *dev, - struct rte_syn_filter *filter, uint16_t rx_queue); -static int eth_igb_remove_syn_filter(struct rte_eth_dev *dev); -static int eth_igb_get_syn_filter(struct rte_eth_dev *dev, - struct rte_syn_filter *filter, uint16_t *rx_queue); +static int eth_igb_syn_filter_set(struct rte_eth_dev *dev, + struct rte_eth_syn_filter *filter, + bool add); +static int eth_igb_syn_filter_get(struct rte_eth_dev *dev, + struct rte_eth_syn_filter *filter); +static int eth_igb_syn_filter_handle(struct rte_eth_dev *dev, + enum rte_filter_op filter_op, + void *arg); +static int eth_igb_dev_filter_ctrl(struct rte_eth_dev *dev, + enum rte_filter_type filter_type, + enum rte_filter_op filter_op, + void *arg); static int eth_igb_add_ethertype_filter(struct rte_eth_dev *dev, uint16_t index, struct rte_ethertype_filter *filter, uint16_t rx_queue); @@ -252,9 +259,6 @@ static struct eth_dev_ops eth_igb_ops = { .reta_query = eth_igb_rss_reta_query, .rss_hash_update = eth_igb_rss_hash_update, .rss_hash_conf_get = eth_igb_rss_hash_conf_get, - .add_syn_filter = eth_igb_add_syn_filter, - .remove_syn_filter = eth_igb_remove_syn_filter, - .get_syn_filter = eth_igb_get_syn_filter, .add_ethertype_filter = eth_igb_add_ethertype_filter, .remove_ethertype_filter = eth_igb_remove_ethertype_filter, .get_ethertype_filter = eth_igb_get_ethertype_filter, @@ -267,6 +271,7 @@ static struct eth_dev_ops eth_igb_ops = { .add_5tuple_filter = eth_igb_add_5tuple_filter, .remove_5tuple_filter = eth_igb_remove_5tuple_filter, .get_5tuple_filter = eth_igb_get_5tuple_filter, + .filter_ctrl = eth_igb_dev_filter_ctrl, }; /* @@ -2340,100 +2345,129 @@ eth_igb_rss_reta_query(struct rte_eth_dev *dev, return -ENOSYS;\ } while (0) -/* - * add the syn filter - * - * @param - * dev: Pointer to struct rte_eth_dev. - * 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 -eth_igb_add_syn_filter(struct rte_eth_dev *dev, - struct rte_syn_filter *filter, uint16_t rx_queue) +eth_igb_syn_filter_set(struct rte_eth_dev *dev, + struct rte_eth_syn_filter *filter, + bool add) { struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); uint32_t synqf, rfctl; - MAC_TYPE_FILTER_SUP(hw->mac.type); - - if (rx_queue >= IGB_MAX_RX_QUEUE_NUM) + if (filter->queue >= IGB_MAX_RX_QUEUE_NUM) return -EINVAL; synqf = E1000_READ_REG(hw, E1000_SYNQF(0)); - if (synqf & E1000_SYN_FILTER_ENABLE) - return -EINVAL; - synqf = (uint32_t)(((rx_queue << E1000_SYN_FILTER_QUEUE_SHIFT) & - E1000_SYN_FILTER_QUEUE) | E1000_SYN_FILTER_ENABLE); - - rfctl = E1000_READ_REG(hw, E1000_RFCTL); - if (filter->hig_pri) - rfctl |= E1000_RFCTL_SYNQFP; - else - rfctl &= ~E1000_RFCTL_SYNQFP; + if (add) { + if (synqf & E1000_SYN_FILTER_ENABLE) + return -EINVAL; - E1000_WRITE_REG(hw, E1000_SYNQF(0), synqf); - E1000_WRITE_REG(hw, E1000_RFCTL, rfctl); - return 0; -} + synqf = (uint32_t)(((filter->queue << + E1000_SYN_FILTER_QUEUE_SHIFT) & E1000_SYN_FILTER_QUEUE) + | E1000_SYN_FILTER_ENABLE); -/* - * remove the syn filter - * - * @param - * dev: Pointer to struct rte_eth_dev. - * - * @return - * - On success, zero. - * - On failure, a negative value. - */ -static int -eth_igb_remove_syn_filter(struct rte_eth_dev *dev) -{ - struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); + rfctl = E1000_READ_REG(hw, E1000_RFCTL); + if (filter->hig_pri) + rfctl |= E1000_RFCTL_SYNQFP; + else + rfctl &= ~E1000_RFCTL_SYNQFP; - MAC_TYPE_FILTER_SUP(hw->mac.type); + E1000_WRITE_REG(hw, E1000_RFCTL, rfctl); + } else + synqf = 0; - E1000_WRITE_REG(hw, E1000_SYNQF(0), 0); + E1000_WRITE_REG(hw, E1000_SYNQF(0), synqf); + E1000_WRITE_FLUSH(hw); return 0; } -/* - * get the syn filter's info - * - * @param - * dev: Pointer to struct rte_eth_dev. - * filter: ponter to the filter that returns. - * *rx_queue: pointer to the queue id the filter assigned to. - * - * @return - * - On success, zero. - * - On failure, a negative value. - */ static int -eth_igb_get_syn_filter(struct rte_eth_dev *dev, - struct rte_syn_filter *filter, uint16_t *rx_queue) +eth_igb_syn_filter_get(struct rte_eth_dev *dev, + struct rte_eth_syn_filter *filter) { struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); uint32_t synqf, rfctl; - MAC_TYPE_FILTER_SUP(hw->mac.type); synqf = E1000_READ_REG(hw, E1000_SYNQF(0)); if (synqf & E1000_SYN_FILTER_ENABLE) { rfctl = E1000_READ_REG(hw, E1000_RFCTL); filter->hig_pri = (rfctl & E1000_RFCTL_SYNQFP) ? 1 : 0; - *rx_queue = (uint8_t)((synqf & E1000_SYN_FILTER_QUEUE) >> + filter->queue = (uint8_t)((synqf & E1000_SYN_FILTER_QUEUE) >> E1000_SYN_FILTER_QUEUE_SHIFT); return 0; } + return -ENOENT; } +static int +eth_igb_syn_filter_handle(struct rte_eth_dev *dev, + enum rte_filter_op filter_op, + void *arg) +{ + struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret = 0; + + MAC_TYPE_FILTER_SUP(hw->mac.type); + + if (filter_op == RTE_ETH_FILTER_NOP) + return ret; + + if (arg == NULL) { + PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u", + filter_op); + return -EINVAL; + } + + switch (filter_op) { + case RTE_ETH_FILTER_ADD: + ret = eth_igb_syn_filter_set(dev, + (struct rte_eth_syn_filter *)arg, + TRUE); + break; + case RTE_ETH_FILTER_DELETE: + ret = eth_igb_syn_filter_set(dev, + (struct rte_eth_syn_filter *)arg, + FALSE); + break; + case RTE_ETH_FILTER_GET: + ret = eth_igb_syn_filter_get(dev, + (struct rte_eth_syn_filter *)arg); + break; + default: + PMD_DRV_LOG(ERR, "unsupported operation %u\n", filter_op); + ret = -ENOSYS; + break; + } + + return ret; +} + +static int +eth_igb_dev_filter_ctrl(struct rte_eth_dev *dev, + enum rte_filter_type filter_type, + enum rte_filter_op filter_op, + void *arg) +{ + int ret = 0; + + if (dev == NULL) + return -EINVAL; + + switch (filter_type) { + case RTE_ETH_FILTER_SYN: + ret = eth_igb_syn_filter_handle(dev, filter_op, arg); + break; + default: + PMD_DRV_LOG(WARNING, "Filter type (%d) not supported", + filter_type); + ret = -EINVAL; + break; + } + + return ret; +} + /* * add an ethertype filter * diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c index 2eb609c..0fb80f9 100644 --- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c +++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c @@ -216,11 +216,18 @@ static void ixgbevf_add_mac_addr(struct rte_eth_dev *dev, struct ether_addr *mac_addr, uint32_t index, uint32_t pool); static void ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index); -static int ixgbe_add_syn_filter(struct rte_eth_dev *dev, - struct rte_syn_filter *filter, uint16_t rx_queue); -static int ixgbe_remove_syn_filter(struct rte_eth_dev *dev); -static int ixgbe_get_syn_filter(struct rte_eth_dev *dev, - struct rte_syn_filter *filter, uint16_t *rx_queue); +static int ixgbe_syn_filter_set(struct rte_eth_dev *dev, + struct rte_eth_syn_filter *filter, + bool add); +static int ixgbe_syn_filter_get(struct rte_eth_dev *dev, + struct rte_eth_syn_filter *filter); +static int ixgbe_syn_filter_handle(struct rte_eth_dev *dev, + enum rte_filter_op filter_op, + void *arg); +static int ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev, + enum rte_filter_type filter_type, + enum rte_filter_op filter_op, + void *arg); static int ixgbe_add_ethertype_filter(struct rte_eth_dev *dev, uint16_t index, struct rte_ethertype_filter *filter, uint16_t rx_queue); static int ixgbe_remove_ethertype_filter(struct rte_eth_dev *dev, @@ -367,15 +374,13 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = { #endif /* RTE_NIC_BYPASS */ .rss_hash_update = ixgbe_dev_rss_hash_update, .rss_hash_conf_get = ixgbe_dev_rss_hash_conf_get, - .add_syn_filter = ixgbe_add_syn_filter, - .remove_syn_filter = ixgbe_remove_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, + .filter_ctrl = ixgbe_dev_filter_ctrl, }; /* @@ -3581,105 +3586,126 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index) } } -/* - * add syn filter - * - * @param - * dev: Pointer to struct rte_eth_dev. - * 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. - */ +#define MAC_TYPE_FILTER_SUP(type) do {\ + if ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540 &&\ + (type) != ixgbe_mac_X550)\ + return -ENOSYS;\ +} while (0) + static int -ixgbe_add_syn_filter(struct rte_eth_dev *dev, - struct rte_syn_filter *filter, uint16_t rx_queue) +ixgbe_syn_filter_set(struct rte_eth_dev *dev, + struct rte_eth_syn_filter *filter, + bool add) { 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) + if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM) return -EINVAL; synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF); - if (synqf & IXGBE_SYN_FILTER_ENABLE) - return -EINVAL; - - synqf = (uint32_t)(((rx_queue << IXGBE_SYN_FILTER_QUEUE_SHIFT) & - IXGBE_SYN_FILTER_QUEUE) | IXGBE_SYN_FILTER_ENABLE); + if (add) { + if (synqf & IXGBE_SYN_FILTER_ENABLE) + return -EINVAL; + synqf = (uint32_t)(((filter->queue << + IXGBE_SYN_FILTER_QUEUE_SHIFT) & IXGBE_SYN_FILTER_QUEUE) + | IXGBE_SYN_FILTER_ENABLE); - if (filter->hig_pri) - synqf |= IXGBE_SYN_FILTER_SYNQFP; - else - synqf &= ~IXGBE_SYN_FILTER_SYNQFP; + if (filter->hig_pri) + synqf |= IXGBE_SYN_FILTER_SYNQFP; + else + synqf &= ~IXGBE_SYN_FILTER_SYNQFP; + } else + synqf &= ~(IXGBE_SYN_FILTER_QUEUE | IXGBE_SYN_FILTER_ENABLE); IXGBE_WRITE_REG(hw, IXGBE_SYNQF, synqf); + IXGBE_WRITE_FLUSH(hw); return 0; } -/* - * remove syn filter - * - * @param - * dev: Pointer to struct rte_eth_dev. - * - * @return - * - On success, zero. - * - On failure, a negative value. - */ static int -ixgbe_remove_syn_filter(struct rte_eth_dev *dev) +ixgbe_syn_filter_get(struct rte_eth_dev *dev, + struct rte_eth_syn_filter *filter) { struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); - uint32_t synqf; + uint32_t synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF); - if (hw->mac.type != ixgbe_mac_82599EB) - return -ENOSYS; + if (synqf & IXGBE_SYN_FILTER_ENABLE) { + filter->hig_pri = (synqf & IXGBE_SYN_FILTER_SYNQFP) ? 1 : 0; + filter->queue = (uint16_t)((synqf & IXGBE_SYN_FILTER_QUEUE) + >> 1); + return 0; + } + return -ENOENT; +} - synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF); +static int +ixgbe_syn_filter_handle(struct rte_eth_dev *dev, + enum rte_filter_op filter_op, + void *arg) +{ + struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + int ret = 0; - synqf &= ~(IXGBE_SYN_FILTER_QUEUE | IXGBE_SYN_FILTER_ENABLE); + MAC_TYPE_FILTER_SUP(hw->mac.type); - IXGBE_WRITE_REG(hw, IXGBE_SYNQF, synqf); - return 0; + if (filter_op == RTE_ETH_FILTER_NOP) + return ret; + + if (arg == NULL) { + PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u", + filter_op); + return -EINVAL; + } + + switch (filter_op) { + case RTE_ETH_FILTER_ADD: + ret = ixgbe_syn_filter_set(dev, + (struct rte_eth_syn_filter *)arg, + TRUE); + break; + case RTE_ETH_FILTER_DELETE: + ret = ixgbe_syn_filter_set(dev, + (struct rte_eth_syn_filter *)arg, + FALSE); + break; + case RTE_ETH_FILTER_GET: + ret = ixgbe_syn_filter_get(dev, + (struct rte_eth_syn_filter *)arg); + break; + default: + PMD_DRV_LOG(ERR, "unsupported operation %u\n", filter_op); + ret = -ENOSYS; + break; + } + + return ret; } -/* - * get the syn filter's info - * - * @param - * dev: Pointer to struct rte_eth_dev. - * filter: ponter to the filter that returns. - * *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, uint16_t *rx_queue) - +ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev, + enum rte_filter_type filter_type, + enum rte_filter_op filter_op, + void *arg) { - struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); - uint32_t synqf; + int ret = 0; - if (hw->mac.type != ixgbe_mac_82599EB) - return -ENOSYS; + if (dev == NULL) + return -EINVAL; - synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF); - if (synqf & IXGBE_SYN_FILTER_ENABLE) { - filter->hig_pri = (synqf & IXGBE_SYN_FILTER_SYNQFP) ? 1 : 0; - *rx_queue = (uint16_t)((synqf & IXGBE_SYN_FILTER_QUEUE) >> 1); - return 0; + switch (filter_type) { + case RTE_ETH_FILTER_SYN: + ret = ixgbe_syn_filter_handle(dev, filter_op, arg); + break; + default: + PMD_DRV_LOG(WARNING, "Filter type (%d) not supported", + filter_type); + ret = -EINVAL; + break; } - return -ENOENT; + + return ret; } /*