From patchwork Sat Sep 8 20:31:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Mody, Rasesh" X-Patchwork-Id: 44455 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 [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 6129B5F32; Sat, 8 Sep 2018 22:32:09 +0200 (CEST) Received: from NAM04-BN3-obe.outbound.protection.outlook.com (mail-eopbgr680074.outbound.protection.outlook.com [40.107.68.74]) by dpdk.org (Postfix) with ESMTP id 03D9F5398 for ; Sat, 8 Sep 2018 22:31:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=q2GmL9f21JsH7el5mKTt0j1e1OM2kLYpQhBe6nhg910=; b=XQqY3bqvRYP175aH45wdrQmt9zPelmFmZ+Tx++a04jW/wtXE6WYTlABStqvGrWdG7LxcUuLwcTANsnPEPxLggZA0beCyU4dbhgcY+Y813+lnG1+f6SRwVhN8d0MpA8CB/8T6SW8PcLIsIb3NE2W2qiATuQu5sefDE+w9WiW/SVo= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Rasesh.Mody@cavium.com; Received: from cavium.com (198.186.1.5) by DM6PR07MB5372.namprd07.prod.outlook.com (2603:10b6:5:44::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1101.18; Sat, 8 Sep 2018 20:31:53 +0000 From: Rasesh Mody To: dev@dpdk.org Cc: Shahed Shaikh , ferruh.yigit@intel.com, Dept-EngDPDKDev@cavium.com Date: Sat, 8 Sep 2018 13:31:01 -0700 Message-Id: <1536438666-22184-13-git-send-email-rasesh.mody@cavium.com> X-Mailer: git-send-email 1.7.10.3 In-Reply-To: <1536438666-22184-1-git-send-email-rasesh.mody@cavium.com> References: <1536438666-22184-1-git-send-email-rasesh.mody@cavium.com> MIME-Version: 1.0 X-Originating-IP: [198.186.1.5] X-ClientProxiedBy: BYAPR02CA0031.namprd02.prod.outlook.com (2603:10b6:a02:ee::44) To DM6PR07MB5372.namprd07.prod.outlook.com (2603:10b6:5:44::17) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 5651dea0-082c-489f-f52f-08d615ca1d8c X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989137)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600074)(711020)(2017052603328)(7153060)(7193020); SRVR:DM6PR07MB5372; X-Microsoft-Exchange-Diagnostics: 1; DM6PR07MB5372; 3:ZtKsfAtLtpX8XUCdsga/R7GdwsT3Ly3ego1zRqraDyhfO8Hsdromo2LEPmLHywosvApV8tQkCZwoz4HU+s7/FXDn4zjZr+YuSIr6ICxBjg7xHtklHXlgH6AmTo9v5OtF17hDMAxnO7tWdHCFCMXDGvDgrZGBlw4Tuh7TGsCjZwRlOOTtUU6XVWIPHXbIQnJ2byFcFSHLcDbUuMm28orbYovfEwCzTxloTDGJ38x2m09Ov1EMcLSdZJC1+Sqp7CyT; 25:v+KG89/alpdS2lUpedzMkbsg68K54BijwkXBHqOVKIFdtwG5rBe6hB6d2RAJ1QVoNx2Pr2Cq9bN0rZSJZXSyXwrRtwU3Je5hwvR2wO7Gj7a7UjwX4IvQmBz+LjvRE6xVH5+boVepHD3Nq05PprTEp8uuMjteD+tUu0iAZ3WRkqchuazEoD90MYOAushCQy6rFDMem5Rlvdv/j8OLIyW+v1GF2NjAymWMYBE4H3FmyksN9wRlpWdrePnWHNhsgeWH6w6Xm12O2X/3UNAV8VO4ulfwrRki5c032l13SC3RrJZYa+SuHj8AsQWfGyKBGJOieJbGsy8Vpo5fJ5KNioRoRg==; 31:eEhjhOqst1vAlTaEdZIO05yyC8Uva9/SLXuaWmgkNuy0anlg9hE17MCTG8sYtn+pBsiqeLMET+TuxtAGj3MuG78XpBA+X7pEAZxdOH4mKCSIqZ0UTWmSa4PaHsdwD4Xg9/k9ihzjjNx4JqzeAK3CvGyxsPF7wKDlEewOBDkADAJqMivCjxSzUn3gZQ3giEPLtQYKdGJbL5oMx6G4F519UxcPcg+ITd+THNMtbHbBvkw= X-MS-TrafficTypeDiagnostic: DM6PR07MB5372: X-Microsoft-Exchange-Diagnostics: 1; DM6PR07MB5372; 20:uAtBU7urOKMYfLL/LKHYiU/lm76uRAZU5H+bC+qyF7/wVGo5sM0SjG/ckpeL+fDZJLcljWDj6LtDFSn0oVEybCV1Gd7E8Eh1sv4vNFnGrFwtJ9GJX0YirKmYn1GtT6/n/Wm5PMhlHYUxwC1uMUH7MKpfyYBf4emqmlWSO1dm6+/VJpCMuud1ZBdUZsBlWQ1ycJX0clIj3hcWoL55gh/mAwdI4QWT6mqzJj3U8/HCxyzcRg5YOif3IN1Mg/3ih/J2B1I2ilt78VocrGV9/O6A9JqGXjPZgGWHZMg/vrwQ6nE5hkR6W6yJg33JgvYBE3wjF21wm2vS6u44otxYjPRtticUgbN5/X5Rhgi26sEykwyZ2+vMFlsomFCNlPCUci1afp6SnVBCRabxs1b1igXfjd29h61C3vuJUljqEV/MY1mHRzzsieP6E1E/bHVnkrsLQnCPWgDgMv4Gc3Ops/tMIhs6qH7vhw2ptqj/9Vnxuv4lCTXAxxq3x75X/bY6rNIn; 4:mi2JtFo1XLra5sqlYwSBBM15oqkMz6Cg5TtLA7UeOuocGL5IST9A62mj4wliJW/+50e1tyj1zLXJrcovZvabxbCwZs5wfaH7N4A3wLRGI6NXg15cVa2Hc7otGnFBE4e6LzIPoMVwvDYOv7oU81nQ18J5IgmNr1YzspjC6kmGpGMr317vSrlgfRuMmPfDCAZ5WRSHzEHrvE1k2EqnB6AUGmrOQFgfzYmzHU1lSRLR58l79Lh6cYTaey+yYrZL4DX3qD8J7LtJc9eApmn3HVeXhw== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(823301075)(3002001)(10201501046)(3231311)(944501410)(52105095)(93006095)(93001095)(149027)(150027)(6041310)(20161123562045)(20161123564045)(20161123558120)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(201708071742011)(7699050); SRVR:DM6PR07MB5372; BCL:0; PCL:0; RULEID:; SRVR:DM6PR07MB5372; X-Forefront-PRVS: 07891BF289 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(979002)(396003)(366004)(136003)(346002)(376002)(39860400002)(199004)(189003)(4720700003)(97736004)(2351001)(106356001)(105586002)(72206003)(66066001)(47776003)(4326008)(50466002)(48376002)(25786009)(305945005)(7736002)(2361001)(8676002)(478600001)(316002)(52116002)(69596002)(107886003)(186003)(50226002)(44832011)(16526019)(486006)(21086003)(2906002)(55016002)(26005)(8936002)(476003)(956004)(81156014)(81166006)(86362001)(5660300001)(6666003)(36756003)(16586007)(11346002)(446003)(2616005)(76176011)(3846002)(6116002)(6916009)(68736007)(14444005)(386003)(51416003)(53936002)(7696005)(41533002)(969003)(989001)(999001)(1009001)(1019001); DIR:OUT; SFP:1101; SCL:1; SRVR:DM6PR07MB5372; H:cavium.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; DM6PR07MB5372; 23:wp8NHGJleLpX3VJkXr3th7SkRzZQQYe7QZCz22fGX?= yM8/4dAfWMjNSS9djou6FnYU/WPQqAV1UNqimNcB6XHMBiXg2qfPR5XZxwKq2TZCNxquyiMWTmdAYCrtEvE8DAydm5lf/izuT0nj79kE1p/Q9mN8Q/xWrFMVxdvLOxssRowm6kri/qBKawnidk8yjShtcN+EPqBSUKu5rGYpCDdo4d0/ULyuqo6xbR+MS4Ct6+2GZccnSKYCc/5KamUbvuL2OddHvinjqKqlXwD/lNdRx0/ckOLM4FD2UQAA1T7X7WZbcFFP+/puq3gbixTZFWYNnRpBcZSRmtYLMWokdKZc3HSNQNjSeNOhhvXi5O0Gkd5/JGH1WYMHc3U+bn2BE6boHBs5SHYIzEbr8hEWNdYAD1UeyXRcY55Yk3ie26qGJCX/pNpz8ijgdOCx7cFyMPhgnOGRBYgNRNOll3vV086To450b7RQbScMFW0/yG2IzJYNIyJKNefAJYqApUxEJK3dnkBbJjVF7mdIBZ5LBBbQrZxA6nDoybJwk3gj9Y4P5gPjoMCK9eT/LL1VtSh+qBYfwWFMbNH+TxUgugS86vLm3Nau9mzh3c6z6Wcf2EtQvlq/Ru745205SwXzNaZc3E7amDVbr8ULAWGDwuaZAh6yGN3qPZA7eO75JPBn5f4L6l0DKFDWvkxrRj1SgQEB/IICvToTvxQAOHD6SPYFK3kzYH7iS8uUDHikuSxfIvIhUE/sagNBXAZ+YjQaY7XmlbVW6I9QjkT7Ms68+uIXyRTPVfSoteCV9zlnvntbCzNkJL+ToNuyS4zu2yu5I6HQEM12mBhuvNConXOAxp28fD2hqcgfdm+UKJO0Qahrhlx/WIiE3BZ9so2q1UjCc2viHK4oqz59i/89nyPR0l4aqqNrxMvhQ20EBf0m+RfIzKW5cUoDQqzCMbL90zSGuO0H/FiX+lR5jMvqxd5FOgvy88n+du/jhTz44KTE6oa2p33JKQHOD9Qgk5e2CI0ApyBtndIbbvbVGA2kFjkvGXntsSZFC/tay/uEQhebcDwJhGXZrCtFPz+/NlQNXh//YFAEY2tTfjBJhShQp8iHLmB4cL8x+47voPCEcPQPDTgUG0r0UzSgcVe4t8XmTkEnT+AXe3VzxmlDMYkYssuh+wM6sudtgeU7ZfBDCINvJV2gE+HWVnMsdmY+WzMk/5E3yp41GQU6P5fwaLpkxSqu9oGG1GyDGBfKrNrIVnwvRODFwHqHAB0IX51mlF87ZDRPapAQ89djeIqZvnPwMzXGIlatmJpsqtmTBLZVfpzpe6Szhh9I7/IvQtjWaLgtw9JqdRHT6xIXS+9zZYVVxz0klAAtPACNhd6GXO74CB7lElK7dkjlIodTqks2O9te0tTl59ZGNbh/r6Vg9khLsrNaOxzyJlpKFSB9ugIP/JhpKWRsHgsFRUedVbCWoD4V0pjucdInvWW X-Microsoft-Antispam-Message-Info: 7hf2+yyACHIQUKVX0XlOajMSk9VOJu0ot0AVFmI5eIv1y6RxeF4QNHzSmSb+E9e48uyFWJYXoxuXNkyfdBCj8BPNey1afp3kps47OQBo24m1gS4kFRoXnkD6N//XiYMZ+BhooDQOKI/bPsKhXPZGiXjW9+4uBp9sEjqKLMyRPT9NNhY6IpO9MfSo3spt+2+c6m4uQxiXYB2DJPnjk2WwbPIi3PrPyLpTglZVM4rh/G7dVRAn8vnbcl7vzlMx8DqhPDqeEOOUI/9bgXqfe0ZO/Wdj1L1mG08KanZIws+ywx5T3CrzkZ+Ih48UqIdAsXZKeEMdUVqgnNJ2sVH2OCayJX4MNAME+FimBD6XHmpNis0= X-Microsoft-Exchange-Diagnostics: 1; DM6PR07MB5372; 6:OqKwyR+/u2RobygOWv8VLaE5+3W1JyN/jHMQPW40eEHN1MuA4reDROVfLDbunNFqUncMnynZcwdGnwxApMfOA91Q7eQ8eWHT8OkqDbnaQyV/vzmGLoNEeX0Ve485XEowAii2n31C6Xt0uWjEXAFp2AiUYRVcnU8WCMbohkucfV8u7xhN20Bjfkq9YM6mWmSW99M2ybM4jsebWV3f30zdiuhD78M9Trj+hO9jzLJbBwdypETCRhHP2Wb4mgRDll187CNYEwjQxpIERqtpFstiig5r32SMo5BNcBjgJ4zrw2vRmGYdkVcExGa5qNWm0K1Aas8VrtUcjvGjD5ETYolbFeLt991S5Hj1sbqVJR5J5Cv7ibeUk3E0CcOegzf5X32pcOVMX5x7LUgZ08fLK6uSfeWy7VMoqfzKcSGEY6fk9g62vSHyOMzaliJgEb8RQwkTGLL27pjpSryoqfRW+fGcNA==; 5:7xdmLfRvO8/MLqP7KxDyCTrOgjV82m83RQBhQrTL+8qv2H0hZ0HAJARN28VrRueI4p1FU3FOnoabfA9deHYQxCuaQzh6pH8tlic60IUfiBbEL9cZ9el72mEBSCjMzMfpDMevMlcppLZTDL5IbHa8pK5tIIgFlnhHIXE+1eORZjc=; 7:DPfidLC+QKg93r0L6oVav+03QrANK46h1/NcMLWjyntMoqdGR2AdwblXGhWFxvIfy9ZDJywxsZRTJgcQ52FMjid3xBvaXYFDIB5Qf1Pnlz6I6MXpsbpg8yq98pMymy84Q1sOr9CSKL5VCmVixc98iRt8O+eOkvfewAJCN2QujkPo1jFozjkSKNfQ35ON4PhfTiKPIJnHjvbRD36/JRtkt5rbvsSRoNgV32LQpySR6sc1xXu+W3fwCkB1nL3MJubi SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: cavium.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 Sep 2018 20:31:53.9107 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5651dea0-082c-489f-f52f-08d615ca1d8c X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR07MB5372 Subject: [dpdk-dev] [PATCH 12/17] net/qede: refactor fdir code into generic aRFS 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" From: Shahed Shaikh - In order to prepare the base for RTE FLOW support, convert common code used for flow director support into common aRFS code. Signed-off-by: Shahed Shaikh --- drivers/net/qede/base/ecore_l2.c | 26 ++- drivers/net/qede/base/ecore_l2_api.h | 11 +- drivers/net/qede/qede_ethdev.c | 2 +- drivers/net/qede/qede_ethdev.h | 35 +++- drivers/net/qede/qede_filter.c | 291 +++++++++++++++++++++------------- 5 files changed, 240 insertions(+), 125 deletions(-) diff --git a/drivers/net/qede/base/ecore_l2.c b/drivers/net/qede/base/ecore_l2.c index d71f461..ca4d901 100644 --- a/drivers/net/qede/base/ecore_l2.c +++ b/drivers/net/qede/base/ecore_l2.c @@ -2084,6 +2084,24 @@ void ecore_reset_vport_stats(struct ecore_dev *p_dev) } } +static enum gft_profile_type +ecore_arfs_mode_to_hsi(enum ecore_filter_config_mode mode) +{ + if (mode == ECORE_FILTER_CONFIG_MODE_5_TUPLE) + return GFT_PROFILE_TYPE_4_TUPLE; + + if (mode == ECORE_FILTER_CONFIG_MODE_IP_DEST) + return GFT_PROFILE_TYPE_IP_DST_ADDR; + + if (mode == ECORE_FILTER_CONFIG_MODE_TUNN_TYPE) + return GFT_PROFILE_TYPE_TUNNEL_TYPE; + + if (mode == ECORE_FILTER_CONFIG_MODE_IP_SRC) + return GFT_PROFILE_TYPE_IP_SRC_ADDR; + + return GFT_PROFILE_TYPE_L4_DST_PORT; +} + void ecore_arfs_mode_configure(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt, struct ecore_arfs_config_params *p_cfg_params) @@ -2091,13 +2109,13 @@ void ecore_arfs_mode_configure(struct ecore_hwfn *p_hwfn, if (OSAL_TEST_BIT(ECORE_MF_DISABLE_ARFS, &p_hwfn->p_dev->mf_bits)) return; - if (p_cfg_params->arfs_enable) { + if (p_cfg_params->mode != ECORE_FILTER_CONFIG_MODE_DISABLE) { ecore_gft_config(p_hwfn, p_ptt, p_hwfn->rel_pf_id, p_cfg_params->tcp, p_cfg_params->udp, p_cfg_params->ipv4, p_cfg_params->ipv6, - GFT_PROFILE_TYPE_4_TUPLE); + ecore_arfs_mode_to_hsi(p_cfg_params->mode)); DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "tcp = %s, udp = %s, ipv4 = %s, ipv6 =%s\n", p_cfg_params->tcp ? "Enable" : "Disable", @@ -2107,8 +2125,8 @@ void ecore_arfs_mode_configure(struct ecore_hwfn *p_hwfn, } else { ecore_gft_disable(p_hwfn, p_ptt, p_hwfn->rel_pf_id); } - DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "Configured ARFS mode : %s\n", - p_cfg_params->arfs_enable ? "Enable" : "Disable"); + DP_VERBOSE(p_hwfn, ECORE_MSG_SP, "Configured ARFS mode : %d\n", + (int)p_cfg_params->mode); } enum _ecore_status_t diff --git a/drivers/net/qede/base/ecore_l2_api.h b/drivers/net/qede/base/ecore_l2_api.h index 575b9e3..85034e6 100644 --- a/drivers/net/qede/base/ecore_l2_api.h +++ b/drivers/net/qede/base/ecore_l2_api.h @@ -139,12 +139,21 @@ struct ecore_filter_accept_flags { #define ECORE_ACCEPT_BCAST 0x20 }; +enum ecore_filter_config_mode { + ECORE_FILTER_CONFIG_MODE_DISABLE, + ECORE_FILTER_CONFIG_MODE_5_TUPLE, + ECORE_FILTER_CONFIG_MODE_L4_PORT, + ECORE_FILTER_CONFIG_MODE_IP_DEST, + ECORE_FILTER_CONFIG_MODE_TUNN_TYPE, + ECORE_FILTER_CONFIG_MODE_IP_SRC, +}; + struct ecore_arfs_config_params { bool tcp; bool udp; bool ipv4; bool ipv6; - bool arfs_enable; /* Enable or disable arfs mode */ + enum ecore_filter_config_mode mode; }; /* Add / remove / move / remove-all unicast MAC-VLAN filters. diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index 3a7c466..d5e162c 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -2576,7 +2576,7 @@ static int qede_common_dev_init(struct rte_eth_dev *eth_dev, bool is_vf) adapter->num_tx_queues = 0; adapter->num_rx_queues = 0; - SLIST_INIT(&adapter->fdir_info.fdir_list_head); + SLIST_INIT(&adapter->arfs_info.arfs_list_head); SLIST_INIT(&adapter->vlan_list_head); SLIST_INIT(&adapter->uc_list_head); SLIST_INIT(&adapter->mc_list_head); diff --git a/drivers/net/qede/qede_ethdev.h b/drivers/net/qede/qede_ethdev.h index d54f19b..59828f8 100644 --- a/drivers/net/qede/qede_ethdev.h +++ b/drivers/net/qede/qede_ethdev.h @@ -151,18 +151,43 @@ struct qede_ucast_entry { SLIST_ENTRY(qede_ucast_entry) list; }; -struct qede_fdir_entry { +#ifndef IPV6_ADDR_LEN +#define IPV6_ADDR_LEN (16) +#endif + +struct qede_arfs_tuple { + union { + uint32_t src_ipv4; + uint8_t src_ipv6[IPV6_ADDR_LEN]; + }; + + union { + uint32_t dst_ipv4; + uint8_t dst_ipv6[IPV6_ADDR_LEN]; + }; + + uint16_t src_port; + uint16_t dst_port; + uint16_t eth_proto; + uint8_t ip_proto; + + /* Describe filtering mode needed for this kind of filter */ + enum ecore_filter_config_mode mode; +}; + +struct qede_arfs_entry { uint32_t soft_id; /* unused for now */ uint16_t pkt_len; /* actual packet length to match */ uint16_t rx_queue; /* queue to be steered to */ const struct rte_memzone *mz; /* mz used to hold L2 frame */ - SLIST_ENTRY(qede_fdir_entry) list; + struct qede_arfs_tuple tuple; + SLIST_ENTRY(qede_arfs_entry) list; }; -struct qede_fdir_info { +struct qede_arfs_info { struct ecore_arfs_config_params arfs; uint16_t filter_count; - SLIST_HEAD(fdir_list_head, qede_fdir_entry)fdir_list_head; + SLIST_HEAD(arfs_list_head, qede_arfs_entry)arfs_list_head; }; /* IANA assigned default UDP ports for encapsulation protocols */ @@ -207,7 +232,7 @@ struct qede_dev { struct qede_tunn_params vxlan; struct qede_tunn_params geneve; struct qede_tunn_params ipgre; - struct qede_fdir_info fdir_info; + struct qede_arfs_info arfs_info; bool vlan_strip_flg; char drv_ver[QEDE_PMD_DRV_VER_STR_SIZE]; bool vport_started; diff --git a/drivers/net/qede/qede_filter.c b/drivers/net/qede/qede_filter.c index 4b709e6..bdf2885 100644 --- a/drivers/net/qede/qede_filter.c +++ b/drivers/net/qede/qede_filter.c @@ -129,10 +129,6 @@ */ #define QEDE_MAX_FDIR_PKT_LEN (86) -#ifndef IPV6_ADDR_LEN -#define IPV6_ADDR_LEN (16) -#endif - static inline bool qede_valid_flow(uint16_t flow_type) { return ((flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_TCP) || @@ -141,6 +137,12 @@ static inline bool qede_valid_flow(uint16_t flow_type) (flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_UDP)); } +static uint16_t +qede_arfs_construct_pkt(struct rte_eth_dev *eth_dev, + struct qede_arfs_entry *arfs, + void *buff, + struct ecore_arfs_config_params *params); + /* Note: Flowdir support is only partial. * For ex: drop_queue, FDIR masks, flex_conf are not supported. * Parameters like pballoc/status fields are irrelevant here. @@ -154,17 +156,19 @@ int qede_check_fdir_support(struct rte_eth_dev *eth_dev) /* check FDIR modes */ switch (fdir->mode) { case RTE_FDIR_MODE_NONE: - qdev->fdir_info.arfs.arfs_enable = false; + qdev->arfs_info.arfs.mode = ECORE_FILTER_CONFIG_MODE_DISABLE; DP_INFO(edev, "flowdir is disabled\n"); break; case RTE_FDIR_MODE_PERFECT: if (ECORE_IS_CMT(edev)) { DP_ERR(edev, "flowdir is not supported in 100G mode\n"); - qdev->fdir_info.arfs.arfs_enable = false; + qdev->arfs_info.arfs.mode = + ECORE_FILTER_CONFIG_MODE_DISABLE; return -ENOTSUP; } - qdev->fdir_info.arfs.arfs_enable = true; - DP_INFO(edev, "flowdir is enabled\n"); + qdev->arfs_info.arfs.mode = + ECORE_FILTER_CONFIG_MODE_5_TUPLE; + DP_INFO(edev, "flowdir is enabled (5 Tuple mode)\n"); break; case RTE_FDIR_MODE_PERFECT_TUNNEL: case RTE_FDIR_MODE_SIGNATURE: @@ -179,29 +183,96 @@ int qede_check_fdir_support(struct rte_eth_dev *eth_dev) void qede_fdir_dealloc_resc(struct rte_eth_dev *eth_dev) { struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); - struct qede_fdir_entry *tmp = NULL; + struct qede_arfs_entry *tmp = NULL; - SLIST_FOREACH(tmp, &qdev->fdir_info.fdir_list_head, list) { + SLIST_FOREACH(tmp, &qdev->arfs_info.arfs_list_head, list) { if (tmp) { if (tmp->mz) rte_memzone_free(tmp->mz); - SLIST_REMOVE(&qdev->fdir_info.fdir_list_head, tmp, - qede_fdir_entry, list); + SLIST_REMOVE(&qdev->arfs_info.arfs_list_head, tmp, + qede_arfs_entry, list); rte_free(tmp); } } } static int -qede_config_cmn_fdir_filter(struct rte_eth_dev *eth_dev, - struct rte_eth_fdir_filter *fdir_filter, - bool add) +qede_fdir_to_arfs_filter(struct rte_eth_dev *eth_dev, + struct rte_eth_fdir_filter *fdir, + struct qede_arfs_entry *arfs) +{ + struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); + struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); + struct rte_eth_fdir_input *input; + + static const uint8_t next_proto[] = { + [RTE_ETH_FLOW_NONFRAG_IPV4_TCP] = IPPROTO_TCP, + [RTE_ETH_FLOW_NONFRAG_IPV4_UDP] = IPPROTO_UDP, + [RTE_ETH_FLOW_NONFRAG_IPV6_TCP] = IPPROTO_TCP, + [RTE_ETH_FLOW_NONFRAG_IPV6_UDP] = IPPROTO_UDP, + }; + + input = &fdir->input; + + DP_INFO(edev, "flow_type %d\n", input->flow_type); + + switch (input->flow_type) { + case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: + case RTE_ETH_FLOW_NONFRAG_IPV4_UDP: + /* fill the common ip header */ + arfs->tuple.eth_proto = ETHER_TYPE_IPv4; + arfs->tuple.dst_ipv4 = input->flow.ip4_flow.dst_ip; + arfs->tuple.src_ipv4 = input->flow.ip4_flow.src_ip; + arfs->tuple.ip_proto = next_proto[input->flow_type]; + + /* UDP */ + if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_UDP) { + arfs->tuple.dst_port = input->flow.udp4_flow.dst_port; + arfs->tuple.src_port = input->flow.udp4_flow.src_port; + } else { /* TCP */ + arfs->tuple.dst_port = input->flow.tcp4_flow.dst_port; + arfs->tuple.src_port = input->flow.tcp4_flow.src_port; + } + break; + case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: + case RTE_ETH_FLOW_NONFRAG_IPV6_UDP: + arfs->tuple.eth_proto = ETHER_TYPE_IPv6; + arfs->tuple.ip_proto = next_proto[input->flow_type]; + rte_memcpy(arfs->tuple.dst_ipv6, + &input->flow.ipv6_flow.dst_ip, + IPV6_ADDR_LEN); + rte_memcpy(arfs->tuple.src_ipv6, + &input->flow.ipv6_flow.src_ip, + IPV6_ADDR_LEN); + + /* UDP */ + if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_UDP) { + arfs->tuple.dst_port = input->flow.udp6_flow.dst_port; + arfs->tuple.src_port = input->flow.udp6_flow.src_port; + } else { /* TCP */ + arfs->tuple.dst_port = input->flow.tcp6_flow.dst_port; + arfs->tuple.src_port = input->flow.tcp6_flow.src_port; + } + break; + default: + DP_ERR(edev, "Unsupported flow_type %u\n", + input->flow_type); + return -ENOTSUP; + } + + arfs->rx_queue = fdir->action.rx_queue; + return 0; +} + +static int +qede_config_arfs_filter(struct rte_eth_dev *eth_dev, + struct qede_arfs_entry *arfs, + bool add) { struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); char mz_name[RTE_MEMZONE_NAMESIZE] = {0}; - struct qede_fdir_entry *tmp = NULL; - struct qede_fdir_entry *fdir = NULL; + struct qede_arfs_entry *tmp = NULL; const struct rte_memzone *mz; struct ecore_hwfn *p_hwfn; enum _ecore_status_t rc; @@ -209,17 +280,12 @@ void qede_fdir_dealloc_resc(struct rte_eth_dev *eth_dev) void *pkt; if (add) { - if (qdev->fdir_info.filter_count == QEDE_RFS_MAX_FLTR - 1) { + if (qdev->arfs_info.filter_count == QEDE_RFS_MAX_FLTR - 1) { DP_ERR(edev, "Reached max flowdir filter limit\n"); return -EINVAL; } - fdir = rte_malloc(NULL, sizeof(struct qede_fdir_entry), - RTE_CACHE_LINE_SIZE); - if (!fdir) { - DP_ERR(edev, "Did not allocate memory for fdir\n"); - return -ENOMEM; - } } + /* soft_id could have been used as memzone string, but soft_id is * not currently used so it has no significance. */ @@ -230,98 +296,124 @@ void qede_fdir_dealloc_resc(struct rte_eth_dev *eth_dev) if (!mz) { DP_ERR(edev, "Failed to allocate memzone for fdir, err = %s\n", rte_strerror(rte_errno)); - rc = -rte_errno; - goto err1; + return -rte_errno; } pkt = mz->addr; memset(pkt, 0, QEDE_MAX_FDIR_PKT_LEN); - pkt_len = qede_fdir_construct_pkt(eth_dev, fdir_filter, pkt, - &qdev->fdir_info.arfs); + pkt_len = qede_arfs_construct_pkt(eth_dev, arfs, pkt, + &qdev->arfs_info.arfs); if (pkt_len == 0) { rc = -EINVAL; - goto err2; + goto err1; } + DP_INFO(edev, "pkt_len = %u memzone = %s\n", pkt_len, mz_name); if (add) { - SLIST_FOREACH(tmp, &qdev->fdir_info.fdir_list_head, list) { + SLIST_FOREACH(tmp, &qdev->arfs_info.arfs_list_head, list) { if (memcmp(tmp->mz->addr, pkt, pkt_len) == 0) { DP_INFO(edev, "flowdir filter exist\n"); - rc = 0; - goto err2; + rc = -EEXIST; + goto err1; } } } else { - SLIST_FOREACH(tmp, &qdev->fdir_info.fdir_list_head, list) { + SLIST_FOREACH(tmp, &qdev->arfs_info.arfs_list_head, list) { if (memcmp(tmp->mz->addr, pkt, pkt_len) == 0) break; } if (!tmp) { DP_ERR(edev, "flowdir filter does not exist\n"); rc = -EEXIST; - goto err2; + goto err1; } } p_hwfn = ECORE_LEADING_HWFN(edev); if (add) { - if (!qdev->fdir_info.arfs.arfs_enable) { + if (qdev->arfs_info.arfs.mode == + ECORE_FILTER_CONFIG_MODE_DISABLE) { /* Force update */ eth_dev->data->dev_conf.fdir_conf.mode = RTE_FDIR_MODE_PERFECT; - qdev->fdir_info.arfs.arfs_enable = true; + qdev->arfs_info.arfs.mode = + ECORE_FILTER_CONFIG_MODE_5_TUPLE; DP_INFO(edev, "Force enable flowdir in perfect mode\n"); } /* Enable ARFS searcher with updated flow_types */ ecore_arfs_mode_configure(p_hwfn, p_hwfn->p_arfs_ptt, - &qdev->fdir_info.arfs); + &qdev->arfs_info.arfs); } /* configure filter with ECORE_SPQ_MODE_EBLOCK */ rc = ecore_configure_rfs_ntuple_filter(p_hwfn, NULL, (dma_addr_t)mz->iova, pkt_len, - fdir_filter->action.rx_queue, + arfs->rx_queue, 0, add); if (rc == ECORE_SUCCESS) { if (add) { - fdir->rx_queue = fdir_filter->action.rx_queue; - fdir->pkt_len = pkt_len; - fdir->mz = mz; - SLIST_INSERT_HEAD(&qdev->fdir_info.fdir_list_head, - fdir, list); - qdev->fdir_info.filter_count++; + arfs->pkt_len = pkt_len; + arfs->mz = mz; + SLIST_INSERT_HEAD(&qdev->arfs_info.arfs_list_head, + arfs, list); + qdev->arfs_info.filter_count++; DP_INFO(edev, "flowdir filter added, count = %d\n", - qdev->fdir_info.filter_count); + qdev->arfs_info.filter_count); } else { rte_memzone_free(tmp->mz); - SLIST_REMOVE(&qdev->fdir_info.fdir_list_head, tmp, - qede_fdir_entry, list); + SLIST_REMOVE(&qdev->arfs_info.arfs_list_head, tmp, + qede_arfs_entry, list); rte_free(tmp); /* the node deleted */ rte_memzone_free(mz); /* temp node allocated */ - qdev->fdir_info.filter_count--; + qdev->arfs_info.filter_count--; DP_INFO(edev, "Fdir filter deleted, count = %d\n", - qdev->fdir_info.filter_count); + qdev->arfs_info.filter_count); } } else { DP_ERR(edev, "flowdir filter failed, rc=%d filter_count=%d\n", - rc, qdev->fdir_info.filter_count); + rc, qdev->arfs_info.filter_count); } /* Disable ARFS searcher if there are no more filters */ - if (qdev->fdir_info.filter_count == 0) { - memset(&qdev->fdir_info.arfs, 0, + if (qdev->arfs_info.filter_count == 0) { + memset(&qdev->arfs_info.arfs, 0, sizeof(struct ecore_arfs_config_params)); DP_INFO(edev, "Disabling flowdir\n"); - qdev->fdir_info.arfs.arfs_enable = false; + qdev->arfs_info.arfs.mode = ECORE_FILTER_CONFIG_MODE_DISABLE; ecore_arfs_mode_configure(p_hwfn, p_hwfn->p_arfs_ptt, - &qdev->fdir_info.arfs); + &qdev->arfs_info.arfs); } return 0; -err2: - rte_memzone_free(mz); err1: - if (add) - rte_free(fdir); + rte_memzone_free(mz); + return rc; +} + +static int +qede_config_cmn_fdir_filter(struct rte_eth_dev *eth_dev, + struct rte_eth_fdir_filter *fdir_filter, + bool add) +{ + struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev); + struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); + struct qede_arfs_entry *arfs = NULL; + int rc = 0; + + arfs = rte_malloc(NULL, sizeof(struct qede_arfs_entry), + RTE_CACHE_LINE_SIZE); + if (!arfs) { + DP_ERR(edev, "Did not allocate memory for arfs\n"); + return -ENOMEM; + } + + rc = qede_fdir_to_arfs_filter(eth_dev, fdir_filter, arfs); + if (rc < 0) + return rc; + + rc = qede_config_arfs_filter(eth_dev, arfs, add); + if (rc < 0) + rte_free(arfs); + return rc; } @@ -353,9 +445,9 @@ void qede_fdir_dealloc_resc(struct rte_eth_dev *eth_dev) } /* Fills the L3/L4 headers and returns the actual length of flowdir packet */ -uint16_t -qede_fdir_construct_pkt(struct rte_eth_dev *eth_dev, - struct rte_eth_fdir_filter *fdir, +static uint16_t +qede_arfs_construct_pkt(struct rte_eth_dev *eth_dev, + struct qede_arfs_entry *arfs, void *buff, struct ecore_arfs_config_params *params) @@ -364,64 +456,39 @@ void qede_fdir_dealloc_resc(struct rte_eth_dev *eth_dev) struct ecore_dev *edev = QEDE_INIT_EDEV(qdev); uint16_t *ether_type; uint8_t *raw_pkt; - struct rte_eth_fdir_input *input; - static uint8_t vlan_frame[] = {0x81, 0, 0, 0}; struct ipv4_hdr *ip; struct ipv6_hdr *ip6; struct udp_hdr *udp; struct tcp_hdr *tcp; uint16_t len; - static const uint8_t next_proto[] = { - [RTE_ETH_FLOW_NONFRAG_IPV4_TCP] = IPPROTO_TCP, - [RTE_ETH_FLOW_NONFRAG_IPV4_UDP] = IPPROTO_UDP, - [RTE_ETH_FLOW_NONFRAG_IPV6_TCP] = IPPROTO_TCP, - [RTE_ETH_FLOW_NONFRAG_IPV6_UDP] = IPPROTO_UDP, - }; + raw_pkt = (uint8_t *)buff; - input = &fdir->input; - DP_INFO(edev, "flow_type %d\n", input->flow_type); len = 2 * sizeof(struct ether_addr); raw_pkt += 2 * sizeof(struct ether_addr); - if (input->flow_ext.vlan_tci) { - DP_INFO(edev, "adding VLAN header\n"); - rte_memcpy(raw_pkt, vlan_frame, sizeof(vlan_frame)); - rte_memcpy(raw_pkt + sizeof(uint16_t), - &input->flow_ext.vlan_tci, - sizeof(uint16_t)); - raw_pkt += sizeof(vlan_frame); - len += sizeof(vlan_frame); - } ether_type = (uint16_t *)raw_pkt; raw_pkt += sizeof(uint16_t); len += sizeof(uint16_t); - switch (input->flow_type) { - case RTE_ETH_FLOW_NONFRAG_IPV4_TCP: - case RTE_ETH_FLOW_NONFRAG_IPV4_UDP: - /* fill the common ip header */ + *ether_type = rte_cpu_to_be_16(arfs->tuple.eth_proto); + switch (arfs->tuple.eth_proto) { + case ETHER_TYPE_IPv4: ip = (struct ipv4_hdr *)raw_pkt; - *ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4); ip->version_ihl = QEDE_FDIR_IP_DEFAULT_VERSION_IHL; ip->total_length = sizeof(struct ipv4_hdr); - ip->next_proto_id = input->flow.ip4_flow.proto ? - input->flow.ip4_flow.proto : - next_proto[input->flow_type]; - ip->time_to_live = input->flow.ip4_flow.ttl ? - input->flow.ip4_flow.ttl : - QEDE_FDIR_IPV4_DEF_TTL; - ip->type_of_service = input->flow.ip4_flow.tos; - ip->dst_addr = input->flow.ip4_flow.dst_ip; - ip->src_addr = input->flow.ip4_flow.src_ip; + ip->next_proto_id = arfs->tuple.ip_proto; + ip->time_to_live = QEDE_FDIR_IPV4_DEF_TTL; + ip->dst_addr = arfs->tuple.dst_ipv4; + ip->src_addr = arfs->tuple.src_ipv4; len += sizeof(struct ipv4_hdr); params->ipv4 = true; raw_pkt = (uint8_t *)buff; /* UDP */ - if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV4_UDP) { + if (arfs->tuple.ip_proto == IPPROTO_UDP) { udp = (struct udp_hdr *)(raw_pkt + len); - udp->dst_port = input->flow.udp4_flow.dst_port; - udp->src_port = input->flow.udp4_flow.src_port; + udp->dst_port = arfs->tuple.dst_port; + udp->src_port = arfs->tuple.src_port; udp->dgram_len = sizeof(struct udp_hdr); len += sizeof(struct udp_hdr); /* adjust ip total_length */ @@ -429,8 +496,8 @@ void qede_fdir_dealloc_resc(struct rte_eth_dev *eth_dev) params->udp = true; } else { /* TCP */ tcp = (struct tcp_hdr *)(raw_pkt + len); - tcp->src_port = input->flow.tcp4_flow.src_port; - tcp->dst_port = input->flow.tcp4_flow.dst_port; + tcp->src_port = arfs->tuple.src_port; + tcp->dst_port = arfs->tuple.dst_port; tcp->data_off = QEDE_FDIR_TCP_DEFAULT_DATAOFF; len += sizeof(struct tcp_hdr); /* adjust ip total_length */ @@ -438,43 +505,39 @@ void qede_fdir_dealloc_resc(struct rte_eth_dev *eth_dev) params->tcp = true; } break; - case RTE_ETH_FLOW_NONFRAG_IPV6_TCP: - case RTE_ETH_FLOW_NONFRAG_IPV6_UDP: + case ETHER_TYPE_IPv6: ip6 = (struct ipv6_hdr *)raw_pkt; - *ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6); - ip6->proto = input->flow.ipv6_flow.proto ? - input->flow.ipv6_flow.proto : - next_proto[input->flow_type]; + ip6->proto = arfs->tuple.ip_proto; ip6->vtc_flow = rte_cpu_to_be_32(QEDE_FDIR_IPV6_DEFAULT_VTC_FLOW); - rte_memcpy(&ip6->src_addr, &input->flow.ipv6_flow.src_ip, + rte_memcpy(&ip6->src_addr, arfs->tuple.src_ipv6, IPV6_ADDR_LEN); - rte_memcpy(&ip6->dst_addr, &input->flow.ipv6_flow.dst_ip, + rte_memcpy(&ip6->dst_addr, arfs->tuple.dst_ipv6, IPV6_ADDR_LEN); len += sizeof(struct ipv6_hdr); params->ipv6 = true; raw_pkt = (uint8_t *)buff; /* UDP */ - if (input->flow_type == RTE_ETH_FLOW_NONFRAG_IPV6_UDP) { + if (arfs->tuple.ip_proto == IPPROTO_UDP) { udp = (struct udp_hdr *)(raw_pkt + len); - udp->src_port = input->flow.udp6_flow.src_port; - udp->dst_port = input->flow.udp6_flow.dst_port; + udp->src_port = arfs->tuple.src_port; + udp->dst_port = arfs->tuple.dst_port; len += sizeof(struct udp_hdr); params->udp = true; } else { /* TCP */ tcp = (struct tcp_hdr *)(raw_pkt + len); - tcp->src_port = input->flow.tcp6_flow.src_port; - tcp->dst_port = input->flow.tcp6_flow.dst_port; + tcp->src_port = arfs->tuple.src_port; + tcp->dst_port = arfs->tuple.dst_port; tcp->data_off = QEDE_FDIR_TCP_DEFAULT_DATAOFF; len += sizeof(struct tcp_hdr); params->tcp = true; } break; default: - DP_ERR(edev, "Unsupported flow_type %u\n", - input->flow_type); + DP_ERR(edev, "Unsupported eth_proto %u\n", + arfs->tuple.eth_proto); return 0; }