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 791CF45B96; Mon, 21 Oct 2024 23:09:32 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E2AB840EDF; Mon, 21 Oct 2024 23:06:29 +0200 (CEST) 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 33E3940E09 for ; Mon, 21 Oct 2024 23:06:04 +0200 (CEST) Received: from EUR03-VI1-obe.outbound.protection.outlook.com (mail-vi1eur03lp2110.outbound.protection.outlook.com [104.47.30.110]) by mx-outbound19-70.eu-central-1b.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 21 Oct 2024 21:06:00 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=j0dLIeypoLJdhtzyjfo9DsBicxJilvqFoKRj6IlVtXulyDtkKdbKhvMVQAuzgbQ5Ff3rlqS05szbvhf3REGXJkLBHsoLl0eR6wY6e9ynpgm9UGGlPcWnBI0oU21Z87+px2jpLV6wAP6S/ONi8d+j+Wv5RCejuY0riRmgHgP+I3ZE7nXjfqFqAJYEtZDYnKlBLTSrQSGp6Pw3d8qZPRy9jKYRsSJx3JyySpFPk4DoBKQpmhMsPsrehpRqJ2oZ2cjrHNP/YXb1h/rCliukURunVhmdElxw1+epA+2Q/hrq6xZMhmkIQDXh5JQSvB7AijqwTH4qOm2QmP8Ry60KD5bz9w== 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=JSk4mhiYtNu6Q+unPzK9PFfABzghLJ0XKY5i4rQGsoA=; b=ABXcyoJ9zVF7Lu99JWxCvJYDvwZLcxpleUQrfHT0kce1o7PSA6JoRCX6aRrHJmpNltPiMHrwiz9/Yvq1DNxj3vtrfuaJC9Ibx59gbPCQS7xZX745p9NfrlTjPAIwDHcuEASRSbMCaQH561V++5H1Xcab2tHmX06A5K2s9Dwp4nJu+Q4Vu2vJqUUIBrdaSzD41XDw/h+9ioQyhJWH3RC3QnnopvBn6cTGRMgLitvW2cl86H/Pw0XdXYFxvm9IUTjwThoOSGl15uhn8sbU6gDYtqot8xo23Uxb6xhxPPwQF5PLm3ycXlZKb3Wi7MKd9tAroiDAP3w+inR2kZ+t3nBASw== 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=JSk4mhiYtNu6Q+unPzK9PFfABzghLJ0XKY5i4rQGsoA=; b=lRwTVGJoKHOmPM2zt1A0ofCVPrSzxh55D+FpZax5lXSWPkIeZSTJq3DI6fxhWU0Kwkvt1ATVw9af4Mg0abvSUMW7d8x5uHyx7ei8Y7KBemopSeQfUd7AT5eLhCJyf+Z8WivLvIFkiEil15mkemPbTkiA2aJR2pn8Ld3L3S4IwpM= Received: from AS9PR04CA0154.eurprd04.prod.outlook.com (2603:10a6:20b:48a::17) by AM8P190MB0803.EURP190.PROD.OUTLOOK.COM (2603:10a6:20b:1df::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8069.28; Mon, 21 Oct 2024 21:05:57 +0000 Received: from AMS0EPF000001A8.eurprd05.prod.outlook.com (2603:10a6:20b:48a:cafe::2a) by AS9PR04CA0154.outlook.office365.com (2603:10a6:20b:48a::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8069.29 via Frontend Transport; Mon, 21 Oct 2024 21:05:57 +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 AMS0EPF000001A8.mail.protection.outlook.com (10.167.16.148) with Microsoft SMTP Server id 15.20.8093.14 via Frontend Transport; Mon, 21 Oct 2024 21:05:57 +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, Danylo Vodopianov Subject: [PATCH v1 36/73] net/ntnic: match and action db attributes were added Date: Mon, 21 Oct 2024 23:04:38 +0200 Message-ID: <20241021210527.2075431-37-sil-plv@napatech.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241021210527.2075431-1-sil-plv@napatech.com> References: <20241021210527.2075431-1-sil-plv@napatech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AMS0EPF000001A8:EE_|AM8P190MB0803:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 261336a5-100c-4f53-5770-08dcf21428e2 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|376014|36860700013|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?RBKFGbNiGteKAi0jx2eWnx3LZzU3Jh8zPHOr72y7AhmvcdzGDhfbevI8PUaE?= =?us-ascii?Q?WxGndzshVMYxzmWU1pebdJEUVPmjHuG2Q3DQ3cKbWVlkA8SHfQmGjg/1k8rS?= =?us-ascii?Q?hxnm6af6TZFblOABLMTL3GmZ6FrZtmhqG6DIDdQuvwtahp83qCnvT/eCmg/v?= =?us-ascii?Q?x970CmqslofvFgeXyzGVAIsM0CD6NSVPdve69kHPHoh8ot5PNWVmBq1dJIlS?= =?us-ascii?Q?8iEq+VSDBxmDv/AX7jhM1XYr9mLrdBSv5JUQrKUxTrABIiYAdmLauaK5GNN6?= =?us-ascii?Q?0G3/9Yg3TqrAC/xhXUjeFio4iU8cucfINg7ouVaDqR5xSFUYEtHG9CMq0Zhe?= =?us-ascii?Q?PON32zEkOoqqUv2MwqeHKy1VwdNaQeaZPgRZ4A2oiLeTGjTjlX4gpY42nQfA?= =?us-ascii?Q?JH7VeNURrQxZ/RqEyiARiyu8Xx7QwqYroPf4o1CNc4nopf8f8rba/ObwH79n?= =?us-ascii?Q?qtY4qd38evUqp0QiEjZYf636tZsLe6DCpgE5451kfH3AnKBz5AjHikCWlALb?= =?us-ascii?Q?w712zdWUf0idUxpRYPSPUNYgwWYowD3g2mJT6rpUPwYdO6BdFrtc5A8Go/88?= =?us-ascii?Q?8dA4Ik8Kh88zZXAl3c0A7wVtiAj/4l0ps6lcnRGt/BxrIA2uHIGFGEwS8I8E?= =?us-ascii?Q?KMuJHwlXtly3iBGTDr0UagE6bea+bdyyRmU4Bhqt2H69Qbo/3C5eBR6UE4eT?= =?us-ascii?Q?2wWzs8ZHycwgSbY8W2J9Rj2/W7bdYsw19Qh/S6pgbIHF90tv42h8dLoR9gnl?= =?us-ascii?Q?BqF+cGiXqYKiaN5Ih4gDoNBv7wgrtwqvMYSlNT/zu9QnRQ41az+1IkbJloGj?= =?us-ascii?Q?8D9opdbYKHUFtazSJl2i7LEoqk+dO+ukxez8TF40iZOLb9i1uQ08OtSCzWlD?= =?us-ascii?Q?kJanLZ7mZZ/Pb65NqtVhiMwCBEkCmDGn+KyEg81/kd44sOE4EmYehocVcpMF?= =?us-ascii?Q?2lHB51N8dM2Fcg4QI1xRcVNKiiYwWnwudVd1seh60JclzswaWwF8KZeFeEUg?= =?us-ascii?Q?pPGa0Eb4uiAH2nZ4Acyrf0sgIayBMbLFSNGk8awE/pL+ABu7lIkqByfQP4LJ?= =?us-ascii?Q?KJRp+gxqzOumH9LSONIZWfZrOMWvjcNe5R+xbYOGvZrGYYjUlNEa/yaPEQKu?= =?us-ascii?Q?v72PIx/3/bHTRth+TFP2csBSgom5Xav/BAlFsoR20UJExXFDsj+VE7iw5ZBz?= =?us-ascii?Q?ISnX0BV3s8yIJD4QSU1Niu71leu7MMbsLPUjdKzRXNGl2kl4IsBU21PQaNe9?= =?us-ascii?Q?xtkE+pfaVSbdKZcJyrdYJA6mQNQ1mXYYClbREI9IZa/xFIkV2pOw0174P5H1?= =?us-ascii?Q?0ZAS5+q5H2nkOF03Duji9GSCdVhA/SbpFd6rPuUIoY1iie+q5f1EWDjmrCFv?= =?us-ascii?Q?bxw2WHJZZbMpo9SyxQoYENhuVVKXqhPoouquJ3LxtFtZ3D/EBA=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)(36860700013)(82310400026); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: 69vornQn15CooqRAthdikMvrTKAqIx9VjGyacuvdzTpAnpyzBwifvkljzl+U/tWzItLiaQM1Q3Nj8hSMzmnAzeOYPwUYG1nyRkiDlcPHnGuHTjpOOrW0BkhwQ49g/0eB3o7EdkaRXoKILeShBrq6wGxAAz9LthgiHaQnUX7SQYinhDR9J6QR7R5ECmR/05RaU4TZmeRRukZfFoHSRd/avBbkYlsTOO4TFoR7Tu06/D/lT2hZwykpmaKhDNaljDHyMdKFfITSZtHPqSddyNa6QiYAEaRVQ9hrjTJEjmm5eZpDLq28mt/JFIdVevzUUxo5gwKUDDleRpOaPZG9Y7AzRNPux1h7sIxHz162k2uz8PXoKPY0lysbDZGi8Vty6DhP2noeQYtcjU/UwCM9JzOZaQy9ozSY37KobelRyy9pWnwdBZIRErhW1Q48glfdKRWIudkBgvdmTNTiGPFSLFXGSvMBTFPyc0AwjRPbKkJwsCRx7BpkuaV4P0+Bb9Zj+Wstz23potNc/BLun4RARt293H7l1kiF3Cqrli3Vg8+OTz9CTbDJOJRJogfDVqWRnTf44rLHogDhkTwTS7SEjVpiu2vbjmQl8p1Tcsgw2bIV1zS9kCcxaIMytZoPnqmDIYifsQ/UWEZ1w3qBi+BATX8Xd2K2qXvc0R37ZbMndb+JGUU= X-OriginatorOrg: napatech.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2024 21:05:57.7395 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 261336a5-100c-4f53-5770-08dcf21428e2 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: AMS0EPF000001A8.eurprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM8P190MB0803 X-BESS-ID: 1729544760-304934-12651-45486-1 X-BESS-VER: 2019.1_20241018.1852 X-BESS-Apparent-Source-IP: 104.47.30.110 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVsamBmbmQGYGUDQtxTAxydzc2N A40dDQ3NLIyMzQxMAoNdXS0NIkyTQ5Wak2FgBhcbq0QgAAAA== X-BESS-Outbound-Spam-Score: 0.00 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.259883 [from cloudscan10-204.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 089f8c8174..06493d0938 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 @@ -8,6 +8,9 @@ #include "flow_api_hw_db_inline.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 @@ -109,6 +112,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) @@ -291,6 +308,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; @@ -359,6 +386,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; @@ -551,6 +584,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 */ /******************************************************************************/ @@ -1592,6 +2382,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; } @@ -1646,6 +2438,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; } @@ -1676,6 +2470,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 cbd26629cd..149b354bcb 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 @@ -2681,10 +2681,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) @@ -2872,6 +2892,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, @@ -2991,6 +3023,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); @@ -3027,10 +3060,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