From patchwork Tue Jan 23 13:59:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shreyansh Jain X-Patchwork-Id: 34353 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7E1E51B1C8; Tue, 23 Jan 2018 15:25:47 +0100 (CET) Received: from NAM01-BY2-obe.outbound.protection.outlook.com (mail-by2nam01hn0211.outbound.protection.outlook.com [104.47.34.211]) by dpdk.org (Postfix) with ESMTP id 2AFF71B172 for ; Tue, 23 Jan 2018 15:25:00 +0100 (CET) Received: from BN6PR03CA0080.namprd03.prod.outlook.com (10.164.122.146) by BY2PR03MB476.namprd03.prod.outlook.com (10.141.141.153) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.428.17; Tue, 23 Jan 2018 14:24:52 +0000 Received: from BY2FFO11FD043.protection.gbl (2a01:111:f400:7c0c::115) by BN6PR03CA0080.outlook.office365.com (2603:10b6:405:6f::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.428.17 via Frontend Transport; Tue, 23 Jan 2018 14:24:52 +0000 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; dpdk.org; dkim=none (message not signed) header.d=none;dpdk.org; dmarc=fail action=none header.from=nxp.com; Received-SPF: Fail (protection.outlook.com: domain of nxp.com does not designate 192.88.168.50 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.168.50; helo=tx30smr01.am.freescale.net; Received: from tx30smr01.am.freescale.net (192.88.168.50) by BY2FFO11FD043.mail.protection.outlook.com (10.1.14.228) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.428.12 via Frontend Transport; Tue, 23 Jan 2018 14:24:49 +0000 Received: from Tophie.ap.freescale.net ([10.232.14.39]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id w0NDj5Ri022838; Tue, 23 Jan 2018 06:45:30 -0700 From: Shreyansh Jain To: , CC: , , , Shreyansh Jain Date: Tue, 23 Jan 2018 19:29:07 +0530 Message-ID: <20180123135910.10755-8-shreyansh.jain@nxp.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180123135910.10755-1-shreyansh.jain@nxp.com> References: <20180102125749.2379-1-shreyansh.jain@nxp.com> <20180123135910.10755-1-shreyansh.jain@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131611910918405395; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:SPM; SFS:(10009020)(376002)(346002)(396003)(39860400002)(39380400002)(2980300002)(1110001)(1109001)(339900001)(199004)(189003)(68736007)(51416003)(105606002)(47776003)(110136005)(54906003)(2906002)(106466001)(53936002)(97736004)(81166006)(16586007)(26005)(2950100002)(5890100001)(6666003)(5660300001)(498600001)(81156014)(8676002)(8936002)(356003)(86362001)(50226002)(36756003)(316002)(48376002)(50466002)(575784001)(77096007)(59450400001)(305945005)(104016004)(1076002)(336011)(4326008)(76176011)(85426001)(59010400001); DIR:OUT; SFP:1501; SCL:5; SRVR:BY2PR03MB476; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BY2FFO11FD043; 1:Hp7WaUu+74OET6l20AuKDLU08e3pVOExb+L5PN/MR+iFG3zZVT/vDLbk1sXS7oMLSwwBijnO38zuk1iM0CBK/+2W9hgLtWASlzcms8/5wPCyqhnRtCZgmd9fvkiv7dXu MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1a565d19-1028-4f6e-10aa-08d5626d10e2 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(5600026)(4604075)(2017052603307); SRVR:BY2PR03MB476; X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 3:0AjmAlkomgruK3z9v3e13/spDoQfVfSwOkTq/Mw+fUgSph9tOIrHxRwVBAzGLgQzOFjnlBeBUk0XpGuOvixQeuv6KcZ52DiZnvvDngCWBPQoM5ouSCDS2Rs6rwY1gmWI/xc60HIVpvZnPCAz1ilwpGbOhVGBXahxCN8I21VgN7SX7uJgjNABBQLajbFR6SmzLazqb+2N8QvPSRVqwrJf2egE596ndVzKPvY6lfgcRzIphSl5m/dVaSEiEmtyvB4QTZ6UaRCQjk+STOvLqBgqCWtvpob1OluhaowgFMgzLY8T1lJWL5C0PzYpkB0Xr79DfhWTKvvdk3dZu/ac2nNTZP7bz+7FXpyb25xugu/ZyOI=; 25:dpp+Ybb9vMDDd9CMAVv8/ll2HozcFzi47SACKHmIny6PPd9qqRpCGdYmT8X8HbWJvT9cIngqEr0FU0zEkATpa5Y74rwZ8WFnZVOLjCyHDE2Xgntzc4zNJBd3O9lMhchsYiIPgvV0Xgxl1ABuQIwHKNDZBolTRFU4q6D35Am/ZQ86AbrT6AaeQGyY2m1Ni5cptiv3jVKO6TiQU8qZssV/D5mIM3pyS+4UjIkxh0aimKCs8I4wLwXmI3BXzYPe0JbM3I944fApQPfcs54Mwlxxph1EC1Rs/5VaKqi/TxJkjodydHgVEXmxN7gKgpHMmoW1GeRQ9Hf2bsmPazO1gQLsZQ== X-MS-TrafficTypeDiagnostic: BY2PR03MB476: X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 31:pqzwnCY4QCg/t3ayOQPBSv0yvBe8IdVUqug5+7MY7235P8jOKZQ90B1WEt4hHsIzxWK/ZnlIO7jLc11qVDmvpSlczA0SJsqfwEKK4k20ZpjlTH7eT9zfYE1xYx+erqizMRWlaHFZjvPuuD+6koPZGxp4KT2teVeOpnHHno3iWy33I+wgfdRggr2JpD52XObQxHGTXjUp2iaoTCwXopjw48N3oHVdXBHkHeBNqwjvq1w=; 4:9a0f0iWeoVxcyhrCXo4Fp48sVa1hkfk4xbQiIY6EH0D+ED1weYz6MRvxGhg/eSV4FSNZliyqg3Tqe3dWGpoEVk1qCD4FY7MGGzNSyACjoB/9cAzST+seNwjCRDSA38GlLw0XR4Ybq7NxnSFBeTl0pyVe53j8GWk24W9CjbtqtZQGKJFAMM1N2mUby54yHrOzdbJUOVIeoMgojazMWuJpzcIFyWdZtlmEAnhAhVolZOsnHyQumku+H7tGFwGGJREkvLkvf4Oc618d0X5Xdxe7PR2EQmAN1zv7O+wdm64lcgSArm0mtTEjNpSnfC9nbgJPsfoABc/geiytBYd5lwKiUSBLM/gz9IqDC3O0YZ/QeV0= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197)(66839620246622); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6095135)(2401047)(5005006)(8121501046)(3231023)(2232076)(944501161)(93006095)(93001095)(3002001)(10201501046)(6055026)(6096035)(20161123565025)(20161123563025)(20161123561025)(201703131430075)(201703131433075)(201703131448075)(201703151042153)(20161123559100)(20161123556025)(201708071742011); SRVR:BY2PR03MB476; BCL:0; PCL:0; RULEID:(100000803101)(100110400095)(400006); SRVR:BY2PR03MB476; X-Forefront-PRVS: 05610E64EE X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY2PR03MB476; 23:72rGfDpJ8Z8cQhRG15hmnBtM18z3bB1ZYJzcRgLenD?= UqZ5Q1t8hSgMcXNil4hIwF07TnLR1YKysm1M29JP5fX5wOvTgPIn1rCbrWSIRPwqDQb511hS1wA7/9O5oSR+gZWMecl9iUrn+0ZvqpulODnD0KksyzRVcwrU93+GDbR/haNpKLr7iHfauHp7z2IRMCBk/OdFlLXzxeXOZETacUtiCnJgZ/8FqvB2LVyJ42Uvejs4v+3G3qmC+woCTI7dYIcQYYK+2eTAoOr7eovjFfcKfelkzAwMjg8GQdi7wS4T+kg7yCzGUs1txxO7N0GQpWBRsr+swpCJspw22W1vuVRikx3PUz7DB2n3kKDdiXmYfXB8SSRdmNo8St8S1bmSkq5Rk864qDeFX2jN9rP4oSWjfEX9j88K441UcRUj6yrMzch8dSa1SJGX6Rw+lJQcrWZs4YJaLdD/yfdizD3cs9kWF1mhkYrOuejCUiBV0SMDxuzF2Uu+BYCs83nqT6zrG9JQFi/Gz/WeCd8Zm/F4uTrj2xQT22Z0kdnWC+Nz0xl8QKVsysiY1yrLK5CAuYH3zYQuuwpA56At9NFOtbUgSM0LHbeOpxpp2+/ee5TxF0GzUY9l3fLUp/+J+TeQckJ5j8t/dgIM9eCOSmf1+I5rWIlv+xJXU7qNIQgyFZo+yF0tW3krwDzD8aDKCAxp+r8hWE0EXLra17TkA+Ff1ufIJzzta4QTn9i/yKVefV/0Hn+2wQ9MPkqilyElHsdakm1547MfkT5RS+yd+a8Dez0VTyCJNI6EeARHB+26M5aJ69uPxqYQAXsvjFeYrk9VM3FXBBE5n8YhVCMyi1c0AK2BhY3CPG+B2NSNqTq3c9tu70ZggydG0MbGJLa4HhyvrYdgIVwf99mI0Fu5yn1SEenXXUO45tEkp+VLtpB1e3a3o8r/mHg89DA3aD54U5O6NvtkPQTwKtbhamkQZ33/7ZiFVNUYexttk88Y8n05/YUq7rx5QZ3iOoVD17ulo1R7qgd77hig41YqGv3yc4uXkWETQ+6AXP4t62RvXRObjwI554zwcWkLYh8QjXi9X8CvPK/zm+mIvBdZsQPi5gw4vUriRM/AvYck2KR2MpzhrAhak+QgeaCQoEb5chPyshQxDBuK5mVXdEU1mqoBhvIZ5ntJ6ybwbG2QrHB73IxB8zRcwBviipqnpPOLZVbNU9uuZjcoGsbeihvKx7Rvu1VunWdmBQ6Q== X-Microsoft-Antispam-Message-Info: idx/5lU38K5akRzi8EcDyb8GHfWvrEZ+KBB5y544jZojKNREAC7vXFj5UGLVzS8RiWrU/vNN6CH4TbaVtw5etjOLnUx3TjOeZEZyEOpMlaGzz4e1BkG+5qJEeeKGLMzxTONUwrKNsuiIAOUMxlNTE+TTh+ACQr9W08yJU+SVFYk= X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 6:Qk0NFAmsQepRCVC/BovAwyCPYwWJmFi+oqnUoeP9t/IuVd+uCNUDDK3U9uuVlFVw0Iy8F/wyhGgdZbrKtjxbJPnh+3XltqC7zW09YbOFeAjRiUwG6rQebSiatmfJFOYgPK9dfxQR5eoKF/j7RSs4KUPkEWqPOSxr0EwXW+LADoTDxRAET7RGw8yON4SZxkTnJLXMr+xU0mqy44UkTZzakNL4J5conHWKYOVNxX4fHTR+rBAtlO74mFVQVkrWCtHBUnyRNLPeBaypoDw06rLSIq2h2kARqGQsbLLgArBkQ0MMHqr+SgnCYqBe/u0bY7rTftFmGhbezZo46ybDfKwKKIoGY+Ros1iFxRzRfBpyG4M=; 5:mb3+vPtvqNpifXYBP121U//Kzrpd3bkMSBMXRQ31MT1KLiMQUZo3obYyGnt46qjJHBLTwkO3rTVBLRdNE3taMEEjdSTYAynXkJOU7ldAy10yCi4ezeCitm+JRQOVafWwisVz+hpp23M5aQrJRUsECBl9xfU/VcNQLxoiS5B/lJo=; 24:7tbNkY/gWvHjThAYunv6G3EsaHqDJwQZ4oVNUIdYSjirWXiS53tI9NmGRv6UIZ3KMUmnmQxm2GGg16utkHU73g==; 7:iUgQOb1oi2vAsjZ4mkt90G2Npi/XA54eScIx4GwKSxu9pVjy6gb16hzugDAYkPQ2lF1DcZYBIthqaSN1xr/imJfjGzyjjfe4/+NcsdaefEC0tKOP1RHyKBnL4mSTrO6btShdsB0k6fS1VfWlm54yEXDrz6inGXEHg1J3K0Hrqf6cMTEJohIEhY4+JXDtMOB5/ahfW+6fXtgK1sMmSAEtfddCuw5T75GhDyAciJcKbIJTA8qMt1xVWoJgZe62Z+Vx SpamDiagnosticOutput: 1:22 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Jan 2018 14:24:49.8749 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 1a565d19-1028-4f6e-10aa-08d5626d10e2 X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR03MB476 Subject: [dpdk-dev] [PATCH v2 07/10] drivers/raw: introduce skeleton rawdev driver X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Skeleton rawdevice driver, on the lines of eventdev skeleton, is for showcasing the rawdev library. This driver implements some of the operations of the library based on which a test module can be developed. Design of skeleton involves a virtual device which is plugged into VDEV bus on initialization. Also, enable compilation of rawdev skeleton driver. Signed-off-by: Shreyansh Jain --- config/common_base | 1 + drivers/Makefile | 2 + drivers/raw/Makefile | 9 + drivers/raw/skeleton_rawdev/Makefile | 25 + .../rte_pmd_skeleton_rawdev_version.map | 4 + drivers/raw/skeleton_rawdev/skeleton_rawdev.c | 690 +++++++++++++++++++++ drivers/raw/skeleton_rawdev/skeleton_rawdev.h | 136 ++++ mk/rte.app.mk | 4 + 8 files changed, 871 insertions(+) create mode 100644 drivers/raw/Makefile create mode 100644 drivers/raw/skeleton_rawdev/Makefile create mode 100644 drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.c create mode 100644 drivers/raw/skeleton_rawdev/skeleton_rawdev.h diff --git a/config/common_base b/config/common_base index b8bd25b15..b0f6042d3 100644 --- a/config/common_base +++ b/config/common_base @@ -811,6 +811,7 @@ CONFIG_RTE_LIBRTE_VHOST_DEBUG=n # CONFIG_RTE_LIBRTE_RAWDEV=y CONFIG_RTE_RAWDEV_MAX_DEVS=10 +CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV=y # # Compile vhost PMD diff --git a/drivers/Makefile b/drivers/Makefile index e0488aa2b..ee65c87b0 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -14,5 +14,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto DEPDIRS-crypto := bus mempool DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event DEPDIRS-event := bus mempool net +DIRS-$(CONFIG_RTE_LIBRTE_RAWDEV) += raw +DEPDIRS-raw := bus mempool net event include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile new file mode 100644 index 000000000..da7c8b449 --- /dev/null +++ b/drivers/raw/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2017 NXP + +include $(RTE_SDK)/mk/rte.vars.mk + +# DIRS-$() += +DIRS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev + +include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/drivers/raw/skeleton_rawdev/Makefile b/drivers/raw/skeleton_rawdev/Makefile new file mode 100644 index 000000000..4d9b2f804 --- /dev/null +++ b/drivers/raw/skeleton_rawdev/Makefile @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2017 NXP + +include $(RTE_SDK)/mk/rte.vars.mk + +# +# library name +# +LIB = librte_pmd_skeleton_rawdev.a + +CFLAGS += $(WERROR_FLAGS) +LDLIBS += -lrte_eal +LDLIBS += -lrte_rawdev +LDLIBS += -lrte_bus_vdev + +EXPORT_MAP := rte_pmd_skeleton_rawdev_version.map + +LIBABIVER := 1 + +# +# all source are stored in SRCS-y +# +SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += skeleton_rawdev.c + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map b/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map new file mode 100644 index 000000000..179140fb8 --- /dev/null +++ b/drivers/raw/skeleton_rawdev/rte_pmd_skeleton_rawdev_version.map @@ -0,0 +1,4 @@ +DPDK_18.02 { + + local: *; +}; diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.c b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c new file mode 100644 index 000000000..b38188e11 --- /dev/null +++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c @@ -0,0 +1,690 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2017 NXP + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "skeleton_rawdev.h" + +/* Dynamic log type identifier */ +int skeleton_pmd_logtype; + +/* Count of instances */ +uint16_t skeldev_init_once; + +/**< Rawdev Skeleton dummy driver name */ +#define SKELETON_PMD_RAWDEV_NAME rawdev_skeleton + +/**< Skeleton rawdev driver object */ +static struct rte_vdev_driver skeleton_pmd_drv; + +struct queue_buffers { + void *bufs[SKELETON_QUEUE_MAX_DEPTH]; +}; + +static struct queue_buffers queue_buf[SKELETON_MAX_QUEUES] = {0}; +static void clear_queue_bufs(int queue_id); + +static void skeleton_rawdev_info_get(struct rte_rawdev *dev, + rte_rawdev_obj_t dev_info) +{ + struct skeleton_rawdev *skeldev; + struct skeleton_rawdev_conf *skeldev_conf; + + SKELETON_PMD_FUNC_TRACE(); + + if (!dev_info) { + SKELETON_PMD_ERR("Invalid request"); + return; + } + + skeldev = skeleton_rawdev_get_priv(dev); + + skeldev_conf = dev_info; + + skeldev_conf->num_queues = skeldev->num_queues; + skeldev_conf->capabilities = skeldev->capabilities; + skeldev_conf->device_state = skeldev->device_state; + skeldev_conf->firmware_state = skeldev->fw.firmware_state; +} + +static int skeleton_rawdev_configure(const struct rte_rawdev *dev, + rte_rawdev_obj_t config) +{ + struct skeleton_rawdev *skeldev; + struct skeleton_rawdev_conf *skeldev_conf; + + SKELETON_PMD_FUNC_TRACE(); + + RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); + + if (!config) { + SKELETON_PMD_ERR("Invalid configuration"); + return -EINVAL; + } + + skeldev_conf = config; + skeldev = skeleton_rawdev_get_priv(dev); + + if (skeldev_conf->num_queues <= SKELETON_MAX_QUEUES) + skeldev->num_queues = skeldev_conf->num_queues; + else + return -EINVAL; + + skeldev->capabilities = skeldev_conf->capabilities; + skeldev->num_queues = skeldev_conf->num_queues; + + return 0; +} + +static int skeleton_rawdev_start(struct rte_rawdev *dev) +{ + int ret = 0; + struct skeleton_rawdev *skeldev; + enum skeleton_firmware_state fw_state; + enum skeleton_device_state device_state; + + SKELETON_PMD_FUNC_TRACE(); + + RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); + + skeldev = skeleton_rawdev_get_priv(dev); + + fw_state = skeldev->fw.firmware_state; + device_state = skeldev->device_state; + + if (fw_state == SKELETON_FW_LOADED && + device_state == SKELETON_DEV_STOPPED) { + skeldev->device_state = SKELETON_DEV_RUNNING; + } else { + SKELETON_PMD_ERR("Device not ready for starting"); + ret = -EINVAL; + } + + return ret; +} + +static void skeleton_rawdev_stop(struct rte_rawdev *dev) +{ + struct skeleton_rawdev *skeldev; + + SKELETON_PMD_FUNC_TRACE(); + + if (dev) { + skeldev = skeleton_rawdev_get_priv(dev); + skeldev->device_state = SKELETON_DEV_STOPPED; + } +} + +static void +reset_queues(struct skeleton_rawdev *skeldev) +{ + int i; + + for (i = 0; i < SKELETON_MAX_QUEUES; i++) { + skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH; + skeldev->queues[i].state = SKELETON_QUEUE_DETACH; + } +} + +static void +reset_attribute_table(struct skeleton_rawdev *skeldev) +{ + int i; + + for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) { + if (skeldev->attr[i].name) { + free(skeldev->attr[i].name); + skeldev->attr[i].name = NULL; + } + } +} + +static int skeleton_rawdev_close(struct rte_rawdev *dev) +{ + int ret = 0, i; + struct skeleton_rawdev *skeldev; + enum skeleton_firmware_state fw_state; + enum skeleton_device_state device_state; + + SKELETON_PMD_FUNC_TRACE(); + + RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); + + skeldev = skeleton_rawdev_get_priv(dev); + + fw_state = skeldev->fw.firmware_state; + device_state = skeldev->device_state; + + reset_queues(skeldev); + reset_attribute_table(skeldev); + + switch (fw_state) { + case SKELETON_FW_LOADED: + if (device_state == SKELETON_DEV_RUNNING) { + SKELETON_PMD_ERR("Cannot close running device"); + ret = -EINVAL; + } else { + /* Probably call fw reset here */ + skeldev->fw.firmware_state = SKELETON_FW_READY; + } + break; + case SKELETON_FW_READY: + case SKELETON_FW_ERROR: + default: + SKELETON_PMD_DEBUG("Device already in stopped state"); + ret = -EINVAL; + break; + } + + /* Clear all allocated queues */ + for (i = 0; i < SKELETON_MAX_QUEUES; i++) + clear_queue_bufs(i); + + return ret; +} + +static int skeleton_rawdev_reset(struct rte_rawdev *dev) +{ + struct skeleton_rawdev *skeldev; + + SKELETON_PMD_FUNC_TRACE(); + + RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); + + skeldev = skeleton_rawdev_get_priv(dev); + + SKELETON_PMD_DEBUG("Reseting device"); + skeldev->fw.firmware_state = SKELETON_FW_READY; + + return 0; +} + +static void skeleton_rawdev_queue_def_conf(struct rte_rawdev *dev, + uint16_t queue_id, + rte_rawdev_obj_t queue_conf) +{ + struct skeleton_rawdev *skeldev; + struct skeleton_rawdev_queue *skelq; + + SKELETON_PMD_FUNC_TRACE(); + + if (!dev || !queue_conf) + return; + + skeldev = skeleton_rawdev_get_priv(dev); + skelq = &skeldev->queues[queue_id]; + + if (queue_id < SKELETON_MAX_QUEUES) + rte_memcpy(queue_conf, skelq, + sizeof(struct skeleton_rawdev_queue)); +} + +static void +clear_queue_bufs(int queue_id) +{ + int i; + + /* Clear buffers for queue_id */ + for (i = 0; i < SKELETON_QUEUE_MAX_DEPTH; i++) + queue_buf[queue_id].bufs[i] = NULL; +} + +static int skeleton_rawdev_queue_setup(struct rte_rawdev *dev, + uint16_t queue_id, + rte_rawdev_obj_t queue_conf) +{ + int ret = 0; + struct skeleton_rawdev *skeldev; + struct skeleton_rawdev_queue *q; + + SKELETON_PMD_FUNC_TRACE(); + + if (!dev || !queue_conf) + return -EINVAL; + + skeldev = skeleton_rawdev_get_priv(dev); + q = &skeldev->queues[queue_id]; + + if (skeldev->num_queues > queue_id && + q->depth < SKELETON_QUEUE_MAX_DEPTH) { + rte_memcpy(q, queue_conf, + sizeof(struct skeleton_rawdev_queue)); + clear_queue_bufs(queue_id); + } else { + SKELETON_PMD_ERR("Invalid queue configuration"); + ret = -EINVAL; + } + + return ret; +} + +static int skeleton_rawdev_queue_release(struct rte_rawdev *dev, + uint16_t queue_id) +{ + int ret = 0; + struct skeleton_rawdev *skeldev; + + SKELETON_PMD_FUNC_TRACE(); + + RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); + + skeldev = skeleton_rawdev_get_priv(dev); + + if (skeldev->num_queues > queue_id) { + skeldev->queues[queue_id].state = SKELETON_QUEUE_DETACH; + skeldev->queues[queue_id].depth = SKELETON_QUEUE_DEF_DEPTH; + clear_queue_bufs(queue_id); + } else { + SKELETON_PMD_ERR("Invalid queue configuration"); + ret = -EINVAL; + } + + return ret; +} + +static int skeleton_rawdev_get_attr(struct rte_rawdev *dev, + const char *attr_name, + uint64_t *attr_value) +{ + int i; + uint8_t done = 0; + struct skeleton_rawdev *skeldev; + + SKELETON_PMD_FUNC_TRACE(); + + if (!dev || !attr_name || !attr_value) { + SKELETON_PMD_ERR("Invalid arguments for getting attributes"); + return -EINVAL; + } + + skeldev = skeleton_rawdev_get_priv(dev); + + for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) { + if (!skeldev->attr[i].name) + continue; + + if (!strncmp(skeldev->attr[i].name, attr_name, + SKELETON_ATTRIBUTE_NAME_MAX)) { + *attr_value = skeldev->attr[i].value; + done = 1; + SKELETON_PMD_DEBUG("Attribute (%s) Value (%lu)", + attr_name, *attr_value); + break; + } + } + + if (done) + return 0; + + /* Attribute not found */ + return -EINVAL; +} + +static int skeleton_rawdev_set_attr(struct rte_rawdev *dev, + const char *attr_name, + const uint64_t attr_value) +{ + int i; + uint8_t done = 0; + struct skeleton_rawdev *skeldev; + + SKELETON_PMD_FUNC_TRACE(); + + if (!dev || !attr_name) { + SKELETON_PMD_ERR("Invalid arguments for setting attributes"); + return -EINVAL; + } + + skeldev = skeleton_rawdev_get_priv(dev); + + /* Check if attribute already exists */ + for (i = 0; i < SKELETON_MAX_ATTRIBUTES; i++) { + if (!skeldev->attr[i].name) + break; + + if (!strncmp(skeldev->attr[i].name, attr_name, + SKELETON_ATTRIBUTE_NAME_MAX)) { + /* Update value */ + skeldev->attr[i].value = attr_value; + done = 1; + break; + } + } + + if (!done) { + if (i < (SKELETON_MAX_ATTRIBUTES - 1)) { + /* There is still space to insert one more */ + skeldev->attr[i].name = strdup(attr_name); + if (!skeldev->attr[i].name) + return -ENOMEM; + + skeldev->attr[i].value = attr_value; + return 0; + } + } + + return -EINVAL; +} + +static int skeleton_rawdev_enqueue_bufs(struct rte_rawdev *dev, + struct rte_rawdev_buf **buffers, + unsigned int count, + rte_rawdev_obj_t context) +{ + unsigned int i; + uint16_t q_id; + RTE_SET_USED(dev); + + /* context is essentially the queue_id which is + * transferred as opaque object through the library layer. This can + * help in complex implementation which require more information than + * just an integer - for example, a queue-pair. + */ + q_id = *((int *)context); + + for (i = 0; i < count; i++) + queue_buf[q_id].bufs[i] = buffers[i]->buf_addr; + + return i; +} + +static int skeleton_rawdev_dequeue_bufs(struct rte_rawdev *dev, + struct rte_rawdev_buf **buffers, + unsigned int count, + rte_rawdev_obj_t context) +{ + unsigned int i; + uint16_t q_id; + RTE_SET_USED(dev); + + /* context is essentially the queue_id which is + * transferred as opaque object through the library layer. This can + * help in complex implementation which require more information than + * just an integer - for example, a queue-pair. + */ + q_id = *((int *)context); + + for (i = 0; i < count; i++) + buffers[i]->buf_addr = queue_buf[q_id].bufs[i]; + + return i; +} + +static int skeleton_rawdev_dump(struct rte_rawdev *dev, FILE *f) +{ + RTE_SET_USED(dev); + RTE_SET_USED(f); + + return 0; +} + +static int skeleton_rawdev_firmware_status_get(struct rte_rawdev *dev, + rte_rawdev_obj_t status_info) +{ + struct skeleton_rawdev *skeldev; + + SKELETON_PMD_FUNC_TRACE(); + + skeldev = skeleton_rawdev_get_priv(dev); + + RTE_FUNC_PTR_OR_ERR_RET(dev, -EINVAL); + + if (status_info) + memcpy(status_info, &skeldev->fw.firmware_state, + sizeof(enum skeleton_firmware_state)); + + return 0; +} + + +static int skeleton_rawdev_firmware_version_get( + struct rte_rawdev *dev, + rte_rawdev_obj_t version_info) +{ + struct skeleton_rawdev *skeldev; + struct skeleton_firmware_version_info *vi; + + SKELETON_PMD_FUNC_TRACE(); + + skeldev = skeleton_rawdev_get_priv(dev); + vi = version_info; + + vi->major = skeldev->fw.firmware_version.major; + vi->minor = skeldev->fw.firmware_version.minor; + vi->subrel = skeldev->fw.firmware_version.subrel; + + return 0; +} + +static int skeleton_rawdev_firmware_load(struct rte_rawdev *dev, + rte_rawdev_obj_t firmware_buf) +{ + struct skeleton_rawdev *skeldev; + + SKELETON_PMD_FUNC_TRACE(); + + skeldev = skeleton_rawdev_get_priv(dev); + + /* firmware_buf is a mmaped, possibly DMA'able area, buffer. Being + * dummy, all this does is check if firmware_buf is not NULL and + * sets the state of the firmware. + */ + if (!firmware_buf) + return -EINVAL; + + skeldev->fw.firmware_state = SKELETON_FW_LOADED; + + return 0; +} + +static int skeleton_rawdev_firmware_unload(struct rte_rawdev *dev) +{ + struct skeleton_rawdev *skeldev; + + SKELETON_PMD_FUNC_TRACE(); + + skeldev = skeleton_rawdev_get_priv(dev); + + skeldev->fw.firmware_state = SKELETON_FW_READY; + + return 0; +} + +static const struct rte_rawdev_ops skeleton_rawdev_ops = { + .dev_info_get = skeleton_rawdev_info_get, + .dev_configure = skeleton_rawdev_configure, + .dev_start = skeleton_rawdev_start, + .dev_stop = skeleton_rawdev_stop, + .dev_close = skeleton_rawdev_close, + .dev_reset = skeleton_rawdev_reset, + + .queue_def_conf = skeleton_rawdev_queue_def_conf, + .queue_setup = skeleton_rawdev_queue_setup, + .queue_release = skeleton_rawdev_queue_release, + + .attr_get = skeleton_rawdev_get_attr, + .attr_set = skeleton_rawdev_set_attr, + + .enqueue_bufs = skeleton_rawdev_enqueue_bufs, + .dequeue_bufs = skeleton_rawdev_dequeue_bufs, + + .dump = skeleton_rawdev_dump, + + .xstats_get = NULL, + .xstats_get_names = NULL, + .xstats_get_by_name = NULL, + .xstats_reset = NULL, + + .firmware_status_get = skeleton_rawdev_firmware_status_get, + .firmware_version_get = skeleton_rawdev_firmware_version_get, + .firmware_load = skeleton_rawdev_firmware_load, + .firmware_unload = skeleton_rawdev_firmware_unload, +}; + +static int +skeleton_rawdev_create(const char *name, + struct rte_vdev_device *vdev, + int socket_id) +{ + int ret = 0, i; + struct rte_rawdev *rawdev = NULL; + struct skeleton_rawdev *skeldev = NULL; + + if (!name) { + SKELETON_PMD_ERR("Invalid name of the device!"); + ret = -EINVAL; + goto cleanup; + } + + /* Allocate device structure */ + rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct skeleton_rawdev), + socket_id); + if (rawdev == NULL) { + SKELETON_PMD_ERR("Unable to allocate rawdevice"); + ret = -EINVAL; + goto cleanup; + } + + rawdev->dev_ops = &skeleton_rawdev_ops; + rawdev->device = &vdev->device; + rawdev->driver_name = vdev->device.driver->name; + + skeldev = skeleton_rawdev_get_priv(rawdev); + + skeldev->device_id = SKELETON_DEVICE_ID; + skeldev->vendor_id = SKELETON_VENDOR_ID; + skeldev->capabilities = SKELETON_DEFAULT_CAPA; + + memset(&skeldev->fw, 0, sizeof(struct skeleton_firmware)); + + skeldev->fw.firmware_state = SKELETON_DEV_STOPPED; + skeldev->fw.firmware_version.major = SKELETON_MAJOR_VER; + skeldev->fw.firmware_version.minor = SKELETON_MINOR_VER; + skeldev->fw.firmware_version.subrel = SKELETON_SUB_VER; + + skeldev->device_state = SKELETON_DEV_STOPPED; + + /* Reset/set to default queue configuration for this device */ + for (i = 0; i < SKELETON_MAX_QUEUES; i++) { + skeldev->queues[i].state = SKELETON_QUEUE_DETACH; + skeldev->queues[i].depth = SKELETON_QUEUE_DEF_DEPTH; + } + + /* Clear all allocated queue buffers */ + for (i = 0; i < SKELETON_MAX_QUEUES; i++) + clear_queue_bufs(i); + + return ret; + +cleanup: + if (rawdev) + rte_rawdev_pmd_release(rawdev); + + return ret; +} + +static int +skeleton_rawdev_destroy(const char *name) +{ + int ret; + struct rte_rawdev *rdev; + + if (!name) { + SKELETON_PMD_ERR("Invalid device name"); + return -EINVAL; + } + + rdev = rte_rawdev_pmd_get_named_dev(name); + if (!rdev) { + SKELETON_PMD_ERR("Invalid device name (%s)", name); + return -EINVAL; + } + + /* rte_rawdev_close is called by pmd_release */ + ret = rte_rawdev_pmd_release(rdev); + if (ret) + SKELETON_PMD_DEBUG("Device cleanup failed"); + + return 0; +} + +static int +skeleton_rawdev_probe(struct rte_vdev_device *vdev) +{ + const char *name; + int ret = 0; + + + name = rte_vdev_device_name(vdev); + /* More than one instance is not supported */ + if (skeldev_init_once) { + SKELETON_PMD_ERR("Multiple instance not supported for %s", + name); + return -EINVAL; + } + + SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id()); + + ret = skeleton_rawdev_create(name, vdev, rte_socket_id()); + + /* Device instance created; Second instance not posible */ + skeldev_init_once = 1; + + return ret; +} + +static int +skeleton_rawdev_remove(struct rte_vdev_device *vdev) +{ + const char *name; + int ret; + + name = rte_vdev_device_name(vdev); + + SKELETON_PMD_INFO("Closing %s on NUMA node %d", name, rte_socket_id()); + + ret = skeleton_rawdev_destroy(name); + if (!ret) + skeldev_init_once = 0; + + return ret; +} + +static struct rte_vdev_driver skeleton_pmd_drv = { + .probe = skeleton_rawdev_probe, + .remove = skeleton_rawdev_remove +}; + +RTE_PMD_REGISTER_VDEV(SKELETON_PMD_RAWDEV_NAME, skeleton_pmd_drv); + +RTE_INIT(skeleton_pmd_init_log); + +static void +skeleton_pmd_init_log(void) +{ + skeleton_pmd_logtype = rte_log_register("rawdev.skeleton"); + if (skeleton_pmd_logtype >= 0) + rte_log_set_level(skeleton_pmd_logtype, RTE_LOG_INFO); +} diff --git a/drivers/raw/skeleton_rawdev/skeleton_rawdev.h b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h new file mode 100644 index 000000000..5045b5922 --- /dev/null +++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2017 NXP + */ + +#ifndef __SKELETON_RAWDEV_H__ +#define __SKELETON_RAWDEV_H__ + +#include + +extern int skeleton_pmd_logtype; + +#define SKELETON_PMD_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, skeleton_pmd_logtype, "%s(): " fmt "\n", \ + __func__, ##args) + +#define SKELETON_PMD_FUNC_TRACE() SKELETON_PMD_LOG(DEBUG, ">>") + +#define SKELETON_PMD_DEBUG(fmt, args...) \ + SKELETON_PMD_LOG(DEBUG, fmt, ## args) +#define SKELETON_PMD_INFO(fmt, args...) \ + SKELETON_PMD_LOG(INFO, fmt, ## args) +#define SKELETON_PMD_ERR(fmt, args...) \ + SKELETON_PMD_LOG(ERR, fmt, ## args) +#define SKELETON_PMD_WARN(fmt, args...) \ + SKELETON_PMD_LOG(WARNING, fmt, ## args) +/* Macros for self test application */ +#define SKELETON_TEST_INFO SKELETON_PMD_INFO +#define SKELETON_TEST_DEBUG SKELETON_PMD_DEBUG +#define SKELETON_TEST_ERR SKELETON_PMD_ERR +#define SKELETON_TEST_WARN SKELETON_PMD_WARN + +#define SKELETON_SELFTEST_ARG ("selftest") + +#define SKELETON_VENDOR_ID 0x10 +#define SKELETON_DEVICE_ID 0x01 + +#define SKELETON_MAJOR_VER 1 +#define SKELETON_MINOR_VER 0 +#define SKELETON_SUB_VER 0 + +#define SKELETON_MAX_QUEUES 1 + +enum skeleton_firmware_state { + SKELETON_FW_READY, + SKELETON_FW_LOADED, + SKELETON_FW_ERROR +}; + +enum skeleton_device_state { + SKELETON_DEV_RUNNING, + SKELETON_DEV_STOPPED +}; + +enum skeleton_queue_state { + SKELETON_QUEUE_DETACH, + SKELETON_QUEUE_ATTACH +}; + +#define SKELETON_QUEUE_DEF_DEPTH 10 +#define SKELETON_QUEUE_MAX_DEPTH 25 + +struct skeleton_firmware_version_info { + uint8_t major; + uint8_t minor; + uint8_t subrel; +}; + +struct skeleton_firmware { + /**< Device firmware information */ + struct skeleton_firmware_version_info firmware_version; + /**< Device state */ + enum skeleton_firmware_state firmware_state; + +}; + +#define SKELETON_MAX_ATTRIBUTES 10 +#define SKELETON_ATTRIBUTE_NAME_MAX 20 + +struct skeleton_rawdev_attributes { + /**< Name of the attribute */ + char *name; + /**< Value or reference of value of attribute */ + uint64_t value; +}; + +/**< Device supports firmware loading/unloading */ +#define SKELETON_CAPA_FW_LOAD 0x0001 +/**< Device supports firmware reset */ +#define SKELETON_CAPA_FW_RESET 0x0002 +/**< Device support queue based communication */ +#define SKELETON_CAPA_QUEUES 0x0004 +/**< Default Capabilities: FW_LOAD, FW_RESET, QUEUES */ +#define SKELETON_DEFAULT_CAPA 0x7 + +struct skeleton_rawdev_queue { + uint8_t state; + uint32_t depth; +}; + +struct skeleton_rawdev { + uint16_t device_id; + uint16_t vendor_id; + uint16_t num_queues; + /**< One of SKELETON_CAPA_* */ + uint16_t capabilities; + /**< State of device; linked to firmware state */ + enum skeleton_device_state device_state; + /**< Firmware configuration */ + struct skeleton_firmware fw; + /**< Collection of all communication channels - which can be referred + * to as queues. + */ + struct skeleton_rawdev_queue queues[SKELETON_MAX_QUEUES]; + /**< Global table containing various pre-defined and user-defined + * attributes. + */ + struct skeleton_rawdev_attributes attr[SKELETON_MAX_ATTRIBUTES]; + struct rte_device *device; +}; + +struct skeleton_rawdev_conf { + uint16_t num_queues; + unsigned int capabilities; + enum skeleton_device_state device_state; + enum skeleton_firmware_state firmware_state; +}; + +static inline struct skeleton_rawdev * +skeleton_rawdev_get_priv(const struct rte_rawdev *rawdev) +{ + return rawdev->dev_private; +} + +int test_rawdev_skeldev(void); + +#endif /* __SKELETON_RAWDEV_H__ */ diff --git a/mk/rte.app.mk b/mk/rte.app.mk index b201e861d..c3f4db46f 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -220,6 +220,10 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_OCTEONTX_PMD) += -lrte_pmd_octeontx _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OPDL_EVENTDEV) += -lrte_pmd_opdl_event endif # CONFIG_RTE_LIBRTE_EVENTDEV +ifeq ($(CONFIG_RTE_LIBRTE_RAWDEV),y) +_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += -lrte_pmd_skeleton_rawdev +endif # CONFIG_RTE_LIBRTE_RAWDEV + ifeq ($(CONFIG_RTE_LIBRTE_DPAA2_PMD),y) _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_bus_fslmc _LDLIBS-$(CONFIG_RTE_LIBRTE_DPAA2_PMD) += -lrte_mempool_dpaa2