From patchwork Mon Oct 21 12:06:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simei Su X-Patchwork-Id: 61586 X-Patchwork-Delegate: xiaolong.ye@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8D1931BEE4; Mon, 21 Oct 2019 14:07:27 +0200 (CEST) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by dpdk.org (Postfix) with ESMTP id CAD331BE93 for ; Mon, 21 Oct 2019 14:07:21 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Oct 2019 05:07:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,323,1566889200"; d="scan'208";a="372154303" Received: from npg-dpdk-cvl-simeisu-118d193.sh.intel.com ([10.67.110.183]) by orsmga005.jf.intel.com with ESMTP; 21 Oct 2019 05:07:08 -0700 From: Simei Su To: qi.z.zhang@intel.com, xiaolong.ye@intel.com Cc: dev@dpdk.org, simei.su@intel.com Date: Mon, 21 Oct 2019 20:06:50 +0800 Message-Id: <1571659612-46066-2-git-send-email-simei.su@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1571659612-46066-1-git-send-email-simei.su@intel.com> References: <1571537689-351403-1-git-send-email-simei.su@intel.com> <1571659612-46066-1-git-send-email-simei.su@intel.com> Subject: [dpdk-dev] [PATCH v8 1/3] net/ice: add RSS configuration for gtpu/pppoe 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" This patch adds rss support for gtpu with input set teid and pppoe/pppod with input set source mac and session id. Signed-off-by: Simei Su Acked-by: Qi Zhang --- drivers/net/ice/ice_ethdev.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index e4fd5bc..49d00bd 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -2463,6 +2463,23 @@ static int ice_init_rss(struct ice_pf *pf) PMD_DRV_LOG(ERR, "%s SCTP_IPV4 rss flow fail %d", __func__, ret); + /* configure RSS for gtpu with input set TEID */ + ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_GTP_U_IPV4_TEID, + ICE_FLOW_SEG_HDR_GTPU_IP, 0); + if (ret) + PMD_DRV_LOG(ERR, "%s GTPU_TEID rss flow fail %d", + __func__, ret); + + /** + * configure RSS for pppoe/pppod with input set + * Source MAC and Session ID + */ + ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_PPPOE_SESS_ID_ETH, + ICE_FLOW_SEG_HDR_PPPOE, 0); + if (ret) + PMD_DRV_LOG(ERR, "%s PPPoE/PPPoD_SessionID rss flow fail %d", + __func__, ret); + return 0; } From patchwork Mon Oct 21 12:06:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simei Su X-Patchwork-Id: 61587 X-Patchwork-Delegate: xiaolong.ye@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 52D041BEFA; Mon, 21 Oct 2019 14:07:30 +0200 (CEST) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by dpdk.org (Postfix) with ESMTP id 6B0971BECC for ; Mon, 21 Oct 2019 14:07:22 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Oct 2019 05:07:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,323,1566889200"; d="scan'208";a="372154307" Received: from npg-dpdk-cvl-simeisu-118d193.sh.intel.com ([10.67.110.183]) by orsmga005.jf.intel.com with ESMTP; 21 Oct 2019 05:07:10 -0700 From: Simei Su To: qi.z.zhang@intel.com, xiaolong.ye@intel.com Cc: dev@dpdk.org, simei.su@intel.com Date: Mon, 21 Oct 2019 20:06:51 +0800 Message-Id: <1571659612-46066-3-git-send-email-simei.su@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1571659612-46066-1-git-send-email-simei.su@intel.com> References: <1571537689-351403-1-git-send-email-simei.su@intel.com> <1571659612-46066-1-git-send-email-simei.su@intel.com> Subject: [dpdk-dev] [PATCH v8 2/3] net/ice: change one member type of the pattern structure 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" This patch changes a variable type from uint64_t to void pointer to avoid compilation issues for converting a point to uint64_t in i686 environment. Signed-off-by: Simei Su Acked-by: Xiaolong Ye --- drivers/net/ice/ice_generic_flow.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h index 098a687..b6e4ed0 100644 --- a/drivers/net/ice/ice_generic_flow.h +++ b/drivers/net/ice/ice_generic_flow.h @@ -411,7 +411,7 @@ struct ice_pattern_match_item { enum rte_flow_item_type *pattern_list; /* pattern_list must end with RTE_FLOW_ITEM_TYPE_END */ uint64_t input_set_mask; - uint64_t meta; + void *meta; }; typedef int (*engine_init_t)(struct ice_adapter *ad); From patchwork Mon Oct 21 12:06:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simei Su X-Patchwork-Id: 61588 X-Patchwork-Delegate: xiaolong.ye@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 6F4001BF00; Mon, 21 Oct 2019 14:07:32 +0200 (CEST) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by dpdk.org (Postfix) with ESMTP id 93D841BE93 for ; Mon, 21 Oct 2019 14:07:22 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Oct 2019 05:07:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.67,323,1566889200"; d="scan'208";a="372154314" Received: from npg-dpdk-cvl-simeisu-118d193.sh.intel.com ([10.67.110.183]) by orsmga005.jf.intel.com with ESMTP; 21 Oct 2019 05:07:12 -0700 From: Simei Su To: qi.z.zhang@intel.com, xiaolong.ye@intel.com Cc: dev@dpdk.org, simei.su@intel.com Date: Mon, 21 Oct 2019 20:06:52 +0800 Message-Id: <1571659612-46066-4-git-send-email-simei.su@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1571659612-46066-1-git-send-email-simei.su@intel.com> References: <1571537689-351403-1-git-send-email-simei.su@intel.com> <1571659612-46066-1-git-send-email-simei.su@intel.com> Subject: [dpdk-dev] [PATCH v8 3/3] net/ice: enable advanced RSS 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" This patch supports: (1)symmetric hash by rte_flow RSS action. (2)input set change by rte_flow RSS action. Signed-off-by: Simei Su Acked-by: Qi Zhang --- doc/guides/rel_notes/release_19_11.rst | 1 + drivers/net/ice/Makefile | 1 + drivers/net/ice/ice_ethdev.c | 7 + drivers/net/ice/ice_hash.c | 562 +++++++++++++++++++++++++++++++++ drivers/net/ice/meson.build | 3 +- 5 files changed, 573 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ice/ice_hash.c diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst index 562ef1e..d905bac 100644 --- a/doc/guides/rel_notes/release_19_11.rst +++ b/doc/guides/rel_notes/release_19_11.rst @@ -104,6 +104,7 @@ New Features * Generic filter enhancement - Supported pipeline mode. - Supported new packet type like PPPoE for switch filter. + * Supported input set change and symmetric hash by rte_flow RSS action. * **Updated iavf PMD.** diff --git a/drivers/net/ice/Makefile b/drivers/net/ice/Makefile index 884fc40..7c3b6a7 100644 --- a/drivers/net/ice/Makefile +++ b/drivers/net/ice/Makefile @@ -63,6 +63,7 @@ endif SRCS-$(CONFIG_RTE_LIBRTE_ICE_PMD) += ice_switch_filter.c SRCS-$(CONFIG_RTE_LIBRTE_ICE_PMD) += ice_fdir_filter.c +SRCS-$(CONFIG_RTE_LIBRTE_ICE_PMD) += ice_hash.c ifeq ($(findstring RTE_MACHINE_CPUFLAG_AVX2,$(CFLAGS)),RTE_MACHINE_CPUFLAG_AVX2) CC_AVX2_SUPPORT=1 else diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index 49d00bd..d746758 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -2370,6 +2370,7 @@ static int ice_init_rss(struct ice_pf *pf) uint16_t i, nb_q; int ret = 0; bool is_safe_mode = pf->adapter->is_safe_mode; + uint32_t reg; rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf; nb_q = dev->data->nb_rx_queues; @@ -2413,6 +2414,12 @@ static int ice_init_rss(struct ice_pf *pf) if (ret) return -EINVAL; + /* Enable registers for symmetric_toeplitz function. */ + reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id)); + reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) | + (1 << VSIQF_HASH_CTL_HASH_SCHEME_S); + ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg); + /* configure RSS for IPv4 with input set IPv4 src/dst */ ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV4, ICE_FLOW_SEG_HDR_IPV4, 0); diff --git a/drivers/net/ice/ice_hash.c b/drivers/net/ice/ice_hash.c new file mode 100644 index 0000000..8f9e83e --- /dev/null +++ b/drivers/net/ice/ice_hash.c @@ -0,0 +1,562 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Intel Corporation + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ice_logs.h" +#include "base/ice_type.h" +#include "base/ice_flow.h" +#include "ice_ethdev.h" +#include "ice_generic_flow.h" + +#define ICE_ACTION_RSS_MAX_QUEUE_NUM 32 + +struct rss_type_match_hdr { + uint32_t hdr_mask; + uint64_t eth_rss_hint; +}; + +struct ice_hash_match_type { + uint64_t hash_type; + uint64_t hash_flds; +}; + +struct rss_meta { + uint32_t pkt_hdr; + uint64_t hash_flds; + uint8_t hash_function; +}; + +static int +ice_hash_init(struct ice_adapter *ad); + +static int +ice_hash_create(struct ice_adapter *ad, + struct rte_flow *flow, + void *meta, + struct rte_flow_error *error); + +static int +ice_hash_destroy(struct ice_adapter *ad, + struct rte_flow *flow, + struct rte_flow_error *error); + +static void +ice_hash_uninit(struct ice_adapter *ad); + +static void +ice_hash_free(struct rte_flow *flow); + +static int +ice_hash_parse_pattern_action(struct ice_adapter *ad, + struct ice_pattern_match_item *array, + uint32_t array_len, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + void **meta, + struct rte_flow_error *error); + +/* The first member is protocol header, the second member is ETH_RSS_*. */ +struct rss_type_match_hdr hint_0 = { + ICE_FLOW_SEG_HDR_NONE, 0}; +struct rss_type_match_hdr hint_1 = { + ICE_FLOW_SEG_HDR_IPV4, ETH_RSS_IPV4}; +struct rss_type_match_hdr hint_2 = { + ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_UDP, ETH_RSS_NONFRAG_IPV4_UDP}; +struct rss_type_match_hdr hint_3 = { + ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_TCP, ETH_RSS_NONFRAG_IPV4_TCP}; +struct rss_type_match_hdr hint_4 = { + ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_SCTP, ETH_RSS_NONFRAG_IPV4_SCTP}; +struct rss_type_match_hdr hint_5 = { + ICE_FLOW_SEG_HDR_IPV6, ETH_RSS_IPV6}; +struct rss_type_match_hdr hint_6 = { + ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_UDP, ETH_RSS_NONFRAG_IPV6_UDP}; +struct rss_type_match_hdr hint_7 = { + ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_TCP, ETH_RSS_NONFRAG_IPV6_TCP}; +struct rss_type_match_hdr hint_8 = { + ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_SCTP, ETH_RSS_NONFRAG_IPV6_SCTP}; +struct rss_type_match_hdr hint_9 = { + ICE_FLOW_SEG_HDR_GTPU_IP, ETH_RSS_IPV4}; +struct rss_type_match_hdr hint_10 = { + ICE_FLOW_SEG_HDR_PPPOE, ETH_RSS_IPV4}; +struct rss_type_match_hdr hint_11 = { + ICE_FLOW_SEG_HDR_PPPOE, ETH_RSS_NONFRAG_IPV4_UDP}; +struct rss_type_match_hdr hint_12 = { + ICE_FLOW_SEG_HDR_PPPOE, ETH_RSS_NONFRAG_IPV4_TCP}; +struct rss_type_match_hdr hint_13 = { + ICE_FLOW_SEG_HDR_PPPOE, ETH_RSS_NONFRAG_IPV4_SCTP}; + +/* Supported pattern for os default package. */ +static struct ice_pattern_match_item ice_hash_pattern_list_os[] = { + {pattern_eth_ipv4, ICE_INSET_NONE, &hint_1}, + {pattern_eth_ipv4_udp, ICE_INSET_NONE, &hint_2}, + {pattern_eth_ipv4_tcp, ICE_INSET_NONE, &hint_3}, + {pattern_eth_ipv4_sctp, ICE_INSET_NONE, &hint_4}, + {pattern_eth_ipv6, ICE_INSET_NONE, &hint_5}, + {pattern_eth_ipv6_udp, ICE_INSET_NONE, &hint_6}, + {pattern_eth_ipv6_tcp, ICE_INSET_NONE, &hint_7}, + {pattern_eth_ipv6_sctp, ICE_INSET_NONE, &hint_8}, + {pattern_empty, ICE_INSET_NONE, &hint_0}, +}; + +/* Supported pattern for comms package. */ +static struct ice_pattern_match_item ice_hash_pattern_list_comms[] = { + {pattern_eth_ipv4, ICE_INSET_NONE, &hint_1}, + {pattern_eth_ipv4_udp, ICE_INSET_NONE, &hint_2}, + {pattern_eth_ipv4_tcp, ICE_INSET_NONE, &hint_3}, + {pattern_eth_ipv4_sctp, ICE_INSET_NONE, &hint_4}, + {pattern_eth_ipv6, ICE_INSET_NONE, &hint_5}, + {pattern_eth_ipv6_udp, ICE_INSET_NONE, &hint_6}, + {pattern_eth_ipv6_tcp, ICE_INSET_NONE, &hint_7}, + {pattern_eth_ipv6_sctp, ICE_INSET_NONE, &hint_8}, + {pattern_empty, ICE_INSET_NONE, &hint_0}, + {pattern_eth_ipv4_gtpu_ipv4, ICE_INSET_NONE, &hint_9}, + {pattern_eth_ipv4_gtpu_ipv4_udp, ICE_INSET_NONE, &hint_9}, + {pattern_eth_ipv4_gtpu_ipv4_tcp, ICE_INSET_NONE, &hint_9}, + {pattern_eth_pppoes_ipv4, ICE_INSET_NONE, &hint_10}, + {pattern_eth_pppoes_ipv4_udp, ICE_INSET_NONE, &hint_11}, + {pattern_eth_pppoes_ipv4_tcp, ICE_INSET_NONE, &hint_12}, + {pattern_eth_pppoes_ipv4_sctp, ICE_INSET_NONE, &hint_13}, +}; + +/** + * The first member is input set combination, + * the second member is hash fields. + */ +struct ice_hash_match_type ice_hash_type_list[] = { + {ETH_RSS_IPV4 | ETH_RSS_L3_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)}, + {ETH_RSS_IPV4 | ETH_RSS_L3_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)}, + {ETH_RSS_IPV4, ICE_FLOW_HASH_IPV4}, + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)}, + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L3_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)}, + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV4_UDP, ICE_HASH_UDP_IPV4}, + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)}, + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L3_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)}, + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV4_TCP, ICE_HASH_TCP_IPV4}, + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_SA)}, + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L3_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV4_DA)}, + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV4_SCTP | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV4_SCTP, ICE_HASH_SCTP_IPV4}, + {ETH_RSS_IPV6 | ETH_RSS_L3_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)}, + {ETH_RSS_IPV6 | ETH_RSS_L3_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)}, + {ETH_RSS_IPV6, ICE_FLOW_HASH_IPV6}, + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)}, + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L3_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)}, + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV6_UDP | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_UDP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV6_UDP, ICE_HASH_UDP_IPV6}, + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)}, + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L3_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)}, + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV6_TCP | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_TCP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV6_TCP, ICE_HASH_TCP_IPV6}, + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_SA)}, + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA) | BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L3_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_IPV6_DA)}, + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_SRC_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT)}, + {ETH_RSS_NONFRAG_IPV6_SCTP | ETH_RSS_L4_DST_ONLY, BIT_ULL(ICE_FLOW_FIELD_IDX_SCTP_DST_PORT)}, + {ETH_RSS_NONFRAG_IPV6_SCTP, ICE_HASH_SCTP_IPV6}, +}; + +static struct ice_flow_engine ice_hash_engine = { + .init = ice_hash_init, + .create = ice_hash_create, + .destroy = ice_hash_destroy, + .uninit = ice_hash_uninit, + .free = ice_hash_free, + .type = ICE_FLOW_ENGINE_HASH, +}; + +/* Register parser for os package. */ +static struct ice_flow_parser ice_hash_parser_os = { + .engine = &ice_hash_engine, + .array = ice_hash_pattern_list_os, + .array_len = RTE_DIM(ice_hash_pattern_list_os), + .parse_pattern_action = ice_hash_parse_pattern_action, + .stage = ICE_FLOW_STAGE_RSS, +}; + +/* Register parser for comms package. */ +static struct ice_flow_parser ice_hash_parser_comms = { + .engine = &ice_hash_engine, + .array = ice_hash_pattern_list_comms, + .array_len = RTE_DIM(ice_hash_pattern_list_comms), + .parse_pattern_action = ice_hash_parse_pattern_action, + .stage = ICE_FLOW_STAGE_RSS, +}; + +RTE_INIT(ice_hash_engine_init) +{ + struct ice_flow_engine *engine = &ice_hash_engine; + ice_register_flow_engine(engine); +} + +static int +ice_hash_init(struct ice_adapter *ad) +{ + struct ice_flow_parser *parser = NULL; + + if (ad->active_pkg_type == ICE_PKG_TYPE_OS_DEFAULT) + parser = &ice_hash_parser_os; + else if (ad->active_pkg_type == ICE_PKG_TYPE_COMMS) + parser = &ice_hash_parser_comms; + + return ice_register_parser(parser, ad); +} + +static int +ice_hash_check_inset(const struct rte_flow_item pattern[], + struct rte_flow_error *error) +{ + const struct rte_flow_item *item = pattern; + + for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { + if (item->last) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Not support range"); + return -rte_errno; + } + + /* Ignore spec and mask. */ + if (item->spec || item->mask) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "Invalid spec/mask."); + return -rte_errno; + } + } + + return 0; +} + +static int +ice_hash_parse_action(struct ice_pattern_match_item *pattern_match_item, + const struct rte_flow_action actions[], + void **meta, + struct rte_flow_error *error) +{ + const struct rte_flow_action *action; + enum rte_flow_action_type action_type; + const struct rte_flow_action_rss *rss; + struct rss_type_match_hdr *m = (struct rss_type_match_hdr *) + (pattern_match_item->meta); + uint32_t type_list_len = RTE_DIM(ice_hash_type_list); + struct ice_hash_match_type *type_match_item; + + /* Supported action is RSS. */ + for (action = actions; action->type != + RTE_FLOW_ACTION_TYPE_END; action++) { + action_type = action->type; + switch (action_type) { + case RTE_FLOW_ACTION_TYPE_RSS: + rss = action->conf; + uint16_t i; + uint64_t rss_hf = rss->types; + + /** + * Check simultaneous use of SRC_ONLY and DST_ONLY + * of the same level. + */ + rss_hf = rte_eth_rss_hf_refine(rss_hf); + + /* Check if pattern is empty. */ + if (pattern_match_item->pattern_list != + pattern_empty && rss->func == + RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "Not supported flow"); + + /* Check if rss types match pattern. */ + if (rss->func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) { + if (((rss_hf & ETH_RSS_IPV4) != m->eth_rss_hint) || + ((rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) != m->eth_rss_hint) || + ((rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) != m->eth_rss_hint) || + ((rss_hf & ETH_RSS_NONFRAG_IPV4_SCTP) != m->eth_rss_hint) || + ((rss_hf & ETH_RSS_IPV6) != m->eth_rss_hint) || + ((rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) != m->eth_rss_hint) || + ((rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) != m->eth_rss_hint) || + ((rss_hf & ETH_RSS_NONFRAG_IPV6_SCTP) != m->eth_rss_hint)) + return rte_flow_error_set(error, + ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, + action, "Not supported RSS types"); + } + + if (rss->level) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "a nonzero RSS encapsulation level is not supported"); + + if (rss->key_len == 0) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "RSS hash key_len mustn't be 0"); + + if (rss->queue_num > ICE_ACTION_RSS_MAX_QUEUE_NUM) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "too many queues for RSS context"); + + /* Check hash function and save it to rss_meta. */ + if (rss->func == + RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) + ((struct rss_meta *)*meta)->hash_function = + RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; + + if (rss->func == + RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) + ((struct rss_meta *)*meta)->hash_function = + RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; + + type_match_item = rte_zmalloc("ice_type_match_item", + sizeof(struct ice_hash_match_type), 0); + if (!type_match_item) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "No memory for type_match_item"); + return -ENOMEM; + } + + /* Find matched hash fields according to hash type. */ + for (i = 0; i < type_list_len; i++) { + if (rss_hf == + ice_hash_type_list[i].hash_type) { + type_match_item->hash_type = + ice_hash_type_list[i].hash_type; + type_match_item->hash_flds = + ice_hash_type_list[i].hash_flds; + } + } + + /* Save hash fileds to rss_meta. */ + ((struct rss_meta *)*meta)->hash_flds = + type_match_item->hash_flds; + + rte_free(type_match_item); + break; + + case RTE_FLOW_ACTION_TYPE_END: + break; + + default: + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "Invalid action."); + return -rte_errno; + } + } + + return 0; +} + +static int +ice_hash_parse_pattern_action(__rte_unused struct ice_adapter *ad, + struct ice_pattern_match_item *array, + uint32_t array_len, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + void **meta, + struct rte_flow_error *error) +{ + int ret = 0; + struct ice_pattern_match_item *pattern_match_item; + struct rss_meta *rss_meta_ptr; + + rss_meta_ptr = rte_zmalloc(NULL, sizeof(*rss_meta_ptr), 0); + if (!rss_meta_ptr) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "No memory for rss_meta_ptr"); + return -ENOMEM; + } + + /* Check rss supported pattern and find matched pattern. */ + pattern_match_item = ice_search_pattern_match_item(pattern, + array, array_len, error); + if (!pattern_match_item) + return -rte_errno; + + ret = ice_hash_check_inset(pattern, error); + if (ret) + return -rte_errno; + + /* Save protocol header to rss_meta. */ + *meta = rss_meta_ptr; + ((struct rss_meta *)*meta)->pkt_hdr = ((struct rss_type_match_hdr *) + (pattern_match_item->meta))->hdr_mask; + + /* Check rss action. */ + ret = ice_hash_parse_action(pattern_match_item, actions, meta, error); + if (ret) + return -rte_errno; + + rte_free(pattern_match_item); + + return 0; +} + +static int +ice_hash_create(struct ice_adapter *ad, + struct rte_flow *flow, + void *meta, + struct rte_flow_error *error) +{ + struct ice_pf *pf = &ad->pf; + struct ice_hw *hw = ICE_PF_TO_HW(pf); + struct ice_vsi *vsi = pf->main_vsi; + int ret; + uint32_t reg; + struct ice_rss_cfg *filter_ptr; + + uint32_t headermask = ((struct rss_meta *)meta)->pkt_hdr; + uint64_t hash_field = ((struct rss_meta *)meta)->hash_flds; + uint8_t hash_function = ((struct rss_meta *)meta)->hash_function; + + filter_ptr = rte_zmalloc("ice_rss_filter", + sizeof(struct ice_rss_cfg), 0); + if (!filter_ptr) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "No memory for filter_ptr"); + return -ENOMEM; + } + + if (hash_function == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR) { + /* Enable registers for simple_xor hash function. */ + reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id)); + reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) | + (2 << VSIQF_HASH_CTL_HASH_SCHEME_S); + ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg); + + filter_ptr->symm = 0; + + goto out; + } else if (hash_function == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ) { + ret = ice_add_rss_cfg(hw, vsi->idx, hash_field, headermask, 1); + if (ret) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "rss flow create fail"); + goto error; + } + } else { + ret = ice_add_rss_cfg(hw, vsi->idx, hash_field, headermask, 0); + if (ret) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "rss flow create fail"); + goto error; + } + } + + filter_ptr->packet_hdr = headermask; + filter_ptr->hashed_flds = hash_field; + +out: + flow->rule = filter_ptr; + rte_free(meta); + return 0; + +error: + rte_free(filter_ptr); + rte_free(meta); + return -rte_errno; +} + +static int +ice_hash_destroy(struct ice_adapter *ad, + struct rte_flow *flow, + struct rte_flow_error *error) +{ + struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(ad); + struct ice_hw *hw = ICE_PF_TO_HW(pf); + struct ice_vsi *vsi = pf->main_vsi; + int ret; + uint32_t reg; + struct ice_rss_cfg *filter_ptr; + + filter_ptr = (struct ice_rss_cfg *)flow->rule; + + if (filter_ptr->symm == 0) { + /* Return to symmetric_toeplitz state. */ + reg = ICE_READ_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id)); + reg = (reg & (~VSIQF_HASH_CTL_HASH_SCHEME_M)) | + (1 << VSIQF_HASH_CTL_HASH_SCHEME_S); + ICE_WRITE_REG(hw, VSIQF_HASH_CTL(vsi->vsi_id), reg); + } else { + ret = ice_rem_vsi_rss_cfg(hw, vsi->idx); + if (ret) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_HANDLE, NULL, + "rss flow destroy fail"); + goto error; + } + } + + rte_free(filter_ptr); + return 0; + +error: + rte_free(filter_ptr); + return -rte_errno; +} + +static void +ice_hash_uninit(struct ice_adapter *ad) +{ + if (ad->active_pkg_type == ICE_PKG_TYPE_OS_DEFAULT) + ice_unregister_parser(&ice_hash_parser_os, ad); + else if (ad->active_pkg_type == ICE_PKG_TYPE_COMMS) + ice_unregister_parser(&ice_hash_parser_comms, ad); +} + +static void +ice_hash_free(struct rte_flow *flow) +{ + rte_free(flow->rule); +} diff --git a/drivers/net/ice/meson.build b/drivers/net/ice/meson.build index 908a2ca..f9e897b 100644 --- a/drivers/net/ice/meson.build +++ b/drivers/net/ice/meson.build @@ -11,7 +11,8 @@ sources = files( 'ice_rxtx.c', 'ice_switch_filter.c', 'ice_generic_flow.c', - 'ice_fdir_filter.c' + 'ice_fdir_filter.c', + 'ice_hash.c' ) deps += ['hash']