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 0B46745BB4; Wed, 23 Oct 2024 19:35:48 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id EC6ED42ECA; Wed, 23 Oct 2024 19:35:47 +0200 (CEST) Received: from egress-ip42a.ess.de.barracuda.com (egress-ip42a.ess.de.barracuda.com [18.185.115.201]) by mails.dpdk.org (Postfix) with ESMTP id 1EF3242ECA for ; Wed, 23 Oct 2024 19:35:45 +0200 (CEST) Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05lp2110.outbound.protection.outlook.com [104.47.17.110]) by mx-outbound42-14.eu-central-1c.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 23 Oct 2024 17:35:43 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=t8ssJ4zOGe0VUOBOqHUgHMX6Sj3AxZKANvFYjxd8Fm6Ycr2nNz5wqdX7Z50K5WaxvczecUzsgr7IXyqpzvVcQ+lD+/ib3W4veqAFJr3HUGIS01rmMvdAVM9Ek92XmunuDURn60qyu7wnBIL0ViL7lFZ+Rda4Z4j3OnuH+AbZu9GdIK1V+N4E/I6bG3BuXQRrbTxOQFi1XUQ6niAkWef+VhmUrEH7750eyw6ABn2Tgx3e0KoPbS2cmWDq8Gl7gJjI9amMxu695muAKStU0Vzvp6re16diRKrL7SolD9WT4Kh97tiHho+sS079R+Nqs7Fu8K8XfYE6Uk9HjULCB35SnA== 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=kUMcmd3pgBmx7UB7afNlN2zU8zzm+Pa26Arq88P+dUI=; b=I0yjU6WhlUGGYxHbA1uZC29+Qy+F6h+sDY+wNeeKh62arSfK48EowVmAdzNcsjPJscjVhY5sQaP7b2OyZus/Y2OX91fgYR1H31TH9EZXT7otPySkRlPkVK5GJbTa8OxvS1vMnPcgAWhld5ZfAmEDrsieu/9mmC4tOBqgGSvSFggXjYYjVwkMPGKJ2FEhWEzu7czHJY7T9O+RjMeHdh4Ar9W4gyAC2Wxrgiz6w1vLgmIcypijp49CAzUeU+658n0t7M+DDWSm47dKDppasTRFE7WjeidnAJlYJ3HDqnoyOY0icAKZosxuj1ra9nfu2QCq6AV6g/aqFookwDK6INJgnA== 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=kUMcmd3pgBmx7UB7afNlN2zU8zzm+Pa26Arq88P+dUI=; b=bbHitcxMf9eqfovChLN3wbdgmqCgeer0lpKZFu04E0AnD93BPJloIrrZrI5rfXnND1O9maJ9elBxPGuxoVAj5l6RGNR5EqhN+GSJrkyp+N1g9FSYfjCkvoDHqwznOiiqtqP1C8L03m8A3cRrsHq6mZoePaPU8Eob15m+gwx5sOo= Received: from DU7PR01CA0020.eurprd01.prod.exchangelabs.com (2603:10a6:10:50f::25) by DU0P190MB1929.EURP190.PROD.OUTLOOK.COM (2603:10a6:10:3be::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8093.17; Wed, 23 Oct 2024 17:01:39 +0000 Received: from DB5PEPF00014B9E.eurprd02.prod.outlook.com (2603:10a6:10:50f:cafe::ad) by DU7PR01CA0020.outlook.office365.com (2603:10a6:10:50f::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8093.16 via Frontend Transport; Wed, 23 Oct 2024 17:01:39 +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 DB5PEPF00014B9E.mail.protection.outlook.com (10.167.8.171) with Microsoft SMTP Server id 15.20.8093.14 via Frontend Transport; Wed, 23 Oct 2024 17:01:39 +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 v3 62/73] net/ntnic: added flow statistics Date: Wed, 23 Oct 2024 19:00:10 +0200 Message-ID: <20241023170032.314155-63-sil-plv@napatech.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241023170032.314155-1-sil-plv@napatech.com> References: <20241021210527.2075431-1-sil-plv@napatech.com> <20241023170032.314155-1-sil-plv@napatech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DB5PEPF00014B9E:EE_|DU0P190MB1929:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 94ce1261-5494-4afd-3399-08dcf3845ca6 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|82310400026|36860700013|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?zC3Mv+QIxVOQYvwkSLKRn+0agqaoJdgtl4WT1iM0HNbYdGj2lt33CDaAhQge?= =?us-ascii?Q?Cnl3QhkvjbVruYAIp3pRsdkFsxP2zLYvvBLbn0HWkxiyL1B33NAopIKHDBeY?= =?us-ascii?Q?/LZuAte4mhYQS48tW24Up8B137GDVwc0fBT5TxHvMRrfztSDc5e/xteJDx0r?= =?us-ascii?Q?Ebe3oGS4uh6xvxmXMHgzCwtoftc1r8g1HmF4GuJ6tLAqpUBWHU4fH1anCJdj?= =?us-ascii?Q?nPgtz1v3YnGJgSNeaukYNEQ/yiirCvXgPwQuVOib+rZ5q8ZJqO2EIauNPuqW?= =?us-ascii?Q?/2P9JMg6KtOk26Hcniu8jAnDhRccQgK1lG6fuL/yJ02fHxO5kqvg3lZwFvK7?= =?us-ascii?Q?FRsxP/SFIDzmVLG7CzAJkAiZGJi+vS+Fgz0PQaJ5bSLI/vFctBf43WgWAKyV?= =?us-ascii?Q?ZDjAmvzcwhRUKoQs1aR0akJbDYEO5/9DFj9e/fcYKDc8fo00zg8W/OVOLxce?= =?us-ascii?Q?C0p4QvEsE2OHpkKCGkiLdmLUnaziZMTgqp3ZanZNWtZByOUQi5bYymGQm5c3?= =?us-ascii?Q?FN4uU/xUoneWKWTwsJdZQku+DC3YLsyTM0m/g/ut97F8pgIJ7TuDdSQrXcIJ?= =?us-ascii?Q?BIA7M+N8mQVcY+p63oLnpZQ+EEdgZ2RvXCKlFbUjDvtbqP/KTeioFxoVKjnb?= =?us-ascii?Q?LOlfWHSqZfczhdu9Jth0XfarGMCcXgE6HCfYcSTgGu4aWLC0/erpvtqEWLIN?= =?us-ascii?Q?tHKyimqBHsTl2ZUbW3q2F9/9AyUp0JZUBOGyO7UGXAFYgPoe3qiUl0K20t21?= =?us-ascii?Q?Ne+/Zo07Tk7ll2NhT4Ji6cziOXKf0Ny/f/mfK+7ytbR+JC42NQmwSQruWv9M?= =?us-ascii?Q?LvDf+E3znveoR4C1CdeO6CdEmHw6JJ06UXZwWvFZYtHhoe0GiZ3OXTXlVB+L?= =?us-ascii?Q?TR3fJzvQx6zlIU6klwDgnkSu9ODio/MHSKzh0oWA1XftiGAe0MVYpSzAnI8f?= =?us-ascii?Q?6k0bGA3e2faCuTxVSq1RRKfVyPmoWpm8I0xBe3tX9I9mlBdggTfv85ereTX5?= =?us-ascii?Q?XBiTyoHe49zvWj/OfHrTRczrXl9DFLk6M6A5kQM0SD2+wGCdln0R4QSjmdxP?= =?us-ascii?Q?0I/AZtui3LyeYleBQaaqG7PkWniiJPZX8vlOnZC+ft1NLu7y48gImnMavGui?= =?us-ascii?Q?49Oh1mYgmTZlMFx6yNCB+AhdhAuUe0i9AO4kRXOK8aI0fVuZY2hBRoc5irBS?= =?us-ascii?Q?/fKEYaKCHmDLhFTJ7Q1GHgFoT98F9XaszD8ttrKEPsRfFHWsJpjb0Q1ErgY4?= =?us-ascii?Q?jAI+setppjBaxMDB3nFj2WPthl5LWfxfD7EjssTwyRP+q7cPjb3r/XRDIAYb?= =?us-ascii?Q?8ri0fwqLXC1tGUnzK2UT1TyC1K/MYOQV8mL+8B3xuxEQW2XyAaqNjSFDBEF6?= =?us-ascii?Q?0+fdCC16nypZmfHvFOg5r8LFJHyYi43DxHBX/O1hg+ssN+6veA=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)(376014)(82310400026)(36860700013)(1800799024); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: 2RATJ7re6IgAUiUuVahzIM68f22Bp3XFWF0BczTeIifv5hL0rWqzfigoZNlvo/iqNCPxA3mCCsFMMGx8YtbEXVHd5xcD6JoIz+bLLIVm7YVRlPCEwC2O6vo58koZioqovtndkQN6Q6U2o7UCS4yVgWcyl34qXUoxnkd936fDn13Lp8/GNnWhCmgfWaqirgK2WbNg2RZreuPNUSU4pZQJYUipj40L2wQHTfsuQiTeNAJ066Xgo4riAt0Rj/vU26PvB4GkZTXJSXiwM4+ms7s4a0tNtkrpKrMcKn5jUGbJ5MUdxzNKPxjgExT1rKx9PgO6GXW7kd2+AQtr30f2V1L9vdaYU6Isb5AAwmV/77p+Nc3zzAPIbOlM0tc2eEBKLykfHJlvc9EPtZmQPvEzHsyyyQu9buUKOZzKMnrzJeLv2jn4H1Sz+Y9YXxUznNcb2RYoF0NjBYY12HKDTkAkDZ+9tVmbtEpjT9pexnhAohSjm0Bz1FbX8uIosoZS5gLOFcn8o8rrl360rMapNHYna4seTg64DY69twiL+0kny+6hKPAYJnNxej1GMTY92hUZpZYqgcKyJ2tlISSp/n8qAFVtD6dDhfQ0+GeWXkQX31JgBl9tiVPt83vGCnwRaIfR5Ju2ep0cr10SvDMjGlIupERjZ+ZfN4tsI7MZD3azZdI1xDY= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Oct 2024 17:01:39.2740 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 94ce1261-5494-4afd-3399-08dcf3845ca6 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: DB5PEPF00014B9E.eurprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DU0P190MB1929 X-OriginatorOrg: napatech.com X-BESS-ID: 1729704943-310766-20172-22386-1 X-BESS-VER: 2019.1_20241018.1852 X-BESS-Apparent-Source-IP: 104.47.17.110 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVkampqbmQGYGUNTC3MzExCgp0c jEwCDFxMDQNNnI0jwp1dg4LcXAzNTYSKk2FgAbAxJxQgAAAA== X-BESS-Outbound-Spam-Score: 0.50 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.259925 [from cloudscan22-219.eu-central-1b.ess.aws.cudaops.com] Rule breakdown below pts rule name description ---- ---------------------- -------------------------------- 0.50 BSF_RULE7568M META: Custom Rule 7568M 0.00 BSF_BESS_OUTBOUND META: BESS Outbound X-BESS-Outbound-Spam-Status: SCORE=0.50 using account:ESS113687 scores of KILL_LEVEL=7.0 tests=BSF_RULE7568M, 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 xstats was extended with flow statistics support. Additional counters that shows learn, unlearn, lps, aps and other. Signed-off-by: Danylo Vodopianov --- .../net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c | 40 ++++ drivers/net/ntnic/include/hw_mod_backend.h | 3 + drivers/net/ntnic/include/ntdrv_4ga.h | 1 + drivers/net/ntnic/meson.build | 1 + drivers/net/ntnic/nthw/flow_api/flow_api.c | 11 +- .../ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c | 142 ++++++++++++++ .../flow_api/profile_inline/flm_evt_queue.c | 176 ++++++++++++++++++ .../flow_api/profile_inline/flm_evt_queue.h | 52 ++++++ .../profile_inline/flow_api_profile_inline.c | 46 +++++ .../profile_inline/flow_api_profile_inline.h | 6 + drivers/net/ntnic/nthw/rte_pmd_ntnic.h | 43 +++++ drivers/net/ntnic/ntnic_ethdev.c | 132 +++++++++++++ drivers/net/ntnic/ntnic_mod_reg.h | 7 + 13 files changed, 656 insertions(+), 4 deletions(-) create mode 100644 drivers/net/ntnic/nthw/flow_api/profile_inline/flm_evt_queue.c create mode 100644 drivers/net/ntnic/nthw/flow_api/profile_inline/flm_evt_queue.h create mode 100644 drivers/net/ntnic/nthw/rte_pmd_ntnic.h diff --git a/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c b/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c index 3afc5b7853..8fedfdcd04 100644 --- a/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c +++ b/drivers/net/ntnic/adapter/nt4ga_stat/nt4ga_stat.c @@ -189,6 +189,24 @@ static int nt4ga_stat_setup(struct adapter_info_s *p_adapter_info) return -1; } + if (get_flow_filter_ops() != NULL) { + struct flow_nic_dev *ndev = p_adapter_info->nt4ga_filter.mp_flow_device; + p_nt4ga_stat->flm_stat_ver = ndev->be.flm.ver; + p_nt4ga_stat->mp_stat_structs_flm = calloc(1, sizeof(struct flm_counters_v1)); + + if (!p_nt4ga_stat->mp_stat_structs_flm) { + NT_LOG_DBGX(ERR, GENERAL, "Cannot allocate mem."); + return -1; + } + + p_nt4ga_stat->mp_stat_structs_flm->max_aps = + nthw_fpga_get_product_param(p_adapter_info->fpga_info.mp_fpga, + NT_FLM_LOAD_APS_MAX, 0); + p_nt4ga_stat->mp_stat_structs_flm->max_lps = + nthw_fpga_get_product_param(p_adapter_info->fpga_info.mp_fpga, + NT_FLM_LOAD_LPS_MAX, 0); + } + p_nt4ga_stat->mp_port_load = calloc(NUM_ADAPTER_PORTS_MAX, sizeof(struct port_load_counters)); @@ -236,6 +254,7 @@ static int nt4ga_stat_collect_cap_v1_stats(struct adapter_info_s *p_adapter_info return -1; nthw_stat_t *p_nthw_stat = p_nt4ga_stat->mp_nthw_stat; + struct flow_nic_dev *ndev = p_adapter_info->nt4ga_filter.mp_flow_device; const int n_rx_ports = p_nt4ga_stat->mn_rx_ports; const int n_tx_ports = p_nt4ga_stat->mn_tx_ports; @@ -542,6 +561,27 @@ static int nt4ga_stat_collect_cap_v1_stats(struct adapter_info_s *p_adapter_info (uint64_t)(((__uint128_t)val * 32ULL) / PORT_LOAD_WINDOWS_SIZE); } + /* Update and get FLM stats */ + flow_filter_ops->flow_get_flm_stats(ndev, (uint64_t *)p_nt4ga_stat->mp_stat_structs_flm, + sizeof(struct flm_counters_v1) / sizeof(uint64_t)); + + /* + * Calculate correct load values: + * rpp = nthw_fpga_get_product_param(p_fpga, NT_RPP_PER_PS, 0); + * bin = (uint32_t)(((FLM_LOAD_WINDOWS_SIZE * 1000000000000ULL) / (32ULL * rpp)) - 1ULL); + * load_aps = ((uint64_t)load_aps * 1000000000000ULL) / (uint64_t)((bin+1) * rpp); + * load_lps = ((uint64_t)load_lps * 1000000000000ULL) / (uint64_t)((bin+1) * rpp); + * + * Simplified it gives: + * + * load_lps = (load_lps * 32ULL) / FLM_LOAD_WINDOWS_SIZE + * load_aps = (load_aps * 32ULL) / FLM_LOAD_WINDOWS_SIZE + */ + + p_nt4ga_stat->mp_stat_structs_flm->load_aps = + (p_nt4ga_stat->mp_stat_structs_flm->load_aps * 32ULL) / FLM_LOAD_WINDOWS_SIZE; + p_nt4ga_stat->mp_stat_structs_flm->load_lps = + (p_nt4ga_stat->mp_stat_structs_flm->load_lps * 32ULL) / FLM_LOAD_WINDOWS_SIZE; return 0; } diff --git a/drivers/net/ntnic/include/hw_mod_backend.h b/drivers/net/ntnic/include/hw_mod_backend.h index 17d5755634..9cd9d92823 100644 --- a/drivers/net/ntnic/include/hw_mod_backend.h +++ b/drivers/net/ntnic/include/hw_mod_backend.h @@ -688,6 +688,9 @@ int hw_mod_flm_rcp_set_mask(struct flow_api_backend_s *be, enum hw_flm_e field, int hw_mod_flm_rcp_set(struct flow_api_backend_s *be, enum hw_flm_e field, int index, uint32_t value); +int hw_mod_flm_stat_update(struct flow_api_backend_s *be); +int hw_mod_flm_stat_get(struct flow_api_backend_s *be, enum hw_flm_e field, uint32_t *value); + int hw_mod_flm_lrn_data_set_flush(struct flow_api_backend_s *be, enum hw_flm_e field, const uint32_t *value, uint32_t records, uint32_t *handled_records, uint32_t *inf_word_cnt, diff --git a/drivers/net/ntnic/include/ntdrv_4ga.h b/drivers/net/ntnic/include/ntdrv_4ga.h index 38e4d0ca35..677aa7b6c8 100644 --- a/drivers/net/ntnic/include/ntdrv_4ga.h +++ b/drivers/net/ntnic/include/ntdrv_4ga.h @@ -17,6 +17,7 @@ typedef struct ntdrv_4ga_s { rte_thread_t flm_thread; pthread_mutex_t stat_lck; rte_thread_t stat_thread; + rte_thread_t port_event_thread; } ntdrv_4ga_t; #endif /* __NTDRV_4GA_H__ */ diff --git a/drivers/net/ntnic/meson.build b/drivers/net/ntnic/meson.build index e59ac5bdb3..c0b7729929 100644 --- a/drivers/net/ntnic/meson.build +++ b/drivers/net/ntnic/meson.build @@ -59,6 +59,7 @@ sources = files( 'nthw/flow_api/flow_id_table.c', 'nthw/flow_api/hw_mod/hw_mod_backend.c', 'nthw/flow_api/profile_inline/flm_lrn_queue.c', + 'nthw/flow_api/profile_inline/flm_evt_queue.c', 'nthw/flow_api/profile_inline/flow_api_profile_inline.c', 'nthw/flow_api/profile_inline/flow_api_hw_db_inline.c', 'nthw/flow_api/flow_backend/flow_backend.c', diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c index e953fc1a12..efe9a1a3b9 100644 --- a/drivers/net/ntnic/nthw/flow_api/flow_api.c +++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c @@ -1050,11 +1050,14 @@ int flow_nic_set_hasher_fields(struct flow_nic_dev *ndev, int hsh_idx, int flow_get_flm_stats(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size) { - (void)ndev; - (void)data; - (void)size; + const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops(); + + if (profile_inline_ops == NULL) + return -1; + + if (ndev->flow_profile == FLOW_ETH_DEV_PROFILE_INLINE) + return profile_inline_ops->flow_get_flm_stats_profile_inline(ndev, data, size); - NT_LOG_DBGX(DBG, FILTER, "Not implemented yet"); return -1; } diff --git a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c index f4c29b8bde..1845f74166 100644 --- a/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c +++ b/drivers/net/ntnic/nthw/flow_api/hw_mod/hw_mod_flm.c @@ -712,6 +712,148 @@ int hw_mod_flm_rcp_set(struct flow_api_backend_s *be, enum hw_flm_e field, int i return hw_mod_flm_rcp_mod(be, field, index, &value, 0); } +int hw_mod_flm_stat_update(struct flow_api_backend_s *be) +{ + return be->iface->flm_stat_update(be->be_dev, &be->flm); +} + +int hw_mod_flm_stat_get(struct flow_api_backend_s *be, enum hw_flm_e field, uint32_t *value) +{ + switch (_VER_) { + case 25: + switch (field) { + case HW_FLM_STAT_LRN_DONE: + *value = be->flm.v25.lrn_done->cnt; + break; + + case HW_FLM_STAT_LRN_IGNORE: + *value = be->flm.v25.lrn_ignore->cnt; + break; + + case HW_FLM_STAT_LRN_FAIL: + *value = be->flm.v25.lrn_fail->cnt; + break; + + case HW_FLM_STAT_UNL_DONE: + *value = be->flm.v25.unl_done->cnt; + break; + + case HW_FLM_STAT_UNL_IGNORE: + *value = be->flm.v25.unl_ignore->cnt; + break; + + case HW_FLM_STAT_REL_DONE: + *value = be->flm.v25.rel_done->cnt; + break; + + case HW_FLM_STAT_REL_IGNORE: + *value = be->flm.v25.rel_ignore->cnt; + break; + + case HW_FLM_STAT_PRB_DONE: + *value = be->flm.v25.prb_done->cnt; + break; + + case HW_FLM_STAT_PRB_IGNORE: + *value = be->flm.v25.prb_ignore->cnt; + break; + + case HW_FLM_STAT_AUL_DONE: + *value = be->flm.v25.aul_done->cnt; + break; + + case HW_FLM_STAT_AUL_IGNORE: + *value = be->flm.v25.aul_ignore->cnt; + break; + + case HW_FLM_STAT_AUL_FAIL: + *value = be->flm.v25.aul_fail->cnt; + break; + + case HW_FLM_STAT_TUL_DONE: + *value = be->flm.v25.tul_done->cnt; + break; + + case HW_FLM_STAT_FLOWS: + *value = be->flm.v25.flows->cnt; + break; + + case HW_FLM_LOAD_LPS: + *value = be->flm.v25.load_lps->lps; + break; + + case HW_FLM_LOAD_APS: + *value = be->flm.v25.load_aps->aps; + break; + + default: { + if (_VER_ < 18) + return UNSUP_FIELD; + + switch (field) { + case HW_FLM_STAT_STA_DONE: + *value = be->flm.v25.sta_done->cnt; + break; + + case HW_FLM_STAT_INF_DONE: + *value = be->flm.v25.inf_done->cnt; + break; + + case HW_FLM_STAT_INF_SKIP: + *value = be->flm.v25.inf_skip->cnt; + break; + + case HW_FLM_STAT_PCK_HIT: + *value = be->flm.v25.pck_hit->cnt; + break; + + case HW_FLM_STAT_PCK_MISS: + *value = be->flm.v25.pck_miss->cnt; + break; + + case HW_FLM_STAT_PCK_UNH: + *value = be->flm.v25.pck_unh->cnt; + break; + + case HW_FLM_STAT_PCK_DIS: + *value = be->flm.v25.pck_dis->cnt; + break; + + case HW_FLM_STAT_CSH_HIT: + *value = be->flm.v25.csh_hit->cnt; + break; + + case HW_FLM_STAT_CSH_MISS: + *value = be->flm.v25.csh_miss->cnt; + break; + + case HW_FLM_STAT_CSH_UNH: + *value = be->flm.v25.csh_unh->cnt; + break; + + case HW_FLM_STAT_CUC_START: + *value = be->flm.v25.cuc_start->cnt; + break; + + case HW_FLM_STAT_CUC_MOVE: + *value = be->flm.v25.cuc_move->cnt; + break; + + default: + return UNSUP_FIELD; + } + } + break; + } + + break; + + default: + return UNSUP_VER; + } + + return 0; +} int hw_mod_flm_lrn_data_set_flush(struct flow_api_backend_s *be, enum hw_flm_e field, const uint32_t *value, uint32_t records, diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_evt_queue.c b/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_evt_queue.c new file mode 100644 index 0000000000..98b0e8347a --- /dev/null +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_evt_queue.c @@ -0,0 +1,176 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2024 Napatech A/S + */ + +#include +#include +#include + +#include +#include + +#include "ntlog.h" +#include "flm_evt_queue.h" + +/* Local queues for flm statistic events */ +static struct rte_ring *info_q_local[MAX_INFO_LCL_QUEUES]; + +/* Remote queues for flm statistic events */ +static struct rte_ring *info_q_remote[MAX_INFO_RMT_QUEUES]; + +/* Local queues for flm status records */ +static struct rte_ring *stat_q_local[MAX_STAT_LCL_QUEUES]; + +/* Remote queues for flm status records */ +static struct rte_ring *stat_q_remote[MAX_STAT_RMT_QUEUES]; + + +static struct rte_ring *flm_evt_queue_create(uint8_t port, uint8_t caller) +{ + static_assert((FLM_EVT_ELEM_SIZE & ~(size_t)3) == FLM_EVT_ELEM_SIZE, + "FLM EVENT struct size"); + static_assert((FLM_STAT_ELEM_SIZE & ~(size_t)3) == FLM_STAT_ELEM_SIZE, + "FLM STAT struct size"); + char name[20] = "NONE"; + struct rte_ring *q; + uint32_t elem_size = 0; + uint32_t queue_size = 0; + + switch (caller) { + case FLM_INFO_LOCAL: + if (port >= MAX_INFO_LCL_QUEUES) { + NT_LOG(WRN, + FILTER, + "FLM statistic event queue cannot be created for port %u. Max supported port is %u", + port, + MAX_INFO_LCL_QUEUES - 1); + return NULL; + } + + snprintf(name, 20, "LOCAL_INFO%u", port); + elem_size = FLM_EVT_ELEM_SIZE; + queue_size = FLM_EVT_QUEUE_SIZE; + break; + + case FLM_INFO_REMOTE: + if (port >= MAX_INFO_RMT_QUEUES) { + NT_LOG(WRN, + FILTER, + "FLM statistic event queue cannot be created for vport %u. Max supported vport is %u", + port, + MAX_INFO_RMT_QUEUES - 1); + return NULL; + } + + snprintf(name, 20, "REMOTE_INFO%u", port); + elem_size = FLM_EVT_ELEM_SIZE; + queue_size = FLM_EVT_QUEUE_SIZE; + break; + + case FLM_STAT_LOCAL: + if (port >= MAX_STAT_LCL_QUEUES) { + NT_LOG(WRN, + FILTER, + "FLM status queue cannot be created for port %u. Max supported port is %u", + port, + MAX_STAT_LCL_QUEUES - 1); + return NULL; + } + + snprintf(name, 20, "LOCAL_STAT%u", port); + elem_size = FLM_STAT_ELEM_SIZE; + queue_size = FLM_STAT_QUEUE_SIZE; + break; + + case FLM_STAT_REMOTE: + if (port >= MAX_STAT_RMT_QUEUES) { + NT_LOG(WRN, + FILTER, + "FLM status queue cannot be created for vport %u. Max supported vport is %u", + port, + MAX_STAT_RMT_QUEUES - 1); + return NULL; + } + + snprintf(name, 20, "REMOTE_STAT%u", port); + elem_size = FLM_STAT_ELEM_SIZE; + queue_size = FLM_STAT_QUEUE_SIZE; + break; + + default: + NT_LOG(ERR, FILTER, "FLM queue create illegal caller: %u", caller); + return NULL; + } + + q = rte_ring_create_elem(name, + elem_size, + queue_size, + SOCKET_ID_ANY, + RING_F_SP_ENQ | RING_F_SC_DEQ); + + if (q == NULL) { + NT_LOG(WRN, FILTER, "FLM queues cannot be created due to error %02X", rte_errno); + return NULL; + } + + switch (caller) { + case FLM_INFO_LOCAL: + info_q_local[port] = q; + break; + + case FLM_INFO_REMOTE: + info_q_remote[port] = q; + break; + + case FLM_STAT_LOCAL: + stat_q_local[port] = q; + break; + + case FLM_STAT_REMOTE: + stat_q_remote[port] = q; + break; + + default: + break; + } + + return q; +} + +int flm_inf_queue_get(uint8_t port, bool remote, struct flm_info_event_s *obj) +{ + int ret; + + /* If queues is not created, then ignore and return */ + if (!remote) { + if (port < MAX_INFO_LCL_QUEUES) { + if (info_q_local[port] != NULL) { + ret = rte_ring_sc_dequeue_elem(info_q_local[port], + obj, + FLM_EVT_ELEM_SIZE); + return ret; + } + + if (flm_evt_queue_create(port, FLM_INFO_LOCAL) != NULL) { + /* Recursive call to get data */ + return flm_inf_queue_get(port, remote, obj); + } + } + + } else if (port < MAX_INFO_RMT_QUEUES) { + if (info_q_remote[port] != NULL) { + ret = rte_ring_sc_dequeue_elem(info_q_remote[port], + obj, + FLM_EVT_ELEM_SIZE); + return ret; + } + + if (flm_evt_queue_create(port, FLM_INFO_REMOTE) != NULL) { + /* Recursive call to get data */ + return flm_inf_queue_get(port, remote, obj); + } + } + + return -ENOENT; +} diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_evt_queue.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_evt_queue.h new file mode 100644 index 0000000000..238be7a3b2 --- /dev/null +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flm_evt_queue.h @@ -0,0 +1,52 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2024 Napatech A/S + */ + +#ifndef _FLM_EVT_QUEUE_H_ +#define _FLM_EVT_QUEUE_H_ + +#include "stdint.h" +#include "stdbool.h" + +struct flm_status_event_s { + void *flow; + uint32_t learn_ignore : 1; + uint32_t learn_failed : 1; + uint32_t learn_done : 1; +}; + +struct flm_info_event_s { + uint64_t bytes; + uint64_t packets; + uint64_t timestamp; + uint64_t id; + uint8_t cause; +}; + +enum { + FLM_INFO_LOCAL, + FLM_INFO_REMOTE, + FLM_STAT_LOCAL, + FLM_STAT_REMOTE, +}; + +/* Max number of local queues */ +#define MAX_INFO_LCL_QUEUES 8 +#define MAX_STAT_LCL_QUEUES 8 + +/* Max number of remote queues */ +#define MAX_INFO_RMT_QUEUES 128 +#define MAX_STAT_RMT_QUEUES 128 + +/* queue size */ +#define FLM_EVT_QUEUE_SIZE 8192 +#define FLM_STAT_QUEUE_SIZE 8192 + +/* Event element size */ +#define FLM_EVT_ELEM_SIZE sizeof(struct flm_info_event_s) +#define FLM_STAT_ELEM_SIZE sizeof(struct flm_status_event_s) + +int flm_inf_queue_get(uint8_t port, bool remote, struct flm_info_event_s *obj); + +#endif /* _FLM_EVT_QUEUE_H_ */ 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 bbf450697c..a1cba7f4c7 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 @@ -4467,6 +4467,48 @@ int flow_dev_dump_profile_inline(struct flow_eth_dev *dev, return 0; } +int flow_get_flm_stats_profile_inline(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size) +{ + const enum hw_flm_e fields[] = { + HW_FLM_STAT_FLOWS, HW_FLM_STAT_LRN_DONE, HW_FLM_STAT_LRN_IGNORE, + HW_FLM_STAT_LRN_FAIL, HW_FLM_STAT_UNL_DONE, HW_FLM_STAT_UNL_IGNORE, + HW_FLM_STAT_AUL_DONE, HW_FLM_STAT_AUL_IGNORE, HW_FLM_STAT_AUL_FAIL, + HW_FLM_STAT_TUL_DONE, HW_FLM_STAT_REL_DONE, HW_FLM_STAT_REL_IGNORE, + HW_FLM_STAT_PRB_DONE, HW_FLM_STAT_PRB_IGNORE, + + HW_FLM_STAT_STA_DONE, HW_FLM_STAT_INF_DONE, HW_FLM_STAT_INF_SKIP, + HW_FLM_STAT_PCK_HIT, HW_FLM_STAT_PCK_MISS, HW_FLM_STAT_PCK_UNH, + HW_FLM_STAT_PCK_DIS, HW_FLM_STAT_CSH_HIT, HW_FLM_STAT_CSH_MISS, + HW_FLM_STAT_CSH_UNH, HW_FLM_STAT_CUC_START, HW_FLM_STAT_CUC_MOVE, + + HW_FLM_LOAD_LPS, HW_FLM_LOAD_APS, + }; + + const uint64_t fields_cnt = sizeof(fields) / sizeof(enum hw_flm_e); + + if (!ndev->flow_mgnt_prepared) + return 0; + + if (size < fields_cnt) + return -1; + + hw_mod_flm_stat_update(&ndev->be); + + for (uint64_t i = 0; i < fields_cnt; ++i) { + uint32_t value = 0; + hw_mod_flm_stat_get(&ndev->be, fields[i], &value); + data[i] = (fields[i] == HW_FLM_STAT_FLOWS || fields[i] == HW_FLM_LOAD_LPS || + fields[i] == HW_FLM_LOAD_APS) + ? value + : data[i] + value; + + if (ndev->be.flm.ver < 18 && fields[i] == HW_FLM_STAT_PRB_IGNORE) + break; + } + + return 0; +} + static const struct profile_inline_ops ops = { /* * Management @@ -4483,6 +4525,10 @@ static const struct profile_inline_ops ops = { .flow_destroy_profile_inline = flow_destroy_profile_inline, .flow_flush_profile_inline = flow_flush_profile_inline, .flow_nic_set_hasher_fields_inline = flow_nic_set_hasher_fields_inline, + /* + * Stats + */ + .flow_get_flm_stats_profile_inline = flow_get_flm_stats_profile_inline, /* * NT Flow FLM Meter API */ diff --git a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h index c695842077..b44d3a7291 100644 --- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h +++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.h @@ -52,4 +52,10 @@ int flow_nic_set_hasher_fields_inline(struct flow_nic_dev *ndev, int hsh_idx, struct nt_eth_rss_conf rss_conf); +/* + * Stats + */ + +int flow_get_flm_stats_profile_inline(struct flow_nic_dev *ndev, uint64_t *data, uint64_t size); + #endif /* _FLOW_API_PROFILE_INLINE_H_ */ diff --git a/drivers/net/ntnic/nthw/rte_pmd_ntnic.h b/drivers/net/ntnic/nthw/rte_pmd_ntnic.h new file mode 100644 index 0000000000..4a1ba18a5e --- /dev/null +++ b/drivers/net/ntnic/nthw/rte_pmd_ntnic.h @@ -0,0 +1,43 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2023 Napatech A/S + */ + +#ifndef NTNIC_EVENT_H_ +#define NTNIC_EVENT_H_ + +#include + +typedef struct ntnic_flm_load_s { + uint64_t lookup; + uint64_t lookup_maximum; + uint64_t access; + uint64_t access_maximum; +} ntnic_flm_load_t; + +typedef struct ntnic_port_load_s { + uint64_t rx_pps; + uint64_t rx_pps_maximum; + uint64_t tx_pps; + uint64_t tx_pps_maximum; + uint64_t rx_bps; + uint64_t rx_bps_maximum; + uint64_t tx_bps; + uint64_t tx_bps_maximum; +} ntnic_port_load_t; + +struct ntnic_flm_statistic_s { + uint64_t bytes; + uint64_t packets; + uint64_t timestamp; + uint64_t id; + uint8_t cause; +}; + +enum rte_ntnic_event_type { + RTE_NTNIC_FLM_LOAD_EVENT = RTE_ETH_EVENT_MAX, + RTE_NTNIC_PORT_LOAD_EVENT, + RTE_NTNIC_FLM_STATS_EVENT, +}; + +#endif /* NTNIC_EVENT_H_ */ diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c index f6a74c7df2..9c286a4f35 100644 --- a/drivers/net/ntnic/ntnic_ethdev.c +++ b/drivers/net/ntnic/ntnic_ethdev.c @@ -26,6 +26,8 @@ #include "ntnic_vfio.h" #include "ntnic_mod_reg.h" #include "nt_util.h" +#include "profile_inline/flm_evt_queue.h" +#include "rte_pmd_ntnic.h" const rte_thread_attr_t thread_attr = { .priority = RTE_THREAD_PRIORITY_NORMAL }; #define THREAD_CREATE(a, b, c) rte_thread_create(a, &thread_attr, b, c) @@ -1419,6 +1421,7 @@ drv_deinit(struct drv_s *p_drv) if (fpga_info->profile == FPGA_INFO_PROFILE_INLINE) { THREAD_JOIN(p_nt_drv->flm_thread); profile_inline_ops->flm_free_queues(); + THREAD_JOIN(p_nt_drv->port_event_thread); } /* stop adapter */ @@ -1711,6 +1714,123 @@ static const struct eth_dev_ops nthw_eth_dev_ops = { .rss_hash_conf_get = rss_hash_conf_get, }; +/* + * Port event thread + */ +THREAD_FUNC port_event_thread_fn(void *context) +{ + struct pmd_internals *internals = (struct pmd_internals *)context; + struct drv_s *p_drv = internals->p_drv; + ntdrv_4ga_t *p_nt_drv = &p_drv->ntdrv; + struct adapter_info_s *p_adapter_info = &p_nt_drv->adapter_info; + struct flow_nic_dev *ndev = p_adapter_info->nt4ga_filter.mp_flow_device; + + nt4ga_stat_t *p_nt4ga_stat = &p_nt_drv->adapter_info.nt4ga_stat; + struct rte_eth_dev *eth_dev = &rte_eth_devices[internals->port_id]; + uint8_t port_no = internals->port; + + ntnic_flm_load_t flmdata; + ntnic_port_load_t portdata; + + memset(&flmdata, 0, sizeof(flmdata)); + memset(&portdata, 0, sizeof(portdata)); + + while (ndev != NULL && ndev->eth_base == NULL) + nt_os_wait_usec(1 * 1000 * 1000); + + while (!p_drv->ntdrv.b_shutdown) { + /* + * FLM load measurement + * Do only send event, if there has been a change + */ + if (p_nt4ga_stat->flm_stat_ver > 22 && p_nt4ga_stat->mp_stat_structs_flm) { + if (flmdata.lookup != p_nt4ga_stat->mp_stat_structs_flm->load_lps || + flmdata.access != p_nt4ga_stat->mp_stat_structs_flm->load_aps) { + pthread_mutex_lock(&p_nt_drv->stat_lck); + flmdata.lookup = p_nt4ga_stat->mp_stat_structs_flm->load_lps; + flmdata.access = p_nt4ga_stat->mp_stat_structs_flm->load_aps; + flmdata.lookup_maximum = + p_nt4ga_stat->mp_stat_structs_flm->max_lps; + flmdata.access_maximum = + p_nt4ga_stat->mp_stat_structs_flm->max_aps; + pthread_mutex_unlock(&p_nt_drv->stat_lck); + + if (eth_dev && eth_dev->data && eth_dev->data->dev_private) { + rte_eth_dev_callback_process(eth_dev, + (enum rte_eth_event_type)RTE_NTNIC_FLM_LOAD_EVENT, + &flmdata); + } + } + } + + /* + * Port load measurement + * Do only send event, if there has been a change. + */ + if (p_nt4ga_stat->mp_port_load) { + if (portdata.rx_bps != p_nt4ga_stat->mp_port_load[port_no].rx_bps || + portdata.tx_bps != p_nt4ga_stat->mp_port_load[port_no].tx_bps) { + pthread_mutex_lock(&p_nt_drv->stat_lck); + portdata.rx_bps = p_nt4ga_stat->mp_port_load[port_no].rx_bps; + portdata.tx_bps = p_nt4ga_stat->mp_port_load[port_no].tx_bps; + portdata.rx_pps = p_nt4ga_stat->mp_port_load[port_no].rx_pps; + portdata.tx_pps = p_nt4ga_stat->mp_port_load[port_no].tx_pps; + portdata.rx_pps_maximum = + p_nt4ga_stat->mp_port_load[port_no].rx_pps_max; + portdata.tx_pps_maximum = + p_nt4ga_stat->mp_port_load[port_no].tx_pps_max; + portdata.rx_bps_maximum = + p_nt4ga_stat->mp_port_load[port_no].rx_bps_max; + portdata.tx_bps_maximum = + p_nt4ga_stat->mp_port_load[port_no].tx_bps_max; + pthread_mutex_unlock(&p_nt_drv->stat_lck); + + if (eth_dev && eth_dev->data && eth_dev->data->dev_private) { + rte_eth_dev_callback_process(eth_dev, + (enum rte_eth_event_type)RTE_NTNIC_PORT_LOAD_EVENT, + &portdata); + } + } + } + + /* Process events */ + { + int count = 0; + bool do_wait = true; + + while (count < 5000) { + /* Local FLM statistic events */ + struct flm_info_event_s data; + + if (flm_inf_queue_get(port_no, FLM_INFO_LOCAL, &data) == 0) { + if (eth_dev && eth_dev->data && + eth_dev->data->dev_private) { + struct ntnic_flm_statistic_s event_data; + event_data.bytes = data.bytes; + event_data.packets = data.packets; + event_data.cause = data.cause; + event_data.id = data.id; + event_data.timestamp = data.timestamp; + rte_eth_dev_callback_process(eth_dev, + (enum rte_eth_event_type) + RTE_NTNIC_FLM_STATS_EVENT, + &event_data); + do_wait = false; + } + } + + if (do_wait) + nt_os_wait_usec(10); + + count++; + do_wait = true; + } + } + } + + return THREAD_RETURN; +} + /* * Adapter flm stat thread */ @@ -2237,6 +2357,18 @@ nthw_pci_dev_init(struct rte_pci_device *pci_dev) /* increase initialized ethernet devices - PF */ p_drv->n_eth_dev_init_count++; + + /* Port event thread */ + if (fpga_info->profile == FPGA_INFO_PROFILE_INLINE) { + res = THREAD_CTRL_CREATE(&p_nt_drv->port_event_thread, "nt_port_event_thr", + port_event_thread_fn, (void *)internals); + + if (res) { + NT_LOG(ERR, NTNIC, "%s: error=%d", + (pci_dev->name[0] ? pci_dev->name : "NA"), res); + return -1; + } + } } return 0; diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h index 65e7972c68..7325bd1ea8 100644 --- a/drivers/net/ntnic/ntnic_mod_reg.h +++ b/drivers/net/ntnic/ntnic_mod_reg.h @@ -290,6 +290,13 @@ struct profile_inline_ops { int hsh_idx, struct nt_eth_rss_conf rss_conf); + /* + * Stats + */ + int (*flow_get_flm_stats_profile_inline)(struct flow_nic_dev *ndev, + uint64_t *data, + uint64_t size); + /* * NT Flow FLM queue API */ -- 2.45.0