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 A3FD245BA3; Tue, 22 Oct 2024 19:30:27 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 04B264069F; Tue, 22 Oct 2024 19:30:17 +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 5CED740A7D for ; Tue, 22 Oct 2024 19:30:13 +0200 (CEST) Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05lp2106.outbound.protection.outlook.com [104.47.18.106]) 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 17:30:11 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=BVU6k1dFrsH59scBGcxzh1UsRZcgjt44VHIShKjC8QinBg0QoJbkzJN8nOuHXl5K3Un+t2bML9gipX9NFXcOgICii0jM7O3yAMg88hH+YxZnvsNyH2nimsXvnDtJmOJj1p7VktghCC+Wt+30aSblmTKLT0ofC8b3rLkF+ZCHloX4hwy8C1I4hY+fEIAo+za7BS+ghM8mmtWzlD26szKJwlPkPvE2GtGMq08dKyrkbCD6dmd/RJiVnJPp/DQjtCd1MB6N1H1HItDV2ECryxXGqcq7AZxhUzQclaehnyI4ujRViimIG1mhf8jSynTC5fd2uBW9kfkl9K3eZew5K95Fpw== 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=Cz5eIdyVA0Vv4t3DY29YxmRYwQKmZ4Pcd8tMqbHqp4Kyplc50TAVrwOxDWD5Dt9QmAvD7Yo94kP2gPqHa1Oio0Td4rG5sUTxY3d2TIKNSaeTFeJkp8qdRyzREF7EYY2uu2joWCczzutyunFGlWeqlwmayPjPDJBdEMT/n/CuIFovWT+8RXtNK3V5HSiW4EXiNFUKOVhYZDsr0qHE6UglS6D9GJXAoeFh+3Yab/6TsWQGzd7wkxrDITbfno52K34iJbdTbLxF1z2UAxyiTtYykUwbx9ZoikRhMxzIysJIBa8OMArUe78XkPwqsB7szzIBgctJGGRdMgnJGcu+r6dY0w== 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=XleaOoY7LpVu167nDtL1/IQIpNKd7hrb7NA5Rorx1sAYHVZQRFkPUvMI8uyaaT9vt31yV88II0ZEXCzbHhxuVXxobaRDIJaOhljwyF8fGgehfJb1Iyc6xWnJLpcXanInAOycaRRvPt1J4e0MJyVILX1d849/Btj/KQIXLVHEwBw= Received: from DB9PR06CA0014.eurprd06.prod.outlook.com (2603:10a6:10:1db::19) by AM8P190MB0995.EURP190.PROD.OUTLOOK.COM (2603:10a6:20b:1dc::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8093.16; Tue, 22 Oct 2024 16:57:11 +0000 Received: from DU2PEPF0001E9C2.eurprd03.prod.outlook.com (2603:10a6:10:1db:cafe::38) by DB9PR06CA0014.outlook.office365.com (2603:10a6:10:1db::19) 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:57:11 +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:57:11 +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 62/73] net/ntnic: added flow statistics Date: Tue, 22 Oct 2024 18:55:19 +0200 Message-ID: <20241022165541.3186140-63-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_|AM8P190MB0995:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 5d3a20af-77e0-49d8-14f3-08dcf2ba9276 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|1800799024|82310400026|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?3uMOsvahG5lL395FC40oDvnyxKfVeRIF/zqpVavHiia2rATn4oImlVIZNPd3?= =?us-ascii?Q?wSJn+n/bzkHztl7ayzreoGUss6aZ5AueWi2xu6YkUexm64olWeHlHrWuTmIp?= =?us-ascii?Q?YdFuigju2DeH6nxXNrKBkTCOcl5dZVWQYne7lbEnNtqO14c2W+XQXwpZAcMq?= =?us-ascii?Q?0e1/zafbE85y25DA0dBiH/2Lm2in/IfyIp13OqNkO85XSAX9QQvYsLRIp3mT?= =?us-ascii?Q?wluXG8lZYk7kEQL7E8slTjhbvLS+EB45oLQqcYRchMwoFYZ7VN8lOvu5xH6A?= =?us-ascii?Q?NzhRKngxXH1XMoHa1a4EtnYYCHgDwDNt6Db/1r9Hugi2dz+dMfkHIWds6z0L?= =?us-ascii?Q?9vVYnLn0oO4W5L3g1bf4AeYGvG2/htBefH9R2Oq/zfacVxSB/GFd1ETl7yi5?= =?us-ascii?Q?EjbEN8xWuVNsuJLu40DE+0pW/4qEftZmNIJRkBiTnWLBYH1Rj+hgXrUGYDKe?= =?us-ascii?Q?xH+OLYPF0cxQ2orsI5LAb/5MzDUZYn85uSvnEPwQV9/R6BsjCKVA99qvAUQ9?= =?us-ascii?Q?zAzdIumxaZNNGLaV1evqiod/CQ87CxOjPWxSRrki3sJcGmrgbKTL2VgXSyiQ?= =?us-ascii?Q?0ltWcvDsK3uR7Ppy/Kwl00igiJ0SFyMR/XfvFgRZWUkNKOdHRduW2Pdr9nec?= =?us-ascii?Q?e6Cn/YvAoCfxVLSK2dWnYAk+i4SkibJVvEWvtkgEG6KnaW+Rx/g17Aqm/ZII?= =?us-ascii?Q?01XiplNtUce3KpbVX0JtbVb6v33k9cTShs9J0wVbyPpasVacUSah0mi5SeF0?= =?us-ascii?Q?0Q1vVM+fQUhjWcFzaz1IbAiRVs6UJZbt996L8zp+gxmZAJyT9EGosfCh1TBR?= =?us-ascii?Q?MCnyGU4+la+y4MzciuKlZcPW3U67Il2EeByS3NwpRVu8asv6InYUALDVJmQu?= =?us-ascii?Q?hTpn/92HSljZyW7gSryTOhdsuJxlLINPx4nWzNz7RToqu7yoZi9x4iKsqAob?= =?us-ascii?Q?l9Soarq41g0I/zmsGSS8S3b39dSbnXOjk9leO0gTxH446RelgeyEG9Qo87ms?= =?us-ascii?Q?qe7Y5ng2k0KRzAsmHRo3bpAiIYAQTsgdoCUxUf8WNy5OBT/dEXTCZACAVuS5?= =?us-ascii?Q?mb9Gj4r85MSz/KEn0z61zzrE4ISe9P6re8tQ32EgcidFrUZi2dQSwEBeIsoL?= =?us-ascii?Q?fg90OwILKoTxhZgUhuxhkIn3Vjlm5AU0L5GeUtkqyiTinUh8IVRhKtz/5irO?= =?us-ascii?Q?2S3HSu6Us9is0Bj6xfVUYuxNn37R3gaB2b4tLhGBIJeeARiy5NDTXm4sXRht?= =?us-ascii?Q?cqIJsBWj5xn1kCx0n0qyd3em2LSXqA0bOUde4hCFkVUuymB6MG6sdV9W8z6o?= =?us-ascii?Q?onbENhZHLcgad/usvLv+SB75ah9s2wmVjNf2L4IWz85LQIldyrTnITqReCnH?= =?us-ascii?Q?sm8hbG9Dw+sF1yd4uWA26HQa5auxSPS5D1aOhjs/PZN5yGHFAQ=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)(1800799024)(82310400026)(36860700013); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: 4fBmOzHYLcf9NSiXboleK2ux7GQGZ4WkrLuDo04PfWvEgTk4IX+Mpm29g3XX0Nrp9KbpdFapy/X8u5qRrpfVkv5/S+iGnK9ZRYsQIhsUX7XDiq/+S1pPBAWb8lFXAdfQKDRvXIghxCJjXrVzTkv3CfCfnj4S2+7xCd3R2vZr5cMDHK3TskElcPPBX5TYs34ny5XTqokhlAEyZNxhq5EtcJOPtPmnKwhRrtGkLsGw8/fV8lb3fx/CPfJthbIj7OWm5Bu7HDRl8P1hEH2mtS8bgi3I94UT2YevBPS2Fu7c/Y//Z7xDR/QLpnwUXGaxfNnqI7gN332KVOOxGwL2VN3LSQYflRpRMfnjpaGpNPVj7FT6xhNDw3eMeIFRUkTGhX5GxBx21Knb6me48LJUtFZu3RehY8fdK+AWLAE9Qe1jWiPh1Xg+baTk7AYvKdDj8oZlQvgNijtO6tJXXLxnV97Jbua6UmvDTjohlvF7asLUAU74P0jWNQgZ8rCpFyrO8shd3hAoi1xbTHHmJIk3xhqM8GxuCQKKtVpR4bL/+/rgK1HynrDB7iLPaXhoe8p6ck8EGlgmMe8L2x++LdwausSkKUY/MwpB9WmKS1BA7+CkYkbX3gdd5Q7NsfeONIVV7F7a6B7m7WtpTHwSxLu/7bJPfSdDDBA+lzdnqDZ31YZE0UU= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Oct 2024 16:57:11.1226 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5d3a20af-77e0-49d8-14f3-08dcf2ba9276 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: AM8P190MB0995 X-OriginatorOrg: napatech.com X-BESS-ID: 1729618211-304983-12652-15996-1 X-BESS-VER: 2019.1_20241018.1852 X-BESS-Apparent-Source-IP: 104.47.18.106 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.259902 [from cloudscan12-62.eu-central-1a.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