From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM02-BL2-obe.outbound.protection.outlook.com (mail-bl2nam02on0080.outbound.protection.outlook.com [104.47.38.80]) by dpdk.org (Postfix) with ESMTP id 2F0A77D30 for ; Tue, 2 Jan 2018 13:43:52 +0100 (CET) Received: from BN6PR03CA0083.namprd03.prod.outlook.com (10.164.122.149) by MWHPR03MB2703.namprd03.prod.outlook.com (10.168.207.137) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.323.15; Tue, 2 Jan 2018 12:43:50 +0000 Received: from BN1AFFO11FD048.protection.gbl (2a01:111:f400:7c10::100) by BN6PR03CA0083.outlook.office365.com (2603:10b6:405:6f::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.366.8 via Frontend Transport; Tue, 2 Jan 2018 12:43:50 +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 BN1AFFO11FD048.mail.protection.outlook.com (10.58.53.63) 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:26 +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 w02Chfdd020140; Tue, 2 Jan 2018 05:43:47 -0700 From: Shreyansh Jain To: CC: , , , Shreyansh Jain Date: Tue, 2 Jan 2018 18:27:45 +0530 Message-ID: <20180102125749.2379-2-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: 131593706062826088; (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)(396003)(39860400002)(39380400002)(346002)(376002)(2980300002)(1110001)(1109001)(339900001)(189003)(199004)(36756003)(4326008)(1076002)(53936002)(77096006)(105606002)(106466001)(2351001)(5890100001)(97736004)(53946003)(6916009)(59450400001)(5660300001)(2950100002)(50226002)(86362001)(305945005)(76176011)(51416003)(8936002)(47776003)(8656006)(498600001)(316002)(68736007)(81156014)(356003)(104016004)(8676002)(54906003)(50466002)(16586007)(48376002)(81166006)(2906002)(85426001)(559001)(579004); DIR:OUT; SFP:1101; SCL:1; SRVR:MWHPR03MB2703; H:tx30smr01.am.freescale.net; FPR:; SPF:Fail; PTR:InfoDomainNonexistent; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BN1AFFO11FD048; 1:w++OG7XqGsDyXvmwWyJioSZLGzSL2m40Sl/m0OkJgS14FJcE5+P7rYLMFKykMR/ZCWfnnX0Ex0mPWg0ZKfvzfrDrPnoCWObVM11Zu+mvYGk9YwjrAOsHQEzGaGGkvuSe MIME-Version: 1.0 Content-Type: text/plain X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: ac52046f-34e6-49b5-4a68-08d551de6b04 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(4534020)(4628075)(201703131517081)(5600026)(4604075)(2017052603307); SRVR:MWHPR03MB2703; X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2703; 3:/uWawnflkThi9VtobecNVS0PumzPc05yAHRZH5Z5kjq4zndv2tuylCYZARqtYdYMYpjPhKi3LUZdir49cL7ir9DUGmf9fCBDJsFBC7ICmGvhu52vyhJmrmxwQl9rI9b8G/uOt+3T98vK/pMB/u+quAzIbwsQEdKHJRgW+1byfO74+CfengcBrkokUDbryLwAsfCFcJfxWg5Velas383k1kfDY3uPs15y7W3QTnpRsEZTGoUcCerNN6RznxLe+SBW0Nn2rDbDAWBLA+8iCcQQFjvpMgcLY+UGJY7R6CTN+bd/+CxQXHiMEZrBPqmVjW5Udzufsz1bouw7psKp99PIs8t78lnMWwhXnDIAqEbVq0A=; 25:+neuxMZzajawRnxsM4gv/DN6d7wZ1LDT9ezb0LZIz7SoVE7znTofwQhMy9qy4nFytFs+z4YdPRrYcEr0CYdMP4/r7UU6w8nMYgby2KN/3TPlrOmnV2KeORu7OEim55QE56ga8b1e7fg43n88k4ShS0BAwn3HBhfTZyTt5L6VeVtWQku5riUWgXBf41jYb/j7UFqDtjCQjDFL2kjPDB+lXJVV4FbSRgFBlnEu3tsz+PdJdWGr6RMUsKdqmc5uTJGpzHOiVayEDGR54NpkvsA0vTeX1DbdJDPp6FJbTWYljaU7OitcaP4IIh/twLrM+ZL2Gh31Ay7I8b9gXXL37Qiiww== X-MS-TrafficTypeDiagnostic: MWHPR03MB2703: X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2703; 31:hAVLirTREjKxirsqe15bZ1ZOCu9Py+X/KVxg8uFJ/XzAoiN4l3ZNHuBjeMx+IFyZk8TvVCdUfsYcYCAuOvkOs0ru3gNha1yW5on9DdYnzBbQ83PwMn3z70y3rgL3HokVZYqlBFRhZApOAxeSVgLwNTPnxTH4dDA7836Fr2ymPIQQ7Lx2nHvJcwdEMojW8GfUObGbVMIbxfnJDQdjwrQfXp9bR9672LaABSwYI8qPL9k=; 4:WqCfK4FowjoAoW2J/b9OmUejgcanw2co73trMWh6Kfomplm1bEn6S/N7v8kKs52a3Hjs6QBycNJDaIVA9j94bTOiSxsDuSjKMmzH40lOR6zmgzAjJCHomgtOBp78J+/14LX224maZEaU3CPcOmV+wP8ZhW54DQj5ECMVRQ+fLoPshZzhKJOFaqbiDUIWJPLin1lvHZ2c1w15eZhOA/lXLTZHpXmcfVuLckYCmvHoiAll/B08gHlqlrRm3nvD0MKziQtv+8g2KIaDJKkvBV9TagkWn/a6Lfiu+NM0S7gnNI6ltgjNUINU8YDZl7Cywkdbx531mvyOtBnh8AFzyOUqP7KHfih7NfP6qw8j1R/G63w= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(278428928389397)(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6095135)(2401047)(8121501046)(5005006)(3002001)(3231023)(944510075)(944921075)(946801075)(946901075)(10201501046)(93006095)(93001095)(6055026)(6096035)(20161123565025)(20161123563025)(20161123556025)(201703131430075)(201703131433075)(201703131448075)(201703161259150)(201703151042153)(20161123559100)(20161123561025)(201708071742011); SRVR:MWHPR03MB2703; BCL:0; PCL:0; RULEID:(100000803101)(100110400095)(400006); SRVR:MWHPR03MB2703; X-Forefront-PRVS: 0540846A1D X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; MWHPR03MB2703; 23:1sEt4tfEjxJlUFplB3VJP0CPSDjuYP3Mj1bvRFexm?= =?us-ascii?Q?GapqJ29muDHDUDg1kjGLY79z3fRBh1LiV/qpskUvCIqWHc0agKITgouUyTcP?= =?us-ascii?Q?AVzV6AePhY4YWs6fMx7o/++/KsDF7vbh5IWl5iLbkix5JJtvhwhl1ckPfqMa?= =?us-ascii?Q?RRGRwgAVVQT2JUJRIo+O53AE0pKpuwQDCYliVihRZ2+xY/kDzzVedxFjmH1F?= =?us-ascii?Q?EB+kPZzdIJN/d3FWgEj9LYFJugD7fJMgmimuwGmsgQi5CABWxIs0xy1DGaNF?= =?us-ascii?Q?DTKeA+MWZvd1/DnnRkdEMYioSUthdyFgOj8OgVmPRl6ny4zh/yaOd6e90qIS?= =?us-ascii?Q?VY41ljsXM7VIppfyyGlRbdpowNDrajj+8E+ScR8/Wcr0SFsO/Abf6Z+QvrR5?= =?us-ascii?Q?t+oD+osl44hK8i7vLhyRspof0swvooUMFaBUssBZ6e9qLTTaYgmom0OUs4Gn?= =?us-ascii?Q?53o6B0MC6/Ck3vq65CbmNWg5aMXSV3t98DGQLlS4D2h0k8N/6XL9xo5u5tWz?= =?us-ascii?Q?wWM7hwpPH0ZTtbuBq8faFyoCUZTk01NJG1xuc2F7E6lwVr/z0jXh+kz9+IIS?= =?us-ascii?Q?Mnf44YuVv4eMG20HtfH5oXAkVVtI5qmJIpXUmbLgikGXpgc5Ao1NBU5OGEB9?= =?us-ascii?Q?DJX0OsvFXpXpQx9A5EhTDTGCTbrzwwwOJ6O9CWBnRV9tAggO/RjyhA7Gjkhr?= =?us-ascii?Q?puENaMGhJUdYyiOMiahsr0GJ2LJq+918ydI4SL/+1E1yBrI/UnBGiEdMRGKM?= =?us-ascii?Q?Pqi2dVVX3esGFGKeOFPdjy2RVS+dkmBY4+nrDhcDciI0a4R7JAp3V1HyUsCB?= =?us-ascii?Q?VCCtifwmUy/nAOdvA5WZYUEUbbVxqXEZzaYP0cedI7XHPGULBlQEl75tRgH+?= =?us-ascii?Q?yH5PA6VvzpG4hULyiFRSqSLGaokOmrcXU9AEjm3mnYezYdGQNnRc3BoW4qDO?= =?us-ascii?Q?C2flt7DTw0NRGOqajPru7ylMVUgWahNdZwHcLhHjDjTsh9vF1YijvjFV0Xhf?= =?us-ascii?Q?R154OHkh+vQOxg/y5jfnWB7YzYBRDhnlDUi6WHgeLUrdirTZE9XxHnzWU15+?= =?us-ascii?Q?Q4YB39t5qElmR2lwIrff7KtBegHFCU2AXxEhpA9K5AljnG1+zQT6ZO6lllIQ?= =?us-ascii?Q?mJxpIGrT3s2Sf6tJIRTRDPHyMESB76Dy2HIL+x1hgK8TtHwIhD/EWKPJImcO?= =?us-ascii?Q?27cGjBCDpQR1/Q=3D?= X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2703; 6:G7onO6lf0vTVb7GJesqVZoRdeALP1qyOkYqCb2n989t3gHHMjUhm/trOVMlsRLVYDzfZVFgjXLURVFShNt8ISBB8bJoS9rewG3Mf5U02gXxq1tTX0ud2Kkmhfh8oa7/PBeoI3sJVQSjbJTd0vMtzvLTNJ+Dj9F+l51Qe0NpDr6V3byQJ1b0SpvWRouPGi191iSBWloTTaDEMI7uBs8p9lmTMN7W7Qj9GoRg3icqe5J0y6oafYe2IyRBKPCyCMeaXFK0uPykWk6B3XGLxvbKWZN3MXRZYW1CtsHUJxh7zqo37JMPJTp9OBnLltavDYS9qR2koYeUB82/vBC5LX9Lva27uL5wF1isv/6Bg4vSSCH0=; 5:lSsIJEjy4fWsFHpl1IaHPAXc+ttGVbhPNZEoecR+zf9QsDBublql2ZQCOxEPx/qOCmNmtoHi2wawEYLR05+pMHjkrTp5HaYOhq6Xaqlfw69JrWYmTrkFwHXxfsz/EQXsaNacJDcKy22SWFDZ7iKVIKA6LBjA69DOnAW0r2X6UHU=; 24:DwLF2jmsDAzRps3tPkPUyJQjyUIjPlllXzshpA7M+0w35vuNh+20vsCpPdVOxZDBxb0a7nSJdPbY6owFx61TXP/FdGtCAFtL4iutqtJm5Rc=; 7:Diy4O8Ip1Evx2i0nc8aOl2kjCG0D/keFmQ8XripneofrxAbS7WE2rO0MOmtkmjM0xPX5SLql2YjhU6Fv/saCkNYAAW7rCh1pv33rrwSLL0roeX4I44hGR4iTJHbLLzrQ+uD0woJ+kBEcSwfC0LuKmeXlPIt0Kh9LKkMMmWHcpw1U7du54exBUbk0/qoo+OboJFtuOsM0rxEF2q7+WrsbU1XmnmYf3Zbiy3Bi3oIl9EZq85/D/7NKrwDPW7sdf9pf SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Jan 2018 12:43:26.1266 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: ac52046f-34e6-49b5-4a68-08d551de6b04 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: MWHPR03MB2703 Subject: [dpdk-dev] [PATCH v1 1/5] rawdev: introduce raw device library support 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: , X-List-Received-Date: Tue, 02 Jan 2018 12:43:53 -0000 A device is DPDK has a flavor to it - ethernet, crypto, event etc. A rawdevice represents a generic device map-able to a device flavour not being currently handled out-of-the-box by DPDK framework. A device which can be scanned on an installed bus (pci, fslmc, ...) or instantiated through devargs, can be interfaced using standardized APIs just like other standardized devices. This library introduces an API set which can be plugged on the northbound side to the application layer, and on the southbound side to the driver layer. The APIs of rawdev library exposes some generic operations which can enable configuration and I/O with the raw devices. Signed-off-by: Shreyansh Jain --- lib/librte_rawdev/Makefile | 27 ++ lib/librte_rawdev/rte_rawdev.c | 540 ++++++++++++++++++++++++++++ lib/librte_rawdev/rte_rawdev.h | 586 ++++++++++++++++++++++++++++++ lib/librte_rawdev/rte_rawdev_pmd.h | 588 +++++++++++++++++++++++++++++++ lib/librte_rawdev/rte_rawdev_version.map | 33 ++ 5 files changed, 1774 insertions(+) create mode 100644 lib/librte_rawdev/Makefile create mode 100644 lib/librte_rawdev/rte_rawdev.c create mode 100644 lib/librte_rawdev/rte_rawdev.h create mode 100644 lib/librte_rawdev/rte_rawdev_pmd.h create mode 100644 lib/librte_rawdev/rte_rawdev_version.map diff --git a/lib/librte_rawdev/Makefile b/lib/librte_rawdev/Makefile new file mode 100644 index 000000000..addb288d7 --- /dev/null +++ b/lib/librte_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_rawdev.a + +# library version +LIBABIVER := 1 + +# build flags +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) +LDLIBS += -lrte_eal + +# library source files +SRCS-y += rte_rawdev.c + +# export include files +SYMLINK-y-include += rte_rawdev.h +SYMLINK-y-include += rte_rawdev_pmd.h + +# versioning export map +EXPORT_MAP := rte_rawdev_version.map + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/lib/librte_rawdev/rte_rawdev.c b/lib/librte_rawdev/rte_rawdev.c new file mode 100644 index 000000000..2d34d9b6d --- /dev/null +++ b/lib/librte_rawdev/rte_rawdev.c @@ -0,0 +1,540 @@ +/* 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 +#include +#include +#include +#include + +#include "rte_rawdev.h" +#include "rte_rawdev_pmd.h" + +/* dynamic log identifier */ +int librawdev_logtype; + +/* Maximum rawdevices supported by system. + */ +#define RTE_MAX_RAWDEVPORTS 10 + +struct rte_rawdev rte_rawdevices[RTE_RAWDEV_MAX_DEVS]; + +struct rte_rawdev *rte_rawdevs = &rte_rawdevices[0]; + +static struct rte_rawdev_global rawdev_globals = { + .nb_devs = 0 +}; + +struct rte_rawdev_global *rte_rawdev_globals = &rawdev_globals; + +/* Raw device, northbound API implementation */ +uint8_t +rte_rawdev_count(void) +{ + return rte_rawdev_globals->nb_devs; +} + +uint16_t +rte_rawdev_get_dev_id(const char *name) +{ + uint16_t i; + + if (!name) + return -EINVAL; + + for (i = 0; i < rte_rawdev_globals->nb_devs; i++) + if ((strcmp(rte_rawdevices[i].name, name) + == 0) && + (rte_rawdevices[i].attached == + RTE_RAWDEV_ATTACHED)) + return i; + return -ENODEV; +} + +int +rte_rawdev_socket_id(uint16_t dev_id) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + return dev->socket_id; +} + +int +rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info) +{ + struct rte_rawdev *rawdev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + RTE_FUNC_PTR_OR_ERR_RET(dev_info, -EINVAL); + + if (dev_info == NULL) + return -EINVAL; + + rawdev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*rawdev->dev_ops->dev_info_get, -ENOTSUP); + (*rawdev->dev_ops->dev_info_get)(rawdev, dev_info->dev_private); + + if (dev_info) { + + dev_info->driver_name = rawdev->driver_name; + dev_info->device = rawdev->device; + } + + return 0; +} + +int +rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf) +{ + struct rte_rawdev *dev; + int diag; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + RTE_FUNC_PTR_OR_ERR_RET(dev_conf, -EINVAL); + + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP); + + if (dev->started) { + RTE_RDEV_ERR( + "device %d must be stopped to allow configuration", dev_id); + return -EBUSY; + } + + /* Configure the device */ + diag = (*dev->dev_ops->dev_configure)(dev, dev_conf->dev_private); + if (diag != 0) + RTE_RDEV_ERR("dev%d dev_configure = %d", dev_id, diag); + else + dev->attached = 1; + + return diag; +} + +int +rte_rawdev_queue_conf_get(uint16_t dev_id, + uint16_t queue_id, + rte_rawdev_obj_t queue_conf) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_def_conf, -ENOTSUP); + (*dev->dev_ops->queue_def_conf)(dev, queue_id, queue_conf); + return 0; +} + +int +rte_rawdev_queue_setup(uint16_t dev_id, + uint16_t queue_id, + rte_rawdev_obj_t queue_conf) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_setup, -ENOTSUP); + return (*dev->dev_ops->queue_setup)(dev, queue_id, queue_conf); +} + +int +rte_rawdev_queue_release(uint16_t dev_id, uint16_t queue_id) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_release, -ENOTSUP); + return (*dev->dev_ops->queue_release)(dev, queue_id); +} + +int +rte_rawdev_get_attr(uint16_t dev_id, + const char *attr_name, + uint64_t *attr_value) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->attr_get, -ENOTSUP); + return (*dev->dev_ops->attr_get)(dev, attr_name, attr_value); +} + +int +rte_rawdev_set_attr(uint16_t dev_id, + const char *attr_name, + const uint64_t attr_value) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->attr_set, -ENOTSUP); + return (*dev->dev_ops->attr_set)(dev, attr_name, attr_value); +} + +int +rte_rawdev_enqueue_buffers(uint16_t dev_id, + struct rte_rawdev_buf **buffers, + unsigned int count, + rte_rawdev_obj_t context) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->enqueue_bufs, -ENOTSUP); + return (*dev->dev_ops->enqueue_bufs)(dev, buffers, count, context); +} + +int +rte_rawdev_dequeue_buffers(uint16_t dev_id, + struct rte_rawdev_buf **buffers, + unsigned int count, + rte_rawdev_obj_t context) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dequeue_bufs, -ENOTSUP); + return (*dev->dev_ops->dequeue_bufs)(dev, buffers, count, context); +} + +int +rte_rawdev_dump(uint16_t dev_id, FILE *f) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dump, -ENOTSUP); + return (*dev->dev_ops->dump)(dev, f); +} + +static int +xstats_get_count(uint16_t dev_id) +{ + struct rte_rawdev *dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_names, -ENOTSUP); + return (*dev->dev_ops->xstats_get_names)(dev, NULL, 0); +} + +int +rte_rawdev_xstats_names_get(uint16_t dev_id, + struct rte_rawdev_xstats_name *xstats_names, + unsigned int size) +{ + const struct rte_rawdev *dev; + int cnt_expected_entries; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV); + + cnt_expected_entries = xstats_get_count(dev_id); + + if (xstats_names == NULL || cnt_expected_entries < 0 || + (int)size < cnt_expected_entries || size <= 0) + return cnt_expected_entries; + + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_names, -ENOTSUP); + return (*dev->dev_ops->xstats_get_names)(dev, xstats_names, size); +} + +/* retrieve rawdev extended statistics */ +int +rte_rawdev_xstats_get(uint16_t dev_id, + const unsigned int ids[], + uint64_t values[], + unsigned int n) +{ + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -ENODEV); + const struct rte_rawdev *dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get, -ENOTSUP); + return (*dev->dev_ops->xstats_get)(dev, ids, values, n); +} + +uint64_t +rte_rawdev_xstats_by_name_get(uint16_t dev_id, + const char *name, + unsigned int *id) +{ + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, 0); + const struct rte_rawdev *dev = &rte_rawdevs[dev_id]; + unsigned int temp = -1; + + if (id != NULL) + *id = (unsigned int)-1; + else + id = &temp; /* driver never gets a NULL value */ + + /* implemented by driver */ + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_get_by_name, -ENOTSUP); + return (*dev->dev_ops->xstats_get_by_name)(dev, name, id); +} + +int +rte_rawdev_xstats_reset(uint16_t dev_id, + const uint32_t ids[], uint32_t nb_ids) +{ + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + struct rte_rawdev *dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_reset, -ENOTSUP); + return (*dev->dev_ops->xstats_reset)(dev, ids, nb_ids); +} + +int +rte_rawdev_firmware_status_get(uint16_t dev_id, rte_rawdev_obj_t status_info) +{ + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + struct rte_rawdev *dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_status_get, -ENOTSUP); + return (*dev->dev_ops->firmware_status_get)(dev, status_info); +} + +int +rte_rawdev_firmware_version_get(uint16_t dev_id, rte_rawdev_obj_t version_info) +{ + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + struct rte_rawdev *dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_version_get, -ENOTSUP); + return (*dev->dev_ops->firmware_version_get)(dev, version_info); +} + +int +rte_rawdev_firmware_load(uint16_t dev_id, rte_rawdev_obj_t firmware_image) +{ + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + struct rte_rawdev *dev = &rte_rawdevs[dev_id]; + + if (!firmware_image) + return -EINVAL; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_load, -ENOTSUP); + return (*dev->dev_ops->firmware_load)(dev, firmware_image); +} + +int +rte_rawdev_firmware_unload(uint16_t dev_id) +{ + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + struct rte_rawdev *dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->firmware_load, -ENOTSUP); + return (*dev->dev_ops->firmware_unload)(dev); +} + +int +rte_rawdev_start(uint16_t dev_id) +{ + struct rte_rawdev *dev; + int diag; + + RTE_RDEV_DEBUG("Start dev_id=%" PRIu8, dev_id); + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_start, -ENOTSUP); + + if (dev->started != 0) { + RTE_RDEV_ERR("Device with dev_id=%" PRIu8 "already started", + dev_id); + return 0; + } + + diag = (*dev->dev_ops->dev_start)(dev); + if (diag == 0) + dev->started = 1; + else + return diag; + + return 0; +} + +void +rte_rawdev_stop(uint16_t dev_id) +{ + struct rte_rawdev *dev; + + RTE_RDEV_DEBUG("Stop dev_id=%" PRIu8, dev_id); + + RTE_RAWDEV_VALID_DEVID_OR_RET(dev_id); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_stop); + + if (dev->started == 0) { + RTE_RDEV_ERR("Device with dev_id=%" PRIu8 "already stopped", + dev_id); + return; + } + + (*dev->dev_ops->dev_stop)(dev); + dev->started = 0; +} + +int +rte_rawdev_close(uint16_t dev_id) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP); + /* Device must be stopped before it can be closed */ + if (dev->started == 1) { + RTE_RDEV_ERR("Device %u must be stopped before closing", + dev_id); + return -EBUSY; + } + + return (*dev->dev_ops->dev_close)(dev); +} + +int +rte_rawdev_reset(uint16_t dev_id) +{ + struct rte_rawdev *dev; + + RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, -EINVAL); + dev = &rte_rawdevs[dev_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_reset, -ENOTSUP); + /* Reset is not dependent on state of the device */ + return (*dev->dev_ops->dev_reset)(dev); +} + +static inline uint8_t +rte_rawdev_find_free_device_index(void) +{ + uint16_t dev_id; + + for (dev_id = 0; dev_id < RTE_MAX_RAWDEVPORTS; dev_id++) { + if (rte_rawdevs[dev_id].attached == + RTE_RAWDEV_DETACHED) + return dev_id; + } + + return RTE_MAX_RAWDEVPORTS; +} + +struct rte_rawdev * +rte_rawdev_pmd_allocate(const char *name, size_t dev_priv_size, int socket_id) +{ + struct rte_rawdev *rawdev; + uint16_t dev_id; + + if (rte_rawdev_pmd_get_named_dev(name) != NULL) { + RTE_RDEV_ERR("Event device with name %s already allocated!", + name); + return NULL; + } + + dev_id = rte_rawdev_find_free_device_index(); + if (dev_id == RTE_MAX_RAWDEVPORTS) { + RTE_RDEV_ERR("Reached maximum number of raw devices"); + return NULL; + } + + rawdev = &rte_rawdevs[dev_id]; + + rawdev->dev_private = rte_zmalloc_socket("rawdev private", + dev_priv_size, + RTE_CACHE_LINE_SIZE, + socket_id); + if (!rawdev->dev_private) { + RTE_RDEV_ERR("Unable to allocate memory to Skeleton dev"); + return NULL; + } + + + rawdev->dev_id = dev_id; + rawdev->socket_id = socket_id; + rawdev->started = 0; + snprintf(rawdev->name, RTE_RAWDEV_NAME_MAX_LEN, "%s", name); + + rawdev->attached = RTE_RAWDEV_ATTACHED; + rawdev_globals.nb_devs++; + + return rawdev; +} + +int +rte_rawdev_pmd_release(struct rte_rawdev *rawdev) +{ + int ret; + + if (rawdev == NULL) + return -EINVAL; + + ret = rte_rawdev_close(rawdev->dev_id); + if (ret < 0) + return ret; + + rawdev->attached = RTE_RAWDEV_DETACHED; + rawdev_globals.nb_devs--; + + rawdev->dev_id = 0; + rawdev->socket_id = 0; + rawdev->dev_ops = NULL; + if (rawdev->dev_private) { + rte_free(rawdev->dev_private); + rawdev->dev_private = NULL; + } + + return 0; +} + +RTE_INIT(librawdev_init_log); + +static void +librawdev_init_log(void) +{ + librawdev_logtype = rte_log_register("librte.rawdev"); + if (librawdev_logtype >= 0) + rte_log_set_level(librawdev_logtype, RTE_LOG_INFO); +} diff --git a/lib/librte_rawdev/rte_rawdev.h b/lib/librte_rawdev/rte_rawdev.h new file mode 100644 index 000000000..d199819d4 --- /dev/null +++ b/lib/librte_rawdev/rte_rawdev.h @@ -0,0 +1,586 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2017 NXP + */ + +#ifndef _RTE_RAWDEV_H_ +#define _RTE_RAWDEV_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#define RTE_RAWDEV_MAX_DEVS RTE_MAX_RAWDEVS + +/* Rawdevice object - essentially a void to be typecasted by implementation */ +typedef void *rte_rawdev_obj_t; + +/** + * Get the total number of raw devices that have been successfully + * initialised. + * + * @return + * The total number of usable raw devices. + */ +uint8_t +rte_rawdev_count(void); + +/** + * Get the device identifier for the named raw device. + * + * @param name + * Raw device name to select the raw device identifier. + * + * @return + * Returns raw device identifier on success. + * - <0: Failure to find named raw device. + */ +uint16_t +rte_rawdev_get_dev_id(const char *name); + +/** + * Return the NUMA socket to which a device is connected. + * + * @param dev_id + * The identifier of the device. + * @return + * The NUMA socket id to which the device is connected or + * a default of zero if the socket could not be determined. + * -(-EINVAL) dev_id value is out of range. + */ +int +rte_rawdev_socket_id(uint16_t dev_id); + +/** + * Raw device information forward declaration + */ +struct rte_rawdev_info; + +/** + * Retrieve the contextual information of a raw device. + * + * @param dev_id + * The identifier of the device. + * + * @param[out] dev_info + * A pointer to a structure of type *rte_rawdev_info* to be filled with the + * contextual information of the device. + * + * @return + * - 0: Success, driver updates the contextual information of the raw device + * - <0: Error code returned by the driver info get function. + * + */ +int +rte_rawdev_info_get(uint16_t dev_id, struct rte_rawdev_info *dev_info); + +/** + * Configure a raw device. + * + * This function must be invoked first before any other function in the + * API. This function can also be re-invoked when a device is in the + * stopped state. + * + * The caller may use rte_rawdev_info_get() to get the capability of each + * resources available for this raw device. + * + * @param dev_id + * The identifier of the device to configure. + * @param dev_conf + * The raw device configuration structure encapsulated into rte_rawdev_info + * object. + * It is assumed that the opaque object has enough information which the + * driver/implementation can use to configure the device. It is also assumed + * that once the configuration is done, a `queue_id` type field can be used + * to refer to some arbitrary internal representation of a queue. + * + * @return + * - 0: Success, device configured. + * - <0: Error code returned by the driver configuration function. + */ +int +rte_rawdev_configure(uint16_t dev_id, struct rte_rawdev_info *dev_conf); + + +/** + * Retrieve the current configuration information of a raw queue designated + * by its *queue_id* from the raw driver for a raw device. + * + * This function intended to be used in conjunction with rte_raw_queue_setup() + * where caller needs to set up the queue by overriding few default values. + * + * @param dev_id + * The identifier of the device. + * @param queue_id + * The index of the raw queue to get the configuration information. + * The value must be in the range [0, nb_raw_queues - 1] + * previously supplied to rte_rawdev_configure(). + * @param[out] queue_conf + * The pointer to the default raw queue configuration data. + * @return + * - 0: Success, driver updates the default raw queue configuration data. + * - <0: Error code returned by the driver info get function. + * + * @see rte_raw_queue_setup() + * + */ +int +rte_rawdev_queue_conf_get(uint16_t dev_id, + uint16_t queue_id, + rte_rawdev_obj_t queue_conf); + +/** + * Allocate and set up a raw queue for a raw device. + * + * @param dev_id + * The identifier of the device. + * @param queue_id + * The index of the raw queue to setup. The value must be in the range + * [0, nb_raw_queues - 1] previously supplied to rte_rawdev_configure(). + * @param queue_conf + * The pointer to the configuration data to be used for the raw queue. + * NULL value is allowed, in which case default configuration used. + * + * @see rte_rawdev_queue_conf_get() + * + * @return + * - 0: Success, raw queue correctly set up. + * - <0: raw queue configuration failed + */ +int +rte_rawdev_queue_setup(uint16_t dev_id, + uint16_t queue_id, + rte_rawdev_obj_t queue_conf); + +/** + * Allocate and set up a raw queue for a raw device. + * + * @param dev_id + * The identifier of the device. + * @param queue_id + * The index of the raw queue to setup. The value must be in the range + * [0, nb_raw_queues - 1] previously supplied to rte_rawdev_configure(). + * + * @see rte_rawdev_queue_conf_get() + * + * @return + * - 0: Success, raw queue correctly set up. + * - <0: raw queue configuration failed + */ +int +rte_rawdev_queue_release(uint16_t dev_id, uint16_t queue_id); +/** + * Get the number of raw queues on a specific raw device + * + * @param dev_id + * Raw device identifier. + * @return + * - The number of configured raw queues + */ +uint16_t +rte_rawdev_queue_count(uint16_t dev_id); + +/** + * Start a raw device. + * + * The device start step is the last one and consists of setting the raw + * queues to start accepting the raws and schedules to raw ports. + * + * On success, all basic functions exported by the API (raw enqueue, + * raw dequeue and so on) can be invoked. + * + * @param dev_id + * Raw device identifier + * @return + * - 0: Success, device started. + * < 0: Failure + */ +int +rte_rawdev_start(uint16_t dev_id); + +/** + * Stop a raw device. The device can be restarted with a call to + * rte_rawdev_start() + * + * @param dev_id + * Raw device identifier. + */ +void +rte_rawdev_stop(uint16_t dev_id); + +/** + * Close a raw device. The device cannot be restarted after this call. + * + * @param dev_id + * Raw device identifier + * + * @return + * - 0 on successfully closing device + * - <0 on failure to close device + * - (-EAGAIN) if device is busy + */ +int +rte_rawdev_close(uint16_t dev_id); + +/** + * Reset a raw device. + * This is different from cycle of rte_rawdev_start->rte_rawdev_stop in the + * sense similar to hard or soft reset. + * + * @param dev_id + * Raw device identifiers + * @return + * 0 for sucessful reset, + * !0 for failure in reseting + */ +int +rte_rawdev_reset(uint16_t dev_id); + +#define RTE_RAWDEV_NAME_MAX_LEN (64) +/**< @internal Max length of name of raw PMD */ + + + +/** @internal + * The data structure associated with each raw device. + * It is a placeholder for PMD specific data, encapsulating only information + * related to framework. + */ +struct rte_rawdev { + int socket_id; + /**< Socket ID where memory is allocated */ + uint16_t dev_id; + /**< Device ID for this instance */ + + const struct rte_rawdev_ops *dev_ops; + /**< Functions exported by PMD */ + + struct rte_device *device; + /**< Device info. supplied during device initialization */ + const char *driver_name; + /**< Driver info. supplied by probing */ + + RTE_STD_C11 + uint8_t attached : 1; + /**< Flag indicating the device is attached */ + uint8_t started : 1; + /**< Device state: STARTED(1)/STOPPED(0) */ + + rte_rawdev_obj_t dev_private; + /**< PMD-specific private data */ + + char name[RTE_RAWDEV_NAME_MAX_LEN]; +} __rte_cache_aligned; + +extern struct rte_rawdev *rte_rawdevs; +/** @internal The pool of rte_rawdev structures. */ + +struct rte_rawdev_info { + const char *driver_name; /**< Name of driver handling this device */ + struct rte_device *device; /**< Device encapsulation */ + + int socket_id; + /**< Socket ID where memory is allocated */ + + rte_rawdev_obj_t dev_private; + /**< PMD-specific private data */ +}; + +struct rte_rawdev_buf { + void *buf_addr; +}; + +/** + * Dump internal information about *dev_id* to the FILE* provided in *f*. + * + * @param dev_id + * The identifier of the device. + * + * @param f + * A pointer to a file for output + * + * @return + * - 0: on success + * - <0: on failure. + */ +int +rte_rawdev_dump(uint16_t dev_id, FILE *f); + +/** + * Get an attribute value from implementation. + * Attribute is an opaque handle agreed upon between application and PMD. + * + * Implementations are expected to maintain an array of attribute-value pairs + * based on application calls. Memory management for this structure is + * shared responsibility of implementation and application. + * + * @param dev_id + * The identifier of the device to configure. + * @attr_name + * Opaque object representing an attribute in implementation. + * @attr_value [out] + * Opaque response to the attribute value. In case of error, this remains + * untouched. This is double pointer of void type. + * @return + * 0 for success + * !0 Error; attr_value remains untouched in case of error. + */ +int +rte_rawdev_get_attr(uint16_t dev_id, + const char *attr_name, + uint64_t *attr_value); + +/** + * Set an attribute value. + * Attribute is an opaque handle agreed upon between application and PMD. + * + * @param dev_id + * The identifier of the device to configure. + * @attr_name + * Opaque object representing an attribute in implementation. + * @attr_value + * Value of the attribute represented by attr_name + * @return + * 0 for success + * !0 Error + */ +int +rte_rawdev_set_attr(uint16_t dev_id, + const char *attr_name, + const uint64_t attr_value); + +/** + * Enqueue a stream of buffers to the device. + * + * Rather than specifying a queue, this API passes along an opaque object + * to the driver implementation. That object can be a queue or any other + * contextual information necessary for the device to enqueue buffers. + * + * @param dev_id + * The identifier of the device to configure. + * @param bufs + * Collection of buffers for enqueueing + * @param count + * Count of buffers to enqueue + * @param context + * Opaque context information. + * @return + * >=0 for buffers enqueued + * !0 for failure. + * Whether partial enqueue is failure or success is defined between app + * and driver implementation. + */ +int +rte_rawdev_enqueue_buffers(uint16_t dev_id, + struct rte_rawdev_buf **buffers, + unsigned int count, + rte_rawdev_obj_t context); + +/** + * Dequeue a stream of buffers from the device. + * + * Rather than specifying a queue, this API passes along an opaque object + * to the driver implementation. That object can be a queue or any other + * contextual information necessary for the device to dequeue buffers. + * + * Application should have allocated enough space to store `count` response + * buffers. + * Releasing buffers dequeued is responsibility of the application. + * + * @param dev_id + * The identifier of the device to configure. + * @param bufs + * Collection of buffers dequeued + * @param count + * Max buffers expected to be dequeued + * @param context + * Opaque context information. + * @return + * >=0 for buffers dequeued + * !0 for failure. + * Whether partial enqueue is failure or success is defined between app + * and driver implementation. + */ +int +rte_rawdev_dequeue_buffers(uint16_t dev_id, + struct rte_rawdev_buf **buffers, + unsigned int count, + rte_rawdev_obj_t context); + +/** Maximum name length for extended statistics counters */ +#define RTE_RAW_DEV_XSTATS_NAME_SIZE 64 + +/** + * A name-key lookup element for extended statistics. + * + * This structure is used to map between names and ID numbers + * for extended ethdev statistics. + */ +struct rte_rawdev_xstats_name { + char name[RTE_RAW_DEV_XSTATS_NAME_SIZE]; +}; + +/** + * Retrieve names of extended statistics of a raw device. + * + * @param dev_id + * The identifier of the raw device. + * @param[out] xstats_names + * Block of memory to insert names into. Must be at least size in capacity. + * If set to NULL, function returns required capacity. + * @param size + * Capacity of xstats_names (number of names). + * @return + * - positive value lower or equal to size: success. The return value + * is the number of entries filled in the stats table. + * - positive value higher than size: error, the given statistics table + * is too small. The return value corresponds to the size that should + * be given to succeed. The entries in the table are not valid and + * shall not be used by the caller. + * - negative value on error: + * -ENODEV for invalid *dev_id* + * -ENOTSUP if the device doesn't support this function. + */ +int +rte_rawdev_xstats_names_get(uint16_t dev_id, + struct rte_rawdev_xstats_name *xstats_names, + unsigned int size); + +/** + * Retrieve extended statistics of a raw device. + * + * @param dev_id + * The identifier of the device. + * @param ids + * The id numbers of the stats to get. The ids can be got from the stat + * position in the stat list from rte_rawdev_get_xstats_names(), or + * by using rte_rawdev_get_xstats_by_name() + * @param[out] values + * The values for each stats request by ID. + * @param n + * The number of stats requested + * @return + * - positive value: number of stat entries filled into the values array + * - negative value on error: + * -ENODEV for invalid *dev_id* + * -ENOTSUP if the device doesn't support this function. + */ +int +rte_rawdev_xstats_get(uint16_t dev_id, + const unsigned int ids[], + uint64_t values[], + unsigned int n); + +/** + * Retrieve the value of a single stat by requesting it by name. + * + * @param dev_id + * The identifier of the device + * @param name + * The stat name to retrieve + * @param[out] id + * If non-NULL, the numerical id of the stat will be returned, so that further + * requests for the stat can be got using rte_rawdev_xstats_get, which will + * be faster as it doesn't need to scan a list of names for the stat. + * If the stat cannot be found, the id returned will be (unsigned)-1. + * @return + * - positive value or zero: the stat value + * - negative value: -EINVAL if stat not found, -ENOTSUP if not supported. + */ +uint64_t +rte_rawdev_xstats_by_name_get(uint16_t dev_id, + const char *name, + unsigned int *id); + +/** + * Reset the values of the xstats of the selected component in the device. + * + * @param dev_id + * The identifier of the device + * @param ids + * Selects specific statistics to be reset. When NULL, all statistics + * will be reset. If non-NULL, must point to array of at least + * *nb_ids* size. + * @param nb_ids + * The number of ids available from the *ids* array. Ignored when ids is NULL. + * @return + * - zero: successfully reset the statistics to zero + * - negative value: -EINVAL invalid parameters, -ENOTSUP if not supported. + */ +int +rte_rawdev_xstats_reset(uint16_t dev_id, + const uint32_t ids[], + uint32_t nb_ids); + +/** + * Get Firmware status of the device.. + * Returns a memory allocated by driver/implementation containing status + * information block. It is responsibility of caller to release the buffer. + * + * @param dev_id + * Raw device identifier + * @param status_info + * Pointer to status information area. Caller is responsible for releasing + * the memory associated. + * @return + * 0 for success, + * !0 for failure, `status_info` argument state is undefined + */ +int +rte_rawdev_firmware_status_get(uint16_t dev_id, + rte_rawdev_obj_t status_info); + +/** + * Get Firmware version of the device. + * Returns a memory allocated by driver/implementation containing version + * information block. It is responsibility of caller to release the buffer. + * + * @param dev_id + * Raw device identifier + * @param version_info + * Pointer to version information area. Caller is responsible for releasing + * the memory associated. + * @return + * 0 for success, + * !0 for failure, `version_info` argument state is undefined + */ +int +rte_rawdev_firmware_version_get(uint16_t dev_id, + rte_rawdev_obj_t version_info); + +/** + * Load firmware on the device. + * TODO: In future, methods like directly flashing from file too can be + * supported. + * + * @param dev_id + * Raw device identifier + * @param firmware_image + * Pointer to buffer containing image binary data + * @return + * 0 for successfull Load + * !0 for failure to load the provided image, or image incorrect. + */ +int +rte_rawdev_firmware_load(uint16_t dev_id, rte_rawdev_obj_t firmware_image); + +/** + * Unload firmware from the device. + * + * @param dev_id + * Raw device identifiers + * @return + * 0 for successful Unload + * !0 for failure in unloading + */ +int +rte_rawdev_firmware_unload(uint16_t dev_id); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_RAWDEV_H_ */ diff --git a/lib/librte_rawdev/rte_rawdev_pmd.h b/lib/librte_rawdev/rte_rawdev_pmd.h new file mode 100644 index 000000000..0147ef72f --- /dev/null +++ b/lib/librte_rawdev/rte_rawdev_pmd.h @@ -0,0 +1,588 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2017 NXP + */ + +#ifndef _RTE_RAWDEV_PMD_H_ +#define _RTE_RAWDEV_PMD_H_ + +/** @file + * RTE RAW PMD APIs + * + * @note + * Driver facing APIs for a raw device. These are not to be called directly by + * any application. + * @b EXPERIMENTAL: this API may change without prior notice + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include + +#include "rte_rawdev.h" + +extern int librawdev_logtype; + +/* Logging Macros */ +#define RTE_RDEV_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, librawdev_logtype, "%s(): " fmt "\n", \ + __func__, ##args) + +#define RTE_RDEV_ERR(fmt, args...) \ + RTE_RDEV_LOG(ERR, fmt, ## args) +#define RTE_RDEV_DEBUG(fmt, args...) \ + RTE_RDEV_LOG(DEBUG, fmt, ## args) +#define RTE_RDEV_INFO(fmt, args...) \ + RTE_RDEV_LOG(INFO, fmt, ## args) + + +/* Macros to check for valid device */ +#define RTE_RAWDEV_VALID_DEVID_OR_ERR_RET(dev_id, retval) do { \ + if (!rte_rawdev_pmd_is_valid_dev((dev_id))) { \ + RTE_RDEV_ERR("Invalid dev_id=%d", dev_id); \ + return retval; \ + } \ +} while (0) + +#define RTE_RAWDEV_VALID_DEVID_OR_RET(dev_id) do { \ + if (!rte_rawdev_pmd_is_valid_dev((dev_id))) { \ + RTE_RDEV_ERR("Invalid dev_id=%d", dev_id); \ + return; \ + } \ +} while (0) + +#define RTE_RAWDEV_DETACHED (0) +#define RTE_RAWDEV_ATTACHED (1) + +/* Global structure used for maintaining state of allocated raw devices. + * + * TODO: Should be expanded to : in future. + * Applications should be able to select from a number of type of raw + * devices which were detected or attached to this DPDK instance. + */ +struct rte_rawdev_global { + uint16_t nb_devs; /**< Number of devices found */ +}; + +extern struct rte_rawdev_global *rte_rawdev_globals; +/** Pointer to global raw devices data structure. */ +extern struct rte_rawdev *rte_rawdevs; +/** The pool of rte_rawdev structures. */ + +/** + * Get the rte_rawdev structure device pointer for the named device. + * + * @param name + * device name to select the device structure. + * + * @return + * - The rte_rawdev structure pointer for the given device ID. + */ +static inline struct rte_rawdev * +rte_rawdev_pmd_get_named_dev(const char *name) +{ + struct rte_rawdev *dev; + unsigned int i; + + if (name == NULL) + return NULL; + + for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++) { + dev = &rte_rawdevs[i]; + if ((dev->attached == RTE_RAWDEV_ATTACHED) && + (strcmp(dev->name, name) == 0)) + return dev; + } + + return NULL; +} + +/** + * Validate if the raw device index is a valid attached raw device. + * + * @param dev_id + * raw device index. + * + * @return + * - If the device index is valid (1) or not (0). + */ +static inline unsigned +rte_rawdev_pmd_is_valid_dev(uint8_t dev_id) +{ + struct rte_rawdev *dev; + + if (dev_id >= RTE_RAWDEV_MAX_DEVS) + return 0; + + dev = &rte_rawdevs[dev_id]; + if (dev->attached != RTE_RAWDEV_ATTACHED) + return 0; + else + return 1; +} + +/** + * Definitions of all functions exported by a driver through the + * the generic structure of type *rawdev_ops* supplied in the + * *rte_rawdev* structure associated with a device. + */ + +/** + * Get device information of a device. + * + * @param dev + * Raw device pointer + * @param dev_info + * Raw device information structure + * + * @return + * Returns 0 on success + */ +typedef void (*rawdev_info_get_t)(struct rte_rawdev *dev, + rte_rawdev_obj_t dev_info); + +/** + * Configure a device. + * + * @param dev + * Raw device pointer + * @param config + * Void object containing device specific configuration + * + * @return + * Returns 0 on success + */ +typedef int (*rawdev_configure_t)(const struct rte_rawdev *dev, + rte_rawdev_obj_t config); + +/** + * Start a configured device. + * + * @param dev + * Raw device pointer + * + * @return + * Returns 0 on success + */ +typedef int (*rawdev_start_t)(struct rte_rawdev *dev); + +/** + * Stop a configured device. + * + * @param dev + * Raw device pointer + */ +typedef void (*rawdev_stop_t)(struct rte_rawdev *dev); + +/** + * Close a configured device. + * + * @param dev + * Raw device pointer + * + * @return + * - 0 on success + * - (-EAGAIN) if can't close as device is busy + */ +typedef int (*rawdev_close_t)(struct rte_rawdev *dev); + +/** + * Reset a configured device. + * + * @param dev + * Raw device pointer + * @return + * 0 for success + * !0 for failure + */ +typedef int (*rawdev_reset_t)(struct rte_rawdev *dev); + +/** + * Retrieve the current raw queue configuration. + * + * @param dev + * Raw device pointer + * @param queue_id + * Raw device queue index + * @param[out] queue_conf + * Raw device queue configuration structure + * + */ +typedef void (*rawdev_queue_conf_get_t)(struct rte_rawdev *dev, + uint16_t queue_id, + rte_rawdev_obj_t queue_conf); + +/** + * Setup an raw queue. + * + * @param dev + * Raw device pointer + * @param queue_id + * Rawqueue index + * @param queue_conf + * Rawqueue configuration structure + * + * @return + * Returns 0 on success. + */ +typedef int (*rawdev_queue_setup_t)(struct rte_rawdev *dev, + uint16_t queue_id, + rte_rawdev_obj_t queue_conf); + +/** + * Release resources allocated by given raw queue. + * + * @param dev + * Raw device pointer + * @param queue_id + * Raw queue index + * + */ +typedef int (*rawdev_queue_release_t)(struct rte_rawdev *dev, + uint16_t queue_id); + +/** + * Enqueue an array of raw buffers to the device. + * + * Buffer being used is opaque - it can be obtained from mempool or from + * any other source. Interpretation of buffer is responsibility of driver. + * + * @param dev + * Raw device pointer + * @param bufs + * array of buffers + * @param count + * number of buffers passed + * @context + * an opaque object representing context of the call; for example, an + * application can pass information about the queues on which enqueue needs + * to be done. Or, the enqueue operation might be passed reference to an + * object containing a callback (agreed upon between applicatio and driver). + * + * @return + * >=0 Count of buffers successfully enqueued (0: no buffers enqueued) + * <0 Error count in case of error + */ +typedef int (*rawdev_enqueue_bufs_t)(struct rte_rawdev *dev, + struct rte_rawdev_buf **buffers, + unsigned int count, + rte_rawdev_obj_t context); + +/** + * Dequeue an array of raw buffers from the device. + * + * @param dev + * Raw device pointer + * @param bufs + * array of buffers + * @param count + * Max buffers expected to be dequeued + * @context + * an opaque object representing context of the call. Based on this object, + * the application and driver can coordinate for dequeue operation involving + * agreed upon semantics. For example, queue information/id on which Dequeue + * needs to be performed. + * @return + * >0, ~0: Count of buffers returned + * <0: Error + * Whether short dequeue is success or failure is decided between app and + * driver. + */ +typedef int (*rawdev_dequeue_bufs_t)(struct rte_rawdev *dev, + struct rte_rawdev_buf **buffers, + unsigned int count, + rte_rawdev_obj_t context); + +/** + * Dump internal information + * + * @param dev + * Raw device pointer + * @param f + * A pointer to a file for output + * @return + * 0 for success, + * !0 Error + * + */ +typedef int (*rawdev_dump_t)(struct rte_rawdev *dev, FILE *f); + +/** + * Get an attribute value from implementation. + * Attribute is an opaque handle agreed upon between application and PMD. + * + * @param dev + * Raw device pointer + * @attr_name + * Opaque object representing an attribute in implementation. + * @attr_value [out] + * Opaque response to the attribute value. In case of error, this remains + * untouched. This is double pointer of void type. + * @return + * 0 for success + * !0 Error; attr_value remains untouched in case of error. + */ +typedef int (*rawdev_get_attr_t)(struct rte_rawdev *dev, + const char *attr_name, + uint64_t *attr_value); + +/** + * Set an attribute value. + * Attribute is an opaque handle agreed upon between application and PMD. + * + * @param dev + * Raw device pointer + * @attr_name + * Opaque object representing an attribute in implementation. + * @attr_value + * Value of the attribute represented by attr_name + * @return + * 0 for success + * !0 Error + */ +typedef int (*rawdev_set_attr_t)(struct rte_rawdev *dev, + const char *attr_name, + const uint64_t attr_value); + +/** + * Retrieve a set of statistics from device. + * Note: Being a raw device, the stats are specific to the device being + * implemented thus represented as xstats. + * + * @param dev + * Raw device pointer + * @param ids + * The stat ids to retrieve + * @param values + * The returned stat values + * @param n + * The number of id values and entries in the values array + * @return + * The number of stat values successfully filled into the values array + */ +typedef int (*rawdev_xstats_get_t)(const struct rte_rawdev *dev, + const unsigned int ids[], uint64_t values[], unsigned int n); + +/** + * Resets the statistic values in xstats for the device. + */ +typedef int (*rawdev_xstats_reset_t)(struct rte_rawdev *dev, + const uint32_t ids[], + uint32_t nb_ids); + +/** + * Get names of extended stats of an raw device + * + * @param dev + * Raw device pointer + * @param xstats_names + * Array of name values to be filled in + * @param size + * Number of values in the xstats_names array + * @return + * When size >= the number of stats, return the number of stat values filled + * into the array. + * When size < the number of available stats, return the number of stats + * values, and do not fill in any data into xstats_names. + */ +typedef int (*rawdev_xstats_get_names_t)(const struct rte_rawdev *dev, + struct rte_rawdev_xstats_name *xstats_names, + unsigned int size); + +/** + * Get value of one stats and optionally return its id + * + * @param dev + * Raw device pointer + * @param name + * The name of the stat to retrieve + * @param id + * Pointer to an unsigned int where we store the stat-id. + * This pointer may be null if the id is not required. + * @return + * The value of the stat, or (uint64_t)-1 if the stat is not found. + * If the stat is not found, the id value will be returned as (unsigned)-1, + * if id pointer is non-NULL + */ +typedef uint64_t (*rawdev_xstats_get_by_name_t)(const struct rte_rawdev *dev, + const char *name, + unsigned int *id); + +/** + * Get firmware/device-stack status. + * Implementation to allocate buffer for returning information. + * + * @param dev + * Raw device pointer + * @param status + * void block containing device specific status information + * @return + * 0 for success, + * !0 for failure, with undefined value in `status_info` + */ +typedef int (*rawdev_firmware_status_get_t)(struct rte_rawdev *dev, + rte_rawdev_obj_t status_info); + +/** + * Get firmware version information + * + * @param dev + * Raw device pointer + * @param version_info + * void pointer to version information returned by device + * @return + * 0 for success, + * !0 for failure, with undefined value in `version_info` + */ +typedef int (*rawdev_firmware_version_get_t)(struct rte_rawdev *dev, + rte_rawdev_obj_t version_info); + +/** + * Load firwmare from a buffer (DMA'able) + * + * @param dev + * Raw device pointer + * @param firmware_file + * file pointer to firmware area + * @return + * >0, ~0: for successfull load + * <0: for failure + * + * @see Application may use 'firmware_version_get` for ascertaining successful + * load + */ +typedef int (*rawdev_firmware_load_t)(struct rte_rawdev *dev, + rte_rawdev_obj_t firmware_buf); + +/** + * Unload firwmare + * + * @param dev + * Raw device pointer + * @return + * >0, ~0 for successful unloading + * <0 for failure in unloading + * + * Note: Application can use the `firmware_status_get` or + * `firmware_version_get` to get result of unload. + */ +typedef int (*rawdev_firmware_unload_t)(struct rte_rawdev *dev); + + +/** Rawdevice operations function pointer table */ +struct rte_rawdev_ops { + rawdev_info_get_t dev_info_get; /**< Get device info. */ + rawdev_configure_t dev_configure; /**< Configure device. */ + rawdev_start_t dev_start; /**< Start device. */ + rawdev_stop_t dev_stop; /**< Stop device. */ + rawdev_close_t dev_close; /**< Close device. */ + rawdev_reset_t dev_reset; /**< Reset device. */ + + rawdev_queue_conf_get_t queue_def_conf; + /**< Get raw queue configuration. */ + rawdev_queue_setup_t queue_setup; + /**< Set up an raw queue. */ + rawdev_queue_release_t queue_release; + /**< Release an raw queue. */ + + rawdev_enqueue_bufs_t enqueue_bufs; + /**< Enqueue an array of raw buffers to device. */ + rawdev_dequeue_bufs_t dequeue_bufs; + /**< Dequeue an array of raw buffers from device. */ + /** TODO: Callback based enqueue and dequeue support */ + + rawdev_dump_t dump; + /* Dump internal information */ + + rawdev_get_attr_t attr_get; + /**< Get an attribute managed by the implementation */ + rawdev_set_attr_t attr_set; + /**< Set an attribute managed by the implementation */ + + rawdev_xstats_get_t xstats_get; + /**< Get extended device statistics. */ + rawdev_xstats_get_names_t xstats_get_names; + /**< Get names of extended stats. */ + rawdev_xstats_get_by_name_t xstats_get_by_name; + /**< Get one value by name. */ + rawdev_xstats_reset_t xstats_reset; + /**< Reset the statistics values in xstats. */ + + rawdev_firmware_status_get_t firmware_status_get; + /**< Obtainer firmware status */ + rawdev_firmware_version_get_t firmware_version_get; + /**< Obtain firmware version information */ + rawdev_firmware_load_t firmware_load; + /**< Load firmware */ + rawdev_firmware_unload_t firmware_unload; + /**< Unload firmware */ +}; + +/** + * Allocates a new rawdev slot for an raw device and returns the pointer + * to that slot for the driver to use. + * + * @param name + * Unique identifier name for each device + * @dev_priv_size + * Private data allocated within rte_rawdev object. + * @param socket_id + * Socket to allocate resources on. + * @return + * - Slot in the rte_dev_devices array for a new device; + */ +struct rte_rawdev * +rte_rawdev_pmd_allocate(const char *name, size_t dev_private_size, + int socket_id); + +/** + * Release the specified rawdev device. + * + * @param rawdev + * The *rawdev* pointer is the address of the *rte_rawdev* structure. + * @return + * - 0 on success, negative on error + */ +int +rte_rawdev_pmd_release(struct rte_rawdev *rawdev); + +/** + * Creates a new raw device and returns the pointer to that device. + * + * @param name + * Pointer to a character array containing name of the device + * @param dev_private_size + * Size of raw PMDs private data + * @param socket_id + * Socket to allocate resources on. + * + * @return + * - Raw device pointer if device is successfully created. + * - NULL if device cannot be created. + */ +struct rte_rawdev * +rte_rawdev_pmd_init(const char *name, size_t dev_private_size, + int socket_id); + +/** + * Destroy a raw device + * + * @param name + * Name of the device + * @return + * - 0 on success, negative on error + */ +int +rte_rawdev_pmd_uninit(const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_RAWDEV_PMD_H_ */ diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map new file mode 100644 index 000000000..8de9abdc4 --- /dev/null +++ b/lib/librte_rawdev/rte_rawdev_version.map @@ -0,0 +1,33 @@ +EXPERIMENTAL { + global: + + rte_rawdev_close; + rte_rawdev_configure; + rte_rawdev_count; + rte_rawdev_dequeue_buffers; + rte_rawdev_enqueue_buffers; + rte_rawdev_firmware_load; + rte_rawdev_firmware_status_get; + rte_rawdev_firmware_unload; + rte_rawdev_firmware_version_get; + rte_rawdev_get_attr; + rte_rawdev_get_dev_id; + rte_rawdev_info_get; + rte_rawdev_pmd_allocate; + rte_rawdev_pmd_release; + rte_rawdev_queue_conf_get; + rte_rawdev_queue_setup; + rte_rawdev_queue_release; + rte_rawdev_reset; + rte_rawdev_set_attr; + rte_rawdev_socket_id; + rte_rawdev_start; + rte_rawdev_stop; + rte_rawdev_xstats_by_name_get; + rte_rawdev_xstats_get; + rte_rawdev_xstats_names_get; + rte_rawdev_xstats_reset; + rte_rawdevs; + + local: *; +}; -- 2.14.1