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 E9EE545BCC; Wed, 30 Oct 2024 22:40:10 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 248F24339E; Wed, 30 Oct 2024 22:40:04 +0100 (CET) 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 E68AA43270 for ; Wed, 30 Oct 2024 22:40:00 +0100 (CET) Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05lp2107.outbound.protection.outlook.com [104.47.17.107]) by mx-outbound47-144.eu-central-1c.ess.aws.cudaops.com (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 30 Oct 2024 21:39:57 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=TkOfB2rMaOFJE/EKQMOjBc4c0ea811cdatfWPkU1t/wYZl/pp/wmQ4eqalrM421O1jpxWt9Yszn5rvAUyoewsnUAvdRvh1Y0DAm0M/DY1Af2m7icDlsXGo9GksiloiNOnDTRJfVC9fBQqCQwjxlvNe+M37lqne0yMOH2kTFdpZFiATnatbzlv1aAhg0eQsFdHFtm4S52E3IYG1Cw0IfNKE46BwB8ILuE7OBjUlGzYt48D6x+wH0ohUgY0O1ipszQLUKWlOXwd41YBTfRiC5qrj7ldZFT9gdCHgV/9nBclSGfD1m5PcqdNkKdTA3INUsZ/+l+xGbpBtUrwIiF4UHCcg== 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=xyIKlwqFfc4w1V5G45zbP2DZ2Ryyd19wG2Uu30yP9gw=; b=tV6UWZK/NUjLoMvLHGiG314t/j4wJ0RxKMSh8XVW0aOyiKLPaMFhQOZywsQgET6zoO2hOnAok80RPvt7uwkDVMNNm29J3EgW/GeROSjstY69sWUCx4GjleD6i80Zci5X1tUJcUQF46cXM+3Fiars+vRPBYRpWHuJhTcGoBvoHxF+aU1isUKMGeVHlhy207mseF4gDzyGFmm4Ks66w9HVjIkDsIFCHbNm6UvFYm1YGUt+xNXfMy9hAx1bX4GeKz6spgT6bsyDskRTfu7DQQ+W9wfkNUZ5LQT01fka8mY2AW5QHrHdZvMwTXsZqUCwpkTQzAgisLvnjcxthxeaaYz/gg== 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=xyIKlwqFfc4w1V5G45zbP2DZ2Ryyd19wG2Uu30yP9gw=; b=UEvYCE2l2Z4aNgUV9cFyOLvk/fFqJQdaQrYxfMXwCmEpNvVqtyOO1EeTx+J8oso/AePaUTfe1l+88uXeL7jPkFNQuS3x+95RzMWAOfcqFUumeW09ASekjEfZ1kgUwGXHtZvFH/ihqRc+yKuPeuBv3yBM3bFT0hFK7FmlsJgax1E= Received: from DUZPR01CA0002.eurprd01.prod.exchangelabs.com (2603:10a6:10:3c3::8) by GV1P190MB2092.EURP190.PROD.OUTLOOK.COM (2603:10a6:150:1a2::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8093.32; Wed, 30 Oct 2024 21:39:53 +0000 Received: from DU2PEPF00028D13.eurprd03.prod.outlook.com (2603:10a6:10:3c3:cafe::d7) by DUZPR01CA0002.outlook.office365.com (2603:10a6:10:3c3::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8114.20 via Frontend Transport; Wed, 30 Oct 2024 21:39: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 DU2PEPF00028D13.mail.protection.outlook.com (10.167.242.27) with Microsoft SMTP Server id 15.20.8114.16 via Frontend Transport; Wed, 30 Oct 2024 21:39:51 +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 v5 01/80] net/ntnic: add NT flow dev configuration Date: Wed, 30 Oct 2024 22:38:08 +0100 Message-ID: <20241030213940.3470062-2-sil-plv@napatech.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20241030213940.3470062-1-sil-plv@napatech.com> References: <20241021210527.2075431-1-sil-plv@napatech.com> <20241030213940.3470062-1-sil-plv@napatech.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU2PEPF00028D13:EE_|GV1P190MB2092:EE_ Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 60120173-70ae-4115-bd11-08dcf92b6320 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|1800799024|36860700013|376014|82310400026; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?GELVOkz2dpZ2lXJmnwdF8kWKFeQYUP8oHJhkUIfZKyCZ0h6giwWAeLD8hH7S?= =?us-ascii?Q?64Tg0qdU5Q7P9dBkv96SMZgxCASxCt6iFGv4Tlzememkh4E6jHKEcUUxorIa?= =?us-ascii?Q?3poy4Fdt+qA1H/ma/h994EhWkNhn7nwgmA8iN5n03IbQvyMIXK22TsJ/Lt8J?= =?us-ascii?Q?NTXN18uhoKgQCPZn6dmw1RWf1qtyaxDkEHRslCuz7c94SxJn1anGBEIc4PTK?= =?us-ascii?Q?C8Z7VZHTQD46XQDNt8HhkqEPRYM1RS1Xd0wEYJNKsHrk2fhW17EVeIkNKq57?= =?us-ascii?Q?1QnjLHEQvaqZRZusLFk8TsSGO/UiTSPEoPtFmcST6ZDeIEk1aTAnFB4YiBPK?= =?us-ascii?Q?/Vp/9G4kj2e4jF69Y6zoiBseGuGEuE4byQjf8PFj0IJcPxCUDQTtTgX4cHRb?= =?us-ascii?Q?2trsVzesmYu5kdpN/RiGMu9P6pU59cmZSTCX/3A0P6+9LHctL7LugmGwJIUZ?= =?us-ascii?Q?UqIqjJaJq3fl69iUuC3IOpdD4ROQbAGXbzRXWfSeEsOeV/7Go2I6efmTAK/6?= =?us-ascii?Q?bpemHiMFBpPFsBREvX5+MXtzYxCd747Qg6OXVLAWJT62PreZ2mjVi3Y5NAmU?= =?us-ascii?Q?DMwSXYXmscV3I9oDgcDC6lhhSkRKBQ07LhhJu2xOpwu1/6w8WcXh/fhqB0Vs?= =?us-ascii?Q?t0/T8s8cA5RtVF1OTxE2G+kFy8718HqwxODNzzdhNlnKOE5dz8px6ca+yGDn?= =?us-ascii?Q?tbYc3O1eUxAbMnvQ6rN3DCLxrjirrlPnhg9Hsu1HbLqJ7nwlIc6/wzbkWGL3?= =?us-ascii?Q?YejVdACmQgvc+K3ShIBiSxfL2iywAR2egrOzw+VEA883dguG7OyD+mfA5TN7?= =?us-ascii?Q?xZNx/GI3mzLPKPPe3h/p0/HjdGUnLq0hVuOaVm7KX4IiZB55SHya8TCLO4Ar?= =?us-ascii?Q?4dgezQuxOlLSxvvG3MwjkzQk9dxCUaJ0WnJZLQynxIZruwo+/19lgLM/SXLD?= =?us-ascii?Q?jmlSmHwOrb45LClro+mQVVulevqt+7pu1mmkP8vPuru2f59iIPHilFEWo9u7?= =?us-ascii?Q?xyuJ3ywKiO7mXe7zQFBUVrqZjIB7X1JQUNdRJ46A3iVpjxIHQZBcXu9EVn9+?= =?us-ascii?Q?q2KLhM6wMkVBzi0f42mGYtWMTRdjU6CWjVQrb3PimOzBguLcwRm3DWESz/2k?= =?us-ascii?Q?zTKeFAxa+7BhfoAmD5pQ4VFAsfG6B7aAl2g6pgPiJ/jFseg2oPapEaQPxIMd?= =?us-ascii?Q?6WhWqBX9gpV8KVly0N4WSJNNgFzmRUghKOd2Wid+awh2uqS/kAg+ZlBPU059?= =?us-ascii?Q?M549PZWTj7bV3hcq1u/X/Sy3wfAZFVYZiaKeVwLQ/j2r91SuR8zJxIIUEJLQ?= =?us-ascii?Q?diiw4EvdQU76TDzodtDsLRqsXzaBdvN3tCA2VNekmuV6pyYX8IQwUw57zVvB?= =?us-ascii?Q?nVQPe7m1jx65NdnIOzmgHTE6UFUz+tKHkUKDt9WUwHcD17dBhg=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)(36860700013)(376014)(82310400026); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: HcIAC2wAdKSvDxQri6V3CdaPPL1UDRo8/IjfRX/DRfmmmWbywFNCnJifMoyMcqkteKE5I4ruPXW5Yq5GV1J8jbJYbhDeAk00QktOBAtEdSEs5bGojO/vuCZ7RuXQnB8QDpj+PsAWfTy7UTtlXQG8I4EeMS32Q8e+BJgSZCU4ICV1HiWzMpy7GgvglF7iz239qzkYJUL+2x/bwv0zEn3RTbEe0s0irbMKzINPjTm8Y1P+CMzuBpljTcyVqEqp/1pUp9uF/zo7Ws27IhwncOrnyw246HNQm/kE6FlHwZQBe1np5MenAB7pC0Qxpz12Cgo607LXVp28zx+I6nZ0R2HRPDxTZ17C6c8FiE0djISC07ZjwHaEJLLtlx7DJO8q//UpwMETzvCtX9O3V3PVzMyOHoc5B8znkeLrzc3A5CfUV6ab8aCTudh9I0Wp+JDcTguYTwNtu4fOIysAvkgG3SQFblgLk8eVAy7BvEmRdi70HOdA1BtkAD8vT5Fw2bhdhGmILYQ7H90c3HvXk9XwYKWC3D2HTwz+PpoP/SbzHEpSXI8cTQjhspsUXdQLnPUdeCb4E4cBDS+TOouDibvCnwH4GM6ekX8nXO+Hcju5av4fI9SMCYXMPkRMaFXXFRuwJYTUjvwsAuPtn61WkBTballmo/yh+wjO30syRX1YB8dqKWM= X-OriginatorOrg: napatech.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Oct 2024 21:39:51.8330 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 60120173-70ae-4115-bd11-08dcf92b6320 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: DU2PEPF00028D13.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV1P190MB2092 X-BESS-ID: 1730324397-312176-12709-40648-1 X-BESS-VER: 2019.1_20241018.1852 X-BESS-Apparent-Source-IP: 104.47.17.107 X-BESS-Parts: H4sIAAAAAAACA4uuVkqtKFGyUioBkjpK+cVKVoZm5maWQGYGUNQyzTQ5LdHA0s TAyMDCOCXVMjnR1NLA1NgsxcwwxTQ5Wak2FgD3gV3NQgAAAA== X-BESS-Outbound-Spam-Score: 0.00 X-BESS-Outbound-Spam-Report: Code version 3.2, rules version 3.2.2.260091 [from cloudscan15-95.eu-central-1a.ess.aws.cudaops.com] Rule breakdown below pts rule name description ---- ---------------------- -------------------------------- 0.00 BSF_BESS_OUTBOUND META: BESS Outbound X-BESS-Outbound-Spam-Status: SCORE=0.00 using account:ESS113687 scores of KILL_LEVEL=7.0 tests=BSF_BESS_OUTBOUND X-BESS-BRTS-Status: 1 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Danylo Vodopianov This API allows enabling of flow profile for NT SmartNIC. Signed-off-by: Danylo Vodopianov --- v5 * remove unnecessary SCATTER_GATHER condition --- drivers/net/ntnic/include/flow_api.h | 30 +++ drivers/net/ntnic/include/flow_api_engine.h | 5 + drivers/net/ntnic/include/ntos_drv.h | 1 + .../ntnic/include/stream_binary_flow_api.h | 9 + drivers/net/ntnic/nthw/flow_api/flow_api.c | 209 +++++++++++++++++- drivers/net/ntnic/ntnic_ethdev.c | 22 ++ drivers/net/ntnic/ntnic_mod_reg.c | 5 + drivers/net/ntnic/ntnic_mod_reg.h | 14 ++ 8 files changed, 285 insertions(+), 10 deletions(-) diff --git a/drivers/net/ntnic/include/flow_api.h b/drivers/net/ntnic/include/flow_api.h index 984450afdc..c80906ec50 100644 --- a/drivers/net/ntnic/include/flow_api.h +++ b/drivers/net/ntnic/include/flow_api.h @@ -34,6 +34,8 @@ struct flow_eth_dev { struct flow_nic_dev *ndev; /* NIC port id */ uint8_t port; + /* App assigned port_id - may be DPDK port_id */ + uint32_t port_id; /* 0th for exception */ struct flow_queue_id_s rx_queue[FLOW_MAX_QUEUES + 1]; @@ -41,6 +43,9 @@ struct flow_eth_dev { /* VSWITCH has exceptions sent on queue 0 per design */ int num_queues; + /* QSL_HSH index if RSS needed QSL v6+ */ + int rss_target_id; + struct flow_eth_dev *next; }; @@ -48,6 +53,8 @@ struct flow_eth_dev { struct flow_nic_dev { uint8_t adapter_no; /* physical adapter no in the host system */ uint16_t ports; /* number of in-ports addressable on this NIC */ + /* flow profile this NIC is initially prepared for */ + enum flow_eth_dev_profile flow_profile; struct hw_mod_resource_s res[RES_COUNT];/* raw NIC resource allocation table */ void *km_res_handle; @@ -73,6 +80,14 @@ struct flow_nic_dev { extern const char *dbg_res_descr[]; +#define flow_nic_set_bit(arr, x) \ + do { \ + uint8_t *_temp_arr = (arr); \ + size_t _temp_x = (x); \ + _temp_arr[_temp_x / 8] = \ + (uint8_t)(_temp_arr[_temp_x / 8] | (uint8_t)(1 << (_temp_x % 8))); \ + } while (0) + #define flow_nic_unset_bit(arr, x) \ do { \ size_t _temp_x = (x); \ @@ -85,6 +100,18 @@ extern const char *dbg_res_descr[]; (arr[_temp_x / 8] & (uint8_t)(1 << (_temp_x % 8))); \ }) +#define flow_nic_mark_resource_used(_ndev, res_type, index) \ + do { \ + struct flow_nic_dev *_temp_ndev = (_ndev); \ + typeof(res_type) _temp_res_type = (res_type); \ + size_t _temp_index = (index); \ + NT_LOG(DBG, FILTER, "mark resource used: %s idx %zu", \ + dbg_res_descr[_temp_res_type], _temp_index); \ + assert(flow_nic_is_bit_set(_temp_ndev->res[_temp_res_type].alloc_bm, \ + _temp_index) == 0); \ + flow_nic_set_bit(_temp_ndev->res[_temp_res_type].alloc_bm, _temp_index); \ + } while (0) + #define flow_nic_mark_resource_unused(_ndev, res_type, index) \ do { \ typeof(res_type) _temp_res_type = (res_type); \ @@ -97,6 +124,9 @@ extern const char *dbg_res_descr[]; #define flow_nic_is_resource_used(_ndev, res_type, index) \ (!!flow_nic_is_bit_set((_ndev)->res[res_type].alloc_bm, index)) +int flow_nic_alloc_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, + uint32_t alignment); + void flow_nic_free_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int idx); int flow_nic_deref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int index); diff --git a/drivers/net/ntnic/include/flow_api_engine.h b/drivers/net/ntnic/include/flow_api_engine.h index db5e6fe09d..d025677e25 100644 --- a/drivers/net/ntnic/include/flow_api_engine.h +++ b/drivers/net/ntnic/include/flow_api_engine.h @@ -41,6 +41,11 @@ enum res_type_e { RES_INVALID }; +/* + * Flow NIC offload management + */ +#define MAX_OUTPUT_DEST (128) + void km_free_ndev_resource_management(void **handle); void kcc_free_ndev_resource_management(void **handle); diff --git a/drivers/net/ntnic/include/ntos_drv.h b/drivers/net/ntnic/include/ntos_drv.h index d51d1e3677..8fd577dfe3 100644 --- a/drivers/net/ntnic/include/ntos_drv.h +++ b/drivers/net/ntnic/include/ntos_drv.h @@ -86,6 +86,7 @@ struct __rte_cache_aligned ntnic_tx_queue { struct pmd_internals { const struct rte_pci_device *pci_dev; + struct flow_eth_dev *flw_dev; char name[20]; int n_intf_no; int lpbk_mode; diff --git a/drivers/net/ntnic/include/stream_binary_flow_api.h b/drivers/net/ntnic/include/stream_binary_flow_api.h index 10529b8843..47e5353344 100644 --- a/drivers/net/ntnic/include/stream_binary_flow_api.h +++ b/drivers/net/ntnic/include/stream_binary_flow_api.h @@ -12,11 +12,20 @@ #define FLOW_MAX_QUEUES 128 +/* + * Flow eth dev profile determines how the FPGA module resources are + * managed and what features are available + */ +enum flow_eth_dev_profile { + FLOW_ETH_DEV_PROFILE_INLINE = 0, +}; + struct flow_queue_id_s { int id; int hw_id; }; struct flow_eth_dev; /* port device */ +struct flow_handle; #endif /* _STREAM_BINARY_FLOW_API_H_ */ diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c b/drivers/net/ntnic/nthw/flow_api/flow_api.c index 34e84559eb..7716a9fc82 100644 --- a/drivers/net/ntnic/nthw/flow_api/flow_api.c +++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c @@ -7,6 +7,7 @@ #include "flow_api_nic_setup.h" #include "ntnic_mod_reg.h" +#include "flow_api.h" #include "flow_filter.h" const char *dbg_res_descr[] = { @@ -35,6 +36,24 @@ const char *dbg_res_descr[] = { static struct flow_nic_dev *dev_base; static pthread_mutex_t base_mtx = PTHREAD_MUTEX_INITIALIZER; +/* + * Resources + */ + +int flow_nic_alloc_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, + uint32_t alignment) +{ + for (unsigned int i = 0; i < ndev->res[res_type].resource_count; i += alignment) { + if (!flow_nic_is_resource_used(ndev, res_type, i)) { + flow_nic_mark_resource_used(ndev, res_type, i); + ndev->res[res_type].ref[i] = 1; + return i; + } + } + + return -1; +} + void flow_nic_free_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, int idx) { flow_nic_mark_resource_unused(ndev, res_type, idx); @@ -55,10 +74,60 @@ int flow_nic_deref_resource(struct flow_nic_dev *ndev, enum res_type_e res_type, return !!ndev->res[res_type].ref[index];/* if 0 resource has been freed */ } +/* + * Nic port/adapter lookup + */ + +static struct flow_eth_dev *nic_and_port_to_eth_dev(uint8_t adapter_no, uint8_t port) +{ + struct flow_nic_dev *nic_dev = dev_base; + + while (nic_dev) { + if (nic_dev->adapter_no == adapter_no) + break; + + nic_dev = nic_dev->next; + } + + if (!nic_dev) + return NULL; + + struct flow_eth_dev *dev = nic_dev->eth_base; + + while (dev) { + if (port == dev->port) + return dev; + + dev = dev->next; + } + + return NULL; +} + +static struct flow_nic_dev *get_nic_dev_from_adapter_no(uint8_t adapter_no) +{ + struct flow_nic_dev *ndev = dev_base; + + while (ndev) { + if (adapter_no == ndev->adapter_no) + break; + + ndev = ndev->next; + } + + return ndev; +} + /* * Device Management API */ +static void nic_insert_eth_port_dev(struct flow_nic_dev *ndev, struct flow_eth_dev *dev) +{ + dev->next = ndev->eth_base; + ndev->eth_base = dev; +} + static int nic_remove_eth_port_dev(struct flow_nic_dev *ndev, struct flow_eth_dev *eth_dev) { struct flow_eth_dev *dev = ndev->eth_base, *prev = NULL; @@ -156,16 +225,6 @@ int flow_delete_eth_dev(struct flow_eth_dev *eth_dev) ndev->be.iface->set_debug_mode(ndev->be.be_dev, FLOW_BACKEND_DEBUG_MODE_NONE); #endif -#ifndef SCATTER_GATHER - - /* free rx queues */ - for (int i = 0; i < eth_dev->num_queues; i++) { - ndev->be.iface->free_rx_queue(ndev->be.be_dev, eth_dev->rx_queue[i].hw_id); - flow_nic_deref_resource(ndev, RES_QUEUE, eth_dev->rx_queue[i].id); - } - -#endif - /* take eth_dev out of ndev list */ if (nic_remove_eth_port_dev(ndev, eth_dev) != 0) NT_LOG(ERR, FILTER, "ERROR : eth_dev %p not found", eth_dev); @@ -242,6 +301,132 @@ static int list_remove_flow_nic(struct flow_nic_dev *ndev) return -1; } +/* + * adapter_no physical adapter no + * port_no local port no + * alloc_rx_queues number of rx-queues to allocate for this eth_dev + */ +static struct flow_eth_dev *flow_get_eth_dev(uint8_t adapter_no, uint8_t port_no, uint32_t port_id, + int alloc_rx_queues, struct flow_queue_id_s queue_ids[], + int *rss_target_id, enum flow_eth_dev_profile flow_profile, + uint32_t exception_path) +{ + const struct profile_inline_ops *profile_inline_ops = get_profile_inline_ops(); + + if (profile_inline_ops == NULL) + NT_LOG(ERR, FILTER, "%s: profile_inline module uninitialized", __func__); + + int i; + struct flow_eth_dev *eth_dev = NULL; + + NT_LOG(DBG, FILTER, + "Get eth-port adapter %i, port %i, port_id %u, rx queues %i, profile %i", + adapter_no, port_no, port_id, alloc_rx_queues, flow_profile); + + if (MAX_OUTPUT_DEST < FLOW_MAX_QUEUES) { + assert(0); + NT_LOG(ERR, FILTER, + "ERROR: Internal array for multiple queues too small for API"); + } + + pthread_mutex_lock(&base_mtx); + struct flow_nic_dev *ndev = get_nic_dev_from_adapter_no(adapter_no); + + if (!ndev) { + /* Error - no flow api found on specified adapter */ + NT_LOG(ERR, FILTER, "ERROR: no flow interface registered for adapter %d", + adapter_no); + pthread_mutex_unlock(&base_mtx); + return NULL; + } + + if (ndev->ports < ((uint16_t)port_no + 1)) { + NT_LOG(ERR, FILTER, "ERROR: port exceeds supported port range for adapter"); + pthread_mutex_unlock(&base_mtx); + return NULL; + } + + if ((alloc_rx_queues - 1) > FLOW_MAX_QUEUES) { /* 0th is exception so +1 */ + NT_LOG(ERR, FILTER, + "ERROR: Exceeds supported number of rx queues per eth device"); + pthread_mutex_unlock(&base_mtx); + return NULL; + } + + /* don't accept multiple eth_dev's on same NIC and same port */ + eth_dev = nic_and_port_to_eth_dev(adapter_no, port_no); + + if (eth_dev) { + NT_LOG(DBG, FILTER, "Re-opening existing NIC port device: NIC DEV: %i Port %i", + adapter_no, port_no); + pthread_mutex_unlock(&base_mtx); + flow_delete_eth_dev(eth_dev); + eth_dev = NULL; + } + + eth_dev = calloc(1, sizeof(struct flow_eth_dev)); + + if (!eth_dev) { + NT_LOG(ERR, FILTER, "ERROR: calloc failed"); + goto err_exit1; + } + + pthread_mutex_lock(&ndev->mtx); + + eth_dev->ndev = ndev; + eth_dev->port = port_no; + eth_dev->port_id = port_id; + + /* Allocate the requested queues in HW for this dev */ + + for (i = 0; i < alloc_rx_queues; i++) { + eth_dev->rx_queue[i] = queue_ids[i]; + + if (i == 0 && (flow_profile == FLOW_ETH_DEV_PROFILE_INLINE && exception_path)) { + /* + * Init QSL UNM - unmatched - redirects otherwise discarded + * packets in QSL + */ + if (hw_mod_qsl_unmq_set(&ndev->be, HW_QSL_UNMQ_DEST_QUEUE, eth_dev->port, + eth_dev->rx_queue[0].hw_id) < 0) + goto err_exit0; + + if (hw_mod_qsl_unmq_set(&ndev->be, HW_QSL_UNMQ_EN, eth_dev->port, 1) < 0) + goto err_exit0; + + if (hw_mod_qsl_unmq_flush(&ndev->be, eth_dev->port, 1) < 0) + goto err_exit0; + } + + eth_dev->num_queues++; + } + + eth_dev->rss_target_id = -1; + + *rss_target_id = eth_dev->rss_target_id; + + nic_insert_eth_port_dev(ndev, eth_dev); + + pthread_mutex_unlock(&ndev->mtx); + pthread_mutex_unlock(&base_mtx); + return eth_dev; + +err_exit0: + pthread_mutex_unlock(&ndev->mtx); + pthread_mutex_unlock(&base_mtx); + +err_exit1: + if (eth_dev) + free(eth_dev); + +#ifdef FLOW_DEBUG + ndev->be.iface->set_debug_mode(ndev->be.be_dev, FLOW_BACKEND_DEBUG_MODE_NONE); +#endif + + NT_LOG(DBG, FILTER, "ERR in %s", __func__); + return NULL; /* Error exit */ +} + struct flow_nic_dev *flow_api_create(uint8_t adapter_no, const struct flow_api_backend_ops *be_if, void *be_dev) { @@ -383,6 +568,10 @@ void *flow_api_get_be_dev(struct flow_nic_dev *ndev) static const struct flow_filter_ops ops = { .flow_filter_init = flow_filter_init, .flow_filter_done = flow_filter_done, + /* + * Device Management API + */ + .flow_get_eth_dev = flow_get_eth_dev, }; void init_flow_filter(void) diff --git a/drivers/net/ntnic/ntnic_ethdev.c b/drivers/net/ntnic/ntnic_ethdev.c index bff893ec7a..510c0e5d23 100644 --- a/drivers/net/ntnic/ntnic_ethdev.c +++ b/drivers/net/ntnic/ntnic_ethdev.c @@ -1355,6 +1355,13 @@ static const struct eth_dev_ops nthw_eth_dev_ops = { static int nthw_pci_dev_init(struct rte_pci_device *pci_dev) { + const struct flow_filter_ops *flow_filter_ops = get_flow_filter_ops(); + + if (flow_filter_ops == NULL) { + NT_LOG_DBGX(ERR, NTNIC, "flow_filter module uninitialized"); + /* Return statement is not necessary here to allow traffic processing by SW */ + } + nt_vfio_init(); const struct port_ops *port_ops = get_port_ops(); @@ -1378,10 +1385,13 @@ nthw_pci_dev_init(struct rte_pci_device *pci_dev) uint32_t n_port_mask = -1; /* All ports enabled by default */ uint32_t nb_rx_queues = 1; uint32_t nb_tx_queues = 1; + uint32_t exception_path = 0; struct flow_queue_id_s queue_ids[MAX_QUEUES]; int n_phy_ports; struct port_link_speed pls_mbps[NUM_ADAPTER_PORTS_MAX] = { 0 }; int num_port_speeds = 0; + enum flow_eth_dev_profile profile = FLOW_ETH_DEV_PROFILE_INLINE; + NT_LOG_DBGX(DBG, NTNIC, "Dev %s PF #%i Init : %02x:%02x:%i", pci_dev->name, pci_dev->addr.function, pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function); @@ -1681,6 +1691,18 @@ nthw_pci_dev_init(struct rte_pci_device *pci_dev) return -1; } + if (flow_filter_ops != NULL) { + internals->flw_dev = flow_filter_ops->flow_get_eth_dev(0, n_intf_no, + eth_dev->data->port_id, nb_rx_queues, queue_ids, + &internals->txq_scg[0].rss_target_id, profile, exception_path); + + if (!internals->flw_dev) { + NT_LOG(ERR, NTNIC, + "Error creating port. Resource exhaustion in HW"); + return -1; + } + } + /* connect structs */ internals->p_drv = p_drv; eth_dev->data->dev_private = internals; diff --git a/drivers/net/ntnic/ntnic_mod_reg.c b/drivers/net/ntnic/ntnic_mod_reg.c index a03c97801b..ac8afdef6a 100644 --- a/drivers/net/ntnic/ntnic_mod_reg.c +++ b/drivers/net/ntnic/ntnic_mod_reg.c @@ -118,6 +118,11 @@ const struct flow_backend_ops *get_flow_backend_ops(void) return flow_backend_ops; } +const struct profile_inline_ops *get_profile_inline_ops(void) +{ + return NULL; +} + static const struct flow_filter_ops *flow_filter_ops; void register_flow_filter_ops(const struct flow_filter_ops *ops) diff --git a/drivers/net/ntnic/ntnic_mod_reg.h b/drivers/net/ntnic/ntnic_mod_reg.h index 5b97b3d8ac..017d15d7bc 100644 --- a/drivers/net/ntnic/ntnic_mod_reg.h +++ b/drivers/net/ntnic/ntnic_mod_reg.h @@ -8,6 +8,7 @@ #include #include "flow_api.h" +#include "stream_binary_flow_api.h" #include "nthw_fpga_model.h" #include "nthw_platform_drv.h" #include "nthw_drv.h" @@ -223,10 +224,23 @@ void register_flow_backend_ops(const struct flow_backend_ops *ops); const struct flow_backend_ops *get_flow_backend_ops(void); void flow_backend_init(void); +const struct profile_inline_ops *get_profile_inline_ops(void); + struct flow_filter_ops { int (*flow_filter_init)(nthw_fpga_t *p_fpga, struct flow_nic_dev **p_flow_device, int adapter_no); int (*flow_filter_done)(struct flow_nic_dev *dev); + /* + * Device Management API + */ + struct flow_eth_dev *(*flow_get_eth_dev)(uint8_t adapter_no, + uint8_t hw_port_no, + uint32_t port_id, + int alloc_rx_queues, + struct flow_queue_id_s queue_ids[], + int *rss_target_id, + enum flow_eth_dev_profile flow_profile, + uint32_t exception_path); }; void register_flow_filter_ops(const struct flow_filter_ops *ops); -- 2.45.0