From patchwork Wed Jan 5 14:00:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105637 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2D917A034D; Wed, 5 Jan 2022 15:00:42 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id ECADA4114A; Wed, 5 Jan 2022 15:00:33 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 546D841144 for ; Wed, 5 Jan 2022 15:00:33 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205BHCZB030856; Wed, 5 Jan 2022 06:00:29 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=YwJ8K2in9T15mfg9NlhHu4ViZwIh8uzp75hD6Yk/8X4=; b=V8vTRGtfpoZtrg4YEsS2/8SmnwC9MlXyn8PZXLelqgvZ4lL8ppQHjCKgEd54EgIGn7Wf brYYVJPxSBJZAqXAd7ArDlpkP8X3zNa8L4sV82UxFepjJN7DbCBmlqzHVygu/5sexBEj Vh94TlU1RZnXgaQNvxejffkKNZh2TBX9fwADvCYqQ3EkR1VYx7qNGdszQt1nsJT7V2P7 nBv8K0agPvK+AVxVakWtjcd3KEL3eLlZW6KfLCp/QGkdYsqA8xYWfPrnKufQQJo08Wwn 9/+pKCY4UVW8hcUgqWz6S3JXyB/ogteQFSrVmcJxLOAN9P+tbGQrEzQyxlcctTb7zNNS ew== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x100-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:29 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 5 Jan 2022 06:00:27 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Wed, 5 Jan 2022 06:00:27 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 866483F709A; Wed, 5 Jan 2022 06:00:25 -0800 (PST) From: Tomasz Duszynski To: , Ray Kinsella , Anatoly Burakov CC: , , Tomasz Duszynski Subject: [PATCH v4 01/11] raw/cnxk_gpio: add GPIO driver skeleton Date: Wed, 5 Jan 2022 15:00:10 +0100 Message-ID: <20220105140020.1615256-2-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: 8mbilF_eOfsfG4snLZlN2ItkeBMXcMoV X-Proofpoint-ORIG-GUID: 8mbilF_eOfsfG4snLZlN2ItkeBMXcMoV X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add initial support for PMD that allows to control particular pins form userspace. Moreover PMD allows to attach custom interrupt handlers to controllable GPIOs. Main users of this PMD are dataplain applications requiring fast and low latency access to pin state. Signed-off-by: Tomasz Duszynski --- doc/guides/rawdevs/cnxk_gpio.rst | 65 ++++++++ doc/guides/rawdevs/index.rst | 1 + drivers/raw/cnxk_gpio/cnxk_gpio.c | 239 ++++++++++++++++++++++++++++++ drivers/raw/cnxk_gpio/cnxk_gpio.h | 22 +++ drivers/raw/cnxk_gpio/meson.build | 8 + drivers/raw/cnxk_gpio/version.map | 3 + drivers/raw/meson.build | 1 + 7 files changed, 339 insertions(+) create mode 100644 doc/guides/rawdevs/cnxk_gpio.rst create mode 100644 drivers/raw/cnxk_gpio/cnxk_gpio.c create mode 100644 drivers/raw/cnxk_gpio/cnxk_gpio.h create mode 100644 drivers/raw/cnxk_gpio/meson.build create mode 100644 drivers/raw/cnxk_gpio/version.map diff --git a/doc/guides/rawdevs/cnxk_gpio.rst b/doc/guides/rawdevs/cnxk_gpio.rst new file mode 100644 index 0000000000..868302d07f --- /dev/null +++ b/doc/guides/rawdevs/cnxk_gpio.rst @@ -0,0 +1,65 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright(c) 2021 Marvell. + +Marvell CNXK GPIO Driver +======================== + +CNXK GPIO PMD configures and manages GPIOs available on the system using +standard enqueue/dequeue mechanism offered by raw device abstraction. PMD relies +both on standard sysfs GPIO interface provided by the Linux kernel and GPIO +kernel driver custom interface allowing one to install userspace interrupt +handlers. + +Features +-------- + +Following features are available: + +- export/unexport a GPIO +- read/write specific value from/to exported GPIO +- set GPIO direction +- set GPIO edge that triggers interrupt +- set GPIO active low +- register interrupt handler for specific GPIO + +Requirements +------------ + +PMD relies on modified kernel GPIO driver which exposes ``ioctl()`` interface +for installing interrupt handlers for low latency signal processing. + +Driver is shipped with Marvell SDK. + +Device Setup +------------ + +CNXK GPIO PMD binds to virtual device which gets created by passing +`--vdev=cnxk_gpio,gpiochip=` command line to EAL. `gpiochip` parameter +tells PMD which GPIO controller should be used. Available controllers are +available under `/sys/class/gpio`. For further details on how Linux represents +GPIOs in userspace please refer to +`sysfs.txt `_. + +If `gpiochip=` was omitted then first gpiochip from the alphabetically +sort list of available gpiochips is used. + +.. code-block:: console + + $ ls /sys/class/gpio + export gpiochip448 unexport + +In above scenario only one GPIO controller is present hence +`--vdev=cnxk_gpio,gpiochip=448` should be passed to EAL. + +Before performing actual data transfer one needs to call +``rte_rawdev_queue_count()`` followed by ``rte_rawdev_queue_conf_get()``. The +former returns number GPIOs available in the system irrespective of GPIOs +being controllable or not. Thus it is user responsibility to pick the proper +ones. The latter call simply returns queue capacity. + +Respective queue needs to be configured with ``rte_rawdev_queue_setup()``. This +call barely exports GPIO to userspace. + +To perform actual data transfer use standard ``rte_rawdev_enqueue_buffers()`` +and ``rte_rawdev_dequeue_buffers()`` APIs. Not all messages produce sensible +responses hence dequeueing is not always necessary. diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst index b6cf917443..0c02da6e90 100644 --- a/doc/guides/rawdevs/index.rst +++ b/doc/guides/rawdevs/index.rst @@ -12,6 +12,7 @@ application through rawdev API. :numbered: cnxk_bphy + cnxk_gpio dpaa2_cmdif dpaa2_qdma ifpga diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c new file mode 100644 index 0000000000..881615d62e --- /dev/null +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "cnxk_gpio.h" + +#define CNXK_GPIO_BUFSZ 128 +#define CNXK_GPIO_CLASS_PATH "/sys/class/gpio" + +static const char *const cnxk_gpio_args[] = { +#define CNXK_GPIO_ARG_GPIOCHIP "gpiochip" + CNXK_GPIO_ARG_GPIOCHIP, + NULL +}; + +static void +cnxk_gpio_format_name(char *name, size_t len) +{ + snprintf(name, len, "cnxk_gpio"); +} + +static int +cnxk_gpio_filter_gpiochip(const struct dirent *dirent) +{ + const char *pattern = "gpiochip"; + + return !strncmp(dirent->d_name, pattern, strlen(pattern)); +} + +static void +cnxk_gpio_set_defaults(struct cnxk_gpiochip *gpiochip) +{ + struct dirent **namelist; + int n; + + n = scandir(CNXK_GPIO_CLASS_PATH, &namelist, cnxk_gpio_filter_gpiochip, + alphasort); + if (n < 0 || n == 0) + return; + + sscanf(namelist[0]->d_name, "gpiochip%d", &gpiochip->num); + while (n--) + free(namelist[n]); + free(namelist); +} + +static int +cnxk_gpio_parse_arg_gpiochip(const char *key __rte_unused, const char *value, + void *extra_args) +{ + long val; + + errno = 0; + val = strtol(value, NULL, 10); + if (errno) + return -errno; + + *(int *)extra_args = (int)val; + + return 0; +} + +static int +cnxk_gpio_parse_args(struct cnxk_gpiochip *gpiochip, + struct rte_devargs *devargs) +{ + struct rte_kvargs *kvlist; + int ret; + + kvlist = rte_kvargs_parse(devargs->args, cnxk_gpio_args); + if (!kvlist) + return 0; + + ret = rte_kvargs_count(kvlist, CNXK_GPIO_ARG_GPIOCHIP); + if (ret == 1) { + ret = rte_kvargs_process(kvlist, CNXK_GPIO_ARG_GPIOCHIP, + cnxk_gpio_parse_arg_gpiochip, + &gpiochip->num); + if (ret) + goto out; + } + + ret = 0; +out: + rte_kvargs_free(kvlist); + + return ret; +} + +static int +cnxk_gpio_read_attr(char *attr, char *val) +{ + FILE *fp; + int ret; + + fp = fopen(attr, "r"); + if (!fp) + return -errno; + + ret = fscanf(fp, "%s", val); + if (ret < 0) + return -errno; + if (ret != 1) + return -EIO; + + ret = fclose(fp); + if (ret) + return -errno; + + return 0; +} + +static int +cnxk_gpio_read_attr_int(char *attr, int *val) +{ + char buf[CNXK_GPIO_BUFSZ]; + int ret; + + ret = cnxk_gpio_read_attr(attr, buf); + if (ret) + return ret; + + ret = sscanf(buf, "%d", val); + if (ret < 0) + return -errno; + + return 0; +} + +static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { +}; + +static int +cnxk_gpio_probe(struct rte_vdev_device *dev) +{ + char name[RTE_RAWDEV_NAME_MAX_LEN]; + struct cnxk_gpiochip *gpiochip; + struct rte_rawdev *rawdev; + char buf[CNXK_GPIO_BUFSZ]; + int ret; + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + cnxk_gpio_format_name(name, sizeof(name)); + rawdev = rte_rawdev_pmd_allocate(name, sizeof(*gpiochip), + rte_socket_id()); + if (!rawdev) { + RTE_LOG(ERR, PMD, "failed to allocate %s rawdev", name); + return -ENOMEM; + } + + rawdev->dev_ops = &cnxk_gpio_rawdev_ops; + rawdev->device = &dev->device; + rawdev->driver_name = dev->device.name; + + gpiochip = rawdev->dev_private; + cnxk_gpio_set_defaults(gpiochip); + + /* defaults may be overwritten by this call */ + ret = cnxk_gpio_parse_args(gpiochip, dev->device.devargs); + if (ret) + goto out; + + /* read gpio base */ + snprintf(buf, sizeof(buf), "%s/gpiochip%d/base", CNXK_GPIO_CLASS_PATH, + gpiochip->num); + ret = cnxk_gpio_read_attr_int(buf, &gpiochip->base); + if (ret) { + RTE_LOG(ERR, PMD, "failed to read %s", buf); + goto out; + } + + /* read number of available gpios */ + snprintf(buf, sizeof(buf), "%s/gpiochip%d/ngpio", CNXK_GPIO_CLASS_PATH, + gpiochip->num); + ret = cnxk_gpio_read_attr_int(buf, &gpiochip->num_gpios); + if (ret) { + RTE_LOG(ERR, PMD, "failed to read %s", buf); + goto out; + } + + gpiochip->gpios = rte_calloc(NULL, gpiochip->num_gpios, + sizeof(struct cnxk_gpio *), 0); + if (!gpiochip->gpios) { + RTE_LOG(ERR, PMD, "failed to allocate gpios memory"); + ret = -ENOMEM; + goto out; + } + + return 0; +out: + rte_rawdev_pmd_release(rawdev); + + return ret; +} + +static int +cnxk_gpio_remove(struct rte_vdev_device *dev) +{ + char name[RTE_RAWDEV_NAME_MAX_LEN]; + struct cnxk_gpiochip *gpiochip; + struct rte_rawdev *rawdev; + + RTE_SET_USED(dev); + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + cnxk_gpio_format_name(name, sizeof(name)); + rawdev = rte_rawdev_pmd_get_named_dev(name); + if (!rawdev) + return -ENODEV; + + gpiochip = rawdev->dev_private; + rte_free(gpiochip->gpios); + rte_rawdev_pmd_release(rawdev); + + return 0; +} + +static struct rte_vdev_driver cnxk_gpio_drv = { + .probe = cnxk_gpio_probe, + .remove = cnxk_gpio_remove, +}; + +RTE_PMD_REGISTER_VDEV(cnxk_gpio, cnxk_gpio_drv); +RTE_PMD_REGISTER_PARAM_STRING(cnxk_gpio, "gpiochip="); diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.h b/drivers/raw/cnxk_gpio/cnxk_gpio.h new file mode 100644 index 0000000000..4dae8316ba --- /dev/null +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#ifndef _CNXK_GPIO_H_ +#define _CNXK_GPIO_H_ + +struct cnxk_gpiochip; + +struct cnxk_gpio { + struct cnxk_gpiochip *gpiochip; + int num; +}; + +struct cnxk_gpiochip { + int num; + int base; + int num_gpios; + struct cnxk_gpio **gpios; +}; + +#endif /* _CNXK_GPIO_H_ */ diff --git a/drivers/raw/cnxk_gpio/meson.build b/drivers/raw/cnxk_gpio/meson.build new file mode 100644 index 0000000000..9a7e716c1e --- /dev/null +++ b/drivers/raw/cnxk_gpio/meson.build @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(C) 2021 Marvell. +# + +deps += ['bus_vdev', 'common_cnxk', 'rawdev', 'kvargs'] +sources = files( + 'cnxk_gpio.c', +) diff --git a/drivers/raw/cnxk_gpio/version.map b/drivers/raw/cnxk_gpio/version.map new file mode 100644 index 0000000000..4a76d1d52d --- /dev/null +++ b/drivers/raw/cnxk_gpio/version.map @@ -0,0 +1,3 @@ +DPDK_21 { + local: *; +}; diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build index 87694a758e..05e7de1bfe 100644 --- a/drivers/raw/meson.build +++ b/drivers/raw/meson.build @@ -7,6 +7,7 @@ endif drivers = [ 'cnxk_bphy', + 'cnxk_gpio', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga', From patchwork Wed Jan 5 14:00:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105636 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 69605A034D; Wed, 5 Jan 2022 15:00:35 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E907941141; Wed, 5 Jan 2022 15:00:32 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 92B7D41140 for ; Wed, 5 Jan 2022 15:00:31 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205CCDb6030899; Wed, 5 Jan 2022 06:00:30 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=MBpRNMc8J5qapEe+T/vfAzmvSIuAZo1DaauAqIv9y4o=; b=Ec88lbJtlPFkbc0EfKV7k9iiQtQHd3zu5QPMv74hBkwK7xZm0ECCVCtKo3yxAs22PJQD Du4JgNsRZc5U0L1HivXocPvFtibYblT0BFgInKO1OnuK8W9FtKQUuba4Hg5OOCr4Cutn zEIVOxsgH8IwYurAzFpV/1u/xw3gjoUZOQW4GAj/7zjj+BaVOUc/vzny2Zo2/qeRxfse TMBcdlRyxaIJXMaWoqoHPzUQ2yorBnrfvpK5SEtQSqLt6Z3yOT5IOK+WYHKnydhSQNv+ nfbo8A/n9d5T3cfqTaomSsoUNcqNblA7nnBIm4F4w0VjXiWnw1hTl8I5+4IxwAHRz3cb pw== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x104-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:30 -0800 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 5 Jan 2022 06:00:29 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Wed, 5 Jan 2022 06:00:29 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id E47D83F7072; Wed, 5 Jan 2022 06:00:27 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v4 02/11] raw/cnxk_gpio: support reading default queue conf Date: Wed, 5 Jan 2022 15:00:11 +0100 Message-ID: <20220105140020.1615256-3-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: QVHqFsEDDwJ9uT448yM1JaTnYqvW0sqe X-Proofpoint-ORIG-GUID: QVHqFsEDDwJ9uT448yM1JaTnYqvW0sqe X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for reading default queue configuration. Signed-off-by: Tomasz Duszynski --- drivers/raw/cnxk_gpio/cnxk_gpio.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index 881615d62e..f80788f7fb 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -138,7 +138,26 @@ cnxk_gpio_read_attr_int(char *attr, int *val) return 0; } +static int +cnxk_gpio_queue_def_conf(struct rte_rawdev *dev, uint16_t queue_id, + rte_rawdev_obj_t queue_conf, size_t queue_conf_size) +{ + unsigned int *conf; + + RTE_SET_USED(dev); + RTE_SET_USED(queue_id); + + if (queue_conf_size != sizeof(*conf)) + return -EINVAL; + + conf = (unsigned int *)queue_conf; + *conf = 1; + + return 0; +} + static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { + .queue_def_conf = cnxk_gpio_queue_def_conf, }; static int From patchwork Wed Jan 5 14:00:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105638 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 494C1A034D; Wed, 5 Jan 2022 15:00:49 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id DF32C4114F; Wed, 5 Jan 2022 15:00:35 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id C161B41147 for ; Wed, 5 Jan 2022 15:00:33 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205CJ2JW030859; Wed, 5 Jan 2022 06:00:33 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=qcRTu8jsIOlhw7ffXxyC6cJXv4/7fqeitq6X2YRcK20=; b=H1KdiubNXe4nqN7ehSit0h1BrX688Z2wmglsKX2WbpjWYDaFayLliBBWnW0RUMidnVRN XjeM/UOi9iVipJzvAihUh7XSiFCM7dkL56k1n5JZEiSid+8R2M/GvQr1P1yqY4inEuTx Ryf0AbSnuJfiqiQpg7g135L9uc3/0VNzlBErt35ljnzbQdcIgv/a8PFB1vhq6h2buznE U9hL10XhckeiNtw0FSKLl+0gld4/lrMu2oxyM9J7H/pQti7tLwTq3QTcmAlaHjSZelqI tsmHQyKrQtRn1EKBt2Y851FlLUinG69z+LeFnpJI+JVDDq06vGY2Qt/O1Oad3Cd7VehV 0A== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x10n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:32 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 5 Jan 2022 06:00:31 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Wed, 5 Jan 2022 06:00:31 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id DB39F3F703F; Wed, 5 Jan 2022 06:00:29 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v4 03/11] raw/cnxk_gpio: support reading queue count Date: Wed, 5 Jan 2022 15:00:12 +0100 Message-ID: <20220105140020.1615256-4-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: LiFeqR3qgprc6H480slgBhZ0bC5HmuYO X-Proofpoint-ORIG-GUID: LiFeqR3qgprc6H480slgBhZ0bC5HmuYO X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for reading number of available queues. Single queue corresponds to GPIO. Signed-off-by: Tomasz Duszynski --- drivers/raw/cnxk_gpio/cnxk_gpio.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index f80788f7fb..3455d6258c 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -156,8 +156,17 @@ cnxk_gpio_queue_def_conf(struct rte_rawdev *dev, uint16_t queue_id, return 0; } +static uint16_t +cnxk_gpio_queue_count(struct rte_rawdev *dev) +{ + struct cnxk_gpiochip *gpiochip = dev->dev_private; + + return gpiochip->num_gpios; +} + static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .queue_def_conf = cnxk_gpio_queue_def_conf, + .queue_count = cnxk_gpio_queue_count, }; static int From patchwork Wed Jan 5 14:00:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105639 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4D32AA034D; Wed, 5 Jan 2022 15:00:56 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 10B9741155; Wed, 5 Jan 2022 15:00:38 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 16F3841152 for ; Wed, 5 Jan 2022 15:00:35 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205BnG8s031004; Wed, 5 Jan 2022 06:00:35 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=fivAhBM1KTbRuGdAVqRTSg/lXkoE/UDmzBomhr4hADo=; b=R6b1mlr8jh40Puw1Qa/of3wwka6XjJjF4yAVD29W58NPemWlepNBOaqfOKCuUXKW6dKL UAB8lcZ9BUO0DQrB3Q5C2j+wP+tw00V9aTmcv/O/an/5RP0hSmMj45mGkkmoyh0h/BT+ ehxPAOcLGH0dI42pqY+S+UnErItwdj73LnUuWsHln3eEwtofbdogCrBcaNvBVneTt6aN 6KL097AJf/PBrfAXZLOuCEkESJZB4jTwMJtttWAfYRS2iNR/kV+It50TotLIBSZZSH1l c5QiqpVcok9pQXr7sV2ShZLF0RnXUdHFMSGmo9HYOQWog3E67v3dIVzlVTAC7ygatb/3 cg== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x11a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:34 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 5 Jan 2022 06:00:33 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Wed, 5 Jan 2022 06:00:33 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id D13A23F7076; Wed, 5 Jan 2022 06:00:31 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v4 04/11] raw/cnxk_gpio: support queue setup Date: Wed, 5 Jan 2022 15:00:13 +0100 Message-ID: <20220105140020.1615256-5-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: QjImhNK4w9dzs2bs8I0BgkJlFXVTFaTF X-Proofpoint-ORIG-GUID: QjImhNK4w9dzs2bs8I0BgkJlFXVTFaTF X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for queue setup. Signed-off-by: Tomasz Duszynski --- drivers/raw/cnxk_gpio/cnxk_gpio.c | 80 +++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index 3455d6258c..c1e74fad43 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -138,6 +138,85 @@ cnxk_gpio_read_attr_int(char *attr, int *val) return 0; } +static int +cnxk_gpio_write_attr(const char *attr, const char *val) +{ + FILE *fp; + int ret; + + if (!val) + return -EINVAL; + + fp = fopen(attr, "w"); + if (!fp) + return -errno; + + ret = fprintf(fp, "%s", val); + if (ret < 0) { + fclose(fp); + return ret; + } + + ret = fclose(fp); + if (ret) + return -errno; + + return 0; +} + +static int +cnxk_gpio_write_attr_int(const char *attr, int val) +{ + char buf[CNXK_GPIO_BUFSZ]; + + snprintf(buf, sizeof(buf), "%d", val); + + return cnxk_gpio_write_attr(attr, buf); +} + +static struct cnxk_gpio * +cnxk_gpio_lookup(struct cnxk_gpiochip *gpiochip, uint16_t queue) +{ + if (queue >= gpiochip->num_gpios) + return NULL; + + return gpiochip->gpios[queue]; +} + +static int +cnxk_gpio_queue_setup(struct rte_rawdev *dev, uint16_t queue_id, + rte_rawdev_obj_t queue_conf, size_t queue_conf_size) +{ + struct cnxk_gpiochip *gpiochip = dev->dev_private; + char buf[CNXK_GPIO_BUFSZ]; + struct cnxk_gpio *gpio; + int ret; + + RTE_SET_USED(queue_conf); + RTE_SET_USED(queue_conf_size); + + gpio = cnxk_gpio_lookup(gpiochip, queue_id); + if (gpio) + return -EEXIST; + + gpio = rte_zmalloc(NULL, sizeof(*gpio), 0); + if (!gpio) + return -ENOMEM; + gpio->num = queue_id + gpiochip->base; + gpio->gpiochip = gpiochip; + + snprintf(buf, sizeof(buf), "%s/export", CNXK_GPIO_CLASS_PATH); + ret = cnxk_gpio_write_attr_int(buf, gpio->num); + if (ret) { + rte_free(gpio); + return ret; + } + + gpiochip->gpios[queue_id] = gpio; + + return 0; +} + static int cnxk_gpio_queue_def_conf(struct rte_rawdev *dev, uint16_t queue_id, rte_rawdev_obj_t queue_conf, size_t queue_conf_size) @@ -167,6 +246,7 @@ cnxk_gpio_queue_count(struct rte_rawdev *dev) static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .queue_def_conf = cnxk_gpio_queue_def_conf, .queue_count = cnxk_gpio_queue_count, + .queue_setup = cnxk_gpio_queue_setup, }; static int From patchwork Wed Jan 5 14:00:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105640 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B70BDA034D; Wed, 5 Jan 2022 15:01:05 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7BE4A41160; Wed, 5 Jan 2022 15:00:39 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id A051341142 for ; Wed, 5 Jan 2022 15:00:37 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205C3ewo030857; Wed, 5 Jan 2022 06:00:36 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=tQX24rBa9rT+/wKG4+AknwiHdpM3VfPEwIl9f1gYG8M=; b=LmAYHUcq5lFeD/6P2HuQgNJUY4MKLl+vgsw4kx6SPwt/pXl74AOKpGzQsfmVwrW81Yi/ /TYziFEBRlNZBVa8v1YoIBoz4f22IxI9HpEyDMf9kQVNzVNnuFSS4BmryoewVR4YCdFY DJ3+u8tx8tYCBa9JiucqRG8yZ5det24FK5Eb4H2BEUf0I8e+Tfaw+wckERLEWWGppWEl /ZTWBT5qj+B+sOBO/yFG0BWi38qb1G0sxLf/5ExsIVlt4XsJwsTnv+I+WsALU+KgerIP AFveFAGWY171BUcxDypodz0wFAIy/hJ6SJd2KNPqwn4xMX85bKgv0tYNmEPLSsRRfSGt iQ== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x11w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:36 -0800 Received: from DC5-EXCH01.marvell.com (10.69.176.38) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 5 Jan 2022 06:00:35 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Wed, 5 Jan 2022 06:00:35 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id BD9423F7077; Wed, 5 Jan 2022 06:00:33 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v4 05/11] raw/cnxk_gpio: support queue release Date: Wed, 5 Jan 2022 15:00:14 +0100 Message-ID: <20220105140020.1615256-6-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: ZjEkmR-f1bCvgbJVn0B2kjVxqkqE6i7V X-Proofpoint-ORIG-GUID: ZjEkmR-f1bCvgbJVn0B2kjVxqkqE6i7V X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for queue release. Signed-off-by: Tomasz Duszynski --- drivers/raw/cnxk_gpio/cnxk_gpio.c | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index c1e74fad43..71f568f7a4 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -217,6 +217,29 @@ cnxk_gpio_queue_setup(struct rte_rawdev *dev, uint16_t queue_id, return 0; } +static int +cnxk_gpio_queue_release(struct rte_rawdev *dev, uint16_t queue_id) +{ + struct cnxk_gpiochip *gpiochip = dev->dev_private; + char buf[CNXK_GPIO_BUFSZ]; + struct cnxk_gpio *gpio; + int ret; + + gpio = cnxk_gpio_lookup(gpiochip, queue_id); + if (!gpio) + return -ENODEV; + + snprintf(buf, sizeof(buf), "%s/unexport", CNXK_GPIO_CLASS_PATH); + ret = cnxk_gpio_write_attr_int(buf, gpiochip->base + queue_id); + if (ret) + return ret; + + gpiochip->gpios[queue_id] = NULL; + rte_free(gpio); + + return 0; +} + static int cnxk_gpio_queue_def_conf(struct rte_rawdev *dev, uint16_t queue_id, rte_rawdev_obj_t queue_conf, size_t queue_conf_size) @@ -247,6 +270,7 @@ static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .queue_def_conf = cnxk_gpio_queue_def_conf, .queue_count = cnxk_gpio_queue_count, .queue_setup = cnxk_gpio_queue_setup, + .queue_release = cnxk_gpio_queue_release, }; static int @@ -320,6 +344,8 @@ cnxk_gpio_remove(struct rte_vdev_device *dev) char name[RTE_RAWDEV_NAME_MAX_LEN]; struct cnxk_gpiochip *gpiochip; struct rte_rawdev *rawdev; + struct cnxk_gpio *gpio; + int i; RTE_SET_USED(dev); @@ -332,6 +358,14 @@ cnxk_gpio_remove(struct rte_vdev_device *dev) return -ENODEV; gpiochip = rawdev->dev_private; + for (i = 0; i < gpiochip->num_gpios; i++) { + gpio = gpiochip->gpios[i]; + if (!gpio) + continue; + + cnxk_gpio_queue_release(rawdev, gpio->num); + } + rte_free(gpiochip->gpios); rte_rawdev_pmd_release(rawdev); From patchwork Wed Jan 5 14:00:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105641 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 61772A034D; Wed, 5 Jan 2022 15:01:14 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7140E4116A; Wed, 5 Jan 2022 15:00:41 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id C67C541165 for ; Wed, 5 Jan 2022 15:00:39 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205BgGii030978; Wed, 5 Jan 2022 06:00:39 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=IUKYZRQfDAmcV3eC2vxTIHCzgfjYjfVu7+FLHSqsj6U=; b=hamM8xu3NA2BC6HhtaRH44D38JYb+Z0yKPpnttcaHeb4MPpke82FJa7gi5IjcyF1fcFl wMma260vPmc5MPBBPA0ulYZLHT+13odmV+6h549s/nPVQqpEUQYduS5f0cwXu5FrTA8T nw2fQ5PDy7vYPguChcqr+WrVPE9QdVlXRvpUf80AZK+rBO4KcDB3t+x+JTBgcPPLA7wW SuF9kjNGO9Mc6I/1vOz7VYMXe6N6goPQT4o8ovSrl2syDbNfqA0caD2/QciziCNLOCo3 GAhWXRgGunhdoYm+MIjsWxUXLtS/GKLn2MQsjftfOmQMW+TXe248xxa/aXKnIjBKEbQ8 +g== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x12q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:38 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 5 Jan 2022 06:00:37 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Wed, 5 Jan 2022 06:00:37 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id AD9135B6921; Wed, 5 Jan 2022 06:00:35 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v4 06/11] raw/cnxk_gpio: support enqueuing buffers Date: Wed, 5 Jan 2022 15:00:15 +0100 Message-ID: <20220105140020.1615256-7-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: OUpJpNOd2nsslSUXDGBlgpbCr0d3erpl X-Proofpoint-ORIG-GUID: OUpJpNOd2nsslSUXDGBlgpbCr0d3erpl X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add dummy support for enqueuing buffers. Signed-off-by: Tomasz Duszynski --- drivers/raw/cnxk_gpio/cnxk_gpio.c | 47 +++++++++++++++++++++++ drivers/raw/cnxk_gpio/cnxk_gpio.h | 1 + drivers/raw/cnxk_gpio/meson.build | 1 + drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h | 38 ++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index 71f568f7a4..235f0d6f7a 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -14,6 +14,7 @@ #include #include "cnxk_gpio.h" +#include "rte_pmd_cnxk_gpio.h" #define CNXK_GPIO_BUFSZ 128 #define CNXK_GPIO_CLASS_PATH "/sys/class/gpio" @@ -266,7 +267,53 @@ cnxk_gpio_queue_count(struct rte_rawdev *dev) return gpiochip->num_gpios; } +static int +cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf) +{ + struct cnxk_gpio_msg *msg = rbuf->buf_addr; + void *rsp = NULL; + int ret; + + switch (msg->type) { + default: + return -EINVAL; + } + + /* get rid of last response if any */ + if (gpio->rsp) { + RTE_LOG(WARNING, PMD, "previous response got overwritten\n"); + rte_free(gpio->rsp); + } + gpio->rsp = rsp; + + return ret; +} + +static int +cnxk_gpio_enqueue_bufs(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers, + unsigned int count, rte_rawdev_obj_t context) +{ + struct cnxk_gpiochip *gpiochip = dev->dev_private; + unsigned int queue = (size_t)context; + struct cnxk_gpio *gpio; + int ret; + + if (count == 0) + return 0; + + gpio = cnxk_gpio_lookup(gpiochip, queue); + if (!gpio) + return -ENODEV; + + ret = cnxk_gpio_process_buf(gpio, buffers[0]); + if (ret) + return ret; + + return 1; +} + static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { + .enqueue_bufs = cnxk_gpio_enqueue_bufs, .queue_def_conf = cnxk_gpio_queue_def_conf, .queue_count = cnxk_gpio_queue_count, .queue_setup = cnxk_gpio_queue_setup, diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.h b/drivers/raw/cnxk_gpio/cnxk_gpio.h index 4dae8316ba..6b54ebe6e6 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.h +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.h @@ -9,6 +9,7 @@ struct cnxk_gpiochip; struct cnxk_gpio { struct cnxk_gpiochip *gpiochip; + void *rsp; int num; }; diff --git a/drivers/raw/cnxk_gpio/meson.build b/drivers/raw/cnxk_gpio/meson.build index 9a7e716c1e..3fbfdd838c 100644 --- a/drivers/raw/cnxk_gpio/meson.build +++ b/drivers/raw/cnxk_gpio/meson.build @@ -6,3 +6,4 @@ deps += ['bus_vdev', 'common_cnxk', 'rawdev', 'kvargs'] sources = files( 'cnxk_gpio.c', ) +headers = files('rte_pmd_cnxk_gpio.h') diff --git a/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h b/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h new file mode 100644 index 0000000000..c71065e10c --- /dev/null +++ b/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#ifndef _RTE_PMD_CNXK_GPIO_H_ +#define _RTE_PMD_CNXK_GPIO_H_ + +/** + * @file rte_pmd_cnxk_gpio.h + * + * Marvell GPIO PMD specific structures and interface + * + * This API allows applications to manage GPIOs in user space along with + * installing interrupt handlers for low latency signal processing. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Available message types */ +enum cnxk_gpio_msg_type { + /** Invalid message type */ + CNXK_GPIO_MSG_TYPE_INVALID, +}; + +struct cnxk_gpio_msg { + /** Message type */ + enum cnxk_gpio_msg_type type; + /** Message data passed to PMD or received from PMD */ + void *data; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_PMD_CNXK_GPIO_H_ */ From patchwork Wed Jan 5 14:00:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105642 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 217E3A034D; Wed, 5 Jan 2022 15:01:22 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B666F41171; Wed, 5 Jan 2022 15:00:43 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 5A1954114B for ; Wed, 5 Jan 2022 15:00:41 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205CXqNO030858; Wed, 5 Jan 2022 06:00:40 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=z8eAVUR/y2ITTYnEu+C2kvdOWuur/xumKm2j0avCiYo=; b=MkesagvJWGIh0/cFcvdU7tZXf+3hGTAFADaK62Gkflk/rsqvn2CN2dPdim66eVWv8YcR 5BhYVtl4dEqphUhwjAWY0RVf4Ixx5DVNYP3Yuae9se7OjSrVCzMe5mtJDGRpgJzwIQhF WO+Aj+bbJ0DMfr1y55uTLdxPGkkPgXwazMQn4aeapfMYY1eGYk16+wDU5DZj39IK7Ftr gbTV6sHlrzYJs+hLpP1sTYG4d0x3mhnHgw9NjlSOL/1oJr3Y9St32jpiREI6Dm7z5IBp sTOOZiVWtJtdllZqtYdeJVOEya8w6yjit8fYuTv0z1O4yUrpCbqZzKi3BvkkTcd2svzZ Yg== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x135-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:40 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 5 Jan 2022 06:00:39 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Wed, 5 Jan 2022 06:00:39 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 99FB83F7040; Wed, 5 Jan 2022 06:00:37 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v4 07/11] raw/cnxk_gpio: support dequeuing buffers Date: Wed, 5 Jan 2022 15:00:16 +0100 Message-ID: <20220105140020.1615256-8-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: _oFTe21p49WdQjsPuAoDZbFY9BpoUefH X-Proofpoint-ORIG-GUID: _oFTe21p49WdQjsPuAoDZbFY9BpoUefH X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for dequeuing buffers. Signed-off-by: Tomasz Duszynski --- drivers/raw/cnxk_gpio/cnxk_gpio.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index 235f0d6f7a..909fa9d390 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -312,8 +312,34 @@ cnxk_gpio_enqueue_bufs(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers, return 1; } +static int +cnxk_gpio_dequeue_bufs(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers, + unsigned int count, rte_rawdev_obj_t context) +{ + struct cnxk_gpiochip *gpiochip = dev->dev_private; + unsigned int queue = (size_t)context; + struct cnxk_gpio *gpio; + + if (count == 0) + return 0; + + gpio = cnxk_gpio_lookup(gpiochip, queue); + if (!gpio) + return -ENODEV; + + if (gpio->rsp) { + buffers[0]->buf_addr = gpio->rsp; + gpio->rsp = NULL; + + return 1; + } + + return 0; +} + static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .enqueue_bufs = cnxk_gpio_enqueue_bufs, + .dequeue_bufs = cnxk_gpio_dequeue_bufs, .queue_def_conf = cnxk_gpio_queue_def_conf, .queue_count = cnxk_gpio_queue_count, .queue_setup = cnxk_gpio_queue_setup, From patchwork Wed Jan 5 14:00:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105643 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id A3DD0A034D; Wed, 5 Jan 2022 15:01:28 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C42D741176; Wed, 5 Jan 2022 15:00:44 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id A7D2E41159 for ; Wed, 5 Jan 2022 15:00:43 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205CJ2Jg030859; Wed, 5 Jan 2022 06:00:42 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=34fTv+m5IDJKfSsdMiXSMvBuhMMYF/IkRxd4k/xF3XI=; b=VT0/pyUKEi/AEw5qGmHOgMgnWO6kR0VxkG622/WiLqOkNCZW1hOntaF1hOKV2DHJTCZA oIq6YNcD8iLM5SB2EjHMpbHGLj6H9dxdnsIyDUsi59GQz9lNqorzhQCuVk123sAiMkG1 hFrfjTQZVT7G9cjS532rDtoUXuKBoKOoYGHVukOev2ok0cZFeMwt3U0z6Ovan3HFOPpK 2QHsN/U//pc8GtHMGWmNGw3q/QWW5li5I+fi3T4Ppuk0z7+ZXp2yFo+IZo1oTDph7s7l 0mQ3kGc+XsFz2MBG9qlDaDQojg4tcFK+vJFkjBGE7LbKS6YWPlk4U7XGH7I3BQaV6TOG VA== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x13d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:42 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 5 Jan 2022 06:00:41 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Wed, 5 Jan 2022 06:00:41 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 95C513F7077; Wed, 5 Jan 2022 06:00:39 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v4 08/11] raw/cnxk_gpio: support standard GPIO operations Date: Wed, 5 Jan 2022 15:00:17 +0100 Message-ID: <20220105140020.1615256-9-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: X8rXAJCtDPQemEQrK1u7S-vxPo8OCujb X-Proofpoint-ORIG-GUID: X8rXAJCtDPQemEQrK1u7S-vxPo8OCujb X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for standard GPIO operations i.e ones normally provided by GPIO sysfs interface. Signed-off-by: Tomasz Duszynski --- doc/guides/rawdevs/cnxk_gpio.rst | 98 ++++++++ drivers/raw/cnxk_gpio/cnxk_gpio.c | 147 +++++++++++- drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h | 279 +++++++++++++++++++++- 3 files changed, 521 insertions(+), 3 deletions(-) diff --git a/doc/guides/rawdevs/cnxk_gpio.rst b/doc/guides/rawdevs/cnxk_gpio.rst index 868302d07f..f6c3c942c5 100644 --- a/doc/guides/rawdevs/cnxk_gpio.rst +++ b/doc/guides/rawdevs/cnxk_gpio.rst @@ -63,3 +63,101 @@ call barely exports GPIO to userspace. To perform actual data transfer use standard ``rte_rawdev_enqueue_buffers()`` and ``rte_rawdev_dequeue_buffers()`` APIs. Not all messages produce sensible responses hence dequeueing is not always necessary. + +CNXK GPIO PMD +------------- + +PMD accepts ``struct cnxk_gpio_msg`` messages which differ by type and payload. +Message types along with description are listed below. As for the usage examples +please refer to ``cnxk_gpio_selftest()``. There's a set of convenient wrappers +available, one for each existing command. + +Set GPIO value +~~~~~~~~~~~~~~ + +Message is used to set output to low or high. This does not work for GPIOs +configured as input. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_VALUE``. + +Payload must be an integer set to 0 (low) or 1 (high). + +Consider using ``rte_pmd_gpio_set_pin_value()`` wrapper. + +Set GPIO edge +~~~~~~~~~~~~~ + +Message is used to set edge that triggers interrupt. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_EDGE``. + +Payload must be `enum cnxk_gpio_pin_edge`. + +Consider using ``rte_pmd_gpio_set_pin_edge()`` wrapper. + +Set GPIO direction +~~~~~~~~~~~~~~~~~~ + +Message is used to change GPIO direction to either input or output. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_DIR``. + +Payload must be `enum cnxk_gpio_pin_dir`. + +Consider using ``rte_pmd_gpio_set_pin_dir()`` wrapper. + +Set GPIO active low +~~~~~~~~~~~~~~~~~~~ + +Message is used to set whether pin is active low. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_SET_PIN_ACTIVE_LOW``. + +Payload must be an integer set to 0 or 1. The latter activates inversion. + +Consider using ``rte_pmd_gpio_set_pin_active_low()`` wrapper. + +Get GPIO value +~~~~~~~~~~~~~~ + +Message is used to read GPIO value. Value can be 0 (low) or 1 (high). + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_VALUE``. + +Payload contains integer set to either 0 or 1. + +Consider using ``rte_pmd_gpio_get_pin_value()`` wrapper. + +Get GPIO edge +~~~~~~~~~~~~~ + +Message is used to read GPIO edge. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_EDGE``. + +Payload contains `enum cnxk_gpio_pin_edge`. + +Consider using ``rte_pmd_gpio_get_pin_edge()`` wrapper. + +Get GPIO direction +~~~~~~~~~~~~~~~~~~ + +Message is used to read GPIO direction. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_DIR``. + +Payload contains `enum cnxk_gpio_pin_dir`. + +Consider using ``rte_pmd_gpio_get_pin_dir()`` wrapper. + +Get GPIO active low +~~~~~~~~~~~~~~~~~~~ + +Message is used check whether inverted logic is active. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_GET_PIN_ACTIVE_LOW``. + +Payload contains an integer set to 0 or 1. The latter means inverted logic +is turned on. + +Consider using ``rte_pmd_gpio_get_pin_active_low()`` wrapper. diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index 909fa9d390..e24d8c1b6e 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -267,14 +267,159 @@ cnxk_gpio_queue_count(struct rte_rawdev *dev) return gpiochip->num_gpios; } +static const struct { + enum cnxk_gpio_pin_edge edge; + const char *name; +} cnxk_gpio_edge_name[] = { + { CNXK_GPIO_PIN_EDGE_NONE, "none" }, + { CNXK_GPIO_PIN_EDGE_FALLING, "falling" }, + { CNXK_GPIO_PIN_EDGE_RISING, "rising" }, + { CNXK_GPIO_PIN_EDGE_BOTH, "both" }, +}; + +static const char * +cnxk_gpio_edge_to_name(enum cnxk_gpio_pin_edge edge) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(cnxk_gpio_edge_name); i++) { + if (cnxk_gpio_edge_name[i].edge == edge) + return cnxk_gpio_edge_name[i].name; + } + + return NULL; +} + +static enum cnxk_gpio_pin_edge +cnxk_gpio_name_to_edge(const char *name) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(cnxk_gpio_edge_name); i++) { + if (!strcmp(cnxk_gpio_edge_name[i].name, name)) + break; + } + + return cnxk_gpio_edge_name[i].edge; +} + +static const struct { + enum cnxk_gpio_pin_dir dir; + const char *name; +} cnxk_gpio_dir_name[] = { + { CNXK_GPIO_PIN_DIR_IN, "in" }, + { CNXK_GPIO_PIN_DIR_OUT, "out" }, + { CNXK_GPIO_PIN_DIR_HIGH, "high" }, + { CNXK_GPIO_PIN_DIR_LOW, "low" }, +}; + +static const char * +cnxk_gpio_dir_to_name(enum cnxk_gpio_pin_dir dir) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(cnxk_gpio_dir_name); i++) { + if (cnxk_gpio_dir_name[i].dir == dir) + return cnxk_gpio_dir_name[i].name; + } + + return NULL; +} + +static enum cnxk_gpio_pin_dir +cnxk_gpio_name_to_dir(const char *name) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(cnxk_gpio_dir_name); i++) { + if (!strcmp(cnxk_gpio_dir_name[i].name, name)) + break; + } + + return cnxk_gpio_dir_name[i].dir; +} + static int cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf) { struct cnxk_gpio_msg *msg = rbuf->buf_addr; + enum cnxk_gpio_pin_edge edge; + enum cnxk_gpio_pin_dir dir; + char buf[CNXK_GPIO_BUFSZ]; void *rsp = NULL; - int ret; + int ret, val, n; + + n = snprintf(buf, sizeof(buf), "%s/gpio%d", CNXK_GPIO_CLASS_PATH, + gpio->num); switch (msg->type) { + case CNXK_GPIO_MSG_TYPE_SET_PIN_VALUE: + snprintf(buf + n, sizeof(buf) - n, "/value"); + ret = cnxk_gpio_write_attr_int(buf, !!*(int *)msg->data); + break; + case CNXK_GPIO_MSG_TYPE_SET_PIN_EDGE: + snprintf(buf + n, sizeof(buf) - n, "/edge"); + edge = *(enum cnxk_gpio_pin_edge *)msg->data; + ret = cnxk_gpio_write_attr(buf, cnxk_gpio_edge_to_name(edge)); + break; + case CNXK_GPIO_MSG_TYPE_SET_PIN_DIR: + snprintf(buf + n, sizeof(buf) - n, "/direction"); + dir = *(enum cnxk_gpio_pin_dir *)msg->data; + ret = cnxk_gpio_write_attr(buf, cnxk_gpio_dir_to_name(dir)); + break; + case CNXK_GPIO_MSG_TYPE_SET_PIN_ACTIVE_LOW: + snprintf(buf + n, sizeof(buf) - n, "/active_low"); + val = *(int *)msg->data; + ret = cnxk_gpio_write_attr_int(buf, val); + break; + case CNXK_GPIO_MSG_TYPE_GET_PIN_VALUE: + snprintf(buf + n, sizeof(buf) - n, "/value"); + ret = cnxk_gpio_read_attr_int(buf, &val); + if (ret) + break; + + rsp = rte_zmalloc(NULL, sizeof(int), 0); + if (!rsp) + return -ENOMEM; + + *(int *)rsp = val; + break; + case CNXK_GPIO_MSG_TYPE_GET_PIN_EDGE: + snprintf(buf + n, sizeof(buf) - n, "/edge"); + ret = cnxk_gpio_read_attr(buf, buf); + if (ret) + break; + + rsp = rte_zmalloc(NULL, sizeof(enum cnxk_gpio_pin_edge), 0); + if (!rsp) + return -ENOMEM; + + *(enum cnxk_gpio_pin_edge *)rsp = cnxk_gpio_name_to_edge(buf); + break; + case CNXK_GPIO_MSG_TYPE_GET_PIN_DIR: + snprintf(buf + n, sizeof(buf) - n, "/direction"); + ret = cnxk_gpio_read_attr(buf, buf); + if (ret) + break; + + rsp = rte_zmalloc(NULL, sizeof(enum cnxk_gpio_pin_dir), 0); + if (!rsp) + return -ENOMEM; + + *(enum cnxk_gpio_pin_dir *)rsp = cnxk_gpio_name_to_dir(buf); + break; + case CNXK_GPIO_MSG_TYPE_GET_PIN_ACTIVE_LOW: + snprintf(buf + n, sizeof(buf) - n, "/active_low"); + ret = cnxk_gpio_read_attr_int(buf, &val); + if (ret) + break; + + rsp = rte_zmalloc(NULL, sizeof(int), 0); + if (!rsp) + return -ENOMEM; + + *(int *)rsp = val; + break; default: return -EINVAL; } diff --git a/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h b/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h index c71065e10c..7c3dc225ca 100644 --- a/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h +++ b/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h @@ -5,6 +5,10 @@ #ifndef _RTE_PMD_CNXK_GPIO_H_ #define _RTE_PMD_CNXK_GPIO_H_ +#include +#include +#include + /** * @file rte_pmd_cnxk_gpio.h * @@ -20,8 +24,46 @@ extern "C" { /** Available message types */ enum cnxk_gpio_msg_type { - /** Invalid message type */ - CNXK_GPIO_MSG_TYPE_INVALID, + /** Type used to set output value */ + CNXK_GPIO_MSG_TYPE_SET_PIN_VALUE, + /** Type used to set edge */ + CNXK_GPIO_MSG_TYPE_SET_PIN_EDGE, + /** Type used to set direction */ + CNXK_GPIO_MSG_TYPE_SET_PIN_DIR, + /** Type used to set inverted logic */ + CNXK_GPIO_MSG_TYPE_SET_PIN_ACTIVE_LOW, + /** Type used to read value */ + CNXK_GPIO_MSG_TYPE_GET_PIN_VALUE, + /** Type used to read edge */ + CNXK_GPIO_MSG_TYPE_GET_PIN_EDGE, + /** Type used to read direction */ + CNXK_GPIO_MSG_TYPE_GET_PIN_DIR, + /** Type used to read inverted logic state */ + CNXK_GPIO_MSG_TYPE_GET_PIN_ACTIVE_LOW, +}; + +/** Available edges */ +enum cnxk_gpio_pin_edge { + /** Set edge to none */ + CNXK_GPIO_PIN_EDGE_NONE, + /** Set edge to falling */ + CNXK_GPIO_PIN_EDGE_FALLING, + /** Set edge to rising */ + CNXK_GPIO_PIN_EDGE_RISING, + /** Set edge to both rising and falling */ + CNXK_GPIO_PIN_EDGE_BOTH, +}; + +/** Available directions */ +enum cnxk_gpio_pin_dir { + /** Set direction to input */ + CNXK_GPIO_PIN_DIR_IN, + /** Set direction to output */ + CNXK_GPIO_PIN_DIR_OUT, + /** Set direction to output and value to 1 */ + CNXK_GPIO_PIN_DIR_HIGH, + /* Set direction to output and value to 0 */ + CNXK_GPIO_PIN_DIR_LOW, }; struct cnxk_gpio_msg { @@ -31,6 +73,239 @@ struct cnxk_gpio_msg { void *data; }; +/** @internal helper routine for enqueuing/dequeuing messages */ +static __rte_always_inline int +__rte_pmd_gpio_enq_deq(uint16_t dev_id, int gpio, void *req, void *rsp, + size_t rsp_size) +{ + struct rte_rawdev_buf *bufs[1]; + struct rte_rawdev_buf buf; + void *q; + int ret; + + q = (void *)(size_t)gpio; + buf.buf_addr = req; + bufs[0] = &buf; + + ret = rte_rawdev_enqueue_buffers(dev_id, bufs, RTE_DIM(bufs), q); + if (ret < 0) + return ret; + if (ret != RTE_DIM(bufs)) + return -EIO; + + if (!rsp) + return 0; + + ret = rte_rawdev_dequeue_buffers(dev_id, bufs, RTE_DIM(bufs), q); + if (ret < 0) + return ret; + if (ret != RTE_DIM(bufs)) + return -EIO; + + rte_memcpy(rsp, buf.buf_addr, rsp_size); + rte_free(buf.buf_addr); + + return 0; +} + +/** + * Set output to specific value + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * @param val + * Value output will be set to. 0 represents low state while + * 1 high state + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_set_pin_value(uint16_t dev_id, int gpio, int val) +{ + struct cnxk_gpio_msg msg = { + .type = CNXK_GPIO_MSG_TYPE_SET_PIN_VALUE, + .data = &val, + }; + + return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, NULL, 0); +} + +/** + * Select signal edge that triggers interrupt + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * @param edge + * Signal edge that triggers interrupt + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_set_pin_edge(uint16_t dev_id, int gpio, + enum cnxk_gpio_pin_edge edge) +{ + struct cnxk_gpio_msg msg = { + .type = CNXK_GPIO_MSG_TYPE_SET_PIN_EDGE, + .data = &edge + }; + + return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, NULL, 0); +} + +/** + * Configure GPIO as input or output + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * @param dir + * Direction of the GPIO + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_set_pin_dir(uint16_t dev_id, int gpio, enum cnxk_gpio_pin_dir dir) +{ + struct cnxk_gpio_msg msg = { + .type = CNXK_GPIO_MSG_TYPE_SET_PIN_DIR, + .data = &dir, + }; + + return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, NULL, 0); +} + +/** + * Enable or disable inverted logic + * + * If GPIO is configured as output then writing 1 or 0 will result in setting + * output to respectively low or high + * + * If GPIO is configured as input then logic inversion applies to edges. Both + * current and future settings are affected + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * @param val + * 0 to disable, 1 to enable inverted logic + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_set_pin_active_low(uint16_t dev_id, int gpio, int val) +{ + struct cnxk_gpio_msg msg = { + .type = CNXK_GPIO_MSG_TYPE_SET_PIN_ACTIVE_LOW, + .data = &val, + }; + + return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, NULL, 0); +} + +/** + * Read GPIO value + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * @param val + * Where to store read logical signal value i.e 0 or 1 + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_get_pin_value(uint16_t dev_id, int gpio, int *val) +{ + struct cnxk_gpio_msg msg = { + .type = CNXK_GPIO_MSG_TYPE_GET_PIN_VALUE, + }; + + return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, val, sizeof(*val)); +} + +/** + * Read GPIO edge + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * @param edge + * Where to store edge + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_get_pin_edge(uint16_t dev_id, int gpio, + enum cnxk_gpio_pin_edge *edge) +{ + struct cnxk_gpio_msg msg = { + .type = CNXK_GPIO_MSG_TYPE_GET_PIN_EDGE, + }; + + return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, edge, sizeof(*edge)); +} + +/** + * Read GPIO direction + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * @param dir + * Where to store direction + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_get_pin_dir(uint16_t dev_id, int gpio, enum cnxk_gpio_pin_dir *dir) +{ + struct cnxk_gpio_msg msg = { + .type = CNXK_GPIO_MSG_TYPE_GET_PIN_DIR, + }; + + return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, dir, sizeof(*dir)); +} + +/** + * Read whether GPIO is active low + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * @param val + * Where to store active low state + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_get_pin_active_low(uint16_t dev_id, int gpio, int *val) +{ + struct cnxk_gpio_msg msg = { + .type = CNXK_GPIO_MSG_TYPE_GET_PIN_ACTIVE_LOW, + .data = &val, + }; + + return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, val, sizeof(*val)); +} + #ifdef __cplusplus } #endif From patchwork Wed Jan 5 14:00:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105644 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 93181A034D; Wed, 5 Jan 2022 15:01:36 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 525834118A; Wed, 5 Jan 2022 15:00:47 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id C34B34117D for ; Wed, 5 Jan 2022 15:00:45 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205CJ2Jh030859; Wed, 5 Jan 2022 06:00:45 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=bYkxJ9sOT+aAjTJr8LGf7YOtBInVlXGARdk0Vu1B3Zg=; b=hTnE7NC/EseKmm9PXEb8XJ93UTU7uqf7orTScO83TlfNTk+f2v8CHd+L+I8j5BqadsT4 xv7RvJlNcqct7ZW3Bw3+mIh6iwwsWZD59+Q/Tu8W5r4cFX781iQrMXmX4qJYAvK/NLEd H2P7q+exnp41uhj2NZR58QT/97+1atNffoG+d4VNcp0EP6ga0pF74fnhCzJTZAoTsPGl 5knDAO/dXcXuovEMP2gWWoVobNe7HpOfFNpH3UYovgmOE2/JP+H5L67lcC9pGwi8yYh6 zKnoh51tqWol9LMrnKAJo7TZTGFDtHV2R2Gcwz/0FWtVBEP1oYr4K2JTMJ3gTAxPc9kn dQ== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x13p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:44 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 5 Jan 2022 06:00:42 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Wed, 5 Jan 2022 06:00:42 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 87D065B6933; Wed, 5 Jan 2022 06:00:41 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v4 09/11] raw/cnxk_gpio: support custom irq handlers Date: Wed, 5 Jan 2022 15:00:18 +0100 Message-ID: <20220105140020.1615256-10-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: fQobMpKs9o_g9cF_eLVvyW98C_6j0Ti6 X-Proofpoint-ORIG-GUID: fQobMpKs9o_g9cF_eLVvyW98C_6j0Ti6 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for custom interrupt handlers. Custom interrupt handlers bypass kernel completely and are meant for fast and low latency access to GPIO state. Signed-off-by: Tomasz Duszynski --- doc/guides/rawdevs/cnxk_gpio.rst | 21 +++ drivers/raw/cnxk_gpio/cnxk_gpio.c | 37 ++++ drivers/raw/cnxk_gpio/cnxk_gpio.h | 8 + drivers/raw/cnxk_gpio/cnxk_gpio_irq.c | 216 ++++++++++++++++++++++ drivers/raw/cnxk_gpio/meson.build | 1 + drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h | 116 ++++++++++++ 6 files changed, 399 insertions(+) create mode 100644 drivers/raw/cnxk_gpio/cnxk_gpio_irq.c diff --git a/doc/guides/rawdevs/cnxk_gpio.rst b/doc/guides/rawdevs/cnxk_gpio.rst index f6c3c942c5..ad93ec0d44 100644 --- a/doc/guides/rawdevs/cnxk_gpio.rst +++ b/doc/guides/rawdevs/cnxk_gpio.rst @@ -161,3 +161,24 @@ Payload contains an integer set to 0 or 1. The latter means inverted logic is turned on. Consider using ``rte_pmd_gpio_get_pin_active_low()`` wrapper. + +Request interrupt +~~~~~~~~~~~~~~~~~ + +Message is used to install custom interrupt handler. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_REGISTER_IRQ``. + +Payload needs to be set to ``struct cnxk_gpio_irq`` which describes interrupt +being requested. + +Consider using ``rte_pmd_gpio_register_gpio()`` wrapper. + +Free interrupt +~~~~~~~~~~~~~~ + +Message is used to remove installed interrupt handler. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_UNREGISTER_IRQ``. + +Consider using ``rte_pmd_gpio_unregister_gpio()`` wrapper. diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index e24d8c1b6e..b30427c01c 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -339,6 +339,28 @@ cnxk_gpio_name_to_dir(const char *name) return cnxk_gpio_dir_name[i].dir; } +static int +cnxk_gpio_register_irq(struct cnxk_gpio *gpio, struct cnxk_gpio_irq *irq) +{ + int ret; + + ret = cnxk_gpio_irq_request(gpio->num - gpio->gpiochip->base, irq->cpu); + if (ret) + return ret; + + gpio->handler = irq->handler; + gpio->data = irq->data; + gpio->cpu = irq->cpu; + + return 0; +} + +static int +cnxk_gpio_unregister_irq(struct cnxk_gpio *gpio) +{ + return cnxk_gpio_irq_free(gpio->num - gpio->gpiochip->base); +} + static int cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf) { @@ -420,6 +442,13 @@ cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf) *(int *)rsp = val; break; + case CNXK_GPIO_MSG_TYPE_REGISTER_IRQ: + ret = cnxk_gpio_register_irq(gpio, + (struct cnxk_gpio_irq *)msg->data); + break; + case CNXK_GPIO_MSG_TYPE_UNREGISTER_IRQ: + ret = cnxk_gpio_unregister_irq(gpio); + break; default: return -EINVAL; } @@ -523,6 +552,10 @@ cnxk_gpio_probe(struct rte_vdev_device *dev) if (ret) goto out; + ret = cnxk_gpio_irq_init(gpiochip); + if (ret) + goto out; + /* read gpio base */ snprintf(buf, sizeof(buf), "%s/gpiochip%d/base", CNXK_GPIO_CLASS_PATH, gpiochip->num); @@ -581,10 +614,14 @@ cnxk_gpio_remove(struct rte_vdev_device *dev) if (!gpio) continue; + if (gpio->handler) + cnxk_gpio_unregister_irq(gpio); + cnxk_gpio_queue_release(rawdev, gpio->num); } rte_free(gpiochip->gpios); + cnxk_gpio_irq_fini(); rte_rawdev_pmd_release(rawdev); return 0; diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.h b/drivers/raw/cnxk_gpio/cnxk_gpio.h index 6b54ebe6e6..c052ca5735 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.h +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.h @@ -11,6 +11,9 @@ struct cnxk_gpio { struct cnxk_gpiochip *gpiochip; void *rsp; int num; + void (*handler)(int gpio, void *data); + void *data; + int cpu; }; struct cnxk_gpiochip { @@ -20,4 +23,9 @@ struct cnxk_gpiochip { struct cnxk_gpio **gpios; }; +int cnxk_gpio_irq_init(struct cnxk_gpiochip *gpiochip); +void cnxk_gpio_irq_fini(void); +int cnxk_gpio_irq_request(int gpio, int cpu); +int cnxk_gpio_irq_free(int gpio); + #endif /* _CNXK_GPIO_H_ */ diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio_irq.c b/drivers/raw/cnxk_gpio/cnxk_gpio_irq.c new file mode 100644 index 0000000000..2fa8e69899 --- /dev/null +++ b/drivers/raw/cnxk_gpio/cnxk_gpio_irq.c @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "cnxk_gpio.h" + +#define OTX_IOC_MAGIC 0xF2 +#define OTX_IOC_SET_GPIO_HANDLER \ + _IOW(OTX_IOC_MAGIC, 1, struct otx_gpio_usr_data) +#define OTX_IOC_CLR_GPIO_HANDLER \ + _IO(OTX_IOC_MAGIC, 2) + +struct otx_gpio_usr_data { + uint64_t isr_base; + uint64_t sp; + uint64_t cpu; + uint64_t gpio_num; +}; + +struct cnxk_gpio_irq_stack { + LIST_ENTRY(cnxk_gpio_irq_stack) next; + void *sp_buffer; + int cpu; + int inuse; +}; + +struct cnxk_gpio_irqchip { + int fd; + /* serialize access to this struct */ + pthread_mutex_t lock; + LIST_HEAD(, cnxk_gpio_irq_stack) stacks; + + struct cnxk_gpiochip *gpiochip; +}; + +static struct cnxk_gpio_irqchip *irqchip; + +static void +cnxk_gpio_irq_stack_free(int cpu) +{ + struct cnxk_gpio_irq_stack *stack; + + LIST_FOREACH(stack, &irqchip->stacks, next) { + if (stack->cpu == cpu) + break; + } + + if (!stack) + return; + + if (stack->inuse) + stack->inuse--; + + if (stack->inuse == 0) { + LIST_REMOVE(stack, next); + rte_free(stack->sp_buffer); + rte_free(stack); + } +} + +static void * +cnxk_gpio_irq_stack_alloc(int cpu) +{ +#define ARM_STACK_ALIGNMENT (2 * sizeof(void *)) +#define IRQ_STACK_SIZE 0x200000 + + struct cnxk_gpio_irq_stack *stack; + + LIST_FOREACH(stack, &irqchip->stacks, next) { + if (stack->cpu == cpu) + break; + } + + if (stack) { + stack->inuse++; + return (char *)stack->sp_buffer + IRQ_STACK_SIZE; + } + + stack = rte_malloc(NULL, sizeof(*stack), 0); + if (!stack) + return NULL; + + stack->sp_buffer = + rte_zmalloc(NULL, IRQ_STACK_SIZE * 2, ARM_STACK_ALIGNMENT); + if (!stack->sp_buffer) { + rte_free(stack); + return NULL; + } + + stack->cpu = cpu; + stack->inuse = 1; + LIST_INSERT_HEAD(&irqchip->stacks, stack, next); + + return (char *)stack->sp_buffer + IRQ_STACK_SIZE; +} + +static void +cnxk_gpio_irq_handler(int gpio_num) +{ + struct cnxk_gpiochip *gpiochip = irqchip->gpiochip; + struct cnxk_gpio *gpio; + + if (gpio_num >= gpiochip->num_gpios) + goto out; + + gpio = gpiochip->gpios[gpio_num]; + if (likely(gpio->handler)) + gpio->handler(gpio_num, gpio->data); + +out: + roc_atf_ret(); +} + +int +cnxk_gpio_irq_init(struct cnxk_gpiochip *gpiochip) +{ + if (irqchip) + return 0; + + irqchip = rte_zmalloc(NULL, sizeof(*irqchip), 0); + if (!irqchip) + return -ENOMEM; + + irqchip->fd = open("/dev/otx-gpio-ctr", O_RDWR | O_SYNC); + if (irqchip->fd < 0) { + rte_free(irqchip); + return -errno; + } + + pthread_mutex_init(&irqchip->lock, NULL); + LIST_INIT(&irqchip->stacks); + irqchip->gpiochip = gpiochip; + + return 0; +} + +void +cnxk_gpio_irq_fini(void) +{ + if (!irqchip) + return; + + close(irqchip->fd); + rte_free(irqchip); + irqchip = NULL; +} + +int +cnxk_gpio_irq_request(int gpio, int cpu) +{ + struct otx_gpio_usr_data data; + void *sp; + int ret; + + pthread_mutex_lock(&irqchip->lock); + + sp = cnxk_gpio_irq_stack_alloc(cpu); + if (!sp) { + ret = -ENOMEM; + goto out_unlock; + } + + data.isr_base = (uint64_t)cnxk_gpio_irq_handler; + data.sp = (uint64_t)sp; + data.cpu = (uint64_t)cpu; + data.gpio_num = (uint64_t)gpio; + + mlockall(MCL_CURRENT | MCL_FUTURE); + ret = ioctl(irqchip->fd, OTX_IOC_SET_GPIO_HANDLER, &data); + if (ret) { + ret = -errno; + goto out_free_stack; + } + + pthread_mutex_unlock(&irqchip->lock); + + return 0; + +out_free_stack: + cnxk_gpio_irq_stack_free(cpu); +out_unlock: + pthread_mutex_unlock(&irqchip->lock); + + return ret; +} + +int +cnxk_gpio_irq_free(int gpio) +{ + int ret; + + pthread_mutex_lock(&irqchip->lock); + + ret = ioctl(irqchip->fd, OTX_IOC_CLR_GPIO_HANDLER, gpio); + if (ret) { + pthread_mutex_unlock(&irqchip->lock); + return -errno; + } + + cnxk_gpio_irq_stack_free(irqchip->gpiochip->gpios[gpio]->cpu); + + pthread_mutex_unlock(&irqchip->lock); + + return 0; +} diff --git a/drivers/raw/cnxk_gpio/meson.build b/drivers/raw/cnxk_gpio/meson.build index 3fbfdd838c..9b55f029c7 100644 --- a/drivers/raw/cnxk_gpio/meson.build +++ b/drivers/raw/cnxk_gpio/meson.build @@ -5,5 +5,6 @@ deps += ['bus_vdev', 'common_cnxk', 'rawdev', 'kvargs'] sources = files( 'cnxk_gpio.c', + 'cnxk_gpio_irq.c', ) headers = files('rte_pmd_cnxk_gpio.h') diff --git a/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h b/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h index 7c3dc225ca..e3096dc14f 100644 --- a/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h +++ b/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h @@ -40,6 +40,10 @@ enum cnxk_gpio_msg_type { CNXK_GPIO_MSG_TYPE_GET_PIN_DIR, /** Type used to read inverted logic state */ CNXK_GPIO_MSG_TYPE_GET_PIN_ACTIVE_LOW, + /** Type used to register interrupt handler */ + CNXK_GPIO_MSG_TYPE_REGISTER_IRQ, + /** Type used to remove interrupt handler */ + CNXK_GPIO_MSG_TYPE_UNREGISTER_IRQ, }; /** Available edges */ @@ -66,6 +70,25 @@ enum cnxk_gpio_pin_dir { CNXK_GPIO_PIN_DIR_LOW, }; +/** + * GPIO interrupt handler + * + * @param gpio + * Zero-based GPIO number + * @param data + * Cookie passed to interrupt handler + */ +typedef void (*cnxk_gpio_irq_handler_t)(int gpio, void *data); + +struct cnxk_gpio_irq { + /** Interrupt handler */ + cnxk_gpio_irq_handler_t handler; + /** User data passed to irq handler */ + void *data; + /** CPU which will run irq handler */ + int cpu; +}; + struct cnxk_gpio_msg { /** Message type */ enum cnxk_gpio_msg_type type; @@ -306,6 +329,99 @@ rte_pmd_gpio_get_pin_active_low(uint16_t dev_id, int gpio, int *val) return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, val, sizeof(*val)); } +/** + * Attach interrupt handler to GPIO + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * @param cpu + * CPU which will be handling interrupt + * @param handler + * Interrupt handler to be executed + * @param data + * Data to be passed to interrupt handler + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_register_irq(uint16_t dev_id, int gpio, int cpu, + cnxk_gpio_irq_handler_t handler, void *data) +{ + struct cnxk_gpio_irq irq = { + .handler = handler, + .data = data, + .cpu = cpu, + }; + struct cnxk_gpio_msg msg = { + .type = CNXK_GPIO_MSG_TYPE_REGISTER_IRQ, + .data = &irq, + }; + + return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, NULL, 0); +} + +/** + * Detach interrupt handler from GPIO + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_unregister_irq(uint16_t dev_id, int gpio) +{ + struct cnxk_gpio_msg msg = { + .type = CNXK_GPIO_MSG_TYPE_UNREGISTER_IRQ, + .data = &gpio, + }; + + return __rte_pmd_gpio_enq_deq(dev_id, gpio, &msg, NULL, 0); +} + +/** + * Enable interrupt + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * @param edge + * Edge that should trigger interrupt + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_enable_interrupt(uint16_t dev_id, int gpio, + enum cnxk_gpio_pin_edge edge) +{ + return rte_pmd_gpio_set_pin_edge(dev_id, gpio, edge); +} + +/** + * Disable interrupt + * + * @param dev_id + * The identifier of the device + * @param gpio + * Zero-based GPIO number + * + * @return + * Returns 0 on success, negative error code otherwise + */ +static __rte_always_inline int +rte_pmd_gpio_disable_interrupt(uint16_t dev_id, int gpio) +{ + return rte_pmd_gpio_set_pin_edge(dev_id, gpio, CNXK_GPIO_PIN_EDGE_NONE); +} + #ifdef __cplusplus } #endif From patchwork Wed Jan 5 14:00:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105645 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 4BCFAA034D; Wed, 5 Jan 2022 15:01:43 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id BF1F8411A4; Wed, 5 Jan 2022 15:00:49 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 936D941199 for ; Wed, 5 Jan 2022 15:00:47 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205BgGip030978; Wed, 5 Jan 2022 06:00:46 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=Que0lAGr5UuInTBDz6cULx8lnRbsFriX8Mi6jwliOgU=; b=LYsem60eO3A23xnJg+RSeox2iZEwAiatEYcvDuA1aKAs+7cjHNokO/aZz59WyVYVRf9w CxhyHY1lvUE+szgztesmHt1NhDzs1DMlI6xE/CmOjdfjZaFixUlfzm1LrjS4iKJBP0RA /3/yP4QOs+NsAEaS2B4eIQ61N0x4+CjDdjEC1cYx9lM1vcAX0nAN5m3SLeZK+SM9uVPj ezXyDUgajrFy9h4qwrVD5pMKOD/noUBV5VRP3ZO8aXm0QoqSiyzHzgaODr1VE/3RAHFu v/EK2cxok4IKNuqCK5zqKBkzVPb116eiLeD+HPWaex+bjHPp8cmmHWXh4QY7DCo65MdP Ug== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x149-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:46 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 5 Jan 2022 06:00:44 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Wed, 5 Jan 2022 06:00:44 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 7995B5B692E; Wed, 5 Jan 2022 06:00:43 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v4 10/11] raw/cnxk_gpio: support selftest Date: Wed, 5 Jan 2022 15:00:19 +0100 Message-ID: <20220105140020.1615256-11-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: WqcXw9KCP4q0IZ6OajbmBZ1-Q065SnKU X-Proofpoint-ORIG-GUID: WqcXw9KCP4q0IZ6OajbmBZ1-Q065SnKU X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for performing selftest. Signed-off-by: Tomasz Duszynski --- doc/guides/rawdevs/cnxk_gpio.rst | 11 + drivers/raw/cnxk_gpio/cnxk_gpio.c | 1 + drivers/raw/cnxk_gpio/cnxk_gpio.h | 2 + drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c | 386 +++++++++++++++++++++ drivers/raw/cnxk_gpio/meson.build | 1 + 5 files changed, 401 insertions(+) create mode 100644 drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c diff --git a/doc/guides/rawdevs/cnxk_gpio.rst b/doc/guides/rawdevs/cnxk_gpio.rst index ad93ec0d44..c03a5b937c 100644 --- a/doc/guides/rawdevs/cnxk_gpio.rst +++ b/doc/guides/rawdevs/cnxk_gpio.rst @@ -182,3 +182,14 @@ Message is used to remove installed interrupt handler. Message must have type set to ``CNXK_GPIO_MSG_TYPE_UNREGISTER_IRQ``. Consider using ``rte_pmd_gpio_unregister_gpio()`` wrapper. + +Self test +--------- + +On EAL initialization CNXK GPIO device will be probed and populated into +the list of raw devices on condition ``--vdev=cnxk_gpio,gpiochip=`` was +passed. ``rte_rawdev_get_dev_id("CNXK_GPIO")`` returns unique device id. Use +this identifier for further rawdev function calls. + +Selftest rawdev API can be used to verify the PMD functionality. Note it blindly +assumes that all GPIOs are controllable so some errors during test are expected. diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index b30427c01c..16a886b693 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -518,6 +518,7 @@ static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .queue_count = cnxk_gpio_queue_count, .queue_setup = cnxk_gpio_queue_setup, .queue_release = cnxk_gpio_queue_release, + .dev_selftest = cnxk_gpio_selftest, }; static int diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.h b/drivers/raw/cnxk_gpio/cnxk_gpio.h index c052ca5735..1b31b5a486 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.h +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.h @@ -23,6 +23,8 @@ struct cnxk_gpiochip { struct cnxk_gpio **gpios; }; +int cnxk_gpio_selftest(uint16_t dev_id); + int cnxk_gpio_irq_init(struct cnxk_gpiochip *gpiochip); void cnxk_gpio_irq_fini(void); int cnxk_gpio_irq_request(int gpio, int cpu); diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c b/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c new file mode 100644 index 0000000000..6502902f86 --- /dev/null +++ b/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c @@ -0,0 +1,386 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "cnxk_gpio.h" +#include "rte_pmd_cnxk_gpio.h" + +#define CNXK_GPIO_BUFSZ 128 + +#define OTX_IOC_MAGIC 0xF2 +#define OTX_IOC_TRIGGER_GPIO_HANDLER \ + _IO(OTX_IOC_MAGIC, 3) + +static int fd; + +static int +cnxk_gpio_attr_exists(const char *attr) +{ + struct stat st; + + return !stat(attr, &st); +} + +static int +cnxk_gpio_read_attr(char *attr, char *val) +{ + FILE *fp; + int ret; + + fp = fopen(attr, "r"); + if (!fp) + return -errno; + + ret = fscanf(fp, "%s", val); + if (ret < 0) + return -errno; + if (ret != 1) + return -EIO; + + ret = fclose(fp); + if (ret) + return -errno; + + return 0; +} + +#define CNXK_GPIO_ERR_STR(err, str, ...) do { \ + if (err) { \ + RTE_LOG(ERR, PMD, "%s:%d: " str " (%d)\n", __func__, __LINE__, \ + ##__VA_ARGS__, err); \ + goto out; \ + } \ +} while (0) + +static int +cnxk_gpio_validate_attr(char *attr, const char *expected) +{ + char buf[CNXK_GPIO_BUFSZ]; + int ret; + + ret = cnxk_gpio_read_attr(attr, buf); + if (ret) + return ret; + + if (strncmp(buf, expected, sizeof(buf))) + return -EIO; + + return 0; +} + +#define CNXK_GPIO_PATH_FMT "/sys/class/gpio/gpio%d" + +static int +cnxk_gpio_test_input(uint16_t dev_id, int base, int gpio) +{ + char buf[CNXK_GPIO_BUFSZ]; + int ret, n; + + n = snprintf(buf, sizeof(buf), CNXK_GPIO_PATH_FMT, base + gpio); + snprintf(buf + n, sizeof(buf) - n, "/direction"); + + ret = rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_IN); + CNXK_GPIO_ERR_STR(ret, "failed to set dir to input"); + ret = cnxk_gpio_validate_attr(buf, "in"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_value(dev_id, gpio, 1) | + rte_pmd_gpio_set_pin_value(dev_id, gpio, 0); + if (!ret) { + ret = -EIO; + CNXK_GPIO_ERR_STR(ret, "input pin overwritten"); + } + + snprintf(buf + n, sizeof(buf) - n, "/edge"); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, + CNXK_GPIO_PIN_EDGE_FALLING); + CNXK_GPIO_ERR_STR(ret, "failed to set edge to falling"); + ret = cnxk_gpio_validate_attr(buf, "falling"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, + CNXK_GPIO_PIN_EDGE_RISING); + CNXK_GPIO_ERR_STR(ret, "failed to change edge to rising"); + ret = cnxk_gpio_validate_attr(buf, "rising"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, CNXK_GPIO_PIN_EDGE_BOTH); + CNXK_GPIO_ERR_STR(ret, "failed to change edge to both"); + ret = cnxk_gpio_validate_attr(buf, "both"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, CNXK_GPIO_PIN_EDGE_NONE); + CNXK_GPIO_ERR_STR(ret, "failed to set edge to none"); + ret = cnxk_gpio_validate_attr(buf, "none"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + /* + * calling this makes sure kernel driver switches off inverted + * logic + */ + rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_IN); + +out: + return ret; +} + +static int +cnxk_gpio_trigger_irq(int gpio) +{ + int ret; + + ret = ioctl(fd, OTX_IOC_TRIGGER_GPIO_HANDLER, gpio); + + return ret == -1 ? -errno : 0; +} + +static void +cnxk_gpio_irq_handler(int gpio, void *data) +{ + *(int *)data = gpio; +} + +static int +cnxk_gpio_test_irq(uint16_t dev_id, int gpio) +{ + int irq_data, ret; + + ret = rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_IN); + CNXK_GPIO_ERR_STR(ret, "failed to set dir to input"); + + irq_data = 0; + ret = rte_pmd_gpio_register_irq(dev_id, gpio, rte_lcore_id(), + cnxk_gpio_irq_handler, &irq_data); + CNXK_GPIO_ERR_STR(ret, "failed to register irq handler"); + + ret = rte_pmd_gpio_enable_interrupt(dev_id, gpio, + CNXK_GPIO_PIN_EDGE_RISING); + CNXK_GPIO_ERR_STR(ret, "failed to enable interrupt"); + + ret = cnxk_gpio_trigger_irq(gpio); + CNXK_GPIO_ERR_STR(ret, "failed to trigger irq"); + rte_delay_ms(1); + ret = *(volatile int *)&irq_data == gpio ? 0 : -EIO; + CNXK_GPIO_ERR_STR(ret, "failed to test irq"); + + ret = rte_pmd_gpio_disable_interrupt(dev_id, gpio); + CNXK_GPIO_ERR_STR(ret, "failed to disable interrupt"); + + ret = rte_pmd_gpio_unregister_irq(dev_id, gpio); + CNXK_GPIO_ERR_STR(ret, "failed to unregister irq handler"); +out: + rte_pmd_gpio_disable_interrupt(dev_id, gpio); + rte_pmd_gpio_unregister_irq(dev_id, gpio); + + return ret; +} + +static int +cnxk_gpio_test_output(uint16_t dev_id, int base, int gpio) +{ + char buf[CNXK_GPIO_BUFSZ]; + int ret, val, n; + + n = snprintf(buf, sizeof(buf), CNXK_GPIO_PATH_FMT, base + gpio); + + snprintf(buf + n, sizeof(buf) - n, "/direction"); + ret = rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_OUT); + CNXK_GPIO_ERR_STR(ret, "failed to set dir to out"); + ret = cnxk_gpio_validate_attr(buf, "out"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + snprintf(buf + n, sizeof(buf) - n, "/value"); + ret = rte_pmd_gpio_set_pin_value(dev_id, gpio, 0); + CNXK_GPIO_ERR_STR(ret, "failed to set value to 0"); + ret = cnxk_gpio_validate_attr(buf, "0"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + ret = rte_pmd_gpio_get_pin_value(dev_id, gpio, &val); + CNXK_GPIO_ERR_STR(ret, "failed to read value"); + if (val) + ret = -EIO; + CNXK_GPIO_ERR_STR(ret, "read %d instead of 0", val); + + ret = rte_pmd_gpio_set_pin_value(dev_id, gpio, 1); + CNXK_GPIO_ERR_STR(ret, "failed to set value to 1"); + ret = cnxk_gpio_validate_attr(buf, "1"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + ret = rte_pmd_gpio_get_pin_value(dev_id, gpio, &val); + CNXK_GPIO_ERR_STR(ret, "failed to read value"); + if (val != 1) + ret = -EIO; + CNXK_GPIO_ERR_STR(ret, "read %d instead of 1", val); + + snprintf(buf + n, sizeof(buf) - n, "/direction"); + ret = rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_LOW); + CNXK_GPIO_ERR_STR(ret, "failed to set dir to low"); + ret = cnxk_gpio_validate_attr(buf, "out"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + snprintf(buf + n, sizeof(buf) - n, "/value"); + ret = cnxk_gpio_validate_attr(buf, "0"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + snprintf(buf + n, sizeof(buf) - n, "/direction"); + ret = rte_pmd_gpio_set_pin_dir(dev_id, gpio, CNXK_GPIO_PIN_DIR_HIGH); + CNXK_GPIO_ERR_STR(ret, "failed to set dir to high"); + ret = cnxk_gpio_validate_attr(buf, "out"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + snprintf(buf + n, sizeof(buf) - n, "/value"); + ret = cnxk_gpio_validate_attr(buf, "1"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + snprintf(buf + n, sizeof(buf) - n, "/edge"); + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, + CNXK_GPIO_PIN_EDGE_FALLING); + ret = ret == 0 ? -EIO : 0; + CNXK_GPIO_ERR_STR(ret, "changed edge to falling"); + ret = cnxk_gpio_validate_attr(buf, "none"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, + CNXK_GPIO_PIN_EDGE_RISING); + ret = ret == 0 ? -EIO : 0; + CNXK_GPIO_ERR_STR(ret, "changed edge to rising"); + ret = cnxk_gpio_validate_attr(buf, "none"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, CNXK_GPIO_PIN_EDGE_BOTH); + ret = ret == 0 ? -EIO : 0; + CNXK_GPIO_ERR_STR(ret, "changed edge to both"); + ret = cnxk_gpio_validate_attr(buf, "none"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + /* this one should succeed */ + ret = rte_pmd_gpio_set_pin_edge(dev_id, gpio, CNXK_GPIO_PIN_EDGE_NONE); + CNXK_GPIO_ERR_STR(ret, "failed to change edge to none"); + ret = cnxk_gpio_validate_attr(buf, "none"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + snprintf(buf + n, sizeof(buf) - n, "/active_low"); + ret = rte_pmd_gpio_set_pin_active_low(dev_id, gpio, 1); + CNXK_GPIO_ERR_STR(ret, "failed to set active_low to 1"); + ret = cnxk_gpio_validate_attr(buf, "1"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_get_pin_active_low(dev_id, gpio, &val); + CNXK_GPIO_ERR_STR(ret, "failed to read active_low"); + if (val != 1) + ret = -EIO; + CNXK_GPIO_ERR_STR(ret, "read %d instead of 1", val); + + snprintf(buf + n, sizeof(buf) - n, "/value"); + ret = rte_pmd_gpio_set_pin_value(dev_id, gpio, 1); + CNXK_GPIO_ERR_STR(ret, "failed to set value to 1"); + ret = cnxk_gpio_validate_attr(buf, "1"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + ret = rte_pmd_gpio_set_pin_value(dev_id, gpio, 0); + CNXK_GPIO_ERR_STR(ret, "failed to set value to 0"); + ret = cnxk_gpio_validate_attr(buf, "0"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + + snprintf(buf + n, sizeof(buf) - n, "/active_low"); + ret = rte_pmd_gpio_set_pin_active_low(dev_id, gpio, 0); + CNXK_GPIO_ERR_STR(ret, "failed to set active_low to 0"); + ret = cnxk_gpio_validate_attr(buf, "0"); + CNXK_GPIO_ERR_STR(ret, "failed to validate %s", buf); + +out: + return ret; +} + +int +cnxk_gpio_selftest(uint16_t dev_id) +{ + struct cnxk_gpiochip *gpiochip; + unsigned int queues, i, size; + char buf[CNXK_GPIO_BUFSZ]; + struct rte_rawdev *rawdev; + struct cnxk_gpio *gpio; + int ret; + + rawdev = rte_rawdev_pmd_get_named_dev("cnxk_gpio"); + gpiochip = rawdev->dev_private; + + queues = rte_rawdev_queue_count(dev_id); + if (queues == 0) + return -ENODEV; + + ret = rte_rawdev_start(dev_id); + if (ret) + return ret; + + fd = open("/dev/otx-gpio-ctr", O_RDWR | O_SYNC); + if (fd < 0) + return -errno; + + for (i = 0; i < queues; i++) { + RTE_LOG(INFO, PMD, "testing queue %d (gpio%d)\n", i, + gpiochip->base + i); + + ret = rte_rawdev_queue_conf_get(dev_id, i, &size, sizeof(size)); + if (ret) { + RTE_LOG(ERR, PMD, + "failed to read queue configuration (%d)\n", + ret); + continue; + } + + if (size != 1) { + RTE_LOG(ERR, PMD, "wrong queue size received\n"); + continue; + } + + ret = rte_rawdev_queue_setup(dev_id, i, NULL, 0); + if (ret) { + RTE_LOG(ERR, PMD, "failed to setup queue (%d)\n", ret); + continue; + } + + gpio = gpiochip->gpios[i]; + snprintf(buf, sizeof(buf), CNXK_GPIO_PATH_FMT, gpio->num); + if (!cnxk_gpio_attr_exists(buf)) { + RTE_LOG(ERR, PMD, "%s does not exist\n", buf); + continue; + } + + ret = cnxk_gpio_test_input(dev_id, gpiochip->base, i); + if (ret) + goto release; + + ret = cnxk_gpio_test_irq(dev_id, i); + if (ret) + goto release; + + ret = cnxk_gpio_test_output(dev_id, gpiochip->base, i); + if (ret) + goto release; + +release: + ret = rte_rawdev_queue_release(dev_id, i); + if (ret) { + RTE_LOG(ERR, PMD, "failed to release queue (%d)\n", + ret); + continue; + } + + if (cnxk_gpio_attr_exists(buf)) { + RTE_LOG(ERR, PMD, "%s still exists\n", buf); + continue; + } + } + + close(fd); + + return 0; +} diff --git a/drivers/raw/cnxk_gpio/meson.build b/drivers/raw/cnxk_gpio/meson.build index 9b55f029c7..a75a5b9084 100644 --- a/drivers/raw/cnxk_gpio/meson.build +++ b/drivers/raw/cnxk_gpio/meson.build @@ -6,5 +6,6 @@ deps += ['bus_vdev', 'common_cnxk', 'rawdev', 'kvargs'] sources = files( 'cnxk_gpio.c', 'cnxk_gpio_irq.c', + 'cnxk_gpio_selftest.c', ) headers = files('rte_pmd_cnxk_gpio.h') From patchwork Wed Jan 5 14:00:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105646 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 984FCA034D; Wed, 5 Jan 2022 15:01:52 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3CB9C41182; Wed, 5 Jan 2022 15:00:51 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id 2D60E411B2 for ; Wed, 5 Jan 2022 15:00:50 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 205CCDbI030899; Wed, 5 Jan 2022 06:00:49 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=mvN7NtmBVisS61hDEm5NO76oVCC9QnDdB5z9ucTgdGI=; b=NnaC+pjDDmgJggq86RBNKGCfAPIeic8lYxV6Qvv2HeD330pS2vvViC4nCe/eXxn1Z4OP 8QuHSqtJ7yjeghdNKDD/9fFCcWFpOYyDu5y3Ne4k2GzkwDlWDR1Vm3+BKOoeDhUKPDwI BqjWB3CBoGnl3CEMGgFc1i0a7aN6uxJkVvld5tofCXGFvBjdHO/2+bBxHCEefF/d736j JgHixo+ZJ/8Q8C0OqqCjKCnsNOZGM3EJG7fY48NTph+7KIAjTxyn70T1TUIM/bf277IH I/+ejuupX8g7VY7IdVBKjZ81R8fUqBDrwRBgwptd2VuLa+EoRz7kZ6yH6jTwq+2wXQ/F RQ== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dd214x15e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Wed, 05 Jan 2022 06:00:48 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.18; Wed, 5 Jan 2022 06:00:46 -0800 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.18 via Frontend Transport; Wed, 5 Jan 2022 06:00:46 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 6B74B3F7079; Wed, 5 Jan 2022 06:00:45 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v4 11/11] raw/cnxk_gpio: add option to allow using subset of GPIOs Date: Wed, 5 Jan 2022 15:00:20 +0100 Message-ID: <20220105140020.1615256-12-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220105140020.1615256-1-tduszynski@marvell.com> References: <20211213081732.2096334-1-tduszynski@marvell.com> <20220105140020.1615256-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: MdCa-RfOPaP8ox5NJ3IcLA-NA16w9I_t X-Proofpoint-ORIG-GUID: MdCa-RfOPaP8ox5NJ3IcLA-NA16w9I_t X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-05_03,2022-01-04_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add PMD parameter that allows one to select only subset of available GPIOs. This might be useful in cases where some GPIOs are already reserved yet still available for userspace access but particular app should not touch them. Signed-off-by: Tomasz Duszynski Reviewed-by: Jerin Jacob Kollanukkaran --- doc/guides/rawdevs/cnxk_gpio.rst | 5 + drivers/raw/cnxk_gpio/cnxk_gpio.c | 173 +++++++++++++++++---- drivers/raw/cnxk_gpio/cnxk_gpio.h | 2 + drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c | 20 +-- drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h | 8 + 5 files changed, 170 insertions(+), 38 deletions(-) diff --git a/doc/guides/rawdevs/cnxk_gpio.rst b/doc/guides/rawdevs/cnxk_gpio.rst index c03a5b937c..adff535a77 100644 --- a/doc/guides/rawdevs/cnxk_gpio.rst +++ b/doc/guides/rawdevs/cnxk_gpio.rst @@ -57,6 +57,11 @@ former returns number GPIOs available in the system irrespective of GPIOs being controllable or not. Thus it is user responsibility to pick the proper ones. The latter call simply returns queue capacity. +In order to allow using only subset of available GPIOs `allowlist` PMD param may +be used. For example passing `--vdev=cnxk_gpio,gpiochip=448,allowlist=[0,1,2,3]` +to EAL will deny using all GPIOs except those specified explicitly in the +`allowlist`. + Respective queue needs to be configured with ``rte_rawdev_queue_setup()``. This call barely exports GPIO to userspace. diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index 16a886b693..0951899a45 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -22,9 +22,13 @@ static const char *const cnxk_gpio_args[] = { #define CNXK_GPIO_ARG_GPIOCHIP "gpiochip" CNXK_GPIO_ARG_GPIOCHIP, +#define CNXK_GPIO_ARG_ALLOWLIST "allowlist" + CNXK_GPIO_ARG_ALLOWLIST, NULL }; +static char *allowlist; + static void cnxk_gpio_format_name(char *name, size_t len) { @@ -73,13 +77,23 @@ cnxk_gpio_parse_arg_gpiochip(const char *key __rte_unused, const char *value, } static int -cnxk_gpio_parse_args(struct cnxk_gpiochip *gpiochip, - struct rte_devargs *devargs) +cnxk_gpio_parse_arg_allowlist(const char *key __rte_unused, const char *value, + void *extra_args __rte_unused) +{ + allowlist = strdup(value); + if (!allowlist) + return -ENOMEM; + + return 0; +} + +static int +cnxk_gpio_parse_args(struct cnxk_gpiochip *gpiochip, const char *args) { struct rte_kvargs *kvlist; int ret; - kvlist = rte_kvargs_parse(devargs->args, cnxk_gpio_args); + kvlist = rte_kvargs_parse(args, cnxk_gpio_args); if (!kvlist) return 0; @@ -92,6 +106,14 @@ cnxk_gpio_parse_args(struct cnxk_gpiochip *gpiochip, goto out; } + ret = rte_kvargs_count(kvlist, CNXK_GPIO_ARG_ALLOWLIST); + if (ret == 1) { + ret = rte_kvargs_process(kvlist, CNXK_GPIO_ARG_ALLOWLIST, + cnxk_gpio_parse_arg_allowlist, NULL); + if (ret) + goto out; + } + ret = 0; out: rte_kvargs_free(kvlist); @@ -99,6 +121,60 @@ cnxk_gpio_parse_args(struct cnxk_gpiochip *gpiochip, return ret; } +static int +cnxk_gpio_parse_allowlist(struct cnxk_gpiochip *gpiochip) +{ + int i, ret, val, queue = 0; + char *token; + int *list; + + list = rte_calloc(NULL, gpiochip->num_gpios, sizeof(*list), 0); + if (!list) + return -ENOMEM; + + /* replace brackets with something meaningless for strtol() */ + allowlist[0] = ' '; + allowlist[strlen(allowlist) - 1] = ' '; + + /* quiesce -Wcast-qual */ + token = strtok((char *)(uintptr_t)allowlist, ","); + do { + errno = 0; + val = strtol(token, NULL, 10); + if (errno) { + RTE_LOG(ERR, PMD, "failed to parse %s\n", token); + ret = -errno; + goto out; + } + + if (val < 0 || val >= gpiochip->num_gpios) { + RTE_LOG(ERR, PMD, "gpio%d out of 0-%d range\n", val, + gpiochip->num_gpios - 1); + ret = -EINVAL; + goto out; + } + + for (i = 0; i < queue; i++) { + if (list[i] != val) + continue; + + RTE_LOG(WARNING, PMD, "gpio%d already allowed\n", val); + break; + } + if (i == queue) + list[queue++] = val; + } while ((token = strtok(NULL, ","))); + + gpiochip->allowlist = list; + gpiochip->num_queues = queue; + + return 0; +out: + rte_free(list); + + return ret; +} + static int cnxk_gpio_read_attr(char *attr, char *val) { @@ -175,13 +251,24 @@ cnxk_gpio_write_attr_int(const char *attr, int val) return cnxk_gpio_write_attr(attr, buf); } +static bool +cnxk_gpio_queue_valid(struct cnxk_gpiochip *gpiochip, uint16_t queue) +{ + return queue < gpiochip->num_queues; +} + +static int +cnxk_queue_to_gpio(struct cnxk_gpiochip *gpiochip, uint16_t queue) +{ + return gpiochip->allowlist ? gpiochip->allowlist[queue] : queue; +} + static struct cnxk_gpio * cnxk_gpio_lookup(struct cnxk_gpiochip *gpiochip, uint16_t queue) { - if (queue >= gpiochip->num_gpios) - return NULL; + int gpio = cnxk_queue_to_gpio(gpiochip, queue); - return gpiochip->gpios[queue]; + return gpiochip->gpios[gpio]; } static int @@ -191,11 +278,14 @@ cnxk_gpio_queue_setup(struct rte_rawdev *dev, uint16_t queue_id, struct cnxk_gpiochip *gpiochip = dev->dev_private; char buf[CNXK_GPIO_BUFSZ]; struct cnxk_gpio *gpio; - int ret; + int num, ret; RTE_SET_USED(queue_conf); RTE_SET_USED(queue_conf_size); + if (!cnxk_gpio_queue_valid(gpiochip, queue_id)) + return -EINVAL; + gpio = cnxk_gpio_lookup(gpiochip, queue_id); if (gpio) return -EEXIST; @@ -203,7 +293,9 @@ cnxk_gpio_queue_setup(struct rte_rawdev *dev, uint16_t queue_id, gpio = rte_zmalloc(NULL, sizeof(*gpio), 0); if (!gpio) return -ENOMEM; - gpio->num = queue_id + gpiochip->base; + + num = cnxk_queue_to_gpio(gpiochip, queue_id); + gpio->num = num + gpiochip->base; gpio->gpiochip = gpiochip; snprintf(buf, sizeof(buf), "%s/export", CNXK_GPIO_CLASS_PATH); @@ -213,7 +305,7 @@ cnxk_gpio_queue_setup(struct rte_rawdev *dev, uint16_t queue_id, return ret; } - gpiochip->gpios[queue_id] = gpio; + gpiochip->gpios[num] = gpio; return 0; } @@ -224,18 +316,22 @@ cnxk_gpio_queue_release(struct rte_rawdev *dev, uint16_t queue_id) struct cnxk_gpiochip *gpiochip = dev->dev_private; char buf[CNXK_GPIO_BUFSZ]; struct cnxk_gpio *gpio; - int ret; + int num, ret; + + if (!cnxk_gpio_queue_valid(gpiochip, queue_id)) + return -EINVAL; gpio = cnxk_gpio_lookup(gpiochip, queue_id); if (!gpio) return -ENODEV; snprintf(buf, sizeof(buf), "%s/unexport", CNXK_GPIO_CLASS_PATH); - ret = cnxk_gpio_write_attr_int(buf, gpiochip->base + queue_id); + ret = cnxk_gpio_write_attr_int(buf, gpio->num); if (ret) return ret; - gpiochip->gpios[queue_id] = NULL; + num = cnxk_queue_to_gpio(gpiochip, queue_id); + gpiochip->gpios[num] = NULL; rte_free(gpio); return 0; @@ -245,16 +341,17 @@ static int cnxk_gpio_queue_def_conf(struct rte_rawdev *dev, uint16_t queue_id, rte_rawdev_obj_t queue_conf, size_t queue_conf_size) { - unsigned int *conf; + struct cnxk_gpiochip *gpiochip = dev->dev_private; + struct cnxk_gpio_queue_conf *conf = queue_conf; - RTE_SET_USED(dev); - RTE_SET_USED(queue_id); + if (!cnxk_gpio_queue_valid(gpiochip, queue_id)) + return -EINVAL; if (queue_conf_size != sizeof(*conf)) return -EINVAL; - conf = (unsigned int *)queue_conf; - *conf = 1; + conf->size = 1; + conf->gpio = cnxk_queue_to_gpio(gpiochip, queue_id); return 0; } @@ -264,7 +361,7 @@ cnxk_gpio_queue_count(struct rte_rawdev *dev) { struct cnxk_gpiochip *gpiochip = dev->dev_private; - return gpiochip->num_gpios; + return gpiochip->num_queues; } static const struct { @@ -463,21 +560,27 @@ cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf) return ret; } +static bool +cnxk_gpio_valid(struct cnxk_gpiochip *gpiochip, int gpio) +{ + return gpio < gpiochip->num_gpios && gpiochip->gpios[gpio]; +} + static int cnxk_gpio_enqueue_bufs(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers, unsigned int count, rte_rawdev_obj_t context) { struct cnxk_gpiochip *gpiochip = dev->dev_private; - unsigned int queue = (size_t)context; + unsigned int gpio_num = (size_t)context; struct cnxk_gpio *gpio; int ret; if (count == 0) return 0; - gpio = cnxk_gpio_lookup(gpiochip, queue); - if (!gpio) - return -ENODEV; + if (!cnxk_gpio_valid(gpiochip, gpio_num)) + return -EINVAL; + gpio = gpiochip->gpios[gpio_num]; ret = cnxk_gpio_process_buf(gpio, buffers[0]); if (ret) @@ -491,15 +594,15 @@ cnxk_gpio_dequeue_bufs(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers, unsigned int count, rte_rawdev_obj_t context) { struct cnxk_gpiochip *gpiochip = dev->dev_private; - unsigned int queue = (size_t)context; + unsigned int gpio_num = (size_t)context; struct cnxk_gpio *gpio; if (count == 0) return 0; - gpio = cnxk_gpio_lookup(gpiochip, queue); - if (!gpio) - return -ENODEV; + if (!cnxk_gpio_valid(gpiochip, gpio_num)) + return -EINVAL; + gpio = gpiochip->gpios[gpio_num]; if (gpio->rsp) { buffers[0]->buf_addr = gpio->rsp; @@ -549,7 +652,7 @@ cnxk_gpio_probe(struct rte_vdev_device *dev) cnxk_gpio_set_defaults(gpiochip); /* defaults may be overwritten by this call */ - ret = cnxk_gpio_parse_args(gpiochip, dev->device.devargs); + ret = cnxk_gpio_parse_args(gpiochip, rte_vdev_device_args(dev)); if (ret) goto out; @@ -574,6 +677,15 @@ cnxk_gpio_probe(struct rte_vdev_device *dev) RTE_LOG(ERR, PMD, "failed to read %s", buf); goto out; } + gpiochip->num_queues = gpiochip->num_gpios; + + if (allowlist) { + ret = cnxk_gpio_parse_allowlist(gpiochip); + free(allowlist); + allowlist = NULL; + if (ret) + goto out; + } gpiochip->gpios = rte_calloc(NULL, gpiochip->num_gpios, sizeof(struct cnxk_gpio *), 0); @@ -585,6 +697,8 @@ cnxk_gpio_probe(struct rte_vdev_device *dev) return 0; out: + free(allowlist); + rte_free(gpiochip->allowlist); rte_rawdev_pmd_release(rawdev); return ret; @@ -621,6 +735,7 @@ cnxk_gpio_remove(struct rte_vdev_device *dev) cnxk_gpio_queue_release(rawdev, gpio->num); } + rte_free(gpiochip->allowlist); rte_free(gpiochip->gpios); cnxk_gpio_irq_fini(); rte_rawdev_pmd_release(rawdev); @@ -634,4 +749,6 @@ static struct rte_vdev_driver cnxk_gpio_drv = { }; RTE_PMD_REGISTER_VDEV(cnxk_gpio, cnxk_gpio_drv); -RTE_PMD_REGISTER_PARAM_STRING(cnxk_gpio, "gpiochip="); +RTE_PMD_REGISTER_PARAM_STRING(cnxk_gpio, + "gpiochip= " + "allowlist="); diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.h b/drivers/raw/cnxk_gpio/cnxk_gpio.h index 1b31b5a486..e62f78a760 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.h +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.h @@ -20,7 +20,9 @@ struct cnxk_gpiochip { int num; int base; int num_gpios; + int num_queues; struct cnxk_gpio **gpios; + int *allowlist; }; int cnxk_gpio_selftest(uint16_t dev_id); diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c b/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c index 6502902f86..303931fa0f 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c @@ -302,10 +302,11 @@ cnxk_gpio_test_output(uint16_t dev_id, int base, int gpio) int cnxk_gpio_selftest(uint16_t dev_id) { + struct cnxk_gpio_queue_conf conf; struct cnxk_gpiochip *gpiochip; - unsigned int queues, i, size; char buf[CNXK_GPIO_BUFSZ]; struct rte_rawdev *rawdev; + unsigned int queues, i; struct cnxk_gpio *gpio; int ret; @@ -325,10 +326,7 @@ cnxk_gpio_selftest(uint16_t dev_id) return -errno; for (i = 0; i < queues; i++) { - RTE_LOG(INFO, PMD, "testing queue %d (gpio%d)\n", i, - gpiochip->base + i); - - ret = rte_rawdev_queue_conf_get(dev_id, i, &size, sizeof(size)); + ret = rte_rawdev_queue_conf_get(dev_id, i, &conf, sizeof(conf)); if (ret) { RTE_LOG(ERR, PMD, "failed to read queue configuration (%d)\n", @@ -336,7 +334,9 @@ cnxk_gpio_selftest(uint16_t dev_id) continue; } - if (size != 1) { + RTE_LOG(INFO, PMD, "testing queue%d (gpio%d)\n", i, conf.gpio); + + if (conf.size != 1) { RTE_LOG(ERR, PMD, "wrong queue size received\n"); continue; } @@ -347,22 +347,22 @@ cnxk_gpio_selftest(uint16_t dev_id) continue; } - gpio = gpiochip->gpios[i]; + gpio = gpiochip->gpios[conf.gpio]; snprintf(buf, sizeof(buf), CNXK_GPIO_PATH_FMT, gpio->num); if (!cnxk_gpio_attr_exists(buf)) { RTE_LOG(ERR, PMD, "%s does not exist\n", buf); continue; } - ret = cnxk_gpio_test_input(dev_id, gpiochip->base, i); + ret = cnxk_gpio_test_input(dev_id, gpiochip->base, conf.gpio); if (ret) goto release; - ret = cnxk_gpio_test_irq(dev_id, i); + ret = cnxk_gpio_test_irq(dev_id, conf.gpio); if (ret) goto release; - ret = cnxk_gpio_test_output(dev_id, gpiochip->base, i); + ret = cnxk_gpio_test_output(dev_id, gpiochip->base, conf.gpio); if (ret) goto release; diff --git a/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h b/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h index e3096dc14f..80a37be9c7 100644 --- a/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h +++ b/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h @@ -22,6 +22,14 @@ extern "C" { #endif +/* Queue default configuration */ +struct cnxk_gpio_queue_conf { + /** Queue size */ + int size; + /** GPIO number as seen by hardware */ + int gpio; +}; + /** Available message types */ enum cnxk_gpio_msg_type { /** Type used to set output value */