Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/133810/?format=api
http://patchwork.dpdk.org/api/patches/133810/?format=api", "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20231103062606.2632012-5-chaoyong.he@corigine.com/", "project": { "id": 1, "url": "http://patchwork.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<20231103062606.2632012-5-chaoyong.he@corigine.com>", "list_archive_url": "https://inbox.dpdk.org/dev/20231103062606.2632012-5-chaoyong.he@corigine.com", "date": "2023-11-03T06:25:59", "name": "[04/11] net/nfp: support flow API for CoreNIC firmware", "commit_ref": null, "pull_url": null, "state": "changes-requested", "archived": true, "hash": "1dfac57c7d52bdf74085935d780a7ecf47a7a3da", "submitter": { "id": 2554, "url": "http://patchwork.dpdk.org/api/people/2554/?format=api", "name": "Chaoyong He", "email": "chaoyong.he@corigine.com" }, "delegate": { "id": 319, "url": "http://patchwork.dpdk.org/api/users/319/?format=api", "username": "fyigit", "first_name": "Ferruh", "last_name": "Yigit", "email": "ferruh.yigit@amd.com" }, "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20231103062606.2632012-5-chaoyong.he@corigine.com/mbox/", "series": [ { "id": 30130, "url": "http://patchwork.dpdk.org/api/series/30130/?format=api", "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=30130", "date": "2023-11-03T06:25:55", "name": "Add basic flow support for corenic firmware", "version": 1, "mbox": "http://patchwork.dpdk.org/series/30130/mbox/" } ], "comments": "http://patchwork.dpdk.org/api/patches/133810/comments/", "check": "success", "checks": "http://patchwork.dpdk.org/api/patches/133810/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@inbox.dpdk.org", "Delivered-To": "patchwork@inbox.dpdk.org", "Received": [ "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 6056E43275;\n\tFri, 3 Nov 2023 07:27:03 +0100 (CET)", "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id C9EBF42DCD;\n\tFri, 3 Nov 2023 07:26:40 +0100 (CET)", "from NAM10-DM6-obe.outbound.protection.outlook.com\n (mail-dm6nam10on2112.outbound.protection.outlook.com [40.107.93.112])\n by mails.dpdk.org (Postfix) with ESMTP id 7918F42D35\n for <dev@dpdk.org>; Fri, 3 Nov 2023 07:26:38 +0100 (CET)", "from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5)\n by MN2PR13MB4102.namprd13.prod.outlook.com (2603:10b6:208:262::16)\n with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6954.24; Fri, 3 Nov\n 2023 06:26:36 +0000", "from SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::45b3:d83c:cff2:4a1b]) by SJ0PR13MB5545.namprd13.prod.outlook.com\n ([fe80::45b3:d83c:cff2:4a1b%6]) with mapi id 15.20.6954.021; Fri, 3 Nov 2023\n 06:26:36 +0000" ], "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;\n b=FBHemgOHQSgsJ7rqCTpxjhnG2Ea7CBCr+jt2qkoPros6VzOdZHWsVVTnFhVpNIWGAxjIroa8z981mITfhAk5qVjdrc6n2Cb/djCF/cxNz64rVpm0Oyy0K8ik11YRs3f/oZDXYwauyMaC4iJi1J7A98B9cpbUx8qMJG8lLEp25IhtrQcsWkEtdRfBo3Nd+fQNx/auvQX15XT9n8zkZMpfatsFWaEc7ssZC0js2hb1TBiBhnvm9S4PCQs/rHOGXzRWT4Dcw4YEYV+WK3O4Sf81yXf7yvDIkj27JzrJJisQCbOo7UEs1zm/PkhgkZWG0HVBRg2U38mKgtkzby7qG/0SaA==", "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n s=arcselector9901;\n 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;\n bh=ceMV+MrpGUpYXxDZbJQFvXi/mL4FVWpG6B9pSrH9EUg=;\n b=hn7B88WHcpb3emQx3X0GWeLdePTadZikH4yH3FIevVuiJnZDYG7k+j1vz+LRWwWA/YiUAbebEoS7N+Kau24mMewuF+GVKxnN4H0y4zkgYSjCN4dkRRMpcwU4U9xhG6prDcXXei7EEqNKu5NZf+R4QxO1mb9eSMi4QXqK9fZedzUxjSoxAbTb0UQQ1DQMXLWzDyIh5QnKApP0BsbXdsw17plY8y8hCj5P7F8R8TKWlIBvRXTDTK9gqZLYsZUDWHdvIWStTH32tYILbS8X1Q/EBoX9uUKpfalBR/X3jzgJD5gBxHo/11UU7ham12CKjpEbQuYEJ2raaUvLbhpOvBm7FQ==", "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass\n smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com;\n dkim=pass header.d=corigine.com; arc=none", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com;\n h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n bh=ceMV+MrpGUpYXxDZbJQFvXi/mL4FVWpG6B9pSrH9EUg=;\n b=j5KaRX1ytqDSVEpUCj/7UtDohTdHQ3nsjzsHRosmcjuPEwRpkdYDTNdtF1vNoHYTAWGHBXQ7Geolqw0bHQWYSW7Kpq9dCMoQPuAm/entUr2RCMHKsoaCErvpio/Iq4a4eCpROC8eiRhqi6TVP83GsF5QUnfjIAQdgGYg1nX1sD0=", "Authentication-Results": "dkim=none (message not signed)\n header.d=none;dmarc=none action=none header.from=corigine.com;", "From": "Chaoyong He <chaoyong.he@corigine.com>", "To": "dev@dpdk.org", "Cc": "oss-drivers@corigine.com, Chaoyong He <chaoyong.he@corigine.com>,\n Long Wu <long.wu@corigine.com>, Peng Zhang <peng.zhang@corigine.com>", "Subject": "[PATCH 04/11] net/nfp: support flow API for CoreNIC firmware", "Date": "Fri, 3 Nov 2023 14:25:59 +0800", "Message-Id": "<20231103062606.2632012-5-chaoyong.he@corigine.com>", "X-Mailer": "git-send-email 2.39.1", "In-Reply-To": "<20231103062606.2632012-1-chaoyong.he@corigine.com>", "References": "<20231103062606.2632012-1-chaoyong.he@corigine.com>", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "X-ClientProxiedBy": "BYAPR02CA0044.namprd02.prod.outlook.com\n (2603:10b6:a03:54::21) To SJ0PR13MB5545.namprd13.prod.outlook.com\n (2603:10b6:a03:424::5)", "MIME-Version": "1.0", "X-MS-PublicTrafficType": "Email", "X-MS-TrafficTypeDiagnostic": "SJ0PR13MB5545:EE_|MN2PR13MB4102:EE_", "X-MS-Office365-Filtering-Correlation-Id": "d65fb47b-3353-4557-d794-08dbdc35d4a8", "X-MS-Exchange-SenderADCheck": "1", "X-MS-Exchange-AntiSpam-Relay": "0", "X-Microsoft-Antispam": "BCL:0;", "X-Microsoft-Antispam-Message-Info": "\n dAgJtL4JrKk0w4bOf1fe4iaq+gJx6FhDr3yppRhaK58KHERJ28Vd1lsd1f0r+XJgbC49Di7gctzdeXN+dRVVgQIXddq+9/OM2asIoWI8cE7xWSdANcxcDwlDGoEGAiSR316sYP9jY8vlqs376L01U99DDpXgB6rtZon1HAaNKz7ZLRXSN49mZ8hQ4RLfUWrYq/kOb+j8qLdzGDpo0B6X3YNMS3bKs6MODk+ZOiWw/LZxH0eoqnNBmnzu50pgnO7u4Lnd8f9Xaf2zFfflFCUKy1YUP+JXuvDVDsGliIH4l/ouGSxnwa0YHntZW9enPwiWUy0wvnkw2cqdxPUhyZZGxu41tKPOZCN025y4j78/JX8osODU1DP323HMzrHOHoGKT1O+/jWgpBfExxsJc2I5JFfC7C7XTyAB7flSUE5qYmQ7td7za1Kks9AOBu7QCdtJp+A5SvPBJLe/kC7fNPtVzcgxYS5LPDu/T0nGm4nY8aN/B61Amk8vcfCQQijYpiHX9xCZNgnUEYlPG9tpGMOP1NHlKHVyAaM2pa3+sBP2SAYU6sMV7R2DxfHD6WueA1PdXoZLMaNP0zLIHhMTcDm1wIhm42TWAjQ78VHvt8tIPzUKQ9jZkw5MXfN64Mj3jrUB1Ryv24tTp9nQ0XXBc/ehVcVputfPMvSavtoHMeaQ0kA=", "X-Forefront-Antispam-Report": "CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n IPV:NLI; SFV:NSPM; H:SJ0PR13MB5545.namprd13.prod.outlook.com; PTR:; CAT:NONE;\n SFS:(13230031)(39840400004)(346002)(396003)(366004)(136003)(376002)(230922051799003)(186009)(64100799003)(451199024)(1800799009)(316002)(6916009)(54906003)(66476007)(66556008)(66946007)(6666004)(6486002)(478600001)(52116002)(6506007)(30864003)(5660300002)(38350700005)(41300700001)(36756003)(2906002)(86362001)(4326008)(8676002)(8936002)(44832011)(107886003)(1076003)(2616005)(26005)(83380400001)(38100700002)(6512007);\n DIR:OUT; SFP:1102;", "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1", "X-MS-Exchange-AntiSpam-MessageData-0": "=?utf-8?q?y16Jj7aglouzPWL2auwecEBeJ2qf?=\n\t=?utf-8?q?U3fUCakD4zsKPZL9B6fZ/lb7lI3JU7z++Z0QzEDloWbmMVyKmbV8nt/GhSmyPobJw?=\n\t=?utf-8?q?qMaeasSdWdP9GXgbrb+P1gVh4niHX1aY3Iwnd+5rvnk2NgOrQIF2oYOb889S1IsPX?=\n\t=?utf-8?q?DO/SJf+MJ4j6xU/1mMlYUnQTF1qmN3hfa3nwDU8LbGziGkv8xHZVA/tHFHyMNXH/i?=\n\t=?utf-8?q?pdqkvmg6LJo/Ej0DRIALU2Zi5RRpJNw0arjagMELIMlrP881aA5MXl6hYvLJ99G2t?=\n\t=?utf-8?q?8yqru2WMK4keX3f12o8MrPEsHqAUyL/9y4kV84dE3mV68C1VT/Fi19bXdVdAOm4xh?=\n\t=?utf-8?q?pggvb5OCmS4g+nIXErgVoRAGRKOwK+f697fk83TK6wkavvzS6pEwQke7MU3br26dk?=\n\t=?utf-8?q?P3SuzWVipVBD/bPD1a0V9x5+wvjWqyUehXs81Ez2dEhp/F4x3KHLHIkXaf3anQEj3?=\n\t=?utf-8?q?cxYQKGh6hnyeQKuZ0ml5UlRqzNOJ3dzeXRm5fRKaePryK2gm2G4eWK1ZK03NPIiEV?=\n\t=?utf-8?q?aQmUHSZhUzJ+uiT3Hq5a8W4c7koQ+5HS8dBVVEtaxFmaIZgrXe0wELmKTa4qdjd38?=\n\t=?utf-8?q?PW3Flr4U71cy/2jW6cVp8eCpg3P+Iu8qxs+s7BeFYaaIPNX4VCdIdb8Ctme9ioDSu?=\n\t=?utf-8?q?TJSjVL9LVahpABoqn1gzF8Pqv9l73Gs/UEIknoG2S+LNc+O9fbJg+HPY5qYmsuy27?=\n\t=?utf-8?q?ERJRnfpDqtET+BgAyK65DB6x0OVKRdaO7fJgxOS0X4YWzbfcrfAvL6omfrQlFM/jw?=\n\t=?utf-8?q?s2I7TTmjDyvmFjgNkbre6uVHW4H39D28CAmeKixaopLVclNi5M6JT1MrZL/LsJf2S?=\n\t=?utf-8?q?wm7+8IjfDZRt73ZooOiS1QBsq3oXpt10rztZJetbPMEqul1BbK+FM1Fpg2L+eKqxy?=\n\t=?utf-8?q?9B9zz7ZmkeU/W53YeGDp+7f0Ekrrw6bP8uKgNzCUqSB+XntLBuEKJCSvrNC7ZPhpY?=\n\t=?utf-8?q?iZgULElQKjWpquGlWSn/c1LSLQqrG6e4oLOAAho1VQa3kf0SWxPP9u5VCOFv4TKqG?=\n\t=?utf-8?q?coUuNj/JcHIxTs6sxIYDws/lsQS4m747u6cOhhF+ZP/f9JH8RKqAkPrsFE3FkaV2T?=\n\t=?utf-8?q?v8hv7ZQM5+zv35WqiMWVU3mwka/RHqngX5focPm6Oa5YSU/n7ZIEmc8uumVdSl7r9?=\n\t=?utf-8?q?B0vEQGyj3PvohWTA+rOZRcZ1Xw7uSCMcVhf0Wlx91w8+5iYYbkvsYJ/pwYC7wMUdz?=\n\t=?utf-8?q?m39636Tz9UKkxLmleC6/c3XfNFyPxoXnK7n+esZ4R0ZEXAJj5ToQvP7MU+vHJtvO+?=\n\t=?utf-8?q?Alyk9wmyaQqv24X1qgiHLszn65ulRGPmunC50pgxxAUgLvnU/E3c0Q77W4YokpB+X?=\n\t=?utf-8?q?jwx0fx+iskUi/mmCbo2sabyzF3mfz8uZmO6v2Cexgxu2a+Gaql4+/k/Z5oyyxUqAm?=\n\t=?utf-8?q?pKrCSiT1hqz+30+Smcu+G+ZhzJ1ftxvsCJ9NH4+uL77POdHG90XYhF+Td1W15BmcW?=\n\t=?utf-8?q?Zuxuec+hkZnYXtWvETjBSAuNY71XZi9N1Tt2Pd2bTIfvJFbwF+Vfb723ejVz4ACRy?=\n\t=?utf-8?q?OBP+6iJO9GOaGkrgg85aKARwhySkevO0Jw=3D=3D?=", "X-OriginatorOrg": "corigine.com", "X-MS-Exchange-CrossTenant-Network-Message-Id": "\n d65fb47b-3353-4557-d794-08dbdc35d4a8", "X-MS-Exchange-CrossTenant-AuthSource": "SJ0PR13MB5545.namprd13.prod.outlook.com", "X-MS-Exchange-CrossTenant-AuthAs": "Internal", "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "03 Nov 2023 06:26:36.4920 (UTC)", "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted", "X-MS-Exchange-CrossTenant-Id": "fe128f2c-073b-4c20-818e-7246a585940c", "X-MS-Exchange-CrossTenant-MailboxType": "HOSTED", "X-MS-Exchange-CrossTenant-UserPrincipalName": "\n NRQcOAQUhQ70SOH0uPnb2MNvDWqgjNKo7e2aaPyaNdAOcCWaFoPuVH548biF30LsGlxLtX8fplk4ZYbAKrSo4rVjZuV38CX8FEOmwwr2SXM=", "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "MN2PR13MB4102", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org" }, "content": "Add the flow validate/create/destroy/flush API of nfp PMD with CoreNIC\nfirmware.\n\nThe flow create API construct a control cmsg and send it to\nfirmware, then add this flow to the hash table.\n\nThe flow destroy API construct a control cmsg and send it to\nfirmware, then delete this flow from the hash table.\n\nThe flow flush API just iterate the flows in hash table and\ncall the flow destroy API.\n\nSigned-off-by: Chaoyong He <chaoyong.he@corigine.com>\nReviewed-by: Long Wu <long.wu@corigine.com>\nReviewed-by: Peng Zhang <peng.zhang@corigine.com>\n---\n drivers/net/nfp/nfp_ethdev.c | 1 +\n drivers/net/nfp/nfp_net_cmsg.h | 28 +++\n drivers/net/nfp/nfp_net_common.h | 1 +\n drivers/net/nfp/nfp_net_flow.c | 409 ++++++++++++++++++++++++++++++-\n drivers/net/nfp/nfp_net_flow.h | 2 +\n 5 files changed, 434 insertions(+), 7 deletions(-)", "diff": "diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c\nindex af5e5d333a..37dae8a82a 100644\n--- a/drivers/net/nfp/nfp_ethdev.c\n+++ b/drivers/net/nfp/nfp_ethdev.c\n@@ -530,6 +530,7 @@ static const struct eth_dev_ops nfp_net_eth_dev_ops = {\n \t.fw_version_get = nfp_net_firmware_version_get,\n \t.flow_ctrl_get = nfp_net_flow_ctrl_get,\n \t.flow_ctrl_set = nfp_net_flow_ctrl_set,\n+\t.flow_ops_get = nfp_net_flow_ops_get,\n };\n \n static inline void\ndiff --git a/drivers/net/nfp/nfp_net_cmsg.h b/drivers/net/nfp/nfp_net_cmsg.h\nindex 15e0bb60d8..b526feaff2 100644\n--- a/drivers/net/nfp/nfp_net_cmsg.h\n+++ b/drivers/net/nfp/nfp_net_cmsg.h\n@@ -8,6 +8,34 @@\n \n #include \"nfp_net_common.h\"\n \n+#define NFP_NET_CMSG_ACTION_DROP (0x1 << 0) /* Drop action */\n+#define NFP_NET_CMSG_ACTION_QUEUE (0x1 << 1) /* Queue action */\n+#define NFP_NET_CMSG_ACTION_MARK (0x1 << 2) /* Mark action */\n+\n+/**\n+ * Action data\n+ * Bit 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0\n+ * -----\\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n+ * Word +-------------------------------+-------------------------------+\n+ * 0 | | Queue | Actions |\n+ * +-----------------+-------------+-------------------------------+\n+ * 1 | Mark ID |\n+ * +---------------------------------------------------------------+\n+ *\n+ * Queue – Queue ID, 7 bits.\n+ * Actions – An action bitmap, each bit represents an action type:\n+ * - Bit 0: Drop action. Drop the packet.\n+ * - Bit 1: Queue action. Use the queue specified by “Queue” field.\n+ * If not set, the queue is usually specified by RSS.\n+ * - Bit 2: Mark action. Mark packet with Mark ID.\n+ */\n+struct nfp_net_cmsg_action {\n+\tuint16_t action;\n+\tuint8_t queue;\n+\tuint8_t spare;\n+\tuint16_t mark_id;\n+};\n+\n enum nfp_net_cfg_mbox_cmd {\n \tNFP_NET_CFG_MBOX_CMD_FS_ADD_V4, /* Add Flow Steer rule for V4 table */\n \tNFP_NET_CFG_MBOX_CMD_FS_DEL_V4, /* Delete Flow Steer rule for V4 table */\ndiff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h\nindex 48791af93a..464a191a9c 100644\n--- a/drivers/net/nfp/nfp_net_common.h\n+++ b/drivers/net/nfp/nfp_net_common.h\n@@ -114,6 +114,7 @@ struct nfp_net_priv {\n \tuint32_t hash_seed; /**< Hash seed for hash tables in this structure. */\n \tstruct rte_hash *flow_table; /**< Hash table to store flow rules. */\n \tuint16_t flow_count; /**< Flow count in hash table */\n+\tbool flow_position[NFP_NET_FLOW_LIMIT]; /**< Flow position array */\n };\n \n struct nfp_app_fw_nic {\ndiff --git a/drivers/net/nfp/nfp_net_flow.c b/drivers/net/nfp/nfp_net_flow.c\nindex 6c02b0f82e..88386a31f0 100644\n--- a/drivers/net/nfp/nfp_net_flow.c\n+++ b/drivers/net/nfp/nfp_net_flow.c\n@@ -11,8 +11,9 @@\n #include <rte_malloc.h>\n \n #include \"nfp_logs.h\"\n+#include \"nfp_net_cmsg.h\"\n \n-__rte_unused static int\n+static int\n nfp_net_flow_table_add(struct nfp_net_priv *priv,\n \t\tstruct rte_flow *nfp_flow)\n {\n@@ -27,7 +28,7 @@ nfp_net_flow_table_add(struct nfp_net_priv *priv,\n \treturn 0;\n }\n \n-__rte_unused static int\n+static int\n nfp_net_flow_table_delete(struct nfp_net_priv *priv,\n \t\tstruct rte_flow *nfp_flow)\n {\n@@ -42,7 +43,7 @@ nfp_net_flow_table_delete(struct nfp_net_priv *priv,\n \treturn 0;\n }\n \n-__rte_unused static struct rte_flow *\n+static struct rte_flow *\n nfp_net_flow_table_search(struct nfp_net_priv *priv,\n \t\tstruct rte_flow *nfp_flow)\n {\n@@ -59,11 +60,58 @@ nfp_net_flow_table_search(struct nfp_net_priv *priv,\n \treturn flow_find;\n }\n \n-__rte_unused static struct rte_flow *\n-nfp_net_flow_alloc(uint32_t match_len,\n+static int\n+nfp_net_flow_position_acquire(struct nfp_net_priv *priv,\n+\t\tuint32_t priority,\n+\t\tstruct rte_flow *nfp_flow)\n+{\n+\tuint32_t i;\n+\n+\tif (priority != 0) {\n+\t\ti = NFP_NET_FLOW_LIMIT - priority - 1;\n+\n+\t\tif (priv->flow_position[i]) {\n+\t\t\tPMD_DRV_LOG(ERR, \"There is already a flow rule in this place.\");\n+\t\t\treturn -EAGAIN;\n+\t\t}\n+\n+\t\tpriv->flow_position[i] = true;\n+\t\tnfp_flow->position = priority;\n+\t\treturn 0;\n+\t}\n+\n+\tfor (i = 0; i < NFP_NET_FLOW_LIMIT; i++) {\n+\t\tif (!priv->flow_position[i]) {\n+\t\t\tpriv->flow_position[i] = true;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (i == NFP_NET_FLOW_LIMIT) {\n+\t\tPMD_DRV_LOG(ERR, \"The limited flow number is reach.\");\n+\t\treturn -ERANGE;\n+\t}\n+\n+\tnfp_flow->position = NFP_NET_FLOW_LIMIT - i - 1;\n+\n+\treturn 0;\n+}\n+\n+static void\n+nfp_net_flow_position_free(struct nfp_net_priv *priv,\n+\t\tstruct rte_flow *nfp_flow)\n+{\n+\tpriv->flow_position[nfp_flow->position] = false;\n+}\n+\n+static struct rte_flow *\n+nfp_net_flow_alloc(struct nfp_net_priv *priv,\n+\t\tuint32_t priority,\n+\t\tuint32_t match_len,\n \t\tuint32_t action_len,\n \t\tuint32_t port_id)\n {\n+\tint ret;\n \tchar *data;\n \tstruct rte_flow *nfp_flow;\n \tstruct nfp_net_flow_payload *payload;\n@@ -76,6 +124,10 @@ nfp_net_flow_alloc(uint32_t match_len,\n \tif (data == NULL)\n \t\tgoto free_flow;\n \n+\tret = nfp_net_flow_position_acquire(priv, priority, nfp_flow);\n+\tif (ret != 0)\n+\t\tgoto free_payload;\n+\n \tnfp_flow->port_id = port_id;\n \tpayload = &nfp_flow->payload;\n \tpayload->match_len = match_len;\n@@ -85,19 +137,362 @@ nfp_net_flow_alloc(uint32_t match_len,\n \n \treturn nfp_flow;\n \n+free_payload:\n+\trte_free(data);\n free_flow:\n \trte_free(nfp_flow);\n \n \treturn NULL;\n }\n \n-__rte_unused static void\n-nfp_net_flow_free(struct rte_flow *nfp_flow)\n+static void\n+nfp_net_flow_free(struct nfp_net_priv *priv,\n+\t\tstruct rte_flow *nfp_flow)\n {\n+\tnfp_net_flow_position_free(priv, nfp_flow);\n \trte_free(nfp_flow->payload.match_data);\n \trte_free(nfp_flow);\n }\n \n+static int\n+nfp_net_flow_calculate_items(const struct rte_flow_item items[],\n+\t\tuint32_t *match_len)\n+{\n+\tconst struct rte_flow_item *item;\n+\n+\tfor (item = items; item->type != RTE_FLOW_ITEM_TYPE_END; ++item) {\n+\t\tswitch (item->type) {\n+\t\tdefault:\n+\t\t\tPMD_DRV_LOG(ERR, \"Can't calculate match length\");\n+\t\t\t*match_len = 0;\n+\t\t\treturn -ENOTSUP;\n+\t\t}\n+\t}\n+\n+\treturn -EINVAL;\n+}\n+\n+static void\n+nfp_net_flow_process_priority(__rte_unused struct rte_flow *nfp_flow,\n+\t\tuint32_t match_len)\n+{\n+\tswitch (match_len) {\n+\tdefault:\n+\t\tbreak;\n+\t}\n+}\n+\n+static struct rte_flow *\n+nfp_net_flow_setup(struct rte_eth_dev *dev,\n+\t\tconst struct rte_flow_attr *attr,\n+\t\tconst struct rte_flow_item items[],\n+\t\t__rte_unused const struct rte_flow_action actions[])\n+{\n+\tint ret;\n+\tchar *hash_data;\n+\tuint32_t port_id;\n+\tuint32_t action_len;\n+\tstruct nfp_net_hw *hw;\n+\tuint32_t match_len = 0;\n+\tstruct nfp_net_priv *priv;\n+\tstruct rte_flow *nfp_flow;\n+\tstruct rte_flow *flow_find;\n+\tstruct nfp_app_fw_nic *app_fw_nic;\n+\n+\thw = dev->data->dev_private;\n+\tapp_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);\n+\tpriv = app_fw_nic->ports[hw->idx]->priv;\n+\n+\tret = nfp_net_flow_calculate_items(items, &match_len);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Key layers calculate failed.\");\n+\t\treturn NULL;\n+\t}\n+\n+\taction_len = sizeof(struct nfp_net_cmsg_action);\n+\tport_id = ((struct nfp_net_hw *)dev->data->dev_private)->nfp_idx;\n+\n+\tnfp_flow = nfp_net_flow_alloc(priv, attr->priority, match_len, action_len, port_id);\n+\tif (nfp_flow == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Alloc nfp flow failed.\");\n+\t\treturn NULL;\n+\t}\n+\n+\t/* Calculate and store the hash_key for later use */\n+\thash_data = nfp_flow->payload.match_data;\n+\tnfp_flow->hash_key = rte_jhash(hash_data, match_len + action_len,\n+\t\t\tpriv->hash_seed);\n+\n+\t/* Find the flow in hash table */\n+\tflow_find = nfp_net_flow_table_search(priv, nfp_flow);\n+\tif (flow_find != NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"This flow is already exist.\");\n+\t\tgoto free_flow;\n+\t}\n+\n+\tpriv->flow_count++;\n+\n+\tnfp_net_flow_process_priority(nfp_flow, match_len);\n+\n+\treturn nfp_flow;\n+\n+free_flow:\n+\tnfp_net_flow_free(priv, nfp_flow);\n+\n+\treturn NULL;\n+}\n+\n+static int\n+nfp_net_flow_teardown(struct nfp_net_priv *priv,\n+\t\t__rte_unused struct rte_flow *nfp_flow)\n+{\n+\tpriv->flow_count--;\n+\n+\treturn 0;\n+}\n+\n+static int\n+nfp_net_flow_offload(struct nfp_net_hw *hw,\n+\t\tstruct rte_flow *flow,\n+\t\tbool delete_flag)\n+{\n+\tint ret;\n+\tchar *tmp;\n+\tuint32_t msg_size;\n+\tstruct nfp_net_cmsg *cmsg;\n+\n+\tmsg_size = sizeof(uint32_t) + flow->payload.match_len +\n+\t\t\tflow->payload.action_len;\n+\tcmsg = nfp_net_cmsg_alloc(msg_size);\n+\tif (cmsg == NULL) {\n+\t\tPMD_DRV_LOG(ERR, \"Alloc cmsg failed.\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tcmsg->cmd = flow->payload.cmsg_type;\n+\tif (delete_flag)\n+\t\tcmsg->cmd++;\n+\n+\ttmp = (char *)cmsg->data;\n+\trte_memcpy(tmp, flow->payload.match_data, flow->payload.match_len);\n+\ttmp += flow->payload.match_len;\n+\trte_memcpy(tmp, flow->payload.action_data, flow->payload.action_len);\n+\n+\tret = nfp_net_cmsg_xmit(hw, cmsg, msg_size);\n+\tif (ret != 0) {\n+\t\tPMD_DRV_LOG(ERR, \"Send cmsg failed.\");\n+\t\tret = -EINVAL;\n+\t\tgoto free_cmsg;\n+\t}\n+\n+free_cmsg:\n+\tnfp_net_cmsg_free(cmsg);\n+\n+\treturn ret;\n+}\n+\n+static int\n+nfp_net_flow_validate(struct rte_eth_dev *dev,\n+\t\tconst struct rte_flow_attr *attr,\n+\t\tconst struct rte_flow_item items[],\n+\t\tconst struct rte_flow_action actions[],\n+\t\tstruct rte_flow_error *error)\n+{\n+\tint ret;\n+\tstruct nfp_net_hw *hw;\n+\tstruct rte_flow *nfp_flow;\n+\tstruct nfp_net_priv *priv;\n+\tstruct nfp_app_fw_nic *app_fw_nic;\n+\n+\thw = dev->data->dev_private;\n+\tapp_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);\n+\tpriv = app_fw_nic->ports[hw->idx]->priv;\n+\n+\tnfp_flow = nfp_net_flow_setup(dev, attr, items, actions);\n+\tif (nfp_flow == NULL) {\n+\t\treturn rte_flow_error_set(error, ENOTSUP,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\tNULL, \"This flow can not be offloaded.\");\n+\t}\n+\n+\tret = nfp_net_flow_teardown(priv, nfp_flow);\n+\tif (ret != 0) {\n+\t\treturn rte_flow_error_set(error, EINVAL,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\tNULL, \"Flow resource free failed.\");\n+\t}\n+\n+\tnfp_net_flow_free(priv, nfp_flow);\n+\n+\treturn 0;\n+}\n+\n+static struct rte_flow *\n+nfp_net_flow_create(struct rte_eth_dev *dev,\n+\t\tconst struct rte_flow_attr *attr,\n+\t\tconst struct rte_flow_item items[],\n+\t\tconst struct rte_flow_action actions[],\n+\t\tstruct rte_flow_error *error)\n+{\n+\tint ret;\n+\tstruct nfp_net_hw *hw;\n+\tstruct rte_flow *nfp_flow;\n+\tstruct nfp_net_priv *priv;\n+\tstruct nfp_app_fw_nic *app_fw_nic;\n+\n+\thw = dev->data->dev_private;\n+\tapp_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);\n+\tpriv = app_fw_nic->ports[hw->idx]->priv;\n+\n+\tnfp_flow = nfp_net_flow_setup(dev, attr, items, actions);\n+\tif (nfp_flow == NULL) {\n+\t\trte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\tNULL, \"This flow can not be offloaded.\");\n+\t\treturn NULL;\n+\t}\n+\n+\t/* Add the flow to flow hash table */\n+\tret = nfp_net_flow_table_add(priv, nfp_flow);\n+\tif (ret != 0) {\n+\t\trte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\tNULL, \"Add flow to the flow table failed.\");\n+\t\tgoto flow_teardown;\n+\t}\n+\n+\t/* Add the flow to hardware */\n+\tret = nfp_net_flow_offload(hw, nfp_flow, false);\n+\tif (ret != 0) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\tNULL, \"Add flow to firmware failed.\");\n+\t\tgoto table_delete;\n+\t}\n+\n+\treturn nfp_flow;\n+\n+table_delete:\n+\tnfp_net_flow_table_delete(priv, nfp_flow);\n+flow_teardown:\n+\tnfp_net_flow_teardown(priv, nfp_flow);\n+\tnfp_net_flow_free(priv, nfp_flow);\n+\n+\treturn NULL;\n+}\n+\n+static int\n+nfp_net_flow_destroy(struct rte_eth_dev *dev,\n+\t\tstruct rte_flow *nfp_flow,\n+\t\tstruct rte_flow_error *error)\n+{\n+\tint ret;\n+\tstruct nfp_net_hw *hw;\n+\tstruct nfp_net_priv *priv;\n+\tstruct rte_flow *flow_find;\n+\tstruct nfp_app_fw_nic *app_fw_nic;\n+\n+\thw = dev->data->dev_private;\n+\tapp_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);\n+\tpriv = app_fw_nic->ports[hw->idx]->priv;\n+\n+\t/* Find the flow in flow hash table */\n+\tflow_find = nfp_net_flow_table_search(priv, nfp_flow);\n+\tif (flow_find == NULL) {\n+\t\trte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\tNULL, \"Flow does not exist.\");\n+\t\tret = -EINVAL;\n+\t\tgoto exit;\n+\t}\n+\n+\t/* Delete the flow from hardware */\n+\tret = nfp_net_flow_offload(hw, nfp_flow, true);\n+\tif (ret != 0) {\n+\t\trte_flow_error_set(error, EINVAL,\n+\t\t\t\tRTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\tNULL, \"Delete flow from firmware failed.\");\n+\t\tret = -EINVAL;\n+\t\tgoto exit;\n+\t}\n+\n+\t/* Delete the flow from flow hash table */\n+\tret = nfp_net_flow_table_delete(priv, nfp_flow);\n+\tif (ret != 0) {\n+\t\trte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\tNULL, \"Delete flow from the flow table failed.\");\n+\t\tret = -EINVAL;\n+\t\tgoto exit;\n+\t}\n+\n+\tret = nfp_net_flow_teardown(priv, nfp_flow);\n+\tif (ret != 0) {\n+\t\trte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\tNULL, \"Flow teardown failed.\");\n+\t\tret = -EINVAL;\n+\t\tgoto exit;\n+\t}\n+\n+exit:\n+\tnfp_net_flow_free(priv, nfp_flow);\n+\n+\treturn ret;\n+}\n+\n+static int\n+nfp_net_flow_flush(struct rte_eth_dev *dev,\n+\t\tstruct rte_flow_error *error)\n+{\n+\tint ret = 0;\n+\tvoid *next_data;\n+\tuint32_t iter = 0;\n+\tconst void *next_key;\n+\tstruct nfp_net_hw *hw;\n+\tstruct rte_flow *nfp_flow;\n+\tstruct rte_hash *flow_table;\n+\tstruct nfp_app_fw_nic *app_fw_nic;\n+\n+\thw = dev->data->dev_private;\n+\tapp_fw_nic = NFP_PRIV_TO_APP_FW_NIC(hw->pf_dev->app_fw_priv);\n+\tflow_table = app_fw_nic->ports[hw->idx]->priv->flow_table;\n+\n+\twhile (rte_hash_iterate(flow_table, &next_key, &next_data, &iter) >= 0) {\n+\t\tnfp_flow = next_data;\n+\t\tret = nfp_net_flow_destroy(dev, nfp_flow, error);\n+\t\tif (ret != 0)\n+\t\t\tbreak;\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static const struct rte_flow_ops nfp_net_flow_ops = {\n+\t.validate = nfp_net_flow_validate,\n+\t.create = nfp_net_flow_create,\n+\t.destroy = nfp_net_flow_destroy,\n+\t.flush = nfp_net_flow_flush,\n+};\n+\n+int\n+nfp_net_flow_ops_get(struct rte_eth_dev *dev,\n+\t\tconst struct rte_flow_ops **ops)\n+{\n+\tstruct nfp_net_hw *hw;\n+\n+\tif ((dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) != 0) {\n+\t\t*ops = NULL;\n+\t\tPMD_DRV_LOG(ERR, \"Port is a representor.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\thw = dev->data->dev_private;\n+\tif ((hw->super.cap_ext & NFP_NET_CFG_CTRL_FLOW_STEER) == 0) {\n+\t\t*ops = NULL;\n+\t\treturn 0;\n+\t}\n+\n+\t*ops = &nfp_net_flow_ops;\n+\n+\treturn 0;\n+}\n+\n int\n nfp_net_flow_priv_init(struct nfp_pf_dev *pf_dev,\n \t\tuint16_t port)\ndiff --git a/drivers/net/nfp/nfp_net_flow.h b/drivers/net/nfp/nfp_net_flow.h\nindex 5ec80ba3b6..558cd0e2bb 100644\n--- a/drivers/net/nfp/nfp_net_flow.h\n+++ b/drivers/net/nfp/nfp_net_flow.h\n@@ -20,9 +20,11 @@ struct rte_flow {\n \tstruct nfp_net_flow_payload payload;\n \tuint32_t hash_key;\n \tuint32_t port_id;\n+\tuint32_t position; /**< Use as priority */\n };\n \n int nfp_net_flow_priv_init(struct nfp_pf_dev *pf_dev, uint16_t port);\n void nfp_net_flow_priv_uninit(struct nfp_pf_dev *pf_dev, uint16_t port);\n+int nfp_net_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops);\n \n #endif /* __NFP_NET_FLOW_H__ */\n", "prefixes": [ "04/11" ] }{ "id": 133810, "url": "