From patchwork Tue Jan 30 14:57:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shreyansh Jain X-Patchwork-Id: 34722 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 2E31D1B68A; Tue, 30 Jan 2018 16:25:09 +0100 (CET) Received: from NAM02-CY1-obe.outbound.protection.outlook.com (mail-cys01nam02on0084.outbound.protection.outlook.com [104.47.37.84]) by dpdk.org (Postfix) with ESMTP id 6FF771B3E0 for ; Tue, 30 Jan 2018 16:24:50 +0100 (CET) Received: from MWHPR03CA0022.namprd03.prod.outlook.com (10.175.133.160) by BY2PR03MB474.namprd03.prod.outlook.com (10.141.141.149) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.444.14; Tue, 30 Jan 2018 15:24:48 +0000 Received: from BN1AFFO11FD030.protection.gbl (2a01:111:f400:7c10::110) by MWHPR03CA0022.outlook.office365.com (2603:10b6:300:117::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.444.14 via Frontend Transport; Tue, 30 Jan 2018 15:24:48 +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 BN1AFFO11FD030.mail.protection.outlook.com (10.58.52.168) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.444.13 via Frontend Transport; Tue, 30 Jan 2018 15:24:47 +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 w0UEh7sk023996; Tue, 30 Jan 2018 07:43:32 -0700 From: Shreyansh Jain To: CC: , , , , Shreyansh Jain Date: Tue, 30 Jan 2018 20:27:06 +0530 Message-ID: <20180130145710.24757-8-shreyansh.jain@nxp.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180130145710.24757-1-shreyansh.jain@nxp.com> References: <20180123135910.10755-1-shreyansh.jain@nxp.com> <20180130145710.24757-1-shreyansh.jain@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131617994883962710; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(346002)(39860400002)(396003)(39380400002)(376002)(2980300002)(1110001)(1109001)(339900001)(189003)(199004)(305945005)(26005)(97736004)(85426001)(4326008)(76176011)(86362001)(51416003)(47776003)(6862004)(5660300001)(50226002)(2950100002)(336011)(356003)(2351001)(105606002)(316002)(6666003)(8936002)(81166006)(8676002)(53936002)(106466001)(68736007)(16586007)(5890100001)(50466002)(48376002)(2906002)(1076002)(54906003)(77096007)(104016004)(498600001)(59450400001)(81156014)(36756003); DIR:OUT; SFP:1101; SCL:1; SRVR:BY2PR03MB474; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1AFFO11FD030; 1:9W/v0fR3aR78N3dRKa97jdAe587VziM61a5XVQ/RMeDEJmPGunktUh2ccmJ1gDmY4nAqJ5ghdwLtt+DeMkKVvGUXGQLNS48hB9pxFmFmrEDpfv1ylDro43DmnxeyLTfx MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 450757f6-234b-403c-8c56-08d567f5997f X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(5600026)(4604075)(2017052603307); SRVR:BY2PR03MB474; X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB474; 3:OWPYp5BjJmLHUN9bqkubGIgrMvQvKFiTW65gfjC1gORYwjmrKMIM5jQZwsXZKkh0+NYBDQLdyXhwZTZjpUCoyjwBcsnTkrcjaM+TpFNILmHOn+v5GXnazigNKwEiSQktZ/zwsotBQibtxDPtKxWehtZVev9lcWILGpiFqMVgYIxb5NYYTjI/oE57SJ0oBLTrZ7mD3Z7Xr0HJYHw69dJrOOdxfin8GOz4KgtDpCWeODNZZVm+YVJh4yYfrkar0EIy9PePXYz/tglXXYd5FbNpNzpi3LOm89impcE8t4DnAOoavH6ssQASsnSvTvEVdU6goYXXRCQusZReAdTbo2D4+nrZiMRJcOZx4Lodi36TNko=; 25:UNTBvpmFu0SLGjJ5hu8OxDoFLTIhTCuwxxr/duIYc6XLmS9m7iTgF32SJQ5DITADdsfo5e7iVmVNZmXStiwlRUr+EcJ3imggvunhIKDOvknrG1V+nkQpIlWU3wBBvx/dvbkha6U5hBWNENBgISD+0mwHvlHiZwXHGTBboBHo7YU7oMZqbzmS1yF7dnb/OACifsJ36SI2RaMMmyK6+7bRnUIXTk8Pf1hWbyDTxdsZokJbHMbOnfusyYCPGAn6EaZR7ICvZxz3v4mTQGI4MEewox8xOdw99stpLtHm6Wt4QlVkiGLI2dXC/9XgVtt7DNpetLXStZNdBdcc/wzDlPE2Pg== X-MS-TrafficTypeDiagnostic: BY2PR03MB474: X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB474; 31:hfE2sNEt48Suo1/Dz2KIu99Vb1iSVAt4o7o4cWhurE+zxjYozyIbIK8xmjMjbGglNyENjwR97P/P/l8/dnOCDZ1fEjtL2CqLCwDkCrQqobrH6AkAATe6E7cTL1gCJ5MvsZ9dewYWzRayo7P4ATswNMKkIqJky4zPmu1Wcnj/B3DkoiRRgSzwjZFL7GfCeCjdc7wmLsTgb5JbiobRkx9Cz6XdVftdeVf+9HKBelFAlRM=; 4:HrrqKf0IB2pC+VS2dlxiCWOSxVR4nrrzH3JIIfxY/2F2CMOiJtRFGOb9RWzlyrTmve+UtEl0N/H+OuxtRiBvuAEwNmCNhoV94ZDxBP9PWAs5GKfHudz3IM03IBVdPZsQbzke/zQbBKmNgjxON79sktzN+S82jcVpG3C87OKlf+CinQY87xC5Hv/c/YmLY/rMNytKzY5GbujbwOtX8SDHu++/CoRkPtoXJC7fp0Qr0PV+sLlXR/0RlA1emA7A2ZFqQGOIMMeEGRXicwVJBWy7xaLNAOoSQSaC3ZrmToScQDzi5XxDGUWLXIUWJIIBmH8K X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6095135)(2401047)(5005006)(8121501046)(3002001)(3231101)(944501161)(10201501046)(93006095)(93001095)(6055026)(6096035)(20161123561025)(20161123563025)(201703131430075)(201703131448075)(201703131433075)(201703151042153)(20161123559100)(20161123556025)(20161123565025)(201708071742011); SRVR:BY2PR03MB474; BCL:0; PCL:0; RULEID:(400006); SRVR:BY2PR03MB474; X-Forefront-PRVS: 0568F32D91 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY2PR03MB474; 23:/vKlQ1Wic0dSc2KyxE63PZuvL8AvIfkOo/05mAAcUY?= sxKnWai/MKlqE2imixZ5yRRiYMHdme2kcCwsZECdje+cf/Toq8kNcGXpntWYCdQblkjAjBqKTG6RC04EImHYIDdNl2Cr+FYFgyMPq6F+Ll4sO34FrGmPMVN5M9NkGTkEol/A98TXlo9waZGGpLOI6dbXt7mKYBz8GdvVmo5W3Z/KAhcGyk6b7Nt3UpLFXE9UceLCOYLksXjjAz0EmTyi8JAyNdorSHxAdXU4tC6o7Ord0ZmYTAaDoNsHo/8Y+f5XAQP+lZ/6hcZTBMIf4BWWLJWmJxoEmFAJ20FEAIASeU7LRVUl4KQEsPFkk+cuYLuMKDVZ45yfFrwSVxoSo1Z0dlxf5FQ+lFYNnqnSUUmuS1wQi83+gCE3lig5CUx+BsyF3PQXXzc/SwAH9n7RSbd6/ByGv6LnHn0rGfLD6d4UQM1Yz72wh9AN5tv/0I3ruD3F2KPdom+TBucW054lHrUrvqnjsbFCX7Plg1c+XGAGOyXm+aEpxBp+RQTEbXOoNXGzazuK1gPTlfMxso3kc0s+2n1IOYXRa6KnfpwA5A3K9+5vFKw+Me1EIYmg3bo1/AWjCKy+C3IAJlRmFeKbeHb/D0/X9IMpNBRTH5YZXu35AAsUWPHgZG8s9gfpNY/Iw1qZTjg3+VdoNSRnyIobU3mcpud/P7lNXR1/xW+NgrkLNoBLyrFAJpqKZeN5hVp91GEtJvpPJ30vHO4DtGqrldA3v1XiMzUkFBhVtzYwrgvHNamYKxwtXsbLEofSspgyceDXyuoKYYNeQeIBWYXAXGPVMBIw5s+JnXlWJ0YLfJ26U//51v3zqndTTk5ciUopslh6d+wKqyWDQNJO2TJUfQdRL3c3duifpnkebEC814la3IvOb7lxTjDPT4N/dEPBUnBEbulw2AK8EUu6YDNGdSK6itker/Ng1r5u2aKpsnTih0t5H619ZTzz+ihP/8OSS2A7Fl3eMKOeQdJ5zuJj+hBA92T9XergTwsM0WPqFDS6010MVV/dsTBzq0rXKxlEsyWsOJchJMjhbaJ+CNMUnkfq7x9Qpz3sNoNaisN7GCwfPyvsNai5zAaWIl/8u2FczWNdn/alQ9zBpGi0oZstZWF9nu X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB474; 6:XedZzF3omZHW/QGm0O6ct7NZftQ3ZIi5QtNm2F9+uuxQM93AHfnCfvv+h5rckay2S/I/6hx2ox3unkESfMpqrMeh96stqlqg303zMaXIoa43S9EL/HpgK1b3bDn9urzjJplly+YeyHq56VypNkwJr2FqO4brmq9n5JGdneZSB6iMghcxlrR0jNbLZfNnPUvzQpe/Ey0jf7BhWR1y27YvSwoYQVwvfLLir3mDIgmfH5cMn1VdXFWZVIqdk+m/Imo1xMhjipdc4uVlPw2blP7m4WYGeXelY3pqv0KBpA/i1G7XDiS06NuAFcPBLsMQ0wcYjnh0bMMRkKrIf/lFNRv1gMPor9+dYJ1qm8GT4NIiYRA=; 5:BV5d/cf+4e2RX5Y36Tt6Tx0PnVLbS5hrygWbQ6b60YGZN8mVzUkB8h7taQgXBWDuDsPP5lunSvnuUyHa0JhIqLSep62svpq1aPg0opW1YU3hEBadX+m7vHmfK4qhxwKGukJmPA7d/UyN6Fax4tunY8GwWCgkpss41kie6beJb0A=; 24:ETA2GPo4GJC9VgSqxmhtSOnXW7ZV7sbRdiH12MKr50hKXxgwJIAWImlgsqXZCh+/Pk+r6r5xSGm8yXJv5mgRUMljVUtA1NhZDLe2D9B6JvQ=; 7:vaYhEBJ6LcHD9uHFdV82PFW2xOyTAEoF5Q34SsVT0ljw7AW4sBEQtKP89xXGosH2YSrTzOdV2va3fnB3ptMBv1NNKenb4rI9hMliwvkrHbESFr1Tc1DmBzWK0U+JHYGXhteedrF8Z6ngv2htSoH3geJHUtlhGLKgVNu7Ox+BEcnsOIcWSMNmYwNwASXYWnURtWx02RpyaZNRwP8/d1ifmtGUMaIKL6sb/SL1pyspU5dZ5bX05/TaAAMEMqac0QUd SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Jan 2018 15:24:47.1326 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 450757f6-234b-403c-8c56-08d567f5997f 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: BY2PR03MB474 Subject: [dpdk-dev] [PATCH v3 07/11] 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 | 27 + .../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, 873 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 812cff129..0002f83a2 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..6318359d1 --- /dev/null +++ b/drivers/raw/skeleton_rawdev/Makefile @@ -0,0 +1,27 @@ +# 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 += -DALLOW_EXPERIMENTAL_API +CFLAGS += -O3 +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