From patchwork Wed Jan 31 09:13:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shreyansh Jain X-Patchwork-Id: 34758 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 6EC1D1B748; Wed, 31 Jan 2018 09:59:38 +0100 (CET) Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0071.outbound.protection.outlook.com [104.47.2.71]) by dpdk.org (Postfix) with ESMTP id C6E5C1B747 for ; Wed, 31 Jan 2018 09:59:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=KkjmbybKjfYOWDHyos0R5baYxEDH7dGHgqWOL1d3Zxg=; b=J9udctAgRH8Tml0AiAEaAvWYG79z7OzaWJm+r0QsVPOs9fUXVz4gY1XWTf/Gd3mdfaBEkl9Ay12EZBRfCLVQTrRH1IyP2o73KtjSnYwtacjbpn51B/p9/jpujiLQdGRw5SfEd5/HktDyb1bNuBxfJIN4drVKaMfxWLlRWhL5QvA= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=shreyansh.jain@nxp.com; Received: from Tophie.ap.freescale.net (192.88.169.1) by VI1PR0401MB2462.eurprd04.prod.outlook.com (2603:10a6:800:55::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.444.14; Wed, 31 Jan 2018 08:59:15 +0000 From: Shreyansh Jain To: thomas@monjalon.net Cc: dev@dpdk.org, hemant.agrawal@nxp.com, fiona.trahe@intel.com, rosen.xu@intel.com, Shreyansh Jain Date: Wed, 31 Jan 2018 14:43:15 +0530 Message-Id: <20180131091318.7894-8-shreyansh.jain@nxp.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180131091318.7894-1-shreyansh.jain@nxp.com> References: <20180130145710.24757-1-shreyansh.jain@nxp.com> <20180131091318.7894-1-shreyansh.jain@nxp.com> MIME-Version: 1.0 X-Originating-IP: [192.88.169.1] X-ClientProxiedBy: HK2PR02CA0168.apcprd02.prod.outlook.com (2603:1096:201:1f::28) To VI1PR0401MB2462.eurprd04.prod.outlook.com (2603:10a6:800:55::17) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: a4b1c7fb-a45c-4b42-9ebc-08d56888ea53 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(4534165)(4627221)(201703031133081)(201702281549075)(48565401081)(5600026)(4604075)(2017052603307)(7153060)(7193020); SRVR:VI1PR0401MB2462; X-Microsoft-Exchange-Diagnostics: 1; VI1PR0401MB2462; 3:TAP4UgT9r/0nZsqfxkVyCMAIQIQIRgI6gI5LACeHgliaXr5wo41d96uQmTfxUjeoMuhht/lXF0eXrNV3IpIToG9hySQIHsr8YB9ariWR94KAfR4WfnWtiO5374bpy/HUAn74hEu5hLG8+z6/7f/zt/fodODHErMP+29Pon1T19uC1FWhnxJkM/dF8JVZ9RQecBvrShSnACREDgzcwsiNFkLAev9ySRJJxuadv3nIpTliuscXKs9iJATiRgvTEbIL; 25:prFH7NnHpgNHPjGE/J/Yi9bWy8FqmzfyuGTjHnpiXXmgqv0ayOvT4jZ+ix6Ch6uDgtsQA2M8WQr8gFJfNnpb6Zy9HlaqP150At2N14m+3gWTKNMnh0oB6GcHkz2X5OqA36KU4t3zmGchoNrABGKXcMjYAQRmGQmpzhSLiGVWCljNMRxc+ZSlr5dgmOdObAeRbg7QLtD/FJqm8A3fsAuCcbQMeyQEKKSmia6pI4CqqkbH3MhYb9lnv0OS7a6LnvP/ZmW6gWz7TuPQX+fzQRrCAFT0F9tnv4iSATX/RYTU2V9naAaMohgJ43BNCc1S8ONsdLg4LbzfMTZ6DUlKD+PNAg==; 31:x34BJZZJulMEqMcJy8JNQ0Y8gsi7P6uSb4tKevoIXMkEMhMSfCzAp4S4EIW6nY7M+2iyXJ64Bww8ytuPP/S2dWhGM0KExZJWWZHpSDVxBzSRpds9sbPjScwa/7dwjsUz8RmNnDDIMIlg2OoPpt8OMSDvCKY6CknoblezZudLNRXnsXdFWTIS2gJ+K3FDM4hOkoulb1IFrcImcBSQ/nxXtx5ZKEiWhxNjsxOs6ff9t+Q= X-MS-TrafficTypeDiagnostic: VI1PR0401MB2462: X-Microsoft-Exchange-Diagnostics: 1; VI1PR0401MB2462; 20:r7CnKLRCjqYy3oVIA9V6BkLq/CqXVWvTpOjblDO15qFpY+0F/jzzPiL8sK8ulukChqNNEIB26JhNYQaGb5nosfcnJXEQrBd5dND7ydLwjClK32Cxw/kkVullkYY2Ite6Q4Ns71bXH4p1PXVU//+txpQCcafNvd8LuyWLdxEWHhaAQgYB3bmhYBMWNG8NMzOPtTLqcc3xc5z8YIHeS/J4/1Zz2CnEMByH11fI3X/cWlxYNWwkKcPuMJnA2167DxSoh94W+O8tWpGrL1k4ewZl4Af3pjjE0d0FEZ7A/9N8mYQDDCGR2SXS/16fRAUmvvlO/jJW6Imml6UM3+/rvzW2FqSqk1FDxx/XtTJdRgO9h253zXqpWB/M/uvVu+EZjn8iDM6SVtstghrhjo0uK2NNqDNAygg7I6GvEwnVbKmWgbXC5Z/DlS4sMHqlx7TZP7SniA1iwiwu+o0Qgb3Yk8HE0agPfZQTJmaoXyV6ycx7XYdF3Gf+HC/70cJ7EHWaLw5D; 4:oURQi77nevZ57uywDNcn/uqChA/+dbG6wYTh+TzcNrqe1AlHAaylX9Qv0PxvMkdL9OB05m9B9XPOZKYpOSEQbsfPkf33ka7i2wvyyTIwW/4YpxxhrVi0S94q8G1fZytKQpogoCIXN/0+lzxGdLYQ5qwZ8cEizpJHGcZ0cffb15OHo7q50Gf3edDERrqHqgb8HVSoBwmq7aVq6zoQpbULo7gcqbZwYrXJN72qr6LMXv7FU3NT/H69eMkppDV41/7cE2NP/gzXUES7m4xH+4MLH4+yMYf9LUREHhm/LUv8e3iAGA5uajzY1k//SpV4IB76 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040501)(2401047)(5005006)(8121501046)(3002001)(3231101)(2400082)(944501161)(93006095)(93001095)(10201501046)(6055026)(6041288)(20161123562045)(20161123560045)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(6072148)(201708071742011); SRVR:VI1PR0401MB2462; BCL:0; PCL:0; RULEID:; SRVR:VI1PR0401MB2462; X-Forefront-PRVS: 056929CBB8 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(396003)(39380400002)(376002)(366004)(346002)(39860400002)(199004)(189003)(6486002)(5890100001)(6512007)(50226002)(8676002)(48376002)(4326008)(81156014)(316002)(8936002)(66066001)(2950100002)(81166006)(6916009)(53936002)(16526019)(5660300001)(47776003)(186003)(26005)(106356001)(2361001)(97736004)(16586007)(305945005)(478600001)(51416003)(386003)(36756003)(86362001)(105586002)(68736007)(2351001)(76176011)(1076002)(52116002)(2906002)(6506007)(25786009)(3846002)(6116002)(50466002)(59450400001)(7736002); DIR:OUT; SFP:1101; SCL:1; SRVR:VI1PR0401MB2462; H:Tophie.ap.freescale.net; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; VI1PR0401MB2462; 23:vIducikiwYdkyDNYZgIPDYCQUZTgXxqJ816yPny?= QTqJ+m2IGDpo3YBm/HWNbkN8tKUdHaRlk2jPGlNPqRTfW5JaJ/ucfYNELRLrMg3WyEhA0Lu8I93jF7kB0o+GNm0E5N6Jd080LmPwSa/iWl46X0n9hZ8qyojoY0dl2pbZf55ds1pLDNTBWjgb1oPe8xf9aRdZjElH4x/lerhd8rGd2ESFTOa36++zvmyPDTy49jz2gHnNo9xcntIt/PGnyY3opBiKbBnfr/bbZQ/ZGhvnKhpNRdXuT7P6nHBvTulCVwgbLNL43ZoXSc6FsDshmjrxNdLmOYCKltvoRHRqjqnAniiFy9O2Axhp1x1PWF6c+050D7HUoL4PKFD7+J2nF16iEeTashhx64xJQIY8SgOv/oQtNNCaob3E7reMNDdf/dcCvGLIXyjU7sxspujreEkdbabVq8OokF0dWdjVAbRYrminV38pSb1wFxbpXNsTWowV4Ug4k4arpBsiqOE6EgjRQPqRWW+vxCEG0vNRqqIbqHmapHUl6wb+CLdu67m1xgfZ8ZCcJtrnr92Oeu+5m4opfJDVnRAtk4Vlfo9VKi+wjQwMqBgp8gJ/MNl2/jRsseK8qSlrlFfH8IDftu2gIexy2x2TmUC9GIycTrTm0tjfM9k6pzfVPByDyIz2A+Pz4hw4xut97nTR/cVzAsIc1qhibvg1VnzPaiGypSFVemvp01ouu9JcvqMeFlRxlZckaeZ/TxdrsB0Bj5MPJR3jOYlaMihMFxhljD/4jCv0Wo7zWTWOhe5Jy59RVyqvAnS4nXKjM210er95hMNCmbabi4nbdrH4S7BO/Xsr3AAJc47Rnn5wvgl3Mbkc4e1mwzkD6K2rSCLqM0wr2ME+WbRNfdPjmA91J6dEClhU+mRwSU6p3mllai3Nu6BW+VjeHtyVnUh4Z/EWnH0FGvjSey4GBATQpU1iO1CA8rAq+Pto0/Cm5cKgR7vD/TR8O1hlCKzmBEI6KbylUX2uKjulV+RBBQEuyn8MzMyyi5sXreXvRH7MXqTaj5Kua+xqbBPTOI896Cy4E3zRHgeImlP+wW8tZhkxnSb6plBLvnZrNEPsZwqC/5Ks4515nYUSDZ+Wi18sIbZFgZ/HsxCgi7vI0zSheOJz0GG7kT9VBVbpYz1FVp96TNjlXocLz9Fqds62h3uJ7bd0= X-Microsoft-Exchange-Diagnostics: 1; VI1PR0401MB2462; 6:1otYQd0LmqJSHRtgx1ptUeFee+PmVM1o0y0Sxvj+QIj2eGRHMxuDgxA9JvKF5nELKvF5cRZWcS/P2Ad744DB2BTquuJY5YZKg7TsUZZrafglLzLrWvpAaPzz0xp8Knays9ww0BWNERQBh3+Q1EsddgMz1XraH6fUm6gjnXfkoS51u9lMYVRfI2xbuWfs63vjRA3H1CXeGNhgYy7g1iBUmSKnRkAcm5dy2Wl35uba4RufPWWragO8fJznSBRwVJ2Omzuk/R1QS0e2yfAEn6asBfoHt2wyO6wSSiT+09KRZV7eUW9RvKRujwtGwybdXEfab6GLjUILBFhhb2CXSAI4NM+vRp5RhACmicgIrhOgmJc=; 5:7cuhsPNHzpEDaZeFZaac5aM9NAo//9QdRb7wpDaXsy9BrXw/oXEY3WNqr+eUTOHck0YQRyWAoLKoe/G8AlUJNnT/NnFlzsByzHFnugVvM1KDDaVjIJqDOizOZjehonm0RWCETSpGMmuXn5ooeWEs4p9FGn76/qtFqimezeqb7x0=; 24:Xt3QYWs6ZmYs7902hLHINkaE8xN/KvigraGWBv9sc7KrjmXefDR3a3YOPUeb/3G7SqNeJk/XCgDQpw4KIotyOSWhsfGdqabskCMGURwckFs=; 7:W+MtMVrCIInmEREJhzN7J9nbT+YFQVadgHv20eAf0MUNxqd6dQ6lJtfZX9ksXNpWlMb+bfi41QqCLJpCM76NZGk8BlwBSDWle2fODIobW90DVHeIjVXi743m8eGEohUMWxCTDXCqRx/JpJ+G57RMzA4DcU0oeeE0yjqcumJ7jJvtgHP74TX1VM3xZlP+IyoJ7l9myikJEgTzieH+G/CuYJBJtl9SKNJ5shSJw36B7ukte2srZWTavLdHjeavdteq SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 Jan 2018 08:59:15.6013 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a4b1c7fb-a45c-4b42-9ebc-08d56888ea53 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB2462 Subject: [dpdk-dev] [PATCH v4 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 --- MAINTAINERS | 1 + 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 + 9 files changed, 874 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/MAINTAINERS b/MAINTAINERS index fdaefb1df..320bcf9a4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -319,6 +319,7 @@ Rawdev API - EXPERIMENTAL M: Shreyansh Jain M: Hemant Agrawal F: lib/librte_rawdev/* +F: drivers/rawdev/skeleton/* Bus Drivers 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..062d732ec --- /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] = {}; +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_FW_READY; + 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