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 1196345BC0; Tue, 29 Oct 2024 18:18:37 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 39D6442FB9; Tue, 29 Oct 2024 18:17:20 +0100 (CET) Received: from egress-ip42b.ess.de.barracuda.com (egress-ip42b.ess.de.barracuda.com [18.185.115.246]) by mails.dpdk.org (Postfix) with ESMTP id 1AD3E4327A for ; Tue, 29 Oct 2024 18:17:10 +0100 (CET) Received: from EUR05-VI1-obe.outbound.protection.outlook.com (mail-vi1eur05lp2170.outbound.protection.outlook.com [104.47.17.170]) by mx-outbound43-199.eu-central-1c.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 29 Oct 2024 17:17:06 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=SoD0RlRnzT3/fMeJpQFSJczWLYPi67FAv1+JWblpyD7LnrWbRYz77GEmu9pgP7vC6AxrB06lustK7i9/Z13rFjBLrlbgGvrsH02mZX3RQtKljdWBXsnnOa2I17UVAMA6Wii0l8QKNHQj/PL5kZyD5tcniOacwdAc9y2i/QcohwwwDhqqMNtTwIkX4mYyvQvLzqRRVPjdlQ7dHDzObJeGSSf4+cYG89a1/yHW/ZZaeA7KrbTrL1E5sbqbhsn+NGj7I4OJeYctfKKlACd/6xcbvyy0TJOMANe9xTvBRhAGWRZ34/lUgheWiA65QokNk7vF714dYMVjvFAfQEI2VHpwZA== 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=4UQd9MXDrH9OABT6LYlEkINAZqCexV0Z+NIyMXFV7KI=; b=KlMP7WSMJ+82v1zJU2KA7rWPVFuQn/kjJqz6fuOlntQTsJhOmyo4Yo85eCpKPt+sqTTSEVffBBLjUIFl0f5HNpL/Nj4ppwU1B7FD63P3ffAj9V2TPNPd0OFB4tbPc2EiJcEVCEOj0kWCXXQW6uMb+7i8palJu8zSCX3iWRUJF/in2t9WThPyl+HiI6fRdMcCA84i5sm/g0O43IiZ2YEwMzDdAwXzAuvci1VEcGoVngRSoJurMfAaT4Vapy9V/nGop1zZzfZ/4xMF415EO1V+KCNcSh3Tx3W9eO+QTHY5OAw+1A/ewEy0uQIT/1w8JXFNy1vSBFjSZL6VkH/X8n/P/A== 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=4UQd9MXDrH9OABT6LYlEkINAZqCexV0Z+NIyMXFV7KI=; b=aCaff8ogjdhw4rlTqlVrs5D4HtpA4puoktj3LAMHPHhwF1/fJWnvDhseSSLHfzzOn+XCDufvycm2F5t90mChz3WnTB1wtifH8vBx/9o8jXG91DqmrQJD3etEHQD8L64dP7oD7wSOkDpr5k/6xrsJRLW0QTSui2+UpriJiuEEDt8= Received: from DUZPR01CA0187.eurprd01.prod.exchangelabs.com (2603:10a6:10:4b6::17) by DB9P190MB1114.EURP190.PROD.OUTLOOK.COM (2603:10a6:10:22c::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8093.32; Tue, 29 Oct 2024 16:43:54 +0000 Received: from DU2PEPF00028D06.eurprd03.prod.outlook.com (2603:10a6:10:4b6:cafe::7) by DUZPR01CA0187.outlook.office365.com (2603:10a6:10:4b6::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8114.17 via Frontend Transport; Tue, 29 Oct 2024 16:43:53 +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 DU2PEPF00028D06.mail.protection.outlook.com (10.167.242.166) with Microsoft SMTP Server id 15.20.8114.16 via Frontend Transport; Tue, 29 Oct 2024 16:43:53 +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 v4 62/86] net/ntnic: added flow statistics Date: Tue, 29 Oct 2024 17:42:06 +0100 Message-ID: <20241029164243.1648775-63-sil-plv@napatech.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241029164243.1648775-1-sil-plv@napatech.com> References: <20241021210527.2075431-1-sil-plv@napatech.com> <20241029164243.1648775-1-sil-plv@napatech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU2PEPF00028D06:EE_|DB9P190MB1114:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: f24ca985-7a73-4042-3f52-08dcf838e001 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|82310400026|376014|36860700013; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?byvufOfSnK/HklrUh29cnTnezh+W8CHu2jyAsTj/617Mv0kHLxrhgcjM5JPP?= =?us-ascii?Q?zCRNA2jI8cxU27uhxEbaSDUTmw67qpQVKeWpJ2fIdFDJZWRfYb3NOLKjABKE?= =?us-ascii?Q?VIVJg3MhApWcaU424PvOUg15n45nr1r5wbaPqlL6u1FpQzq9p6j3eQUlFIe2?= =?us-ascii?Q?MlHvcxA8k/u2zQW0uPpuJ8sPlPcHo+w5LBruqF/MDwm9XeflKK6DlPquHB9F?= =?us-ascii?Q?3XfeGp+6Y2S9E8W1XX5XxvxFjzjKAp09lHZiUxDCP/uSMR1xhy8YQAIAPSw/?= =?us-ascii?Q?JI52kPi8eDuwdKYyjmC8vtgxMjz4a5F03fHRhPJnQx9BzGYkZPBUPdTs2c2a?= =?us-ascii?Q?P0//ohFwkUFn0pA8PG/TIM+ZUIm592YqvdhTTsolcdJ8cMeiElTZOkvyB+fO?= =?us-ascii?Q?mA570Tcq2iwbQAi2qRSzBRebgZVG4/8CQH8qTHOvsiMrr0BRLiZH7w8ArXEl?= =?us-ascii?Q?YQWYgCxqUUpOPQGGMqINSsyMX/qtS0pu+b1OUueUwVsBGg18OhWmBu3hCxas?= =?us-ascii?Q?KjA7/DReNuyR1etFRr4W4RCa5fWEk9mEA71gWdi7dTDND3f8D25HZ+qSNF2b?= =?us-ascii?Q?B/crQ2YaN0NUDIEbO0+dnZJWbxN1V1VsBHeIIBkXotGwRtf/HUBqjVVxH2h3?= =?us-ascii?Q?AZFmAm7BtCUapW61YQ1N/StJWquwgjV78egcjETr4wZ+veqyrGYiB4VrYx79?= =?us-ascii?Q?T8MGpV5aCAOW1rx9Tl0cXFEq2WmVE3zExNRTAdEDOblXLdBvrzSHNjmXbF5K?= =?us-ascii?Q?gGrYXlTbuh0MrV0j1lKccQTMY91I7LIkdZn5TaJHB+CkwxI8N4QJiqJfJce8?= =?us-ascii?Q?stfAhx9RZUPDdhz3xrY9A8upVkZ/qETqm3NrIGQXuL2edRv2RvsEhKnB4Kut?= =?us-ascii?Q?Mtgck0yMOZljWWHwv/5FLUCmB5kKdC2Wubt/aQYfyzp4Q3BYZ1dqv4nWx9zI?= =?us-ascii?Q?auNpnmbupAiWJ82ZqVjcqsKkLrO52GhOiUxq+/JqOa8/ZWqqSnYcQxRAqFmN?= =?us-ascii?Q?EljttCKzpA/+7tXe4bzawCQ2yvPsT3YmxszOe0t1l0zucF3CEvi/HeHQswtt?= =?us-ascii?Q?GQlz5Eef6XHZgie7G6PLPHquDJtchVIq3QeBA4alCKWSLyr1uK9FNn2TNV0G?= =?us-ascii?Q?tWOT3HOhLznTn1Y8rgUIvmRaT/zDJpkPd7xJx0fx22+j7rGWIBAv9rCxUcQX?= =?us-ascii?Q?c+pYUbvg1vL/LiBdhV+cgmWgM/xYSoJkjKzbVEdssaB1L/srphawudxm0FGU?= =?us-ascii?Q?R3ybmc29tE1bXcLwniSuH6A84xrBOlBKk1vbS+rt6mIXuQsbls5dPf9awunp?= =?us-ascii?Q?E91bJ9EkKh5NJxZt9mrIA4pJs5/3uMWfXNKTng9yI2pfeLFGVg+OoMWJJVKy?= =?us-ascii?Q?V+CObMWQoiB3Wv7kG+EIXu9BjPn7XF56PCS2sboqlDWUJjI4+w=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)(82310400026)(376014)(36860700013); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: 7NsuIrU7RtZhb9I8B2Ji8QuiEBgk9nkN5KpYux/+iFEMkLww1gheTAxnqKpVNVL7mnNzce1S7WapY6hhp4H+/XNtvs74H4CTghF5zvcfaMKwwqoRzmEZ+eYRCd9tfq+ynX1BEgPIDyr6OReK4hIXNAyhZIldsLCpv/0K8IcGOmMl9fiCFDWhhrhoI9CWxF9BVN0WmCXuwNujZZ0wzyYyireICeKw39EKEa/EkHHAdNIFlRom3nVn05l74x3Dcrej01uWFHJ8Mh2hRtad3DhGdwOiUn96sgbv0p5lLX4PNwtgPelyGW8zKfRzrKTlg49xFtrx/1VgAqJ++NTZJ0WBrkx2jO+OsDbuA+YIGm/fXd74HprxuVkruMh1rn0i4ggF0m5kOdd/FJ1d0Pj3SiDKSNl0JMRqjN17Oa02vdvJ7O+JBhW6S1f0fGD+qqJpVEztYxupfOiHGS4XlqT665bMOucwoonbRl8La3zRlYBZVxHwC2n/IESaTj3nzaRI7a1AaH88mHh6c+1IkSKw7rTGclZy0HT7fuHvHsXFgeNa8r4glgBpp6dyYaeGgHGUwh1nFEnPoifdGqO2fTeNhlpMPhRtH24qmXMuCPtJuXY7PjBz8eB3DN+LVLEaAR6n8aVRd2nAtbxEgqPttBxMw48bpoSBnDdipUk9kjRwpa9Nz10= X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Oct 2024 16:43:53.6834 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f24ca985-7a73-4042-3f52-08dcf838e001 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: DU2PEPF00028D06.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9P190MB1114 X-OriginatorOrg: napatech.com X-BESS-ID: 1730222226-311207-12661-29628-1 X-BESS-VER: 2019.1_20241018.1852 X-BESS-Apparent-Source-IP: 104.47.17.170 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVkampqbmQGYGUNTSPMUi1TTVPN koLdE80dDAzCg5zSTR1NwsMcXCwDQlSak2FgDfS7WZQgAAAA== X-BESS-Outbound-Spam-Score: 0.50 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.260064 [from cloudscan14-53.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 73e3c05f56..9ad165bb4e 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 @@ -4466,6 +4466,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 @@ -4482,6 +4524,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 5635bd3b42..4a0dafeff0 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 */ @@ -1709,6 +1712,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 */ @@ -2235,6 +2355,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