From patchwork Tue Jan 2 12:57:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shreyansh Jain X-Patchwork-Id: 32831 X-Patchwork-Delegate: thomas@monjalon.net 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 AEDFD1B01D; Tue, 2 Jan 2018 13:43:59 +0100 (CET) Received: from NAM01-BY2-obe.outbound.protection.outlook.com (mail-by2nam01on0046.outbound.protection.outlook.com [104.47.34.46]) by dpdk.org (Postfix) with ESMTP id 468631B01B for ; Tue, 2 Jan 2018 13:43:58 +0100 (CET) Received: from MWHPR03CA0004.namprd03.prod.outlook.com (10.175.133.142) by CY1PR03MB2361.namprd03.prod.outlook.com (10.166.207.148) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.366.8; Tue, 2 Jan 2018 12:43:56 +0000 Received: from BL2FFO11FD028.protection.gbl (2a01:111:f400:7c09::124) by MWHPR03CA0004.outlook.office365.com (2603:10b6:300:117::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.386.5 via Frontend Transport; Tue, 2 Jan 2018 12:43:56 +0000 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=nxp.com; nxp.com; dkim=none (message not signed) header.d=none;nxp.com; 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 BL2FFO11FD028.mail.protection.outlook.com (10.173.161.107) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.20.345.12 via Frontend Transport; Tue, 2 Jan 2018 12:43:31 +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 w02Chfdf020140; Tue, 2 Jan 2018 05:43:53 -0700 From: Shreyansh Jain To: CC: , , , Shreyansh Jain Date: Tue, 2 Jan 2018 18:27:47 +0530 Message-ID: <20180102125749.2379-4-shreyansh.jain@nxp.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180102125749.2379-1-shreyansh.jain@nxp.com> References: <20180102125749.2379-1-shreyansh.jain@nxp.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131593706114866793; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(336005)(39860400002)(39380400002)(396003)(376002)(346002)(2980300002)(1109001)(1110001)(339900001)(199004)(189003)(59450400001)(54906003)(53936002)(77096006)(6666003)(6916009)(2950100002)(498600001)(51416003)(5660300001)(97736004)(36756003)(2906002)(1076002)(76176011)(48376002)(50466002)(105606002)(8676002)(4326008)(81166006)(86362001)(106466001)(305945005)(81156014)(8936002)(47776003)(68736007)(5890100001)(356003)(50226002)(2351001)(85426001)(104016004)(316002)(8656006)(16586007); DIR:OUT; SFP:1101; SCL:1; SRVR:CY1PR03MB2361; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD028; 1:2S/7qmCWiHNr8MS6xoDcWqhZTU8QQJ2NzpBoMEBn1lZVI+LjBC4eWtsLMj/KJwsE2BoZ9oABocX41my3O/tcWgDx1rzONSdZ43mzR3HVDrIFrTuKrc/VfWAI+Wf8ZkYm MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 7d7dfe5e-2faf-42d1-fd09-08d551de6e1b X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(4534020)(4628075)(201703131517081)(5600026)(4604075)(2017052603307); SRVR:CY1PR03MB2361; X-Microsoft-Exchange-Diagnostics: 1; CY1PR03MB2361; 3:ZIGlyYQK+K/cQHD/uAwAJL5LgwdijoKGCPhnuxcIz2p+sqe79ANBRhtphmY3Pz2bRV1P8XTwwBIofKv9SPutMsBJNYZ/He0PgUf/Rrkmucw/kZRgawtj4Oo2VAFwpAJhpTnnIaWHPsAQYAnzITG/K00OPe4P4KkAF6vvHQbW/zPVROuLf+Izn06npsfEb3ZyQdgy+yO/b3Yb8rg7iDuGeThf8bvJ1gSbDhi4R6/yutxJFHlMX2QUhjYn38QfB1SbTIwOYmzl4Oh9NBdOPIl+IQFBV+WYcWnlnWWLaLJyHQA4d/yv5YkteDq/zolGOOPmYcX/nC6aMkoTWPP/QKDthyAY9Gkga2uBlXFiNqbBVaM=; 25:/h4jTm2PG74EZKOmLPBuQbX2U0Rcf1J+SbnqB4CbhEBSdmGKsYhdwKUt7CEleHK14TnFhbFozqyrCzXxFwba5bG8fAJmbX+ezbiUx4hqKzNlaOKPVHjxxV+A81DMJ5CCKpS9D9FLXrlIPFig1MFtyPdexX4W8PTw/SDKaHZZ0tyBnQ2HpyV8exK+zzEYB2EqAZ7+Gb49+baCV/C75PwVgS0btbQYK/cZxJQx3TnhAGio7hwASz4H4osX2njeYLfMqvhu/l3mG8PZNy2JCBJBpegKEF4UAPDupGnItnEhqjgV0ODyAoHF5h4LF9GhJ2pZZQ3sh2Gy6XVms/o9K+57fw== X-MS-TrafficTypeDiagnostic: CY1PR03MB2361: X-Microsoft-Exchange-Diagnostics: 1; CY1PR03MB2361; 31:zhFUDJmXPrgzuG0kJO2CTTDlzZd9zmWYTx2nbcxVhFue6i59feHSzB5ytjxZRNF91pj3VBf6X2zojBv0Zh7VTLV1p4w4/lsJULFx/u7RDefNQWi8PnMeyvjOgQAQkFLiE01SxwzdBVeSCh+LjOIlqhxP7J5FujbON+Usd/hpfOkbq89ZtYKxkLuWTMcQbr8kcIc+jBp4ng0xSZXynkpNaVjgeYsVTOBJcd09keOKsM8=; 4:669+M1B1uUnxzFnZAalxiktuclMoLOIqnORKCzX7fgZOQZlhkQwfXyVKZZgyze5GjA/Pzele3VDGsH3Z1NDER8A8TOfDD0286oF0Nv+cJiPkhahtrjND/7Z24hOaG5c38o94MSCtUEDE8j9ZMi6G549SF1SZ8kHUm2AhLmDjsphmgANh6uPh/4MGHk8pBMjDNEg/OHabQPHRLdUJBdLiqliApJouKzAPt38QJW91fIt4qSBOWomwfeS6Lxj7kLucAySOK4PiXgBgTbjDaIVFgrCkofXU6neew7qcZWg/rxJDK6L8wjMZQLtCGrW/NxZr 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)(93006095)(93001095)(3231023)(944510075)(944921075)(946801075)(946901075)(3002001)(10201501046)(6055026)(6096035)(20161123565025)(20161123559100)(20161123556025)(201703131430075)(201703131433075)(201703131448075)(201703161259150)(201703151042153)(20161123563025)(20161123561025)(201708071742011); SRVR:CY1PR03MB2361; BCL:0; PCL:0; RULEID:(100000803101)(100110400095)(400006); SRVR:CY1PR03MB2361; X-Forefront-PRVS: 0540846A1D X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY1PR03MB2361; 23:3sjosgKiuScL5SCcX6KuSID4gudraOoWfbrX2NOOZ?= Ktf0c/SQ2BhICLa4n5F9hccjLU7QT4BhLYVqCYnFCHFqZmkRwl0yxeg1MvofmZm9zO9+F/DV4IsWwhvl9f2mILyiCCPbpmm/51urJhCKPJ2wmVWDirLYb8+iI7BWuPduVHsIHdZ6RTk7c7zn68QCgFWtjms4ewlAsSzpnrCU/uWVQUXJvDBVKCgekOfCPvlB7yrCCZgplmkQP+qOyBUH2Q6Jm84NwZ2qjE8W3JA7B1B/U9vBe8mhapFKKAERDKhA0X3zJKnltLAW8xUCBL7Dfg7AVmi0x3YI7JBx0F6RbJqgUSATy1DOJX/ErE+0LlUMIMuqnb6klssgT0kNtyLeqAHA0N+7b1Hhb+OzczVZWcnVRM3pTX8ABObDz62OPOHGi9arpAi1DhSmD4+Tv8prf/opMxyiD2NqGWNmwef6aIL82G6SFBqtgvn1DWG/8nSB0VSwCYDTMybwDhvsoKT2zE9nyiMLH6xpRaMrW2Z24YkS8PslmtVp2HoNSk1ft4yCdFwB3lw4CN9asY1VxxWtOI48gnAItb93UYFfp0j2UrrXRjmfwD/VWw485mzVz9fF49KM+OC0g/isUP/LXIpCXtHriYZ1WvBlVtGbMM/+TPa1ZxsyrPb5IYGPkege8aTL8X5qb27enaSPKouL/lsFqwHwKVZv8dIXf0c7qB6W31VlwVfXNqqBi4HEphYF/E6pODIJG5eOxheNNRl64qE1lZnTKMWhyvTn5MkHCySS8u3ylGkeU7QgHNf8Btw+NZSc2VbADx7DeZyFUVSno9YVwwFVwXxoTFlXtJaxz9Vg+KNteDbZjG33usBXI/Nduxq6SPmB5lP9CSM3TpAS12AX+zPRYkB6Zkvv1HzOjh7yTIBrXaRpJXAEdMw+s4VAwXoYc3ZA4xgTSRB4TWbx+7ahzLLs3CIs+4Ar5Wd9hQkcqIBNd4JbNgumO8aiFqcz+xNVFi9Nfn8vhBMKiP8iID+8gQb0BNeNB9RamOslF5Y6TKwssz/VJckEWQ8zcel5j+Rrx+Gg9fodd5wyaaCLcJ0cLTNaEHjGq9MowUP5rLgt2nNon1355yVFIUJ/GzSo06iFQD9pHgKBqJmpYszidtECkxWfbHhOAOOauXvEV/8kp7NIg== X-Microsoft-Exchange-Diagnostics: 1; CY1PR03MB2361; 6:/zRIL46Qege94jAInO0wi39LyibHVq28OoXq/MbuAYA35nyFlQIZ/T3HQaQjnpmLllTojO05KG4sVAgZDXpIKqyaYG+rruS7f061e++Nu8L5MCkhyYQGZb9QH0BjfhVJSs0TQecjLIuB48HEXp6Aa/d4RZ6lWxV7JkPEbG7ZcDGXod1z5MmM64xeUzi3UcVkKsUlJfwUA6TpLPSNbi+XLzkCFxuLpryTuPCBnSx3+hdSNehTucCYy2ZZJViWcVe9rGaO7p2lakJ+ijIOosms15D0O+Pf7EIyG/ppRwd/qXZp3aP4Y16Clvmci/MV+jtSSF2c+xo85SZq/QhpXVFTjX8PKm3cXYqbeKngf81idng=; 5:MKUYC6f7+uequ4y/4STBC+BJp4QJEOcFVT6O7iK+GjsEomWz8zOTiyX/fiJrXCzhEMGmOA81ZTFxXBKqIZBE/LisbqBKM//8Q/+GOoO/GAztlTtujnHpKaC0T6F/TKB4p7YXtm5P3x1P/TPbg5Ps2Gf+Yx96jIdyt+WP7J2zhmc=; 24:1wjljDx9pZuZ03h30pu/tmXlNu8pHZeMA/H8Cm7hxt71Ni8c6Wzy95P53Olp645PZptbw6FUgaRr+gmYLGjgsu9Jx3vp0JgnxoJpCICbD4g=; 7:ySkIRtv4azSOvkwPeixkDPNWZdA8woV4wDCBFpzGqqUGXc3ovQg37SzFSPM43u67RS9LCOS/NYnwx9rjcJjTAJ5Tde0me8N/XXpznwk1M3pRP7zDR5UKK/jStqOdI0SggAB0xELfIKELshLOLURQ9JIZojVCt4jq76mVLaS3rOaAn4aZcZ323/eXtijwqZSKnKIZT6zIQSG1dqxbj9WKO7LuVyr3w2Ery23dTUWKmEPVd9ZmPHMPySOl65N4AiBL SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Jan 2018 12:43:31.3150 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7d7dfe5e-2faf-42d1-fd09-08d551de6e1b 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: CY1PR03MB2361 Subject: [dpdk-dev] [PATCH v1 3/5] 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. * Enqueue and Dequeue buffers essentially hold a series of buffers for a sequence enqueue->dequeue operation. Important in this is use of context as parameter to define opaque information (like queue_id) transacted between application and driver. * Device start and stop are dummy-fied operations for enabling and disabling the device. * Firmware operations are not implemented but can be easily extended with corresponding test cases in the unittest framework. Signed-off-by: Shreyansh Jain --- drivers/raw/Makefile | 9 + drivers/raw/skeleton_rawdev/Makefile | 25 + .../rte_pmd_skeleton_rawdev_version.map | 4 + drivers/raw/skeleton_rawdev/skeleton_rawdev.c | 668 +++++++++++++++++++++ drivers/raw/skeleton_rawdev/skeleton_rawdev.h | 130 ++++ 5 files changed, 836 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/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..56e6805df --- /dev/null +++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.c @@ -0,0 +1,668 @@ +/* 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 "skeleton_rawdev.h" + +/* Dynamic log type identifier */ +int skeleton_pmd_logtype; + +#define SKELETON_PMD_RAWDEV_NAME rawdev_skeleton +/**< Rawdev Skeleton dummy driver name */ + +static struct rte_vdev_driver skeleton_pmd_drv; +/**< Skeleton rawdev driver object */ + +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; + + name = rte_vdev_device_name(vdev); + + SKELETON_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id()); + + return skeleton_rawdev_create(name, vdev, rte_socket_id()); +} + +static int +skeleton_rawdev_remove(struct rte_vdev_device *vdev) +{ + const char *name; + + name = rte_vdev_device_name(vdev); + + SKELETON_PMD_INFO("Closing %s on NUMA node %d", name, rte_socket_id()); + + return skeleton_rawdev_destroy(name); +} + +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..2610d96e6 --- /dev/null +++ b/drivers/raw/skeleton_rawdev/skeleton_rawdev.h @@ -0,0 +1,130 @@ +/* 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) + +#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 { + struct skeleton_firmware_version_info firmware_version; + /**< Device firmware information */ + enum skeleton_firmware_state firmware_state; + /**< Device state */ +}; + +#define SKELETON_MAX_ATTRIBUTES 10 +#define SKELETON_ATTRIBUTE_NAME_MAX 20 + +struct skeleton_rawdev_attributes { + char *name; + /**< Name of the attribute */ + uint64_t value; + /**< Value or reference of value of attribute */ +}; + +#define SKELETON_CAPA_FW_LOAD 0x0001 +/**< Device supports firmware loading/unloading */ +#define SKELETON_CAPA_FW_RESET 0x0002 +/**< Device supports firmware reset */ +#define SKELETON_CAPA_QUEUES 0x0004 +/**< Device support queue based communication */ + +#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; + uint16_t capabilities; + /**< One of SKELETON_CAPA_* */ + + enum skeleton_device_state device_state; + /**< State of device; linked to firmware state */ + + struct skeleton_firmware fw; + /**< Firmware configuration */ + + struct skeleton_rawdev_queue queues[SKELETON_MAX_QUEUES]; + /**< Collection of all communication channels - which can be referred + * to as queues. + */ + struct skeleton_rawdev_attributes attr[SKELETON_MAX_ATTRIBUTES]; + /**< Global table containing various pre-defined and user-defined + * 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; +} + +#endif /* __SKELETON_RAWDEV_H__ */