From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3593D45BCC; Wed, 30 Oct 2024 22:44:10 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C9646434EE; Wed, 30 Oct 2024 22:41:37 +0100 (CET) Received: from egress-ip42b.ess.de.barracuda.com (egress-ip42b.ess.de.barracuda.com [18.185.115.246]) by mails.dpdk.org (Postfix) with ESMTP id 41DCE4349E for ; Wed, 30 Oct 2024 22:40:33 +0100 (CET) Received: from EUR03-VI1-obe.outbound.protection.outlook.com (mail-vi1eur03lp2113.outbound.protection.outlook.com [104.47.30.113]) by mx-outbound17-81.eu-central-1b.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 30 Oct 2024 21:40:28 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=guKn5DIu8xxyTM6MbHOTGIZHEnRjF8FRGjuX0XPVERPXVvtuuoT+/H7tJz7+L+S86zuL0snQw0c1IT83RBr4nAJDVXjiDOrWEgJQIRVn8/LasEzN+kd2xLPiCCciGoTEgh8tZ9a3xxUktzsvupHcTrB53iQ/47/ldSaCaZr8vQSyuJtnOBRL5eGZJKahpwlrJyXH+93ldI6/29JcvkedJhECXSSuFHb36YNb01Ylu/W8+VIwha11/U/3grp+tCmAPJ8bjR6RGdgqMRe33Ol7O/Oo06/ACGR+ODXofDfUv58KSCRy+/Kk3xrd25mc3RW+OMOWrPBY50U+0C+4caDS8g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=++uiEy/2R7XwNMwd96sJ6unj7np6H+3zBOe4s0xgRrs=; b=VYymwli5DuC9GoaBCH8JuIaotIhfKkTNyZVwKdsps0xnHqMdbPvU9HY4r1PywJwcyDm+zOmAQA75IshWP0EJojagi35KD6k94cVfJkgmxCJnc8P1FIKboFxw+AprV9NzWw7htzMs6DIBUuXQ2i+vtEAli+LfnNH0DGsEjr56Egcf5QIZ1VSrm/UJLXt7klolWuiYg3fQLzaIEysiANnZ2wa5DJ9cq/x45Z8/U3gkn3jBeRDm+czsxn44Wj8TafKEhKbMizDEi0pALEVdH+XMDPbefGq1SUkF7DBOLwdaVowWoKZUTfoSelh86dzWg33901A4HNOcYUdB821RYwi6eQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=fail (sender ip is 178.72.21.4) smtp.rcpttodomain=dpdk.org smtp.mailfrom=napatech.com; dmarc=fail (p=reject sp=reject pct=100) action=oreject header.from=napatech.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=napatech.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=++uiEy/2R7XwNMwd96sJ6unj7np6H+3zBOe4s0xgRrs=; b=SJ23+1W3aYYLc5+SkZ9n3sjofG3NmqaTzYsieQXJuv2LLHENmbzzNTK8uYPlqA9amWIh/zm1B/LYOekfdtnTAm9n6gDYXYJGTpx73mNyz+81ZetWkQG0bpK+8yyH5YjdBBxeuZSOi6G3X60YqUw1NPTC3O0EsB+geXolvHwGFUs= Received: from DUZPR01CA0010.eurprd01.prod.exchangelabs.com (2603:10a6:10:3c3::12) by DB8P190MB0681.EURP190.PROD.OUTLOOK.COM (2603:10a6:10:126::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8093.32; Wed, 30 Oct 2024 21:40:26 +0000 Received: from DU2PEPF00028D13.eurprd03.prod.outlook.com (2603:10a6:10:3c3:cafe::69) by DUZPR01CA0010.outlook.office365.com (2603:10a6:10:3c3::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8114.20 via Frontend Transport; Wed, 30 Oct 2024 21:40:26 +0000 X-MS-Exchange-Authentication-Results: spf=fail (sender IP is 178.72.21.4) smtp.mailfrom=napatech.com; dkim=none (message not signed) header.d=none;dmarc=fail action=oreject header.from=napatech.com; Received-SPF: Fail (protection.outlook.com: domain of napatech.com does not designate 178.72.21.4 as permitted sender) receiver=protection.outlook.com; client-ip=178.72.21.4; helo=localhost.localdomain; Received: from localhost.localdomain (178.72.21.4) by DU2PEPF00028D13.mail.protection.outlook.com (10.167.242.27) with Microsoft SMTP Server id 15.20.8114.16 via Frontend Transport; Wed, 30 Oct 2024 21:40:26 +0000 From: Serhii Iliushyk To: dev@dpdk.org Cc: mko-plv@napatech.com, sil-plv@napatech.com, ckm@napatech.com, andrew.rybchenko@oktetlabs.ru, ferruh.yigit@amd.com, stephen@networkplumber.org, Danylo Vodopianov Subject: [PATCH v5 36/80] net/ntnic: match and action db attributes were added Date: Wed, 30 Oct 2024 22:38:43 +0100 Message-ID: <20241030213940.3470062-37-sil-plv@napatech.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241030213940.3470062-1-sil-plv@napatech.com> References: <20241021210527.2075431-1-sil-plv@napatech.com> <20241030213940.3470062-1-sil-plv@napatech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU2PEPF00028D13:EE_|DB8P190MB0681:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 0a956e1e-e5f1-4a83-d4b8-08dcf92b7796 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|82310400026|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?T+fH5EaVtLfRjaZ2NmfGYS/OwvOhzu+I6WE/D/2nyRoSyNtPDV0UbCAbeOcg?= =?us-ascii?Q?ftDCgbnN7HVSVQlyZ3FAYfeWDL36qMLZNJAKuMBI8P3aSvxcxNTBK19iUzma?= =?us-ascii?Q?1t3pAKe/CtWRA5I4vnsi1F4dLOFKmkgB37auxcW1OQZIK6uEH+qwFmzbFNco?= =?us-ascii?Q?MjgEZxzqMMotLzbj2/zjMxjsI+bLdecGuHVFVxw6WScUX0WK+DQw2J+6KjFQ?= =?us-ascii?Q?HJNTl0dfEDikJ3Cffr+aC6Ap+xF5Vxx4KZUU4PXoxnrqZRLgb3ZwO38igyI+?= =?us-ascii?Q?oljGHtpltXlguXdRZvRdRbHzjRSSlziuHP4lvXOO7Qqu7lYYnERzKNwUsdyF?= =?us-ascii?Q?MSVhdwgjxFhhbUE0LEHWyyP3m8vCazC5yDF0k3gcxQTUZ8iNMfRfEEVkcrU7?= =?us-ascii?Q?Fxx19KRNmQ4qaMW2rZPeYXKkZBrCASesPt3zEW1BUKSF8QRGpKTIPHvG2ckp?= =?us-ascii?Q?0oAEqZCEVz0eI7qTIdgysx+0mDkjps5zouLPnH32MALVBQYCXDuieWIxmobg?= =?us-ascii?Q?GePCI0EkZMVdEcGmND08PCRoMy4dhHSIdqzDMICv6iVmqMNRxPNxZ5bGboV5?= =?us-ascii?Q?KoKPTYeyVlgfTfsVc8fMJ4U2QdGs6a1CeAi24MtFHpZ0wpLzXbQjx3n+tRMK?= =?us-ascii?Q?0CfX5/T+zJZfDwl3E1ysr7WoAQuSPYauj0psu2nHtYpX5gYOEeoVzvAcUND1?= =?us-ascii?Q?olzYe6HPdMyynAqIC+wZuL5hOa0tg0NpITh1uqtvQ/9KSX29N7ha3E1PpcCp?= =?us-ascii?Q?PoGtUwTclArujoomjMfh+Liu5c6Tir/VH4ZXJxwg/Phk7XFj40ySzZG5Qzv+?= =?us-ascii?Q?Qsvoou6j0t1V+NnaONstB5icYcDfYxyfhkeLaTi6ljvDwDlI6+bo0Tp1nlQk?= =?us-ascii?Q?jXpDPdJaopt7djswIfxVTYAaT1SHbmwGGfVXqIhmYxU+xKk8KKz4rgNQAU+r?= =?us-ascii?Q?79zub0MVGko6fu2fXD17BH+Gn2azrMXfcy1GG/cLn+DO6uAqatW2OQ1MyKD7?= =?us-ascii?Q?JSyzJrk6iO/aLQ+JDW4ERyC0ALjUdMWUUFUVWjxylwJreZuLd8JQ+3NbU6Fz?= =?us-ascii?Q?gSDDdzXcb09nxSM4zI/KgyZYxUBY6YG7tOM1am+gEa1nS7hD1GjU8vSlmJaU?= =?us-ascii?Q?bMThvqWsFmHZYd3lX7dKHqG5/TMIk5WN6XGI+ufJWgSXplSKdUkQFhXVdfqN?= =?us-ascii?Q?2ZLCMYQwSO3gFWB+KjfY8/8kKpqGSg2Hq6cC7mjkNUpPQH25c3XMWqfPx6FT?= =?us-ascii?Q?p/rSyR/ppjuWi4TXb8H0iAd8TY/E4eHQAI+OBOfco4TqSuDKLKEr+mAAkC01?= =?us-ascii?Q?0Q1Qm9y0xuSHxHMeJhR+ZuOEBeAMSSbtgKEDXbQDqCZXvkg5LclC5mhCAath?= =?us-ascii?Q?tIbWs0lHCbt+/fSyWPoK8NwsM5IWzpsX327VNcRLuzJ5gd0h3g=3D=3D?= X-Forefront-Antispam-Report: CIP:178.72.21.4; CTRY:DK; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:localhost.localdomain; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230040)(1800799024)(376014)(82310400026)(36860700013); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: tEjI6+jp8x0PME8f6OkvQAosr+jga6m2HHvIDdeLUx0e5YlhhbX/n6IdRauSjc4cXLRwylXvHmOfVs+4u41nO2pZsAgbh62/xqm+cEXfv6v/BwKPVyUdLWbmogqjjmb+lFoOSxrs7AHXfUCCI4r2bV+xEunNYnDWHUNHcoYTEOf1X0TWnAKJTEN/o1KYVEplmdNmf/N2Rml8N0pweKGws2fXRa3/KXMZkf8vsFfdviCa4uRaokXPhxYOSA6sKYhktvTe+i3Ogm459HLyRUadcYqh6KY7/amJF4D/xGKIr/fe2mO/bRsd1PCCINumI8EN9AbNlEDJHa36V2R/rjy25DRZcYxt/j5P/fEQqSd3XZ9XpQQQuquX3q8M60DOZig3UUh8VjHMxQa+rEZclp7JguIoHLUB3ARlI9n7mNsj1uhWAWKdXClU4a/NyFXSEHKvPTeeWdTvMSmjcL/zGDqGDgl2Xl4ejv6Ta7rhBZXq5gpTeNBjBZH1eBggM8joJ1JjDKKsPn/xwCYLaKhPMOhrhxqxaGYuV5VJ5hvFN+Vn0NRfLrH73+vqUHEzXq/U78lucrtnjg3tAMkmv/ncQrkK/a8Xtw8TGdjOWts9Ml3A+XKrQmSoegYrlfJR/qTaar7l/DC63kUW/sFP3k3fUGAQantESxR1z3dCUj0mBGbd40Y= X-OriginatorOrg: napatech.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Oct 2024 21:40:26.1926 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 0a956e1e-e5f1-4a83-d4b8-08dcf92b7796 X-MS-Exchange-CrossTenant-Id: c4540d0b-728a-4233-9da5-9ea30c7ec3ed X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=c4540d0b-728a-4233-9da5-9ea30c7ec3ed; Ip=[178.72.21.4]; Helo=[localhost.localdomain] X-MS-Exchange-CrossTenant-AuthSource: DU2PEPF00028D13.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB8P190MB0681 X-BESS-ID: 1730324428-304433-12636-44628-1 X-BESS-VER: 2019.1_20241018.1852 X-BESS-Apparent-Source-IP: 104.47.30.113 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVsamBpYGQGYGUNQoxcQk0Tw1yT zFOMXMwCLZwMIwLTnRwNA4NS0pyTDRQqk2FgDPlZ86QgAAAA== X-BESS-Outbound-Spam-Score: 0.00 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.260091 [from cloudscan16-249.eu-central-1b.ess.aws.cudaops.com] Rule breakdown below pts rule name description ---- ---------------------- -------------------------------- 0.00 BSF_BESS_OUTBOUND META: BESS Outbound X-BESS-Outbound-Spam-Status: SCORE=0.00 using account:ESS113687 scores of KILL_LEVEL=7.0 tests=BSF_BESS_OUTBOUND X-BESS-BRTS-Status: 1 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Danylo Vodopianov Implements match/action dereferencing Signed-off-by: Danylo Vodopianov --- .../profile_inline/flow_api_hw_db_inline.c | 795 ++++++++++++++++++ .../profile_inline/flow_api_hw_db_inline.h | 35 + .../profile_inline/flow_api_profile_inline.c | 55 ++ 3 files changed, 885 insertions(+) diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c index 0ae058b91e..52f85b65af 100644 --- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.c @@ -9,6 +9,9 @@ #include "flow_api_hw_db_inline.h" #include "rte_common.h" +#define HW_DB_INLINE_ACTION_SET_NB 512 +#define HW_DB_INLINE_MATCH_SET_NB 512 + #define HW_DB_FT_LOOKUP_KEY_A 0 #define HW_DB_FT_TYPE_KM 1 @@ -110,6 +113,20 @@ struct hw_db_inline_resource_db { int cfn_hw; int ref; } *cfn; + + uint32_t cfn_priority_counter; + uint32_t set_priority_counter; + + struct hw_db_inline_resource_db_action_set { + struct hw_db_inline_action_set_data data; + int ref; + } action_set[HW_DB_INLINE_ACTION_SET_NB]; + + struct hw_db_inline_resource_db_match_set { + struct hw_db_inline_match_set_data data; + int ref; + uint32_t set_priority; + } match_set[HW_DB_INLINE_MATCH_SET_NB]; }; int hw_db_inline_create(struct flow_nic_dev *ndev, void **db_handle) @@ -292,6 +309,16 @@ void hw_db_inline_deref_idxs(struct flow_nic_dev *ndev, void *db_handle, struct case HW_DB_IDX_TYPE_NONE: break; + case HW_DB_IDX_TYPE_MATCH_SET: + hw_db_inline_match_set_deref(ndev, db_handle, + *(struct hw_db_match_set_idx *)&idxs[i]); + break; + + case HW_DB_IDX_TYPE_ACTION_SET: + hw_db_inline_action_set_deref(ndev, db_handle, + *(struct hw_db_action_set_idx *)&idxs[i]); + break; + case HW_DB_IDX_TYPE_CAT: hw_db_inline_cat_deref(ndev, db_handle, *(struct hw_db_cat_idx *)&idxs[i]); break; @@ -360,6 +387,12 @@ const void *hw_db_inline_find_data(struct flow_nic_dev *ndev, void *db_handle, case HW_DB_IDX_TYPE_NONE: return NULL; + case HW_DB_IDX_TYPE_MATCH_SET: + return &db->match_set[idxs[i].ids].data; + + case HW_DB_IDX_TYPE_ACTION_SET: + return &db->action_set[idxs[i].ids].data; + case HW_DB_IDX_TYPE_CAT: return &db->cat[idxs[i].ids].data; @@ -552,6 +585,763 @@ static void hw_db_inline_setup_default_flm_rcp(struct flow_nic_dev *ndev, int fl } +static void hw_db_copy_ft(struct flow_nic_dev *ndev, int type, int cfn_dst, int cfn_src, + int lookup, int flow_type) +{ + const int max_lookups = 4; + const int cat_funcs = (int)ndev->be.cat.nb_cat_funcs / 8; + + int fte_index_dst = (8 * flow_type + cfn_dst / cat_funcs) * max_lookups + lookup; + int fte_field_dst = cfn_dst % cat_funcs; + + int fte_index_src = (8 * flow_type + cfn_src / cat_funcs) * max_lookups + lookup; + int fte_field_src = cfn_src % cat_funcs; + + uint32_t current_bm_dst = 0; + uint32_t current_bm_src = 0; + uint32_t fte_field_bm_dst = 1 << fte_field_dst; + uint32_t fte_field_bm_src = 1 << fte_field_src; + + switch (type) { + case HW_DB_FT_TYPE_FLM: + hw_mod_cat_fte_flm_get(&ndev->be, HW_CAT_FTE_ENABLE_BM, KM_FLM_IF_FIRST, + fte_index_dst, ¤t_bm_dst); + hw_mod_cat_fte_flm_get(&ndev->be, HW_CAT_FTE_ENABLE_BM, KM_FLM_IF_FIRST, + fte_index_src, ¤t_bm_src); + break; + + case HW_DB_FT_TYPE_KM: + hw_mod_cat_fte_km_get(&ndev->be, HW_CAT_FTE_ENABLE_BM, KM_FLM_IF_FIRST, + fte_index_dst, ¤t_bm_dst); + hw_mod_cat_fte_km_get(&ndev->be, HW_CAT_FTE_ENABLE_BM, KM_FLM_IF_FIRST, + fte_index_src, ¤t_bm_src); + break; + + default: + break; + } + + uint32_t enable = current_bm_src & fte_field_bm_src; + uint32_t final_bm_dst = enable ? (fte_field_bm_dst | current_bm_dst) + : (~fte_field_bm_dst & current_bm_dst); + + if (current_bm_dst != final_bm_dst) { + switch (type) { + case HW_DB_FT_TYPE_FLM: + hw_mod_cat_fte_flm_set(&ndev->be, HW_CAT_FTE_ENABLE_BM, KM_FLM_IF_FIRST, + fte_index_dst, final_bm_dst); + hw_mod_cat_fte_flm_flush(&ndev->be, KM_FLM_IF_FIRST, fte_index_dst, 1); + break; + + case HW_DB_FT_TYPE_KM: + hw_mod_cat_fte_km_set(&ndev->be, HW_CAT_FTE_ENABLE_BM, KM_FLM_IF_FIRST, + fte_index_dst, final_bm_dst); + hw_mod_cat_fte_km_flush(&ndev->be, KM_FLM_IF_FIRST, fte_index_dst, 1); + break; + + default: + break; + } + } +} + + +static int hw_db_inline_filter_apply(struct flow_nic_dev *ndev, + struct hw_db_inline_resource_db *db, + int cat_hw_id, + struct hw_db_match_set_idx match_set_idx, + struct hw_db_flm_ft flm_ft_idx, + struct hw_db_action_set_idx action_set_idx) +{ + (void)match_set_idx; + (void)flm_ft_idx; + + const struct hw_db_inline_match_set_data *match_set = + &db->match_set[match_set_idx.ids].data; + const struct hw_db_inline_cat_data *cat = &db->cat[match_set->cat.ids].data; + + const int km_ft = match_set->km_ft.id1; + const int km_rcp = (int)db->km[match_set->km.id1].data.rcp; + + const int flm_ft = flm_ft_idx.id1; + const int flm_rcp = flm_ft_idx.id2; + + const struct hw_db_inline_action_set_data *action_set = + &db->action_set[action_set_idx.ids].data; + const struct hw_db_inline_cot_data *cot = &db->cot[action_set->cot.ids].data; + + const int qsl_hw_id = action_set->qsl.ids; + const int slc_lr_hw_id = action_set->slc_lr.ids; + const int tpe_hw_id = action_set->tpe.ids; + const int hsh_hw_id = action_set->hsh.ids; + + /* Setup default FLM RCP if needed */ + if (flm_rcp > 0 && db->flm[flm_rcp].ref <= 0) + hw_db_inline_setup_default_flm_rcp(ndev, flm_rcp); + + /* Setup CAT.CFN */ + { + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_SET_ALL_DEFAULTS, cat_hw_id, 0, 0x0); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ENABLE, cat_hw_id, 0, 0x0); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_INV, cat_hw_id, 0, 0x0); + + /* Protocol checks */ + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_INV, cat_hw_id, 0, 0x0); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_ISL, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_CFP, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_MAC, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_L2, cat_hw_id, 0, cat->ptc_mask_l2); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_VNTAG, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_VLAN, cat_hw_id, 0, cat->vlan_mask); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_MPLS, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_L3, cat_hw_id, 0, cat->ptc_mask_l3); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_FRAG, cat_hw_id, 0, + cat->ptc_mask_frag); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_IP_PROT, cat_hw_id, 0, cat->ip_prot); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_L4, cat_hw_id, 0, cat->ptc_mask_l4); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_TUNNEL, cat_hw_id, 0, + cat->ptc_mask_tunnel); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_TNL_L2, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_TNL_VLAN, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_TNL_MPLS, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_TNL_L3, cat_hw_id, 0, + cat->ptc_mask_l3_tunnel); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_TNL_FRAG, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_TNL_IP_PROT, cat_hw_id, 0, + cat->ip_prot_tunnel); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PTC_TNL_L4, cat_hw_id, 0, + cat->ptc_mask_l4_tunnel); + + /* Error checks */ + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ERR_INV, cat_hw_id, 0, 0x0); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ERR_CV, cat_hw_id, 0, 0x1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ERR_FCS, cat_hw_id, 0, 0x1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ERR_TRUNC, cat_hw_id, 0, 0x1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ERR_L3_CS, cat_hw_id, 0, 0x1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ERR_L4_CS, cat_hw_id, 0, 0x1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ERR_TNL_L3_CS, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ERR_TNL_L4_CS, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ERR_TTL_EXP, cat_hw_id, 0, + cat->err_mask_ttl); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ERR_TNL_TTL_EXP, cat_hw_id, 0, + cat->err_mask_ttl_tunnel); + + /* MAC port check */ + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_MAC_PORT, cat_hw_id, 0, + cat->mac_port_mask); + + /* Pattern match checks */ + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PM_CMP, cat_hw_id, 0, 0x0); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PM_DCT, cat_hw_id, 0, 0x0); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PM_EXT_INV, cat_hw_id, 0, 0x0); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PM_CMB, cat_hw_id, 0, 0x0); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PM_AND_INV, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PM_OR_INV, cat_hw_id, 0, -1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_PM_INV, cat_hw_id, 0, -1); + + /* Length checks */ + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_LC, cat_hw_id, 0, 0x0); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_LC_INV, cat_hw_id, 0, -1); + + /* KM and FLM */ + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_KM0_OR, cat_hw_id, 0, 0x1); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_KM1_OR, cat_hw_id, 0, 0x3); + + hw_mod_cat_cfn_flush(&ndev->be, cat_hw_id, 1); + } + + /* Setup CAT.CTS */ + { + const int offset = ((int)ndev->be.cat.cts_num + 1) / 2; + + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_A, offset * cat_hw_id + 0, cat_hw_id); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_B, offset * cat_hw_id + 0, 0); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_A, offset * cat_hw_id + 1, hsh_hw_id); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_B, offset * cat_hw_id + 1, qsl_hw_id); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_A, offset * cat_hw_id + 2, 0); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_B, offset * cat_hw_id + 2, + slc_lr_hw_id); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_A, offset * cat_hw_id + 3, 0); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_B, offset * cat_hw_id + 3, 0); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_A, offset * cat_hw_id + 4, 0); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_B, offset * cat_hw_id + 4, 0); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_A, offset * cat_hw_id + 5, tpe_hw_id); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_B, offset * cat_hw_id + 5, 0); + + hw_mod_cat_cts_flush(&ndev->be, offset * cat_hw_id, 6); + } + + /* Setup CAT.CTE */ + { + hw_mod_cat_cte_set(&ndev->be, HW_CAT_CTE_ENABLE_BM, cat_hw_id, + 0x001 | 0x004 | (qsl_hw_id ? 0x008 : 0) | + (slc_lr_hw_id ? 0x020 : 0) | 0x040 | + (tpe_hw_id ? 0x400 : 0)); + hw_mod_cat_cte_flush(&ndev->be, cat_hw_id, 1); + } + + /* Setup CAT.KM */ + { + uint32_t bm = 0; + + hw_mod_cat_kcs_km_set(&ndev->be, HW_CAT_KCS_CATEGORY, KM_FLM_IF_FIRST, cat_hw_id, + km_rcp); + hw_mod_cat_kcs_km_flush(&ndev->be, KM_FLM_IF_FIRST, cat_hw_id, 1); + + hw_mod_cat_kce_km_get(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cat_hw_id / 8, &bm); + hw_mod_cat_kce_km_set(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cat_hw_id / 8, bm | (1 << (cat_hw_id % 8))); + hw_mod_cat_kce_km_flush(&ndev->be, KM_FLM_IF_FIRST, cat_hw_id / 8, 1); + + hw_db_set_ft(ndev, HW_DB_FT_TYPE_KM, cat_hw_id, HW_DB_FT_LOOKUP_KEY_A, km_ft, 1); + } + + /* Setup CAT.FLM */ + { + uint32_t bm = 0; + + hw_mod_cat_kcs_flm_set(&ndev->be, HW_CAT_KCS_CATEGORY, KM_FLM_IF_FIRST, cat_hw_id, + flm_rcp); + hw_mod_cat_kcs_flm_flush(&ndev->be, KM_FLM_IF_FIRST, cat_hw_id, 1); + + hw_mod_cat_kce_flm_get(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cat_hw_id / 8, &bm); + hw_mod_cat_kce_flm_set(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cat_hw_id / 8, bm | (1 << (cat_hw_id % 8))); + hw_mod_cat_kce_flm_flush(&ndev->be, KM_FLM_IF_FIRST, cat_hw_id / 8, 1); + + hw_db_set_ft(ndev, HW_DB_FT_TYPE_FLM, cat_hw_id, HW_DB_FT_LOOKUP_KEY_A, km_ft, 1); + hw_db_set_ft(ndev, HW_DB_FT_TYPE_FLM, cat_hw_id, HW_DB_FT_LOOKUP_KEY_C, flm_ft, 1); + } + + /* Setup CAT.COT */ + { + hw_mod_cat_cot_set(&ndev->be, HW_CAT_COT_PRESET_ALL, cat_hw_id, 0); + hw_mod_cat_cot_set(&ndev->be, HW_CAT_COT_COLOR, cat_hw_id, cot->frag_rcp << 10); + hw_mod_cat_cot_set(&ndev->be, HW_CAT_COT_KM, cat_hw_id, + cot->matcher_color_contrib); + hw_mod_cat_cot_flush(&ndev->be, cat_hw_id, 1); + } + + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ENABLE, cat_hw_id, 0, 0x1); + hw_mod_cat_cfn_flush(&ndev->be, cat_hw_id, 1); + + return 0; +} + +static void hw_db_inline_filter_clear(struct flow_nic_dev *ndev, + struct hw_db_inline_resource_db *db, + int cat_hw_id) +{ + /* Setup CAT.CFN */ + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_SET_ALL_DEFAULTS, cat_hw_id, 0, 0x0); + hw_mod_cat_cfn_flush(&ndev->be, cat_hw_id, 1); + + /* Setup CAT.CTS */ + { + const int offset = ((int)ndev->be.cat.cts_num + 1) / 2; + + for (int i = 0; i < 6; ++i) { + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_A, offset * cat_hw_id + i, 0); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_B, offset * cat_hw_id + i, 0); + } + + hw_mod_cat_cts_flush(&ndev->be, offset * cat_hw_id, 6); + } + + /* Setup CAT.CTE */ + { + hw_mod_cat_cte_set(&ndev->be, HW_CAT_CTE_ENABLE_BM, cat_hw_id, 0); + hw_mod_cat_cte_flush(&ndev->be, cat_hw_id, 1); + } + + /* Setup CAT.KM */ + { + uint32_t bm = 0; + + hw_mod_cat_kcs_km_set(&ndev->be, HW_CAT_KCS_CATEGORY, KM_FLM_IF_FIRST, cat_hw_id, + 0); + hw_mod_cat_kcs_km_flush(&ndev->be, KM_FLM_IF_FIRST, cat_hw_id, 1); + + hw_mod_cat_kce_km_get(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cat_hw_id / 8, &bm); + hw_mod_cat_kce_km_set(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cat_hw_id / 8, bm & ~(1 << (cat_hw_id % 8))); + hw_mod_cat_kce_km_flush(&ndev->be, KM_FLM_IF_FIRST, cat_hw_id / 8, 1); + + for (int ft = 0; ft < (int)db->nb_km_ft; ++ft) { + hw_db_set_ft(ndev, HW_DB_FT_TYPE_KM, cat_hw_id, HW_DB_FT_LOOKUP_KEY_A, ft, + 0); + } + } + + /* Setup CAT.FLM */ + { + uint32_t bm = 0; + + hw_mod_cat_kcs_flm_set(&ndev->be, HW_CAT_KCS_CATEGORY, KM_FLM_IF_FIRST, cat_hw_id, + 0); + hw_mod_cat_kcs_flm_flush(&ndev->be, KM_FLM_IF_FIRST, cat_hw_id, 1); + + hw_mod_cat_kce_flm_get(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cat_hw_id / 8, &bm); + hw_mod_cat_kce_flm_set(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cat_hw_id / 8, bm & ~(1 << (cat_hw_id % 8))); + hw_mod_cat_kce_flm_flush(&ndev->be, KM_FLM_IF_FIRST, cat_hw_id / 8, 1); + + for (int ft = 0; ft < (int)db->nb_flm_ft; ++ft) { + hw_db_set_ft(ndev, HW_DB_FT_TYPE_FLM, cat_hw_id, HW_DB_FT_LOOKUP_KEY_A, ft, + 0); + hw_db_set_ft(ndev, HW_DB_FT_TYPE_FLM, cat_hw_id, HW_DB_FT_LOOKUP_KEY_C, ft, + 0); + } + } + + hw_mod_cat_cot_set(&ndev->be, HW_CAT_COT_PRESET_ALL, cat_hw_id, 0); + hw_mod_cat_cot_flush(&ndev->be, cat_hw_id, 1); +} + +static void hw_db_inline_filter_copy(struct flow_nic_dev *ndev, + struct hw_db_inline_resource_db *db, int cfn_dst, int cfn_src) +{ + uint32_t val = 0; + + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_COPY_FROM, cfn_dst, 0, cfn_src); + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ENABLE, cfn_dst, 0, 0x0); + hw_mod_cat_cfn_flush(&ndev->be, cfn_dst, 1); + + /* Setup CAT.CTS */ + { + const int offset = ((int)ndev->be.cat.cts_num + 1) / 2; + + for (int i = 0; i < offset; ++i) { + hw_mod_cat_cts_get(&ndev->be, HW_CAT_CTS_CAT_A, offset * cfn_src + i, + &val); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_A, offset * cfn_dst + i, val); + hw_mod_cat_cts_get(&ndev->be, HW_CAT_CTS_CAT_B, offset * cfn_src + i, + &val); + hw_mod_cat_cts_set(&ndev->be, HW_CAT_CTS_CAT_B, offset * cfn_dst + i, val); + } + + hw_mod_cat_cts_flush(&ndev->be, offset * cfn_dst, offset); + } + + /* Setup CAT.CTE */ + { + hw_mod_cat_cte_get(&ndev->be, HW_CAT_CTE_ENABLE_BM, cfn_src, &val); + hw_mod_cat_cte_set(&ndev->be, HW_CAT_CTE_ENABLE_BM, cfn_dst, val); + hw_mod_cat_cte_flush(&ndev->be, cfn_dst, 1); + } + + /* Setup CAT.KM */ + { + uint32_t bit_src = 0; + + hw_mod_cat_kcs_km_get(&ndev->be, HW_CAT_KCS_CATEGORY, KM_FLM_IF_FIRST, cfn_src, + &val); + hw_mod_cat_kcs_km_set(&ndev->be, HW_CAT_KCS_CATEGORY, KM_FLM_IF_FIRST, cfn_dst, + val); + hw_mod_cat_kcs_km_flush(&ndev->be, KM_FLM_IF_FIRST, cfn_dst, 1); + + hw_mod_cat_kce_km_get(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cfn_src / 8, &val); + bit_src = (val >> (cfn_src % 8)) & 0x1; + + hw_mod_cat_kce_km_get(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cfn_dst / 8, &val); + val &= ~(1 << (cfn_dst % 8)); + + hw_mod_cat_kce_km_set(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cfn_dst / 8, val | (bit_src << (cfn_dst % 8))); + hw_mod_cat_kce_km_flush(&ndev->be, KM_FLM_IF_FIRST, cfn_dst / 8, 1); + + for (int ft = 0; ft < (int)db->nb_km_ft; ++ft) { + hw_db_copy_ft(ndev, HW_DB_FT_TYPE_KM, cfn_dst, cfn_src, + HW_DB_FT_LOOKUP_KEY_A, ft); + } + } + + /* Setup CAT.FLM */ + { + uint32_t bit_src = 0; + + hw_mod_cat_kcs_flm_get(&ndev->be, HW_CAT_KCS_CATEGORY, KM_FLM_IF_FIRST, cfn_src, + &val); + hw_mod_cat_kcs_flm_set(&ndev->be, HW_CAT_KCS_CATEGORY, KM_FLM_IF_FIRST, cfn_dst, + val); + hw_mod_cat_kcs_flm_flush(&ndev->be, KM_FLM_IF_FIRST, cfn_dst, 1); + + hw_mod_cat_kce_flm_get(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cfn_src / 8, &val); + bit_src = (val >> (cfn_src % 8)) & 0x1; + + hw_mod_cat_kce_flm_get(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cfn_dst / 8, &val); + val &= ~(1 << (cfn_dst % 8)); + + hw_mod_cat_kce_flm_set(&ndev->be, HW_CAT_KCE_ENABLE_BM, KM_FLM_IF_FIRST, + cfn_dst / 8, val | (bit_src << (cfn_dst % 8))); + hw_mod_cat_kce_flm_flush(&ndev->be, KM_FLM_IF_FIRST, cfn_dst / 8, 1); + + for (int ft = 0; ft < (int)db->nb_flm_ft; ++ft) { + hw_db_copy_ft(ndev, HW_DB_FT_TYPE_FLM, cfn_dst, cfn_src, + HW_DB_FT_LOOKUP_KEY_A, ft); + hw_db_copy_ft(ndev, HW_DB_FT_TYPE_FLM, cfn_dst, cfn_src, + HW_DB_FT_LOOKUP_KEY_C, ft); + } + } + + /* Setup CAT.COT */ + { + hw_mod_cat_cot_set(&ndev->be, HW_CAT_COT_COPY_FROM, cfn_dst, cfn_src); + hw_mod_cat_cot_flush(&ndev->be, cfn_dst, 1); + } + + hw_mod_cat_cfn_set(&ndev->be, HW_CAT_CFN_ENABLE, cfn_dst, 0, 0x1); + hw_mod_cat_cfn_flush(&ndev->be, cfn_dst, 1); +} + +/* + * Algorithm for moving CFN entries to make space with respect of priority. + * The algorithm will make the fewest possible moves to fit a new CFN entry. + */ +static int hw_db_inline_alloc_prioritized_cfn(struct flow_nic_dev *ndev, + struct hw_db_inline_resource_db *db, + struct hw_db_match_set_idx match_set_idx) +{ + const struct hw_db_inline_resource_db_match_set *match_set = + &db->match_set[match_set_idx.ids]; + + uint64_t priority = ((uint64_t)(match_set->data.priority & 0xff) << 56) | + ((uint64_t)(0xffffff - (match_set->set_priority & 0xffffff)) << 32) | + (0xffffffff - ++db->cfn_priority_counter); + + int db_cfn_idx = -1; + + struct { + uint64_t priority; + uint32_t idx; + } sorted_priority[db->nb_cat]; + + memset(sorted_priority, 0x0, sizeof(sorted_priority)); + + uint32_t in_use_count = 0; + + for (uint32_t i = 1; i < db->nb_cat; ++i) { + if (db->cfn[i].ref > 0) { + sorted_priority[db->cfn[i].cfn_hw].priority = db->cfn[i].priority; + sorted_priority[db->cfn[i].cfn_hw].idx = i; + in_use_count += 1; + + } else if (db_cfn_idx == -1) { + db_cfn_idx = (int)i; + } + } + + if (in_use_count >= db->nb_cat - 1) + return -1; + + if (in_use_count == 0) { + db->cfn[db_cfn_idx].ref = 1; + db->cfn[db_cfn_idx].cfn_hw = 1; + db->cfn[db_cfn_idx].priority = priority; + return db_cfn_idx; + } + + int goal = 1; + int free_before = -1000000; + int free_after = 1000000; + int found_smaller = 0; + + for (int i = 1; i < (int)db->nb_cat; ++i) { + if (sorted_priority[i].priority > priority) { /* Bigger */ + goal = i + 1; + + } else if (sorted_priority[i].priority == 0) { /* Not set */ + if (found_smaller) { + if (free_after > i) + free_after = i; + + } else { + free_before = i; + } + + } else {/* Smaller */ + found_smaller = 1; + } + } + + int diff_before = goal - free_before - 1; + int diff_after = free_after - goal; + + if (goal < (int)db->nb_cat && sorted_priority[goal].priority == 0) { + db->cfn[db_cfn_idx].ref = 1; + db->cfn[db_cfn_idx].cfn_hw = goal; + db->cfn[db_cfn_idx].priority = priority; + return db_cfn_idx; + } + + if (diff_after <= diff_before) { + for (int i = free_after; i > goal; --i) { + int *cfn_hw = &db->cfn[sorted_priority[i - 1].idx].cfn_hw; + hw_db_inline_filter_copy(ndev, db, i, *cfn_hw); + hw_db_inline_filter_clear(ndev, db, *cfn_hw); + *cfn_hw = i; + } + + } else { + goal -= 1; + + for (int i = free_before; i < goal; ++i) { + int *cfn_hw = &db->cfn[sorted_priority[i + 1].idx].cfn_hw; + hw_db_inline_filter_copy(ndev, db, i, *cfn_hw); + hw_db_inline_filter_clear(ndev, db, *cfn_hw); + *cfn_hw = i; + } + } + + db->cfn[db_cfn_idx].ref = 1; + db->cfn[db_cfn_idx].cfn_hw = goal; + db->cfn[db_cfn_idx].priority = priority; + + return db_cfn_idx; +} + +static void hw_db_inline_free_prioritized_cfn(struct hw_db_inline_resource_db *db, int cfn_hw) +{ + for (uint32_t i = 0; i < db->nb_cat; ++i) { + if (db->cfn[i].cfn_hw == cfn_hw) { + memset(&db->cfn[i], 0x0, sizeof(struct hw_db_inline_resource_db_cfn)); + break; + } + } +} + +static void hw_db_inline_update_active_filters(struct flow_nic_dev *ndev, void *db_handle, + int group) +{ + struct hw_db_inline_resource_db *db = (struct hw_db_inline_resource_db *)db_handle; + struct hw_db_inline_resource_db_flm_rcp *flm_rcp = &db->flm[group]; + struct hw_db_inline_resource_db_flm_cfn_map *cell; + + for (uint32_t match_set_idx = 0; match_set_idx < db->nb_cat; ++match_set_idx) { + for (uint32_t ft_idx = 0; ft_idx < db->nb_flm_ft; ++ft_idx) { + int active = flm_rcp->ft[ft_idx].ref > 0 && + flm_rcp->match_set[match_set_idx].ref > 0; + cell = &flm_rcp->cfn_map[match_set_idx * db->nb_flm_ft + ft_idx]; + + if (active && cell->cfn_idx == 0) { + /* Setup filter */ + cell->cfn_idx = hw_db_inline_alloc_prioritized_cfn(ndev, db, + flm_rcp->match_set[match_set_idx].idx); + hw_db_inline_filter_apply(ndev, db, db->cfn[cell->cfn_idx].cfn_hw, + flm_rcp->match_set[match_set_idx].idx, + flm_rcp->ft[ft_idx].idx, + group == 0 + ? db->match_set[flm_rcp->match_set[match_set_idx] + .idx.ids] + .data.action_set + : flm_rcp->ft[ft_idx].data.action_set); + } + + if (!active && cell->cfn_idx > 0) { + /* Teardown filter */ + hw_db_inline_filter_clear(ndev, db, db->cfn[cell->cfn_idx].cfn_hw); + hw_db_inline_free_prioritized_cfn(db, + db->cfn[cell->cfn_idx].cfn_hw); + cell->cfn_idx = 0; + } + } + } +} + + +/******************************************************************************/ +/* Match set */ +/******************************************************************************/ + +static int hw_db_inline_match_set_compare(const struct hw_db_inline_match_set_data *data1, + const struct hw_db_inline_match_set_data *data2) +{ + return data1->cat.raw == data2->cat.raw && data1->km.raw == data2->km.raw && + data1->km_ft.raw == data2->km_ft.raw && data1->jump == data2->jump; +} + +struct hw_db_match_set_idx +hw_db_inline_match_set_add(struct flow_nic_dev *ndev, void *db_handle, + const struct hw_db_inline_match_set_data *data) +{ + struct hw_db_inline_resource_db *db = (struct hw_db_inline_resource_db *)db_handle; + struct hw_db_inline_resource_db_flm_rcp *flm_rcp = &db->flm[data->jump]; + struct hw_db_match_set_idx idx = { .raw = 0 }; + int found = 0; + + idx.type = HW_DB_IDX_TYPE_MATCH_SET; + + for (uint32_t i = 0; i < HW_DB_INLINE_MATCH_SET_NB; ++i) { + if (!found && db->match_set[i].ref <= 0) { + found = 1; + idx.ids = i; + } + + if (db->match_set[i].ref > 0 && + hw_db_inline_match_set_compare(data, &db->match_set[i].data)) { + idx.ids = i; + hw_db_inline_match_set_ref(ndev, db, idx); + return idx; + } + } + + if (!found) { + idx.error = 1; + return idx; + } + + found = 0; + + for (uint32_t i = 0; i < db->nb_cat; ++i) { + if (flm_rcp->match_set[i].ref <= 0) { + found = 1; + flm_rcp->match_set[i].ref = 1; + flm_rcp->match_set[i].idx.raw = idx.raw; + break; + } + } + + if (!found) { + idx.error = 1; + return idx; + } + + memcpy(&db->match_set[idx.ids].data, data, sizeof(struct hw_db_inline_match_set_data)); + db->match_set[idx.ids].ref = 1; + db->match_set[idx.ids].set_priority = ++db->set_priority_counter; + + hw_db_inline_update_active_filters(ndev, db, data->jump); + + return idx; +} + +void hw_db_inline_match_set_ref(struct flow_nic_dev *ndev, void *db_handle, + struct hw_db_match_set_idx idx) +{ + (void)ndev; + struct hw_db_inline_resource_db *db = (struct hw_db_inline_resource_db *)db_handle; + + if (!idx.error) + db->match_set[idx.ids].ref += 1; +} + +void hw_db_inline_match_set_deref(struct flow_nic_dev *ndev, void *db_handle, + struct hw_db_match_set_idx idx) +{ + struct hw_db_inline_resource_db *db = (struct hw_db_inline_resource_db *)db_handle; + struct hw_db_inline_resource_db_flm_rcp *flm_rcp; + int jump; + + if (idx.error) + return; + + db->match_set[idx.ids].ref -= 1; + + if (db->match_set[idx.ids].ref > 0) + return; + + jump = db->match_set[idx.ids].data.jump; + flm_rcp = &db->flm[jump]; + + for (uint32_t i = 0; i < db->nb_cat; ++i) { + if (flm_rcp->match_set[i].idx.raw == idx.raw) { + flm_rcp->match_set[i].ref = 0; + hw_db_inline_update_active_filters(ndev, db, jump); + memset(&flm_rcp->match_set[i], 0x0, + sizeof(struct hw_db_inline_resource_db_flm_match_set)); + } + } + + memset(&db->match_set[idx.ids].data, 0x0, sizeof(struct hw_db_inline_match_set_data)); + db->match_set[idx.ids].ref = 0; +} + +/******************************************************************************/ +/* Action set */ +/******************************************************************************/ + +static int hw_db_inline_action_set_compare(const struct hw_db_inline_action_set_data *data1, + const struct hw_db_inline_action_set_data *data2) +{ + if (data1->contains_jump) + return data2->contains_jump && data1->jump == data2->jump; + + return data1->cot.raw == data2->cot.raw && data1->qsl.raw == data2->qsl.raw && + data1->slc_lr.raw == data2->slc_lr.raw && data1->tpe.raw == data2->tpe.raw && + data1->hsh.raw == data2->hsh.raw; +} + +struct hw_db_action_set_idx +hw_db_inline_action_set_add(struct flow_nic_dev *ndev, void *db_handle, + const struct hw_db_inline_action_set_data *data) +{ + struct hw_db_inline_resource_db *db = (struct hw_db_inline_resource_db *)db_handle; + struct hw_db_action_set_idx idx = { .raw = 0 }; + int found = 0; + + idx.type = HW_DB_IDX_TYPE_ACTION_SET; + + for (uint32_t i = 0; i < HW_DB_INLINE_ACTION_SET_NB; ++i) { + if (!found && db->action_set[i].ref <= 0) { + found = 1; + idx.ids = i; + } + + if (db->action_set[i].ref > 0 && + hw_db_inline_action_set_compare(data, &db->action_set[i].data)) { + idx.ids = i; + hw_db_inline_action_set_ref(ndev, db, idx); + return idx; + } + } + + if (!found) { + idx.error = 1; + return idx; + } + + memcpy(&db->action_set[idx.ids].data, data, sizeof(struct hw_db_inline_action_set_data)); + db->action_set[idx.ids].ref = 1; + + return idx; +} + +void hw_db_inline_action_set_ref(struct flow_nic_dev *ndev, void *db_handle, + struct hw_db_action_set_idx idx) +{ + (void)ndev; + struct hw_db_inline_resource_db *db = (struct hw_db_inline_resource_db *)db_handle; + + if (!idx.error) + db->action_set[idx.ids].ref += 1; +} + +void hw_db_inline_action_set_deref(struct flow_nic_dev *ndev, void *db_handle, + struct hw_db_action_set_idx idx) +{ + (void)ndev; + struct hw_db_inline_resource_db *db = (struct hw_db_inline_resource_db *)db_handle; + + if (idx.error) + return; + + db->action_set[idx.ids].ref -= 1; + + if (db->action_set[idx.ids].ref <= 0) { + memset(&db->action_set[idx.ids].data, 0x0, + sizeof(struct hw_db_inline_action_set_data)); + db->action_set[idx.ids].ref = 0; + } +} + /******************************************************************************/ /* COT */ /******************************************************************************/ @@ -1593,6 +2383,8 @@ struct hw_db_flm_ft hw_db_inline_flm_ft_default(struct flow_nic_dev *ndev, void flm_rcp->ft[idx.id1].idx.raw = idx.raw; flm_rcp->ft[idx.id1].ref = 1; + hw_db_inline_update_active_filters(ndev, db, data->jump); + return idx; } @@ -1647,6 +2439,8 @@ struct hw_db_flm_ft hw_db_inline_flm_ft_add(struct flow_nic_dev *ndev, void *db_ flm_rcp->ft[idx.id1].idx.raw = idx.raw; flm_rcp->ft[idx.id1].ref = 1; + hw_db_inline_update_active_filters(ndev, db, data->group); + return idx; } @@ -1677,6 +2471,7 @@ void hw_db_inline_flm_ft_deref(struct flow_nic_dev *ndev, void *db_handle, struc return; flm_rcp->ft[idx.id1].ref = 0; + hw_db_inline_update_active_filters(ndev, db, idx.id2); memset(&flm_rcp->ft[idx.id1], 0x0, sizeof(struct hw_db_inline_resource_db_flm_ft)); } diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.h index 9820225ffa..33de674b72 100644 --- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.h +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_hw_db_inline.h @@ -131,6 +131,10 @@ struct hw_db_hsh_idx { enum hw_db_idx_type { HW_DB_IDX_TYPE_NONE = 0, + + HW_DB_IDX_TYPE_MATCH_SET, + HW_DB_IDX_TYPE_ACTION_SET, + HW_DB_IDX_TYPE_COT, HW_DB_IDX_TYPE_CAT, HW_DB_IDX_TYPE_QSL, @@ -145,6 +149,17 @@ enum hw_db_idx_type { HW_DB_IDX_TYPE_HSH, }; +/* Container types */ +struct hw_db_inline_match_set_data { + struct hw_db_cat_idx cat; + struct hw_db_km_idx km; + struct hw_db_km_ft km_ft; + struct hw_db_action_set_idx action_set; + int jump; + + uint8_t priority; +}; + /* Functionality data types */ struct hw_db_inline_cat_data { uint32_t vlan_mask : 4; @@ -224,6 +239,7 @@ struct hw_db_inline_action_set_data { struct { struct hw_db_cot_idx cot; struct hw_db_qsl_idx qsl; + struct hw_db_slc_lr_idx slc_lr; struct hw_db_tpe_idx tpe; struct hw_db_hsh_idx hsh; }; @@ -262,6 +278,25 @@ const void *hw_db_inline_find_data(struct flow_nic_dev *ndev, void *db_handle, enum hw_db_idx_type type, struct hw_db_idx *idxs, uint32_t size); /**/ + +struct hw_db_match_set_idx +hw_db_inline_match_set_add(struct flow_nic_dev *ndev, void *db_handle, + const struct hw_db_inline_match_set_data *data); +void hw_db_inline_match_set_ref(struct flow_nic_dev *ndev, void *db_handle, + struct hw_db_match_set_idx idx); +void hw_db_inline_match_set_deref(struct flow_nic_dev *ndev, void *db_handle, + struct hw_db_match_set_idx idx); + +struct hw_db_action_set_idx +hw_db_inline_action_set_add(struct flow_nic_dev *ndev, void *db_handle, + const struct hw_db_inline_action_set_data *data); +void hw_db_inline_action_set_ref(struct flow_nic_dev *ndev, void *db_handle, + struct hw_db_action_set_idx idx); +void hw_db_inline_action_set_deref(struct flow_nic_dev *ndev, void *db_handle, + struct hw_db_action_set_idx idx); + +/**/ + struct hw_db_cot_idx hw_db_inline_cot_add(struct flow_nic_dev *ndev, void *db_handle, const struct hw_db_inline_cot_data *data); void hw_db_inline_cot_ref(struct flow_nic_dev *ndev, void *db_handle, struct hw_db_cot_idx idx); diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c index 7487b5150e..193959dfc5 100644 --- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c @@ -2677,10 +2677,30 @@ static int setup_flow_flm_actions(struct flow_eth_dev *dev, return -1; } + /* Setup Action Set */ + struct hw_db_inline_action_set_data action_set_data = { + .contains_jump = 0, + .cot = cot_idx, + .qsl = qsl_idx, + .slc_lr = slc_lr_idx, + .tpe = tpe_idx, + .hsh = hsh_idx, + }; + struct hw_db_action_set_idx action_set_idx = + hw_db_inline_action_set_add(dev->ndev, dev->ndev->hw_db_handle, &action_set_data); + local_idxs[(*local_idx_counter)++] = action_set_idx.raw; + + if (action_set_idx.error) { + NT_LOG(ERR, FILTER, "Could not reference Action Set resource"); + flow_nic_set_error(ERR_MATCH_RESOURCE_EXHAUSTION, error); + return -1; + } + /* Setup FLM FT */ struct hw_db_inline_flm_ft_data flm_ft_data = { .is_group_zero = 0, .group = group, + .action_set = action_set_idx, }; struct hw_db_flm_ft flm_ft_idx = empty_pattern ? hw_db_inline_flm_ft_default(dev->ndev, dev->ndev->hw_db_handle, &flm_ft_data) @@ -2867,6 +2887,18 @@ static struct flow_handle *create_flow_filter(struct flow_eth_dev *dev, struct n } } + struct hw_db_action_set_idx action_set_idx = + hw_db_inline_action_set_add(dev->ndev, dev->ndev->hw_db_handle, + &action_set_data); + + fh->db_idxs[fh->db_idx_counter++] = action_set_idx.raw; + + if (action_set_idx.error) { + NT_LOG(ERR, FILTER, "Could not reference Action Set resource"); + flow_nic_set_error(ERR_MATCH_RESOURCE_EXHAUSTION, error); + goto error_out; + } + /* Setup CAT */ struct hw_db_inline_cat_data cat_data = { .vlan_mask = (0xf << fd->vlans) & 0xf, @@ -2986,6 +3018,7 @@ static struct flow_handle *create_flow_filter(struct flow_eth_dev *dev, struct n struct hw_db_inline_km_ft_data km_ft_data = { .cat = cat_idx, .km = km_idx, + .action_set = action_set_idx, }; struct hw_db_km_ft km_ft_idx = hw_db_inline_km_ft_add(dev->ndev, dev->ndev->hw_db_handle, &km_ft_data); @@ -3022,10 +3055,32 @@ static struct flow_handle *create_flow_filter(struct flow_eth_dev *dev, struct n km_write_data_match_entry(&fd->km, 0); } + /* Setup Match Set */ + struct hw_db_inline_match_set_data match_set_data = { + .cat = cat_idx, + .km = km_idx, + .km_ft = km_ft_idx, + .action_set = action_set_idx, + .jump = fd->jump_to_group != UINT32_MAX ? fd->jump_to_group : 0, + .priority = attr->priority & 0xff, + }; + struct hw_db_match_set_idx match_set_idx = + hw_db_inline_match_set_add(dev->ndev, dev->ndev->hw_db_handle, + &match_set_data); + fh->db_idxs[fh->db_idx_counter++] = match_set_idx.raw; + + if (match_set_idx.error) { + NT_LOG(ERR, FILTER, "Could not reference Match Set resource"); + flow_nic_set_error(ERR_MATCH_RESOURCE_EXHAUSTION, error); + goto error_out; + } + /* Setup FLM FT */ struct hw_db_inline_flm_ft_data flm_ft_data = { .is_group_zero = 1, .jump = fd->jump_to_group != UINT32_MAX ? fd->jump_to_group : 0, + .action_set = action_set_idx, + }; struct hw_db_flm_ft flm_ft_idx = hw_db_inline_flm_ft_add(dev->ndev, dev->ndev->hw_db_handle, &flm_ft_data); -- 2.45.0