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 96C8E45BA3; Tue, 22 Oct 2024 19:01:07 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id CEDDC4114B; Tue, 22 Oct 2024 18:57:05 +0200 (CEST) Received: from egress-ip11b.ess.de.barracuda.com (egress-ip11b.ess.de.barracuda.com [18.185.115.215]) by mails.dpdk.org (Postfix) with ESMTP id EE1E5402BC for ; Tue, 22 Oct 2024 18:56:46 +0200 (CEST) Received: from EUR03-DBA-obe.outbound.protection.outlook.com (mail-dbaeur03lp2170.outbound.protection.outlook.com [104.47.51.170]) by mx-outbound19-119.eu-central-1b.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 22 Oct 2024 16:56:45 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=nEmhWwVYgBTPox3p4ciSMlzQ07+9kMEkf2qXNezMRmWWOCmLXfq6HWWUd3BIL+rRTZlBztBlkBNcJnCMWZo79vnqavrrL+qQSXj8OO7XL4dgKOkHymmGuyN+3gUAX/ifjW9UR+M3unTxFh8RAjnEgCkNVbLIIe08gW28gsugY8XjCIDaRdqpbFNMXL1o4scMk2p9aeQEIUHWOJpTPIXdMqK0ovzkumM5XlB/zthx8al2fYOJ9zwFPcSjkY9LWCh50ZKW8DmxZ20FqRSOdyhnic6E7zqgnSvUSLD5dc1fEhyF9n6d0t1ch1IzbeefBGytlajr0SGU5VWyN7hhcmQ7Ng== 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=xYsgkJtWUoDkCpT4LUrZpg43gkgyNski5/0J0l/WWvY=; b=USoQvYQQGYVPRQfVvd84ew2LBeQs4qxZkMKcOltTVoB57G3vUZAn58CdJcvsvtr9Hq8Eaiz/f2WVz4kICGSiHmgNFxLrjUQLe30D8NQSTDpkgrSPZQMTFmnnCs/QPbdgl3pZxnaa8bGbEMECOqs5Li5m+LU2j73rB3zgvoiNtfSQWF4RhmsOTEmXAx8Q7j7cQ0jEZ6DXgkgqnekJjM3Qe5950GYYp+vDisIjOhwr95IXidfGrvZL33/K3xv+2sSNUeFcWgx5L2xsNb74+c48wAHPj1XCTWgj/yAyJTwADrnbERI88oesJXf1EM1Rbue76gV8/G1wXRyv6/FiOgRPoQ== 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=xYsgkJtWUoDkCpT4LUrZpg43gkgyNski5/0J0l/WWvY=; b=N8D9+SgCrvZrCnEFv/Ids18zyPNNnHfrNJkQhAdELve0rS69cl8GdV2XrKNhHw3OefZFvnPVDgy5e4E9v8oTC8tYHA8R/EJLQi457dBPSXjcR33jas3/WTwPwZAL3SAFAp8S7iVmd20A8AWp9eCGNJYyUnCMfj5JRCPgSQG9+Ik= Received: from DB9PR06CA0019.eurprd06.prod.outlook.com (2603:10a6:10:1db::24) by DB9P190MB2009.EURP190.PROD.OUTLOOK.COM (2603:10a6:10:399::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8069.28; Tue, 22 Oct 2024 16:56:38 +0000 Received: from DU2PEPF0001E9C2.eurprd03.prod.outlook.com (2603:10a6:10:1db:cafe::ba) by DB9PR06CA0019.outlook.office365.com (2603:10a6:10:1db::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8069.29 via Frontend Transport; Tue, 22 Oct 2024 16:56:38 +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 DU2PEPF0001E9C2.mail.protection.outlook.com (10.167.8.71) with Microsoft SMTP Server id 15.20.8093.14 via Frontend Transport; Tue, 22 Oct 2024 16:56:38 +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 v2 36/73] net/ntnic: match and action db attributes were added Date: Tue, 22 Oct 2024 18:54:53 +0200 Message-ID: <20241022165541.3186140-37-sil-plv@napatech.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241022165541.3186140-1-sil-plv@napatech.com> References: <20241021210527.2075431-1-sil-plv@napatech.com> <20241022165541.3186140-1-sil-plv@napatech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU2PEPF0001E9C2:EE_|DB9P190MB2009:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 5c6eb3c2-fa0c-40a1-3f47-08dcf2ba7ec8 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|36860700013|376014|1800799024|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?ED5WnbmJotSZQ0R1OvEzt3z+L7zW9VnnMUXZx81zv+Bka1vijegH9w9ALBa9?= =?us-ascii?Q?xjecqkdSwcS0+9C6/wUQwd8A6sgUrPOa2Q3YeqlpLva8vA7ApxzQNskIprCx?= =?us-ascii?Q?5ERUW9WiyQmNki285nIi4SLYmd0jCHFyZx3aytJ8SLzS1hl/y02Q2fAW3eNz?= =?us-ascii?Q?vMvBwxlJ4B7X3ac6g8Wxe6mZwZby+s8J0NosIjxgzyjieg72bbGcl55F7cSn?= =?us-ascii?Q?dDorCh2qd3TmeXBFSoWoumsmGBfZUUG6wqjxjgeeOmOsth6ab6OIlUEWPslj?= =?us-ascii?Q?nMDzLDJ/a0UR/GCrCclXc574falOB8TwNW1+W2mSNDna0bRpyg/cue1q1IFm?= =?us-ascii?Q?NePpQmio4/ht88J7iXsqBMV/DkChEUQZa4Ybe288ZOQ3h6BqGGp1HxV1PdGu?= =?us-ascii?Q?0N6BDRW/+g5+Ym0Xvtzy+vgIbC125ANtcDdrr7tiEkrfd5OMx8HActbiRRi1?= =?us-ascii?Q?96+AfzYcDpPmETUSGI386/e2HOv3DGzmQ5WptuDwyBm4g2qRVYZip1EYmqVI?= =?us-ascii?Q?J4USRAQuP0es1kneOnq7I37GTnQjWByZj9Q1NKBnk0E956Ur0sZnLHU027O4?= =?us-ascii?Q?oiWnN+ltolHZKXbZk+IraOJdgVWc+pj/DD/9dY4kPvrFVk9Pzd+0B0F0xSVK?= =?us-ascii?Q?rgTYswfi9huh5uDtUYowugRKb3M6oEbIhfCAro2UfDxOHVPwyKu6B3vw7m7B?= =?us-ascii?Q?NTYb65kFh7n6l5qMm1NnRh3Pf7AHhWCKh+nsZkLKmRTE6rgC3QXPqWQuZOLF?= =?us-ascii?Q?sAZ1iU8sqfkaB5BbpBZ7SOKKh0MnaQeXJmXzLfoIJqKf9uQjo9QlbMzGSjTf?= =?us-ascii?Q?Fwii3KLqTO3rcZ+LI+pgdWuIid8wvWBnKVyopKXWJqRavhLedprYYzjKbDvN?= =?us-ascii?Q?8EPBhS2K3OaPSGX1ZPrnCHRxNyW70qUUYJ0tqJcVPuSFpKaf3cE4h2T+/GVR?= =?us-ascii?Q?mXTJaYtcshYKJ5goYnrlRL01+18fHavRIaqATfkR/kTDp2fZv8PDyXXO7nts?= =?us-ascii?Q?RulyWqxUTGGS3JVncYNxboc0gql0LwAYklCNDbMw3mUHwD6RQK2skA6OV+3b?= =?us-ascii?Q?l6gdGnptgid7uUjkpsNotgveWMi7I3b8IPr/Be+1ewYLbAhoR+EAE2wi/r3f?= =?us-ascii?Q?wQrOBn1PY2vKXY6kxBA6bcKNNKVZmHU165zlXbBQ0Y7FPDgBgatCnMLva15V?= =?us-ascii?Q?zKkPXcqoidU8JPGVQ0xTJHs3bwWqosixSY2T+DA84bQ3YOUMZXrOtZylMCsH?= =?us-ascii?Q?ku+8GhFfkg0QPX+X9Lybm0WPBDjZE/JY/viQoF2rvAe8vNUm38l+Lzo91sj7?= =?us-ascii?Q?tzxVc+oZi+KR+7xsXizsaWgyWA0OnmOjQli6R0IF4LW0a36w+Ul2UiiizJDP?= =?us-ascii?Q?3Oc7ukDOhRYAnRlwJScONh2PBGNkIoThfRhBk5YyIpQccY8L+Q=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)(36860700013)(376014)(1800799024)(82310400026); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: Q4HymYQ9zcPcHFnBzR0zXEkxAzsWCSpPKTORW4T8JygK7CD42Dv/XJLbK7dYhMfhIntfYELfsAhJD7ytw1xoT+4MKF2VcJTZ9lNZV0h/kw85CFC9ZmSRIgS5sFo19DQsqjLdU9TYVuBFJ+RvBl+3th+4Voa/mOukB1ZhIKoy8pd8XpFf9Hbv7hnvAA/hmX6PJ0i+KjlA+fE8Q8nxmEwcdO3v250LSqDTyP19/lRCDztJUNbDXhfTYCQXP8cnblW4Umhauny3HL4vNrPXR2DCqjaozZ5KjKelp5WzyCiw0rOuvDk5OEWNGXGfxTReEXRd4ZvvuZNdc28wVx/BMK8u+nNocgkmZ6qDAaR7t8/4ttqdeEqjWS1d+oQmF+lpHud8kmvwC6cjffuHTSFIwcOjA7GzXvCmvF1zQwyAGV9nGKU64myVmN3dZ+ml1BEAUaimA9WIYwT4RBF8aVKLRJzmtZSGIlL28PF0eN8ZgeUAp9W6ZafCC+BGxiEyoZtXdYi3hqwrdG0EXwi0Y3jKK+Jy3BZbDiuMQy+b3AqC73wNzaRpfTql8S+BP1J3wbRB7OZmNj3JkitX5VVDlh/pIqOFtYfgyD0GJ14nbgdT8EaA677aAhh8uRxVeIjju0Ag1TpWI2azJp2NDLQtyrBkQouW91WVfQ6Sp0VkCH9fYpjzqx0= X-OriginatorOrg: napatech.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Oct 2024 16:56:38.1690 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5c6eb3c2-fa0c-40a1-3f47-08dcf2ba7ec8 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: DU2PEPF0001E9C2.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9P190MB2009 X-BESS-ID: 1729616200-304983-12650-14402-2 X-BESS-VER: 2019.1_20241018.1852 X-BESS-Apparent-Source-IP: 104.47.51.170 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVsamBpYGQGYGUDQ1xdgy1dAsMd HUPCk1OTUtydDCJMk0LdXAwjg1KTE1Sak2FgD5aUxVQgAAAA== X-BESS-Outbound-Spam-Score: 0.00 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.259901 [from cloudscan12-68.eu-central-1a.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 0b8ac26b83..ac29c59f26 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 @@ -2678,10 +2678,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) @@ -2868,6 +2888,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, @@ -2987,6 +3019,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); @@ -3023,10 +3056,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