From patchwork Tue Jan 18 13:24: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: 106019 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 128A1A034C; Tue, 18 Jan 2022 14:25:26 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0EF034274B; Tue, 18 Jan 2022 14:25:03 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 370B542745 for ; Tue, 18 Jan 2022 14:25:01 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20IBApjP018565; Tue, 18 Jan 2022 05:25:00 -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=AHXKpgn27nHOBGYunOEkwRMfh/pkXitIwzxURyx0Otw=; b=UG5JYmJ1f40eiKiwpz4TJxgDsglQPBTVS7bYXhIWmfJshW0UozdMf7HSIZ8gNWjPUbwY J1simQR7+1oGOJJiEXVJUuofQOs8iV7xeZg5mFQug7obKCLGWXAYOW65rxrjs+BUSIEo UiPENj5qSVMnWhX6C1PsRpMsxgmOajn+5+BzTA2HoWXHyYp7F/7iHFTchJ7A84MPtzy3 1zBgRqiye8FXQgo0pXA1dJxMcoRxAD2rVCH9piFvRtSTwRnGPaWRnwUDywC8lyqRFIgX VbZPAh9562EhXIFpYfZ4lbnLMwc7M/cZbdxdR05ELfUT9hTVbawVDVFIeNA2AB9TbWG5 Ag== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3dnvea0bv5-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:25:00 -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; Tue, 18 Jan 2022 05:24:30 -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; Tue, 18 Jan 2022 05:24:30 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 046A83F705F; Tue, 18 Jan 2022 05:24:28 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v5 01/11] raw/cnxk_gpio: add GPIO driver skeleton Date: Tue, 18 Jan 2022 14:24:14 +0100 Message-ID: <20220118132424.2573372-2-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: OVnqFnO0d05XvJBijH-CKgp-t3qUlQCv X-Proofpoint-GUID: OVnqFnO0d05XvJBijH-CKgp-t3qUlQCv X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_03,2022-01-18_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/platform/cnxk.rst | 2 + doc/guides/rawdevs/cnxk_gpio.rst | 65 +++++++ doc/guides/rawdevs/index.rst | 1 + doc/guides/rel_notes/release_22_03.rst | 9 + drivers/raw/cnxk_gpio/cnxk_gpio.c | 248 +++++++++++++++++++++++++ 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 + 9 files changed, 359 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/platform/cnxk.rst b/doc/guides/platform/cnxk.rst index 97e38c868c..3dee725ac5 100644 --- a/doc/guides/platform/cnxk.rst +++ b/doc/guides/platform/cnxk.rst @@ -73,6 +73,8 @@ DPDK subsystem. +---+-----+--------------------------------------------------------------+ | 11| BPHY| rte_rawdev | +---+-----+--------------------------------------------------------------+ + | 12| GPIO| rte_rawdev | + +---+-----+--------------------------------------------------------------+ PF0 is called the administrative / admin function (AF) and has exclusive privileges to provision RVU functional block's LFs to each of the PF/VF. 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/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst index 16c66c0641..09039899e8 100644 --- a/doc/guides/rel_notes/release_22_03.rst +++ b/doc/guides/rel_notes/release_22_03.rst @@ -55,6 +55,15 @@ New Features Also, make sure to start the actual text at the margin. ======================================================= +* **Added CNXK GPIO PMD.** + + Added a new rawdevice PMD which allows to manage userspace GPIOs and install + custom GPIO interrupt handlers which bypass kernel. This is especially useful + for applications, that besides providing standard dataplane functionality + want to have fast and low latency access to GPIO pin state. + + See the :doc:`../rawdevs/cnxk_gpio` rawdev guide for more details on this + driver. Removed Items ------------- diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c new file mode 100644 index 0000000000..61069b2185 --- /dev/null +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -0,0 +1,248 @@ +/* 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 int +cnxk_gpio_dev_close(struct rte_rawdev *dev) +{ + RTE_SET_USED(dev); + + return 0; +} + +static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { + .dev_close = cnxk_gpio_dev_close, +}; + +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 Tue Jan 18 13:24: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: 106015 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 A6E12A034C; Tue, 18 Jan 2022 14:24:57 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2D11942726; Tue, 18 Jan 2022 14:24:53 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 997714068E for ; Tue, 18 Jan 2022 14:24:51 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20IBAuMV018843; Tue, 18 Jan 2022 05:24:51 -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=9utLQc1Lj7y+olnPBPYON/LzOg4ihBCnVr9nP+tt0Z0=; b=CkuY31qVAnzPma6wGMhaBnfIFa3yL36oQdgkXOWDZlskbegAekC3gSXiIXYMFdcsk6fa nXXPoIQHFUuo9fI+9Z0o/I4WpsuCgpjDVUQzux25iFquV9Un8P3exsMlcta2XGf9XTLM BdfYxxYJKjcetYHE26JWRytuwOSycztNY/jjUcUr90PVh10BMeGif0y9uTV9zOjGhUJO y7nMbtLICzSzd6BLWH4RLCuXjzYgTGXjen2flnC4iQDJgT3vmNO5jl4R+Ztxs4gW8kTq jZzPSy5N6BKr+fSTyNbgyO9Mrm3gefYjg1eAQ4QgfzyGB9pECtlahToFb/PvLA+XwSCs wQ== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3dnvea0c09-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:24:50 -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; Tue, 18 Jan 2022 05:24:32 -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; Tue, 18 Jan 2022 05:24:32 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 316A13F705D; Tue, 18 Jan 2022 05:24:30 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v5 02/11] raw/cnxk_gpio: support reading default queue conf Date: Tue, 18 Jan 2022 14:24:15 +0100 Message-ID: <20220118132424.2573372-3-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: xdgrO3vkj7OU8HlFZbaL4gTOJk8fi4P0 X-Proofpoint-GUID: xdgrO3vkj7OU8HlFZbaL4gTOJk8fi4P0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_03,2022-01-18_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 61069b2185..1f36f6e22c 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -146,8 +146,27 @@ cnxk_gpio_dev_close(struct rte_rawdev *dev) 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 = { .dev_close = cnxk_gpio_dev_close, + .queue_def_conf = cnxk_gpio_queue_def_conf, }; static int From patchwork Tue Jan 18 13:24: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: 106018 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 993F1A034C; Tue, 18 Jan 2022 14:25:19 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0C7F142739; Tue, 18 Jan 2022 14:25:02 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 2F02542748 for ; Tue, 18 Jan 2022 14:25:00 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20IB9uBx012185; Tue, 18 Jan 2022 05:24:59 -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=2a8OhaD4B20XrSw2hNCVXJ172kDBd0FIXBfouoSM+gY=; b=iRUFlLxIU+gdrDJAeRPV3/qx4nokR2BeArY/QGAqZkOXbEBXYjZ+7NPhAPvPh7Tqhwkc jThwjSNbFW75x84LRSmKFU8tBkFtqiimtobbheI0GfhwnYTdwv42ezYtr9qsc/ap4Zpq NeexCRD6HF55cBtvGABhBXXK4FZ3yF9HjumK/YyDCh8KKXN4CDBs/aBZfs2ACT2k0SUu WF12lK8RvJTG1vuHqqSFQpIaE2seFbKw7CC1Q28tKEk8nn2ydS2NdT45vTqGqVEsNbEW toSZAG5YyW/PtNU/pDlMOi/QZFL7bUwzci6yY4SuyM3HWxelhqL09bMJejwYRUt1Sdyc 2Q== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3dnvea0c0k-14 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:24:59 -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; Tue, 18 Jan 2022 05:24: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; Tue, 18 Jan 2022 05:24:35 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 65FB33F705E; Tue, 18 Jan 2022 05:24:33 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v5 03/11] raw/cnxk_gpio: support reading queue count Date: Tue, 18 Jan 2022 14:24:16 +0100 Message-ID: <20220118132424.2573372-4-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: rOMAsH6-wRb_SZK-gmD-f7Q_VE4eZ58E X-Proofpoint-GUID: rOMAsH6-wRb_SZK-gmD-f7Q_VE4eZ58E X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_03,2022-01-18_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 1f36f6e22c..cee75e389a 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -164,9 +164,18 @@ 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 = { .dev_close = cnxk_gpio_dev_close, .queue_def_conf = cnxk_gpio_queue_def_conf, + .queue_count = cnxk_gpio_queue_count, }; static int From patchwork Tue Jan 18 13:24: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: 106020 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 9C27CA034C; Tue, 18 Jan 2022 14:25:33 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0665B42781; Tue, 18 Jan 2022 14:25:04 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id E48DF42725 for ; Tue, 18 Jan 2022 14:25:01 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20IB9uC1012185; Tue, 18 Jan 2022 05:25:01 -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=1DvBVTVELCdgqd2MQBCxnCarnP2KX0T/w0TNQbPQCwI=; b=EhIg/ClWoqXU1ktgXigLb1Us3FVdMzWBb1dabaxIcIF/lYhePtijPMmR7muL43OCriyW KLQUV4Uv+x0IG5FlqW7XWXrLsu7oIBSsL6GTi4XjPtLpvWZPL+yrF2oIsUCRP5/a8Sfo gMviPwUxQewgMxGbYgo4Fgv1DLbkf6IZYXwKHnlnYbleoRp4UMd0mtd8/JWTMBc1CPi3 4SbGjuu+1FFj91tU2ORFOZsk9+qcI854SeOFoA/yXAxt+jY+H7CQS1pDbaiViI641X0O lw8ovmH3t1hbykqimsOFlTki0tNXxS28lNAp2+Nf+KrQ7mc1rXVuxmAnhqJ6WJWN5Dbg pg== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3dnvea0c0k-15 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:25:00 -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; Tue, 18 Jan 2022 05:24: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; Tue, 18 Jan 2022 05:24:37 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 9AB5E3F7066; Tue, 18 Jan 2022 05:24:35 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v5 04/11] raw/cnxk_gpio: support queue setup Date: Tue, 18 Jan 2022 14:24:17 +0100 Message-ID: <20220118132424.2573372-5-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: Qw5VQCAHSfMePCWccRrLN1mBNfGfAc_z X-Proofpoint-GUID: Qw5VQCAHSfMePCWccRrLN1mBNfGfAc_z X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_03,2022-01-18_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 | 84 ++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index cee75e389a..9baa43187e 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -139,9 +139,80 @@ cnxk_gpio_read_attr_int(char *attr, int *val) } static int -cnxk_gpio_dev_close(struct rte_rawdev *dev) +cnxk_gpio_write_attr(const char *attr, const char *val) { - RTE_SET_USED(dev); + 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; } @@ -172,10 +243,19 @@ cnxk_gpio_queue_count(struct rte_rawdev *dev) return gpiochip->num_gpios; } +static int +cnxk_gpio_dev_close(struct rte_rawdev *dev) +{ + RTE_SET_USED(dev); + + return 0; +} + static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .dev_close = cnxk_gpio_dev_close, .queue_def_conf = cnxk_gpio_queue_def_conf, .queue_count = cnxk_gpio_queue_count, + .queue_setup = cnxk_gpio_queue_setup, }; static int From patchwork Tue Jan 18 13:24: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: 106021 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 4E978A034C; Tue, 18 Jan 2022 14:25:41 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 48B4B42789; Tue, 18 Jan 2022 14:25:05 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 4CD6842725 for ; Tue, 18 Jan 2022 14:25:02 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20IB9uC2012185; Tue, 18 Jan 2022 05:25:01 -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=I6ED1RK8dhQ6wyTBEtmW6DwsekwPa+Zr0oicem6k43M=; b=d5NS9L7byDvvPI5qB0u6hgcspBeRpR4G4dhjrTI+b2AnyykZPPwTRjH3zo5fhSvYScge kzs4jV6N6lcoajVJrEstvZzP95MtMawOkM+S23gKBM/S1/sB5dQreTHVu7nDhDwFDg+o 0WxZ14eQVB722T7drAjNZicOjarI9l+RrcMNFC+vLtf24iZp3mbFe6ddc5kJQH4CInrq RphjCogrpHoEjh6AXlwqES2oqOEbD+Q1//u/3BtUnhlrVfxcm6FKxck26weg5CV8wsQD gOiTQNcfmjeElKtTPTEHNvcIfgNvUoaSUsKf+q/WI5vVISyMdMJ0mpNi/giaHle2FCxW CA== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3dnvea0c0k-16 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:25:01 -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; Tue, 18 Jan 2022 05:24: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; Tue, 18 Jan 2022 05:24:39 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id C6C513F705F; Tue, 18 Jan 2022 05:24:37 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v5 05/11] raw/cnxk_gpio: support queue release Date: Tue, 18 Jan 2022 14:24:18 +0100 Message-ID: <20220118132424.2573372-6-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: hpMgkwLR4yyyU0BnRnM5Mh3HspYZqoHh X-Proofpoint-GUID: hpMgkwLR4yyyU0BnRnM5Mh3HspYZqoHh X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_03,2022-01-18_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 9baa43187e..ec82a55918 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) @@ -256,6 +279,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 @@ -329,6 +353,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); @@ -341,6 +367,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 Tue Jan 18 13:24: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: 106016 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 8F9E7A034C; Tue, 18 Jan 2022 14:25:03 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 47AC84272A; Tue, 18 Jan 2022 14:24:56 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 096154272A for ; Tue, 18 Jan 2022 14:24:53 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20IBAuMY018843; Tue, 18 Jan 2022 05:24:53 -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=jzO+Jjp3GOoCX2A0vYMTJNrwPNGsiRI20i7dKFe2XmY=; b=j68EgNann6GDXfQzudliYzgVK1Cw6bu80Ae7DX4OmVpKhvjDR739SBPG9V34btKal6mN AzE43VeyzI92yj206UaYcMQW7j6DDNwnXm4vKvIb0/ttfQqbZDHGZloz/c/PmoqfNOSJ uPnY9u7JgRXUjQsDi9L6BkiSDCzgW9kvTRnfi1li6GFnQngHRL566ZadLa+0LcQ67M4b NplP2Z4PdnI35TMfkQG0hKRxxdVfXd3H0bPZZatXH0/roWw52Ul4cx8Tw3Ae4w2qxrKC mXHfAJ65ThKMsaoXuIvzns58indJmJkEuYiuBv48s2ro4a1mjlOKVQm8evylXZnAuiTi zg== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3dnvea0c09-10 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:24:53 -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; Tue, 18 Jan 2022 05:24: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; Tue, 18 Jan 2022 05:24:41 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id F2AD53F705D; Tue, 18 Jan 2022 05:24:39 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v5 06/11] raw/cnxk_gpio: support enqueuing buffers Date: Tue, 18 Jan 2022 14:24:19 +0100 Message-ID: <20220118132424.2573372-7-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: RhhzD1q4O2SpJut12m2FicFgMcDdYWwy X-Proofpoint-GUID: RhhzD1q4O2SpJut12m2FicFgMcDdYWwy X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_03,2022-01-18_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 ec82a55918..6f3795df41 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" @@ -274,8 +275,54 @@ cnxk_gpio_dev_close(struct rte_rawdev *dev) return 0; } +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 = { .dev_close = cnxk_gpio_dev_close, + .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 Tue Jan 18 13:24: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: 106022 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 7ACCBA034C; Tue, 18 Jan 2022 14:25:49 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 51CE14278E; Tue, 18 Jan 2022 14:25:09 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 0C5BF42784 for ; Tue, 18 Jan 2022 14:25:03 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20IB9uC3012185; Tue, 18 Jan 2022 05:25:02 -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=NQfPU8jzfI7TNM9JiMBe0a66kfUKFHnd2dRaxVtWwZ8=; b=EozJIVf9Bl71Hn+fwGxmmkFEJAkeWPMOHa08PN/FuK0eLyQCIdbynhJGIaBiC1tHuEj2 UdiUqsd94WlJ08xpbFECjVnPGswSlImTGrQFmro/zDkkSkriKLWpDbrLGl29/PKWFHlw 7FMVqxYqcpIStyx3EUY7ZqMMYxAfJb5a+B8OdftSClJUnYO4cHIKCZEkq1BNvOomCbfJ RFc2QaMBp1oG85aU+GkO7U1XfgJT5oaAonmWkj8nNFHcMwfuaULxUd6F98PMl6ylE1yi wFaegrBp1erypCzg22qaSbar3AxTjo0l/c/l5oSAfKUZJctfjdlR2tKlezmVKfLfxtus nw== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3dnvea0c0k-17 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:25:02 -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; Tue, 18 Jan 2022 05:24:44 -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; Tue, 18 Jan 2022 05:24:44 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 2A7843F705E; Tue, 18 Jan 2022 05:24:41 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v5 07/11] raw/cnxk_gpio: support dequeuing buffers Date: Tue, 18 Jan 2022 14:24:20 +0100 Message-ID: <20220118132424.2573372-8-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: F4SXQwSm8l6VB7cizAK3Fktm2s0i0JU4 X-Proofpoint-GUID: F4SXQwSm8l6VB7cizAK3Fktm2s0i0JU4 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_03,2022-01-18_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 6f3795df41..46f9e63dd7 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -320,9 +320,35 @@ 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 = { .dev_close = cnxk_gpio_dev_close, .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 Tue Jan 18 13:24:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 106023 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 3C2D0A034C; Tue, 18 Jan 2022 14:25:55 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 01B2642728; Tue, 18 Jan 2022 14:25:11 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 36B3642745 for ; Tue, 18 Jan 2022 14:25:05 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20IB9uC5012185; Tue, 18 Jan 2022 05:25:04 -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=imtGd8TbLySPrCKIxQNwuwRKtxT1/dkendhi6KKWAn8=; b=eB8vQoNgxqv8zfz+TUKLh75jRTAD4kiyvJtsUMa1HzWj/UnNE2V9bwpo2lljiGcNRA6p QKkEfkf82vjqjma2AcaJSudlZ9MgDbet1GYuzRhe+mka07ra4Ilq9OBIcKTMUF5k5yUE LdaRAh6s2XtYykhAjBgnUrofP0PxWFNVWuU6RD1ydwmNnggEOXU8xe507/Ji8E/rShqA LoBekzNK2gz/EGgttjr/Lg978TUCZ/Sn6qHhSkDcuGUPt1g243DwWyHJN2higzmxhOCu XCGGG9uWapnrgKG6XIK27WG+0B38JuyFvBQqjZtJ9zyGpY3b/BWlcbVFNb3yEL5XZZBH yA== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3dnvea0c0k-19 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:25:04 -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; Tue, 18 Jan 2022 05:24:46 -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; Tue, 18 Jan 2022 05:24:46 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 68D263F705D; Tue, 18 Jan 2022 05:24:44 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v5 08/11] raw/cnxk_gpio: support standard GPIO operations Date: Tue, 18 Jan 2022 14:24:21 +0100 Message-ID: <20220118132424.2573372-9-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: yag2qeYTbu1nKtJcP5U9aUTc0Fs2gkq- X-Proofpoint-GUID: yag2qeYTbu1nKtJcP5U9aUTc0Fs2gkq- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_03,2022-01-18_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 46f9e63dd7..67c6d4813c 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -267,6 +267,78 @@ 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_dev_close(struct rte_rawdev *dev) { @@ -279,10 +351,83 @@ 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 Tue Jan 18 13:24:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 106017 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 64657A034C; Tue, 18 Jan 2022 14:25:11 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 99F9042743; Tue, 18 Jan 2022 14:24:58 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 326A84271E for ; Tue, 18 Jan 2022 14:24:55 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20IBAuMZ018843; Tue, 18 Jan 2022 05:24:54 -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=O/e92YuHDytS2ubsAjhi/ZYS0Nq6Tc5giLrADvjXv5Q=; b=GB4sNekMzsrlCYBg5RKi2BjpbjsUKiKlwMcHisAJJQq80quoXHwQIH8ZouPHFY6lqfwx ngn2tzkfKSw5yjTdGeEIATRPum2oYP+EFoC86iLGucuFQtNCS8cOXnF2yJHWZ1bvvaDq vVt74H/XcbMSbBM877RHx1WDyzIGbcsbxDZtVXfeLHfug/qLAAxcSv0DxYAiQn5fZps7 Is+pzt+eNLCJLF9tKjVNamXJM+p7vVIWD8Mk8vfZH3dBzoT22yqqO1nWCSltyboCVic9 5o1fCvTtk2UcvzemL1MLY0IjJaZi/m5HGcjDkWg3ZfzGNv3+tv/ygv7HAAL5ghNxiISn Eg== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3dnvea0c09-11 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:24:53 -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; Tue, 18 Jan 2022 05:24:48 -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; Tue, 18 Jan 2022 05:24:48 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 949863F705E; Tue, 18 Jan 2022 05:24:46 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v5 09/11] raw/cnxk_gpio: support custom irq handlers Date: Tue, 18 Jan 2022 14:24:22 +0100 Message-ID: <20220118132424.2573372-10-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: e4qUu8FJgi33Zo5opAvaLYt66ToZ_Drw X-Proofpoint-GUID: e4qUu8FJgi33Zo5opAvaLYt66ToZ_Drw X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_03,2022-01-18_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 | 41 +++- 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, 401 insertions(+), 2 deletions(-) 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 67c6d4813c..58553ad3d9 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -340,13 +340,27 @@ cnxk_gpio_name_to_dir(const char *name) } static int -cnxk_gpio_dev_close(struct rte_rawdev *dev) +cnxk_gpio_register_irq(struct cnxk_gpio *gpio, struct cnxk_gpio_irq *irq) { - RTE_SET_USED(dev); + 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) { @@ -428,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; } @@ -490,6 +511,14 @@ cnxk_gpio_dequeue_bufs(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers, return 0; } +static int +cnxk_gpio_dev_close(struct rte_rawdev *dev) +{ + RTE_SET_USED(dev); + + return 0; +} + static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .dev_close = cnxk_gpio_dev_close, .enqueue_bufs = cnxk_gpio_enqueue_bufs, @@ -532,6 +561,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); @@ -590,10 +623,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 Tue Jan 18 13:24:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 106024 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 A454FA034C; Tue, 18 Jan 2022 14:26:01 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4636C427A4; Tue, 18 Jan 2022 14:25:12 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id E89444278E for ; Tue, 18 Jan 2022 14:25:05 +0100 (CET) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 20IB9uC6012185; Tue, 18 Jan 2022 05:25:05 -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=WuR7cOFU7h0qMMHlNg5K4Lb4rdL/1PbB56CMT/+oqak=; b=Hl1uCLBwqxwc0MPBRuREQyoxOniFG2IAZZ2rp0L5YyX1ayAKa07hNg7ij/40sSNWsl0o 1nIPdXbFWbymdasih1O/k8dNt4w8lhilR+AG7SGWiSXHUEQ3bWcknMw5YiFmKYQxhT7u wsxR+v87LAZW56rLHhTG2U6pueTrRuT6p7CC91dAOAQtv3Be5TmlSryFsZLSZFEy4gn8 xwF5NC5LYg63aGsrWuKFfSfRQJSNX1QG7lhbouu52RGaocyFYCN/z3jsIkviLLtvh1h0 NSU5hUWq3Fc7SXtZ5sAzEgJ/plxOMSfo7Vw16RcACTWieVRUSbZEXJ7o6629vM1Pjk9A 1g== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3dnvea0c0k-20 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:25:05 -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; Tue, 18 Jan 2022 05:24:50 -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; Tue, 18 Jan 2022 05:24:50 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id C254F3F705F; Tue, 18 Jan 2022 05:24:48 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v5 10/11] raw/cnxk_gpio: support selftest Date: Tue, 18 Jan 2022 14:24:23 +0100 Message-ID: <20220118132424.2573372-11-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: RDaf5avJFcvLhH-dpqR5L1PLIPr9dE-M X-Proofpoint-GUID: RDaf5avJFcvLhH-dpqR5L1PLIPr9dE-M X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_03,2022-01-18_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 58553ad3d9..230016b078 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -527,6 +527,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 Tue Jan 18 13:24:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 106025 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 2CDD9A034C; Tue, 18 Jan 2022 14:26:39 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 16EBB4271E; Tue, 18 Jan 2022 14:26: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 C5C9B4271E for ; Tue, 18 Jan 2022 14:26: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 20IBFZsQ021237; Tue, 18 Jan 2022 05:26: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=G28gu3xyi5NxupjM7lD0M2dHPU9Vf7Z2IslpQorN//I=; b=URoO+hfphwU9wdYqSI9Pu5GADN4dhIWewDN2CEcsqYmpVZ7r6oPRhssoY1evda9/NKek tqjXNssWvaEhjENMiQxNwNiNqHVh73Y88z8e60MeixPAdJCRvN4z/JGbcG2kKcYppcNs aWh+dvVoiCNHv3YNbjlHN8Mji0huSbCuerOsUMqfLlgGxtsIvgmp872bcYSLchzb4hXO gmgm//bLpykS4m+yvHJ8pOTlhQ5Y6Xps/Oww8JepMQUNGappxV0vXGAoQ4YIeKEtbfAy sfm71zcDLL5K1C0+NzZKjuXehi6ae3gibmiA6dOb/xTwRbU/plMsPOs/4xOCbineqygv mA== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3dnmttsu2b-11 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Tue, 18 Jan 2022 05:26:36 -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; Tue, 18 Jan 2022 05:24:53 -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; Tue, 18 Jan 2022 05:24:53 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id ED7AA3F705D; Tue, 18 Jan 2022 05:24:50 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski , Jerin Jacob Kollanukkaran Subject: [PATCH v5 11/11] raw/cnxk_gpio: add option to allow using subset of GPIOs Date: Tue, 18 Jan 2022 14:24:24 +0100 Message-ID: <20220118132424.2573372-12-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220118132424.2573372-1-tduszynski@marvell.com> References: <20220105140020.1615256-1-tduszynski@marvell.com> <20220118132424.2573372-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: od-Qcn5MpX64aaYUZZqyvOwA08VLr_Ht X-Proofpoint-ORIG-GUID: od-Qcn5MpX64aaYUZZqyvOwA08VLr_Ht X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-01-18_04,2022-01-18_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 | 49 +++--- drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h | 8 + 5 files changed, 188 insertions(+), 49 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 230016b078..4ff132861d 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; @@ -558,7 +661,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; @@ -583,6 +686,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); @@ -594,6 +706,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; @@ -630,6 +744,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); @@ -643,4 +758,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..7fccc48f30 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio_selftest.c @@ -302,12 +302,13 @@ 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; + int ret, ret2; rawdev = rte_rawdev_pmd_get_named_dev("cnxk_gpio"); gpiochip = rawdev->dev_private; @@ -325,62 +326,68 @@ 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", ret); - continue; + goto out; } - 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; + ret = -EIO; + goto out; } ret = rte_rawdev_queue_setup(dev_id, i, NULL, 0); if (ret) { RTE_LOG(ERR, PMD, "failed to setup queue (%d)\n", ret); - continue; + goto out; } - 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); - if (ret) + ret = -ENOENT; goto release; + } - ret = cnxk_gpio_test_irq(dev_id, i); + ret = cnxk_gpio_test_input(dev_id, gpiochip->base, conf.gpio); if (ret) goto release; - ret = cnxk_gpio_test_output(dev_id, gpiochip->base, i); + ret = cnxk_gpio_test_irq(dev_id, conf.gpio); if (ret) goto release; + ret = cnxk_gpio_test_output(dev_id, gpiochip->base, conf.gpio); release: + ret2 = ret; ret = rte_rawdev_queue_release(dev_id, i); if (ret) { RTE_LOG(ERR, PMD, "failed to release queue (%d)\n", ret); - continue; + break; } if (cnxk_gpio_attr_exists(buf)) { RTE_LOG(ERR, PMD, "%s still exists\n", buf); - continue; + ret = -EIO; + break; + } + + if (ret2) { + ret = ret2; + break; } } +out: close(fd); - return 0; + return ret; } 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 */