From patchwork Mon Dec 13 08:17:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105084 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 A3086A0032; Mon, 13 Dec 2021 09:18:27 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 8199C41156; Mon, 13 Dec 2021 09:18:22 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 25E4C40140 for ; Mon, 13 Dec 2021 09:18:20 +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 1BD7iF7G026887; Mon, 13 Dec 2021 00:18:19 -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=a/R/KBhAknSPUFtPu1xdJWNldQDgiOdrcKwt9GmvCbY=; b=WiGTS8ZtRjj2j3NZ7mpq1bN/W0TPvseasxdtXi/0nIO71zTXQhaKyH37zxvEr+Jp/Pok hcdy6OheYLDSvplPhbuB7V3h8Ygvfi49iMtaSS3b2X6YRYMF+YI4oIOGYYz11R8LkdhC CaWpP/Y+5Ss4AaXGasKnSY02zTxgwoxaUAdkR0VFrC5/lOlLvHHXeLJhKVr+T5TPXJ2h /E7N+SOoFkXpUs4MIVnqJBl6JH8sqoHg1ephd8BzTNKiOp7RhrODwZsKjzQNxfSkUSch iWbi5L23EWY1hbLGSkzsFItCLVrVX8XuOB51XD86zgR/sZ9uSOG3qyVH1q6Jv7x6CToQ AA== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3cx21kg39w-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Dec 2021 00:18:19 -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; Mon, 13 Dec 2021 00:18:18 -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; Mon, 13 Dec 2021 00:18:18 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 0AF5F3F704A; Mon, 13 Dec 2021 00:18:16 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v3 01/10] raw/cnxk_gpio: add GPIO driver skeleton Date: Mon, 13 Dec 2021 09:17:23 +0100 Message-ID: <20211213081732.2096334-2-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213081732.2096334-1-tduszynski@marvell.com> References: <20211128154442.4029049-1-tduszynski@marvell.com> <20211213081732.2096334-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: 0wyX3LgFJLYYp0yup0YR1DRJA4ZGfCx2 X-Proofpoint-ORIG-GUID: 0wyX3LgFJLYYp0yup0YR1DRJA4ZGfCx2 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-13_03,2021-12-10_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add initial support for PMD that allows to control particular pins form userspace. Moreover PMD allows to attach custom interrupt handlers to controllable GPIOs. Main users of this PMD are dataplain applications requiring fast and low latency access to pin state. Signed-off-by: Tomasz Duszynski --- doc/guides/rawdevs/cnxk_gpio.rst | 65 +++++++++ doc/guides/rawdevs/index.rst | 1 + drivers/raw/cnxk_gpio/cnxk_gpio.c | 235 ++++++++++++++++++++++++++++++ drivers/raw/cnxk_gpio/cnxk_gpio.h | 22 +++ drivers/raw/cnxk_gpio/meson.build | 8 + drivers/raw/cnxk_gpio/version.map | 3 + drivers/raw/meson.build | 1 + 7 files changed, 335 insertions(+) create mode 100644 doc/guides/rawdevs/cnxk_gpio.rst create mode 100644 drivers/raw/cnxk_gpio/cnxk_gpio.c create mode 100644 drivers/raw/cnxk_gpio/cnxk_gpio.h create mode 100644 drivers/raw/cnxk_gpio/meson.build create mode 100644 drivers/raw/cnxk_gpio/version.map diff --git a/doc/guides/rawdevs/cnxk_gpio.rst b/doc/guides/rawdevs/cnxk_gpio.rst new file mode 100644 index 0000000000..868302d07f --- /dev/null +++ b/doc/guides/rawdevs/cnxk_gpio.rst @@ -0,0 +1,65 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright(c) 2021 Marvell. + +Marvell CNXK GPIO Driver +======================== + +CNXK GPIO PMD configures and manages GPIOs available on the system using +standard enqueue/dequeue mechanism offered by raw device abstraction. PMD relies +both on standard sysfs GPIO interface provided by the Linux kernel and GPIO +kernel driver custom interface allowing one to install userspace interrupt +handlers. + +Features +-------- + +Following features are available: + +- export/unexport a GPIO +- read/write specific value from/to exported GPIO +- set GPIO direction +- set GPIO edge that triggers interrupt +- set GPIO active low +- register interrupt handler for specific GPIO + +Requirements +------------ + +PMD relies on modified kernel GPIO driver which exposes ``ioctl()`` interface +for installing interrupt handlers for low latency signal processing. + +Driver is shipped with Marvell SDK. + +Device Setup +------------ + +CNXK GPIO PMD binds to virtual device which gets created by passing +`--vdev=cnxk_gpio,gpiochip=` command line to EAL. `gpiochip` parameter +tells PMD which GPIO controller should be used. Available controllers are +available under `/sys/class/gpio`. For further details on how Linux represents +GPIOs in userspace please refer to +`sysfs.txt `_. + +If `gpiochip=` was omitted then first gpiochip from the alphabetically +sort list of available gpiochips is used. + +.. code-block:: console + + $ ls /sys/class/gpio + export gpiochip448 unexport + +In above scenario only one GPIO controller is present hence +`--vdev=cnxk_gpio,gpiochip=448` should be passed to EAL. + +Before performing actual data transfer one needs to call +``rte_rawdev_queue_count()`` followed by ``rte_rawdev_queue_conf_get()``. The +former returns number GPIOs available in the system irrespective of GPIOs +being controllable or not. Thus it is user responsibility to pick the proper +ones. The latter call simply returns queue capacity. + +Respective queue needs to be configured with ``rte_rawdev_queue_setup()``. This +call barely exports GPIO to userspace. + +To perform actual data transfer use standard ``rte_rawdev_enqueue_buffers()`` +and ``rte_rawdev_dequeue_buffers()`` APIs. Not all messages produce sensible +responses hence dequeueing is not always necessary. diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst index b6cf917443..0c02da6e90 100644 --- a/doc/guides/rawdevs/index.rst +++ b/doc/guides/rawdevs/index.rst @@ -12,6 +12,7 @@ application through rawdev API. :numbered: cnxk_bphy + cnxk_gpio dpaa2_cmdif dpaa2_qdma ifpga diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c new file mode 100644 index 0000000000..bcce4b8fb7 --- /dev/null +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -0,0 +1,235 @@ +/* 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) + return ret; + } + + return 0; +} + +static int +cnxk_gpio_read_attr(char *attr, char *val) +{ + FILE *fp; + int ret; + + fp = fopen(attr, "r"); + if (!fp) + return -errno; + + ret = fscanf(fp, "%s", val); + if (ret < 0) + return -errno; + if (ret != 1) + return -EIO; + + ret = fclose(fp); + if (ret) + return -errno; + + return 0; +} + +static int +cnxk_gpio_read_attr_int(char *attr, int *val) +{ + char buf[CNXK_GPIO_BUFSZ]; + int ret; + + ret = cnxk_gpio_read_attr(attr, buf); + if (ret) + return ret; + + ret = sscanf(buf, "%d", val); + if (ret < 0) + return -errno; + + return 0; +} + +static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { +}; + +static int +cnxk_gpio_probe(struct rte_vdev_device *dev) +{ + char name[RTE_RAWDEV_NAME_MAX_LEN]; + struct cnxk_gpiochip *gpiochip; + struct rte_rawdev *rawdev; + char buf[CNXK_GPIO_BUFSZ]; + int ret; + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + cnxk_gpio_format_name(name, sizeof(name)); + rawdev = rte_rawdev_pmd_allocate(name, sizeof(*gpiochip), + rte_socket_id()); + if (!rawdev) { + RTE_LOG(ERR, PMD, "failed to allocate %s rawdev", name); + return -ENOMEM; + } + + rawdev->dev_ops = &cnxk_gpio_rawdev_ops; + rawdev->device = &dev->device; + rawdev->driver_name = dev->device.name; + + gpiochip = rawdev->dev_private; + cnxk_gpio_set_defaults(gpiochip); + + /* defaults may be overwritten by this call */ + ret = cnxk_gpio_parse_args(gpiochip, dev->device.devargs); + if (ret) + goto out; + + /* read gpio base */ + snprintf(buf, sizeof(buf), "%s/gpiochip%d/base", CNXK_GPIO_CLASS_PATH, + gpiochip->num); + ret = cnxk_gpio_read_attr_int(buf, &gpiochip->base); + if (ret) { + RTE_LOG(ERR, PMD, "failed to read %s", buf); + goto out; + } + + /* read number of available gpios */ + snprintf(buf, sizeof(buf), "%s/gpiochip%d/ngpio", CNXK_GPIO_CLASS_PATH, + gpiochip->num); + ret = cnxk_gpio_read_attr_int(buf, &gpiochip->num_gpios); + if (ret) { + RTE_LOG(ERR, PMD, "failed to read %s", buf); + goto out; + } + + gpiochip->gpios = rte_calloc(NULL, gpiochip->num_gpios, + sizeof(struct cnxk_gpio *), 0); + if (!gpiochip->gpios) { + RTE_LOG(ERR, PMD, "failed to allocate gpios memory"); + ret = -ENOMEM; + goto out; + } + + return 0; +out: + rte_rawdev_pmd_release(rawdev); + + return ret; +} + +static int +cnxk_gpio_remove(struct rte_vdev_device *dev) +{ + char name[RTE_RAWDEV_NAME_MAX_LEN]; + struct cnxk_gpiochip *gpiochip; + struct rte_rawdev *rawdev; + + RTE_SET_USED(dev); + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + + cnxk_gpio_format_name(name, sizeof(name)); + rawdev = rte_rawdev_pmd_get_named_dev(name); + if (!rawdev) + return -ENODEV; + + gpiochip = rawdev->dev_private; + rte_free(gpiochip->gpios); + rte_rawdev_pmd_release(rawdev); + + return 0; +} + +static struct rte_vdev_driver cnxk_gpio_drv = { + .probe = cnxk_gpio_probe, + .remove = cnxk_gpio_remove, +}; + +RTE_PMD_REGISTER_VDEV(cnxk_gpio, cnxk_gpio_drv); +RTE_PMD_REGISTER_PARAM_STRING(cnxk_gpio, "gpiochip="); diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.h b/drivers/raw/cnxk_gpio/cnxk_gpio.h new file mode 100644 index 0000000000..4dae8316ba --- /dev/null +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#ifndef _CNXK_GPIO_H_ +#define _CNXK_GPIO_H_ + +struct cnxk_gpiochip; + +struct cnxk_gpio { + struct cnxk_gpiochip *gpiochip; + int num; +}; + +struct cnxk_gpiochip { + int num; + int base; + int num_gpios; + struct cnxk_gpio **gpios; +}; + +#endif /* _CNXK_GPIO_H_ */ diff --git a/drivers/raw/cnxk_gpio/meson.build b/drivers/raw/cnxk_gpio/meson.build new file mode 100644 index 0000000000..9a7e716c1e --- /dev/null +++ b/drivers/raw/cnxk_gpio/meson.build @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(C) 2021 Marvell. +# + +deps += ['bus_vdev', 'common_cnxk', 'rawdev', 'kvargs'] +sources = files( + 'cnxk_gpio.c', +) diff --git a/drivers/raw/cnxk_gpio/version.map b/drivers/raw/cnxk_gpio/version.map new file mode 100644 index 0000000000..4a76d1d52d --- /dev/null +++ b/drivers/raw/cnxk_gpio/version.map @@ -0,0 +1,3 @@ +DPDK_21 { + local: *; +}; diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build index 87694a758e..05e7de1bfe 100644 --- a/drivers/raw/meson.build +++ b/drivers/raw/meson.build @@ -7,6 +7,7 @@ endif drivers = [ 'cnxk_bphy', + 'cnxk_gpio', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga', From patchwork Mon Dec 13 08:17:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105085 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 D9F25A0032; Mon, 13 Dec 2021 09:18:34 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 88EEE4115A; Mon, 13 Dec 2021 09:18:24 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 69AA941154 for ; Mon, 13 Dec 2021 09:18:22 +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 1BD7iF7H026887; Mon, 13 Dec 2021 00:18:21 -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=y/tSvvNwEnncsN2kR7xugnjwtwNx2hrhuTX8EjitIrA=; b=WRNCBRTwjlYRBm3l/qTB2VKfplkLJCKSWfEFFEMMm9TQbbLjcjKXfug8g4iTaq9ZwD44 APfdqKb6lNzX2AFvxQVbw7GK75NbBpMf+w3uF4h+QR/i42RwZpNE0llZMSb90ydjh75D 1PfDFLmknletIsymRJEWVy/U386HvrR0TOXGFEHI4wyw78utXgWCWtDeieDORFl25G1B YDV+LIj8wysivswzfqbXM1RY7uYeMuOd+xuzst1U3NFi62yCK0KXhqUFZTX6HwBX/s4K RYhdLAm16mrfVLkI/X5/x50WxMvYZ0goAldz+ulMY/SArOdrte1B61yCTjDF/ziVx65x 1w== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3cx21kg3a1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Dec 2021 00:18:21 -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; Mon, 13 Dec 2021 00:18:20 -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; Mon, 13 Dec 2021 00:18:20 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id F0CEC3F7045; Mon, 13 Dec 2021 00:18:18 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v3 02/10] raw/cnxk_gpio: support reading default queue conf Date: Mon, 13 Dec 2021 09:17:24 +0100 Message-ID: <20211213081732.2096334-3-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213081732.2096334-1-tduszynski@marvell.com> References: <20211128154442.4029049-1-tduszynski@marvell.com> <20211213081732.2096334-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: qqYCim6DNS0GtzAUrZO3st0Z1UNqLblr X-Proofpoint-ORIG-GUID: qqYCim6DNS0GtzAUrZO3st0Z1UNqLblr X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-13_03,2021-12-10_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 bcce4b8fb7..deedf98af2 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -134,7 +134,26 @@ cnxk_gpio_read_attr_int(char *attr, int *val) return 0; } +static int +cnxk_gpio_queue_def_conf(struct rte_rawdev *dev, uint16_t queue_id, + rte_rawdev_obj_t queue_conf, size_t queue_conf_size) +{ + unsigned int *conf; + + RTE_SET_USED(dev); + RTE_SET_USED(queue_id); + + if (queue_conf_size != sizeof(*conf)) + return -EINVAL; + + conf = (unsigned int *)queue_conf; + *conf = 1; + + return 0; +} + static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { + .queue_def_conf = cnxk_gpio_queue_def_conf, }; static int From patchwork Mon Dec 13 08:17:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105086 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 5A6ABA0032; Mon, 13 Dec 2021 09:18:43 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9031A41160; Mon, 13 Dec 2021 09:18:26 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id E093A410F7 for ; Mon, 13 Dec 2021 09:18:24 +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 1BD7ieBb027462; Mon, 13 Dec 2021 00:18:24 -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=2PdDO2puk5a9kyO6OXvkYcq46iBe2v88QI8pIt7OSoE=; b=BVuBLRUvy3P4RJFWohMNumX8ZcMjyojkFoSuEkI+N+1A3mIe3kvSliLUEMBPKV5FQCkw 2ttXP02Ci0jmSK+lbnDtgFghxHm7a0sDrmqqn62DITaTr6TfWF7agoucTDChnK72HKHB 0Gy7iSy/4UHiSnLqRxOBAgdVYTu9NecLfvC4yk9YDLfwA+nFbIaFvJcmddb20gcD53ed GRLTHmmyIqGHZlXSIQKAWKphySw0fLf/gpy2GGu4vMLAJDr8gLacrwoquSubCwiEp/HV uuQOSb1+2LBv3UfrE1t9VkTWxoluSG+jw+o+N8NaP/pzTdj/OfNQgQJod2fxhnpa6xgn Xw== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3cx21kg3a8-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Dec 2021 00:18:24 -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; Mon, 13 Dec 2021 00:18:22 -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; Mon, 13 Dec 2021 00:18:22 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id E59683F7045; Mon, 13 Dec 2021 00:18:20 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v3 03/10] raw/cnxk_gpio: support reading queue count Date: Mon, 13 Dec 2021 09:17:25 +0100 Message-ID: <20211213081732.2096334-4-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213081732.2096334-1-tduszynski@marvell.com> References: <20211128154442.4029049-1-tduszynski@marvell.com> <20211213081732.2096334-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: m5ysNmkpc8-JCFquIy6EHbS87jda5f2k X-Proofpoint-ORIG-GUID: m5ysNmkpc8-JCFquIy6EHbS87jda5f2k X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-13_03,2021-12-10_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 deedf98af2..84be7f861e 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -152,8 +152,17 @@ cnxk_gpio_queue_def_conf(struct rte_rawdev *dev, uint16_t queue_id, return 0; } +static uint16_t +cnxk_gpio_queue_count(struct rte_rawdev *dev) +{ + struct cnxk_gpiochip *gpiochip = dev->dev_private; + + return gpiochip->num_gpios; +} + static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .queue_def_conf = cnxk_gpio_queue_def_conf, + .queue_count = cnxk_gpio_queue_count, }; static int From patchwork Mon Dec 13 08:17:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105087 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 02AA7A0032; Mon, 13 Dec 2021 09:18:51 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 9EB8341169; Mon, 13 Dec 2021 09:18:28 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 9E08141163 for ; Mon, 13 Dec 2021 09:18:26 +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 1BD7ivXU027548; Mon, 13 Dec 2021 00:18:25 -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=QotEOaZQG2ChvN+vW+KkzXs9G1ZLoyfYlYVwxcYKaqo=; b=S4yKr6mURLRWMpAq+L3XinjHjQeEbyhdrXHjJ0Q8/YG3rpR9PGHvZLbVs16YFpMf8Pi7 7EaayX5B4lvK7rq7J/tW6slJRyfC+mI5ac0KQKvlJy6j+bdF4NSGw76hL/10gZp/lJUA Yw8BtWEcEqeMZ/5q+hrIQFusPk7raD+SNNPTTk1fvPhUuJj3Fdful4Hyb7fOi7cuH/Gv CPjIoE0VjZXaXYdz5kHUGsZP+B8DRBAaoXQcMD4cDrUwSGrMvKzds0Ku276OWfB6Hkmj jhSUJqM1qsGIBnuXPcRfp5M3fUxZkPZvhzF4uOEEoILEHyYRrph2Hq+AKEqRpBpYVFxN iQ== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3cx21kg3ab-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Dec 2021 00:18:25 -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; Mon, 13 Dec 2021 00:18:24 -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; Mon, 13 Dec 2021 00:18:24 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id DA1663F7045; Mon, 13 Dec 2021 00:18:22 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v3 04/10] raw/cnxk_gpio: support queue setup Date: Mon, 13 Dec 2021 09:17:26 +0100 Message-ID: <20211213081732.2096334-5-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213081732.2096334-1-tduszynski@marvell.com> References: <20211128154442.4029049-1-tduszynski@marvell.com> <20211213081732.2096334-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: TAz-GvA4lDMAE8gMw4X34lpD_CZvGT7T X-Proofpoint-ORIG-GUID: TAz-GvA4lDMAE8gMw4X34lpD_CZvGT7T X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-13_03,2021-12-10_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for queue setup. Signed-off-by: Tomasz Duszynski --- drivers/raw/cnxk_gpio/cnxk_gpio.c | 80 +++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index 84be7f861e..98b5dd9cd8 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -134,6 +134,85 @@ cnxk_gpio_read_attr_int(char *attr, int *val) return 0; } +static int +cnxk_gpio_write_attr(const char *attr, const char *val) +{ + FILE *fp; + int ret; + + if (!val) + return -EINVAL; + + fp = fopen(attr, "w"); + if (!fp) + return -errno; + + ret = fprintf(fp, "%s", val); + if (ret < 0) { + fclose(fp); + return ret; + } + + ret = fclose(fp); + if (ret) + return -errno; + + return 0; +} + +static int +cnxk_gpio_write_attr_int(const char *attr, int val) +{ + char buf[CNXK_GPIO_BUFSZ]; + + snprintf(buf, sizeof(buf), "%d", val); + + return cnxk_gpio_write_attr(attr, buf); +} + +static struct cnxk_gpio * +cnxk_gpio_lookup(struct cnxk_gpiochip *gpiochip, uint16_t queue) +{ + if (queue >= gpiochip->num_gpios) + return NULL; + + return gpiochip->gpios[queue]; +} + +static int +cnxk_gpio_queue_setup(struct rte_rawdev *dev, uint16_t queue_id, + rte_rawdev_obj_t queue_conf, size_t queue_conf_size) +{ + struct cnxk_gpiochip *gpiochip = dev->dev_private; + char buf[CNXK_GPIO_BUFSZ]; + struct cnxk_gpio *gpio; + int ret; + + RTE_SET_USED(queue_conf); + RTE_SET_USED(queue_conf_size); + + gpio = cnxk_gpio_lookup(gpiochip, queue_id); + if (gpio) + return -EEXIST; + + gpio = rte_zmalloc(NULL, sizeof(*gpio), 0); + if (!gpio) + return -ENOMEM; + gpio->num = queue_id + gpiochip->base; + gpio->gpiochip = gpiochip; + + snprintf(buf, sizeof(buf), "%s/export", CNXK_GPIO_CLASS_PATH); + ret = cnxk_gpio_write_attr_int(buf, gpio->num); + if (ret) { + rte_free(gpio); + return ret; + } + + gpiochip->gpios[queue_id] = gpio; + + return 0; +} + static int cnxk_gpio_queue_def_conf(struct rte_rawdev *dev, uint16_t queue_id, rte_rawdev_obj_t queue_conf, size_t queue_conf_size) @@ -163,6 +242,7 @@ cnxk_gpio_queue_count(struct rte_rawdev *dev) static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .queue_def_conf = cnxk_gpio_queue_def_conf, .queue_count = cnxk_gpio_queue_count, + .queue_setup = cnxk_gpio_queue_setup, }; static int From patchwork Mon Dec 13 08:17:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105088 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 477C1A00BE; Mon, 13 Dec 2021 09:19:00 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id E727B4117D; Mon, 13 Dec 2021 09:18:29 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 2DC8A4115B for ; Mon, 13 Dec 2021 09:18:28 +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 1BD7ivXV027548; Mon, 13 Dec 2021 00:18:27 -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=DW4c+fNHa/uY2Bc6O9ghtZ6jqoUP0elvOJSaHm6/AQo=; b=FQ7sP6qbaQGf+CdhzJxIXDi30+iQ+NbP0Rdep441RU35dYjdeF7R6ERkd7ngyKlVvIyL CL3ZgRHqCcw0ihieHk6T9N3ubVRKAy4/yR2FWDzI+XGykdRDYv6jAN8SMeod50ZsYTiz +p6nOme9qJ/HFtDnmhjqE9FKiacJf41sPE3pVxXkHuS9HTnBWOwCvAy7enrK14I2bcKl F0aKMbh4GOi6vyHgACxHa7obqjAA14/I4f6hnFLfpcrWYNN+E7KVCTRSNqm+fsDrldD/ memr3s4A11hkgc16zTjrnBFyAifB1Q4Q/Xd82D/d0nn5HTRIDj9466iUWw50OIQFX8uC fw== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3cx21kg3ah-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Dec 2021 00:18:27 -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; Mon, 13 Dec 2021 00:18:26 -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; Mon, 13 Dec 2021 00:18:26 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id C61863F7045; Mon, 13 Dec 2021 00:18:24 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v3 05/10] raw/cnxk_gpio: support queue release Date: Mon, 13 Dec 2021 09:17:27 +0100 Message-ID: <20211213081732.2096334-6-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213081732.2096334-1-tduszynski@marvell.com> References: <20211128154442.4029049-1-tduszynski@marvell.com> <20211213081732.2096334-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: 18sFCMIkV23r4rqh1K8rcQ9EiOXkaDHb X-Proofpoint-ORIG-GUID: 18sFCMIkV23r4rqh1K8rcQ9EiOXkaDHb X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-13_03,2021-12-10_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 98b5dd9cd8..8ac3c5e1be 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -213,6 +213,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) @@ -243,6 +266,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 @@ -316,6 +340,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); @@ -328,6 +354,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 Mon Dec 13 08:17:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105089 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 83FEAA00BE; Mon, 13 Dec 2021 09:19:06 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 06B4D41172; Mon, 13 Dec 2021 09:18:32 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 19F6541182 for ; Mon, 13 Dec 2021 09:18:30 +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 1BD7ie54027465; Mon, 13 Dec 2021 00:18:29 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=pHp5ojAjQaPgZmEd5vZxwlC+20QD1GPC9QQsC8/Hn8k=; b=lDlw68/v43qKqzD6hV+Re9s5fkRMQa7eMYdeJ6k2ghryKwP6TJZ9i9XQOUpdxd/2K4ws sQNLds3PGDrQ7V8io1aquQXBb0Uj6eT4psy+C36BMTeG8sq0iKMABQKP2GZ3korAg79h an5iA4THHQh9ErMP404kwMe38yADcfwGguIJjLQ2A18AhvhX59Kp+3m7ruoMOUB0RwQc l+eVR2xf+hcumYktH8DfgxwqFSNEcej9mxFCcFGeS3wmL9GsZ9wxUBOpjA7OHDVvcmIp OIhr4E/cDdAnR/3JGyT4NGf2qXe0mDaqMIB1cpzqTCnfNwJm4TT4Ffo+sqoMoqFdx4q7 Rg== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3cx21kg3aq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Dec 2021 00:18:29 -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; Mon, 13 Dec 2021 00:18:28 -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; Mon, 13 Dec 2021 00:18:28 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id B1B4D3F7045; Mon, 13 Dec 2021 00:18:26 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v3 06/10] raw/cnxk_gpio: support enqueuing buffers Date: Mon, 13 Dec 2021 09:17:28 +0100 Message-ID: <20211213081732.2096334-7-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213081732.2096334-1-tduszynski@marvell.com> References: <20211128154442.4029049-1-tduszynski@marvell.com> <20211213081732.2096334-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: QwwLfVQVCBm7svhXTYC4YQW_3WzY_p29 X-Proofpoint-ORIG-GUID: QwwLfVQVCBm7svhXTYC4YQW_3WzY_p29 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-13_03,2021-12-10_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 | 46 +++++++++++++++++++++++ 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, 86 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 8ac3c5e1be..9477e7293a 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" @@ -262,7 +263,52 @@ cnxk_gpio_queue_count(struct rte_rawdev *dev) return gpiochip->num_gpios; } +static int +cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf) +{ + struct cnxk_gpio_msg *msg = rbuf->buf_addr; + void *rsp = NULL; + + switch (msg->type) { + default: + return -EINVAL; + } + + /* get rid of last response if any */ + if (gpio->rsp) { + RTE_LOG(WARNING, PMD, "previous response got overwritten\n"); + rte_free(gpio->rsp); + } + gpio->rsp = rsp; + + return ret; +} + +static int +cnxk_gpio_enqueue_bufs(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers, + unsigned int count, rte_rawdev_obj_t context) +{ + struct cnxk_gpiochip *gpiochip = dev->dev_private; + unsigned int queue = (size_t)context; + struct cnxk_gpio *gpio; + int ret; + + if (count == 0) + return 0; + + gpio = cnxk_gpio_lookup(gpiochip, queue); + if (!gpio) + return -ENODEV; + + ret = cnxk_gpio_process_buf(gpio, buffers[0]); + if (ret) + return ret; + + return 1; +} + static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { + .enqueue_bufs = cnxk_gpio_enqueue_bufs, .queue_def_conf = cnxk_gpio_queue_def_conf, .queue_count = cnxk_gpio_queue_count, .queue_setup = cnxk_gpio_queue_setup, diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.h b/drivers/raw/cnxk_gpio/cnxk_gpio.h index 4dae8316ba..6b54ebe6e6 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.h +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.h @@ -9,6 +9,7 @@ struct cnxk_gpiochip; struct cnxk_gpio { struct cnxk_gpiochip *gpiochip; + void *rsp; int num; }; diff --git a/drivers/raw/cnxk_gpio/meson.build b/drivers/raw/cnxk_gpio/meson.build index 9a7e716c1e..3fbfdd838c 100644 --- a/drivers/raw/cnxk_gpio/meson.build +++ b/drivers/raw/cnxk_gpio/meson.build @@ -6,3 +6,4 @@ deps += ['bus_vdev', 'common_cnxk', 'rawdev', 'kvargs'] sources = files( 'cnxk_gpio.c', ) +headers = files('rte_pmd_cnxk_gpio.h') diff --git a/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h b/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h new file mode 100644 index 0000000000..c71065e10c --- /dev/null +++ b/drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#ifndef _RTE_PMD_CNXK_GPIO_H_ +#define _RTE_PMD_CNXK_GPIO_H_ + +/** + * @file rte_pmd_cnxk_gpio.h + * + * Marvell GPIO PMD specific structures and interface + * + * This API allows applications to manage GPIOs in user space along with + * installing interrupt handlers for low latency signal processing. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** Available message types */ +enum cnxk_gpio_msg_type { + /** Invalid message type */ + CNXK_GPIO_MSG_TYPE_INVALID, +}; + +struct cnxk_gpio_msg { + /** Message type */ + enum cnxk_gpio_msg_type type; + /** Message data passed to PMD or received from PMD */ + void *data; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_PMD_CNXK_GPIO_H_ */ From patchwork Mon Dec 13 08:17:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105090 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 A5BDFA00BE; Mon, 13 Dec 2021 09:19:12 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2847F41174; Mon, 13 Dec 2021 09:18:34 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 28ABD41186 for ; Mon, 13 Dec 2021 09:18:32 +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 1BD7ivXY027548; Mon, 13 Dec 2021 00:18:31 -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=lNB44mul1+4+xAAUmEjQYqJDBZzEo6G4GAsbV3WOtPw=; b=Ey4CrV5uaUBaAeQrOokzXW+8xJbsOq4ZYOLqlUCKr3/a4Fy/g3kVi6EW0iAvxpLvVJu8 0H6LaRjmYiD+6slitg3Wlt+6nmvujCxrfSeNOcGt9rGtBOu3nPXUueji/PSeUL0OKBlh 7+4zdA2aD5WiOjsraOzEl0Y9q4JANFfzcqJjmGSQYWSRvSJ7qkiXLEl4s2ZHZhyrgAvf /XfPY0LKMXrIbpK87fjOX47zLZhqk6DSWfL2imme0C3tc4NBK0WvVVRb/8fxfUwXItdQ lmahfeP3cDiErpYdYXzsQPtCYeWiRrVXo6acZHnEo9kKeZRBp+ipagGAvCycgevPuU4w +g== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3cx21kg3b8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Dec 2021 00:18:31 -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; Mon, 13 Dec 2021 00:18:30 -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; Mon, 13 Dec 2021 00:18:30 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 9F8523F7045; Mon, 13 Dec 2021 00:18:28 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v3 07/10] raw/cnxk_gpio: support dequeuing buffers Date: Mon, 13 Dec 2021 09:17:29 +0100 Message-ID: <20211213081732.2096334-8-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213081732.2096334-1-tduszynski@marvell.com> References: <20211128154442.4029049-1-tduszynski@marvell.com> <20211213081732.2096334-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: FbnfdwoSR3MvsmJFh_q_s3236WbbFoeU X-Proofpoint-ORIG-GUID: FbnfdwoSR3MvsmJFh_q_s3236WbbFoeU X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-13_03,2021-12-10_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 9477e7293a..570d9abb17 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -307,8 +307,34 @@ cnxk_gpio_enqueue_bufs(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers, return 1; } +static int +cnxk_gpio_dequeue_bufs(struct rte_rawdev *dev, struct rte_rawdev_buf **buffers, + unsigned int count, rte_rawdev_obj_t context) +{ + struct cnxk_gpiochip *gpiochip = dev->dev_private; + unsigned int queue = (size_t)context; + struct cnxk_gpio *gpio; + + if (count == 0) + return 0; + + gpio = cnxk_gpio_lookup(gpiochip, queue); + if (!gpio) + return -ENODEV; + + if (gpio->rsp) { + buffers[0]->buf_addr = gpio->rsp; + gpio->rsp = NULL; + + return 1; + } + + return 0; +} + static const struct rte_rawdev_ops cnxk_gpio_rawdev_ops = { .enqueue_bufs = cnxk_gpio_enqueue_bufs, + .dequeue_bufs = cnxk_gpio_dequeue_bufs, .queue_def_conf = cnxk_gpio_queue_def_conf, .queue_count = cnxk_gpio_queue_count, .queue_setup = cnxk_gpio_queue_setup, From patchwork Mon Dec 13 08:17:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105091 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 64B12A00BE; Mon, 13 Dec 2021 09:19:18 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 21836411AE; Mon, 13 Dec 2021 09:18:37 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 6AAB7411AB for ; Mon, 13 Dec 2021 09:18:35 +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 1BD7ieBh027462; Mon, 13 Dec 2021 00:18:34 -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=9HTx+j9gv++dHX8+mYYIDXMbafD6V05bUDwhO2LCMYE=; b=S2YSJrBCzWrin9CKfu/KUduSwQUQHOx8+jG4QpCVjPr7u74EjIv/LZELvrGsI5i/hnvx 7yZGJEbxLjKeXVNj/yxjjP6/E3/ff8B8wyumlwZCH7D6b12eNSa1iSankwUEZ4/Y8sq2 cXgSc2Ay/xxfGX36yLUpApyrNsRx6Qsdel5VYRC2/a4WK3gRjGDQrmnll36UxpsvaPeX jzvuC9wp5CvxOvx6yDzmHiC5/WcjbK8BpGARcyrXzThPi+gdO9faQoJnDLVtFFRseabf WIyx6reu23XLLCjXJ80gOrdAItq8kT10t/z1pJfamUlIQFwqrLp6Dtho9FjQJhTnk6MY 5Q== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3cx21kg3bw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Dec 2021 00:18:34 -0800 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 13 Dec 2021 00:18: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; Mon, 13 Dec 2021 00:18:32 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 947E73F7045; Mon, 13 Dec 2021 00:18:30 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v3 08/10] raw/cnxk_gpio: support standard GPIO operations Date: Mon, 13 Dec 2021 09:17:30 +0100 Message-ID: <20211213081732.2096334-9-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213081732.2096334-1-tduszynski@marvell.com> References: <20211128154442.4029049-1-tduszynski@marvell.com> <20211213081732.2096334-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: usbhVl242GKbDDz0Lxf7dV6t3_7unhIz X-Proofpoint-ORIG-GUID: usbhVl242GKbDDz0Lxf7dV6t3_7unhIz X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-13_03,2021-12-10_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 | 146 +++++++++++ drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h | 279 +++++++++++++++++++++- 3 files changed, 521 insertions(+), 2 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 570d9abb17..fa5b1359d0 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -263,13 +263,159 @@ cnxk_gpio_queue_count(struct rte_rawdev *dev) return gpiochip->num_gpios; } +static const struct { + enum cnxk_gpio_pin_edge edge; + const char *name; +} cnxk_gpio_edge_name[] = { + { CNXK_GPIO_PIN_EDGE_NONE, "none" }, + { CNXK_GPIO_PIN_EDGE_FALLING, "falling" }, + { CNXK_GPIO_PIN_EDGE_RISING, "rising" }, + { CNXK_GPIO_PIN_EDGE_BOTH, "both" }, +}; + +static const char * +cnxk_gpio_edge_to_name(enum cnxk_gpio_pin_edge edge) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(cnxk_gpio_edge_name); i++) { + if (cnxk_gpio_edge_name[i].edge == edge) + return cnxk_gpio_edge_name[i].name; + } + + return NULL; +} + +static enum cnxk_gpio_pin_edge +cnxk_gpio_name_to_edge(const char *name) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(cnxk_gpio_edge_name); i++) { + if (!strcmp(cnxk_gpio_edge_name[i].name, name)) + break; + } + + return cnxk_gpio_edge_name[i].edge; +} + +static const struct { + enum cnxk_gpio_pin_dir dir; + const char *name; +} cnxk_gpio_dir_name[] = { + { CNXK_GPIO_PIN_DIR_IN, "in" }, + { CNXK_GPIO_PIN_DIR_OUT, "out" }, + { CNXK_GPIO_PIN_DIR_HIGH, "high" }, + { CNXK_GPIO_PIN_DIR_LOW, "low" }, +}; + +static const char * +cnxk_gpio_dir_to_name(enum cnxk_gpio_pin_dir dir) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(cnxk_gpio_dir_name); i++) { + if (cnxk_gpio_dir_name[i].dir == dir) + return cnxk_gpio_dir_name[i].name; + } + + return NULL; +} + +static enum cnxk_gpio_pin_dir +cnxk_gpio_name_to_dir(const char *name) +{ + unsigned int i; + + for (i = 0; i < RTE_DIM(cnxk_gpio_dir_name); i++) { + if (!strcmp(cnxk_gpio_dir_name[i].name, name)) + break; + } + + return cnxk_gpio_dir_name[i].dir; +} + static int cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf) { struct cnxk_gpio_msg *msg = rbuf->buf_addr; + enum cnxk_gpio_pin_edge edge; + enum cnxk_gpio_pin_dir dir; + char buf[CNXK_GPIO_BUFSZ]; void *rsp = NULL; + int ret, 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 Mon Dec 13 08:17:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105092 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 51799A00BE; Mon, 13 Dec 2021 09:19:25 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1BA87411C9; Mon, 13 Dec 2021 09:18:38 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com [67.231.148.174]) by mails.dpdk.org (Postfix) with ESMTP id D418D411AE for ; Mon, 13 Dec 2021 09:18:35 +0100 (CET) Received: from pps.filterd (m0045849.ppops.net [127.0.0.1]) by mx0a-0016f401.pphosted.com (8.16.1.2/8.16.1.2) with ESMTP id 1BD1Z3CR027207; Mon, 13 Dec 2021 00:18:35 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=2GsUaHA13oXR8LSXQblVbmLoyEAJ0/CSsnxrR9Gqd7k=; b=Wwr9Vocvb9XgO87wZgf6cf/tArE7XlDaXdQQpCcalj0+YRfsBQyz4cI+T53JqkESyEu7 V+4M3PV/tB0qv4jW0kQyZRbVmzyVoc8dzpZXm9BoQAxQ73ySXQt3ZjUgYwyPxOPzkAE7 Bbeq4L9WOXMNqQvuqC5IKbMCe6xIDF+46B1UjG35OHd3FmHBmVUf9y9aHe4VxbS//Ki0 nBb+jRj8apHM6QiwqbdFtc+haiCDPzoNhK2n8C2oUnudDh9Y0XvTbx7EXWbtIzaKvIyg IK5Q8vAQ5CEhp0+4ZPHVLM/FzgicxYcItiOY2Zq0y571ytQTyEaEKko55XPxAzoljBkz zw== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0a-0016f401.pphosted.com (PPS) with ESMTPS id 3cwvmys385-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Dec 2021 00:18:34 -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; Mon, 13 Dec 2021 00:18:34 -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; Mon, 13 Dec 2021 00:18:33 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 7FA2E3F7045; Mon, 13 Dec 2021 00:18:32 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v3 09/10] raw/cnxk_gpio: support custom irq handlers Date: Mon, 13 Dec 2021 09:17:31 +0100 Message-ID: <20211213081732.2096334-10-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213081732.2096334-1-tduszynski@marvell.com> References: <20211128154442.4029049-1-tduszynski@marvell.com> <20211213081732.2096334-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: gjBjDExJWt7k7nUmh4TjmxIJkG54KzUj X-Proofpoint-ORIG-GUID: gjBjDExJWt7k7nUmh4TjmxIJkG54KzUj X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-13_03,2021-12-10_01,2021-12-02_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add support for custom interrupt handlers. Custom interrupt handlers bypass kernel completely and are meant for fast and low latency access to GPIO state. Signed-off-by: Tomasz Duszynski --- doc/guides/rawdevs/cnxk_gpio.rst | 21 +++ drivers/raw/cnxk_gpio/cnxk_gpio.c | 37 ++++ drivers/raw/cnxk_gpio/cnxk_gpio.h | 8 + drivers/raw/cnxk_gpio/cnxk_gpio_irq.c | 216 ++++++++++++++++++++++ drivers/raw/cnxk_gpio/meson.build | 1 + drivers/raw/cnxk_gpio/rte_pmd_cnxk_gpio.h | 116 ++++++++++++ 6 files changed, 399 insertions(+) create mode 100644 drivers/raw/cnxk_gpio/cnxk_gpio_irq.c diff --git a/doc/guides/rawdevs/cnxk_gpio.rst b/doc/guides/rawdevs/cnxk_gpio.rst index f6c3c942c5..ad93ec0d44 100644 --- a/doc/guides/rawdevs/cnxk_gpio.rst +++ b/doc/guides/rawdevs/cnxk_gpio.rst @@ -161,3 +161,24 @@ Payload contains an integer set to 0 or 1. The latter means inverted logic is turned on. Consider using ``rte_pmd_gpio_get_pin_active_low()`` wrapper. + +Request interrupt +~~~~~~~~~~~~~~~~~ + +Message is used to install custom interrupt handler. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_REGISTER_IRQ``. + +Payload needs to be set to ``struct cnxk_gpio_irq`` which describes interrupt +being requested. + +Consider using ``rte_pmd_gpio_register_gpio()`` wrapper. + +Free interrupt +~~~~~~~~~~~~~~ + +Message is used to remove installed interrupt handler. + +Message must have type set to ``CNXK_GPIO_MSG_TYPE_UNREGISTER_IRQ``. + +Consider using ``rte_pmd_gpio_unregister_gpio()`` wrapper. diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c b/drivers/raw/cnxk_gpio/cnxk_gpio.c index fa5b1359d0..f3fdd5a380 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -335,6 +335,28 @@ cnxk_gpio_name_to_dir(const char *name) return cnxk_gpio_dir_name[i].dir; } +static int +cnxk_gpio_register_irq(struct cnxk_gpio *gpio, struct cnxk_gpio_irq *irq) +{ + int ret; + + ret = cnxk_gpio_irq_request(gpio->num - gpio->gpiochip->base, irq->cpu); + if (ret) + return ret; + + gpio->handler = irq->handler; + gpio->data = irq->data; + gpio->cpu = irq->cpu; + + return 0; +} + +static int +cnxk_gpio_unregister_irq(struct cnxk_gpio *gpio) +{ + return cnxk_gpio_irq_free(gpio->num - gpio->gpiochip->base); +} + static int cnxk_gpio_process_buf(struct cnxk_gpio *gpio, struct rte_rawdev_buf *rbuf) { @@ -416,6 +438,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; } @@ -519,6 +548,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); @@ -577,10 +610,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 Mon Dec 13 08:17:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Duszynski X-Patchwork-Id: 105093 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 ABD01A00BE; Mon, 13 Dec 2021 09:19:34 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 99E33411F3; Mon, 13 Dec 2021 09:18:39 +0100 (CET) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id EE567411B6 for ; Mon, 13 Dec 2021 09:18:37 +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 1BD7ieBi027462; Mon, 13 Dec 2021 00:18:37 -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=c1rfaLL+yXUE9CduwwtwdclxX609xvN9WlURF6YlHx0=; b=OXQkSHhDWJ0ZjX9BeSAh0tbq84oS1AUXozDlC7Khy5Wl1NGVF5qRYBN0Bni1n/cekzjG lfTAXSuADDwF8vwWiy+9wqBLeRhyY8qmlMa2tRa9qE4T5UzvaBWYc9F7xnW45Z4n/b3d EOUwf6TNNshQdiXoI/rbR0KITxvX1Ymc+cSac4ZvLDjr09Q9QdDUYMaRkqA+73cAnT1D bxMOwwraW2hRRWpLuYF9Nj7Igu/MoJmEAqTOilQwJ7wg7DtN8jL44RL33kPRSmI+uO9b E2mJ8WbEBxNRUV30pF8nFg22XozMffNrOwDa5QcTdQ12ganCE4PIS4Y7rz22RSm3AK+E ow== Received: from dc5-exch01.marvell.com ([199.233.59.181]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3cx21kg3c8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Mon, 13 Dec 2021 00:18:37 -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; Mon, 13 Dec 2021 00:18:35 -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; Mon, 13 Dec 2021 00:18:35 -0800 Received: from localhost.localdomain (unknown [10.28.34.39]) by maili.marvell.com (Postfix) with ESMTP id 6CFE03F7045; Mon, 13 Dec 2021 00:18:34 -0800 (PST) From: Tomasz Duszynski To: CC: , , Tomasz Duszynski Subject: [PATCH v3 10/10] raw/cnxk_gpio: support selftest Date: Mon, 13 Dec 2021 09:17:32 +0100 Message-ID: <20211213081732.2096334-11-tduszynski@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211213081732.2096334-1-tduszynski@marvell.com> References: <20211128154442.4029049-1-tduszynski@marvell.com> <20211213081732.2096334-1-tduszynski@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: rkb4US5nCeqT1-PvWW5SY-oydGE7xrQf X-Proofpoint-ORIG-GUID: rkb4US5nCeqT1-PvWW5SY-oydGE7xrQf X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-13_03,2021-12-10_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 f3fdd5a380..c9f87a315a 100644 --- a/drivers/raw/cnxk_gpio/cnxk_gpio.c +++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c @@ -514,6 +514,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')