From: Jaspinder Budhal <j-budhal@ti.com>
To: <ogabbay@kernel.org>, <corbet@lwn.net>, <skhan@linuxfoundation.org>
Cc: <dri-devel@lists.freedesktop.org>, <linux-doc@vger.kernel.org>,
<linux-kernel@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>, <j-budhal@ti.com>,
<srk@ti.com>, <s-vadapalli@ti.com>
Subject: [RFC PATCH 2/2] accel/npac: Add NPAC client driver
Date: Wed, 1 Jul 2026 11:55:05 +0530 [thread overview]
Message-ID: <20260701062505.1091840-3-j-budhal@ti.com> (raw)
In-Reply-To: <20260701062505.1091840-1-j-budhal@ti.com>
Add the Linux client driver for the Network Packet ACcelerator (NPAC).
The driver communicates with the NPAC host driver via RPMsg,
allowing offloading of ethernet-related packet processing tasks.
The driver provides the basic framework for receiving offload commands
via IOCTL and communicating with the NPAC hardware accelerator.
Signed-off-by: Jaspinder Budhal <j-budhal@ti.com>
---
drivers/accel/Kconfig | 1 +
drivers/accel/Makefile | 1 +
drivers/accel/npac/Kconfig | 13 ++
drivers/accel/npac/Makefile | 3 +
drivers/accel/npac/npac_drv.c | 218 ++++++++++++++++++++++++++++++++++
5 files changed, 236 insertions(+)
create mode 100644 drivers/accel/npac/Kconfig
create mode 100644 drivers/accel/npac/Makefile
create mode 100644 drivers/accel/npac/npac_drv.c
diff --git a/drivers/accel/Kconfig b/drivers/accel/Kconfig
index bdf48ccafcf2..a6d8c1ebfcf1 100644
--- a/drivers/accel/Kconfig
+++ b/drivers/accel/Kconfig
@@ -28,6 +28,7 @@ source "drivers/accel/amdxdna/Kconfig"
source "drivers/accel/ethosu/Kconfig"
source "drivers/accel/habanalabs/Kconfig"
source "drivers/accel/ivpu/Kconfig"
+source "drivers/accel/npac/Kconfig"
source "drivers/accel/qaic/Kconfig"
source "drivers/accel/rocket/Kconfig"
diff --git a/drivers/accel/Makefile b/drivers/accel/Makefile
index 1d3a7251b950..0df7b9f2ae18 100644
--- a/drivers/accel/Makefile
+++ b/drivers/accel/Makefile
@@ -4,5 +4,6 @@ obj-$(CONFIG_DRM_ACCEL_AMDXDNA) += amdxdna/
obj-$(CONFIG_DRM_ACCEL_ARM_ETHOSU) += ethosu/
obj-$(CONFIG_DRM_ACCEL_HABANALABS) += habanalabs/
obj-$(CONFIG_DRM_ACCEL_IVPU) += ivpu/
+obj-$(CONFIG_DRM_ACCEL_NPAC_CLIENT) += npac/
obj-$(CONFIG_DRM_ACCEL_QAIC) += qaic/
obj-$(CONFIG_DRM_ACCEL_ROCKET) += rocket/
\ No newline at end of file
diff --git a/drivers/accel/npac/Kconfig b/drivers/accel/npac/Kconfig
new file mode 100644
index 000000000000..a9543ac2c7aa
--- /dev/null
+++ b/drivers/accel/npac/Kconfig
@@ -0,0 +1,13 @@
+config DRM_ACCEL_NPAC_CLIENT
+ tristate "NPAC Client Driver"
+ depends on DRM_ACCEL
+ depends on RPMSG
+ help
+ This driver is the NPAC (Network Packet ACcelerator) client,
+ communicating with the NPAC host driver running on a remote
+ processor over RPMsg. The driver registers with the DRM accelerator
+ framework and exposes /dev/accel/accel* as the userspace interface
+ for ACL rule offload operations.
+ If you have a device with NPAC and wish to use it with this
+ driver, say M to compile this driver as a module, or Y to
+ compile it into the kernel.
diff --git a/drivers/accel/npac/Makefile b/drivers/accel/npac/Makefile
new file mode 100644
index 000000000000..89f4773d7041
--- /dev/null
+++ b/drivers/accel/npac/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_DRM_ACCEL_NPAC_CLIENT) += npac_drv.o
diff --git a/drivers/accel/npac/npac_drv.c b/drivers/accel/npac/npac_drv.c
new file mode 100644
index 000000000000..7516382ba74b
--- /dev/null
+++ b/drivers/accel/npac/npac_drv.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0-only OR MIT
+/*
+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/
+ */
+
+#include <drm/drm_accel.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_file.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_ioctl.h>
+#include <linux/completion.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/rpmsg.h>
+
+#define NPAC_RPMSG_SERVICE_NAME "ti.npac"
+#define NPAC_ACK_TIMEOUT_MS 1000
+
+/**
+ * enum npac_acl_cmd - IOCTL command numbers for NPAC ACL operations.
+ */
+enum npac_acl_cmd {
+ /** @NPAC_ACL_ADD_RULE: Add an ACL rule. */
+ NPAC_ACL_ADD_RULE,
+
+ /** @NPAC_ACL_DELETE_RULE: Delete an ACL rule. */
+ NPAC_ACL_DELETE_RULE,
+};
+
+/**
+ * enum npac_acl_match_type - Match field selector for an ACL rule.
+ */
+enum npac_acl_match_type {
+ /** @NPAC_ACL_MATCH_SRC_IPV4: Match on source IPv4 address. */
+ NPAC_ACL_MATCH_SRC_IPV4 = 1,
+
+ /** @NPAC_ACL_MATCH_DST_IPV4: Match on destination IPv4 address. */
+ NPAC_ACL_MATCH_DST_IPV4,
+
+ /** @NPAC_ACL_MATCH_SRC_MAC: Match on source MAC address. */
+ NPAC_ACL_MATCH_SRC_MAC,
+
+ /** @NPAC_ACL_MATCH_DST_MAC: Match on destination MAC address. */
+ NPAC_ACL_MATCH_DST_MAC,
+};
+
+/**
+ * enum npac_acl_verdict - Action to apply when an ACL rule matches.
+ */
+enum npac_acl_verdict {
+ /** @NPAC_ACL_VERDICT_ALLOW: Accept the matched packet. */
+ NPAC_ACL_VERDICT_ALLOW = 1,
+
+ /** @NPAC_ACL_VERDICT_DROP: Drop the matched packet. */
+ NPAC_ACL_VERDICT_DROP,
+};
+
+/* Sized for the largest match field: a 6-byte MAC address. */
+#define NPAC_ACL_MATCH_VALUE_MAX 6
+
+struct npac_acl_offload_rule {
+ __u32 match_type;
+ __u32 verdict;
+ __u8 match_value[NPAC_ACL_MATCH_VALUE_MAX];
+};
+
+#define DRM_IOCTL_NPAC_ACL_ADD_RULE \
+ DRM_IOWR(DRM_COMMAND_BASE + NPAC_ACL_ADD_RULE, struct npac_acl_offload_rule)
+
+#define DRM_IOCTL_NPAC_ACL_DELETE_RULE \
+ DRM_IOWR(DRM_COMMAND_BASE + NPAC_ACL_DELETE_RULE, struct npac_acl_offload_rule)
+
+struct npac_device {
+ struct drm_device drm;
+ struct rpmsg_device *rpdev;
+ struct mutex req_lock; /* lock for request */
+ struct completion ack;
+};
+
+static inline struct npac_device *drm_to_npac_device(struct drm_device *dev)
+{
+ return container_of(dev, struct npac_device, drm);
+}
+
+static int npac_add_rule_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct npac_device *npac = drm_to_npac_device(dev);
+ struct npac_acl_offload_rule *rule = data;
+ int ret;
+
+ dev_dbg(dev->dev, "add rule ioctl received\n");
+
+ mutex_lock(&npac->req_lock);
+ reinit_completion(&npac->ack);
+ ret = rpmsg_send(npac->rpdev->ept, rule, sizeof(*rule));
+ if (ret) {
+ dev_err(dev->dev, "rpmsg_send failed: %d\n", ret);
+ mutex_unlock(&npac->req_lock);
+ return ret;
+ }
+ if (!wait_for_completion_timeout(&npac->ack,
+ msecs_to_jiffies(NPAC_ACK_TIMEOUT_MS))) {
+ dev_err(dev->dev, "ack timed out\n");
+ mutex_unlock(&npac->req_lock);
+ return -ETIMEDOUT;
+ }
+ mutex_unlock(&npac->req_lock);
+ return 0;
+}
+
+static int npac_delete_rule_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file)
+{
+ struct npac_device *npac = drm_to_npac_device(dev);
+ struct npac_acl_offload_rule *rule = data;
+ int ret;
+
+ dev_dbg(dev->dev, "delete rule ioctl received\n");
+
+ mutex_lock(&npac->req_lock);
+ reinit_completion(&npac->ack);
+ ret = rpmsg_send(npac->rpdev->ept, rule, sizeof(*rule));
+ if (ret) {
+ dev_err(dev->dev, "rpmsg_send failed: %d\n", ret);
+ mutex_unlock(&npac->req_lock);
+ return ret;
+ }
+ if (!wait_for_completion_timeout(&npac->ack,
+ msecs_to_jiffies(NPAC_ACK_TIMEOUT_MS))) {
+ dev_err(dev->dev, "ack timed out\n");
+ mutex_unlock(&npac->req_lock);
+ return -ETIMEDOUT;
+ }
+ mutex_unlock(&npac->req_lock);
+ return 0;
+}
+
+static const struct drm_ioctl_desc npac_drm_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(NPAC_ACL_ADD_RULE, npac_add_rule_ioctl, DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF_DRV(NPAC_ACL_DELETE_RULE, npac_delete_rule_ioctl, DRM_ROOT_ONLY),
+};
+
+DEFINE_DRM_ACCEL_FOPS(npac_fops);
+
+static const struct drm_driver npac_drm_driver = {
+ .driver_features = DRIVER_COMPUTE_ACCEL,
+ .ioctls = npac_drm_ioctls,
+ .num_ioctls = ARRAY_SIZE(npac_drm_ioctls),
+ .fops = &npac_fops,
+ .name = "npac",
+ .desc = "NPAC Client Driver",
+};
+
+static int npac_cb(struct rpmsg_device *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ struct npac_device *npac = dev_get_drvdata(&rpdev->dev);
+
+ dev_dbg(&rpdev->dev, "ack received\n");
+ complete(&npac->ack);
+ return 0;
+}
+
+static int npac_probe(struct rpmsg_device *rpdev)
+{
+ struct npac_device *npac;
+ int ret;
+
+ npac = devm_drm_dev_alloc(&rpdev->dev, &npac_drm_driver,
+ struct npac_device, drm);
+ if (IS_ERR(npac))
+ return PTR_ERR(npac);
+
+ npac->rpdev = rpdev;
+ mutex_init(&npac->req_lock);
+ init_completion(&npac->ack);
+ dev_set_drvdata(&rpdev->dev, npac);
+
+ ret = drm_dev_register(&npac->drm, 0);
+ if (ret) {
+ dev_err(&rpdev->dev, "Failed to register DRM accel device: %d\n", ret);
+ return ret;
+ }
+
+ dev_info(&rpdev->dev, "NPAC Client driver probed\n");
+ return 0;
+}
+
+static void npac_remove(struct rpmsg_device *rpdev)
+{
+ struct npac_device *npac = dev_get_drvdata(&rpdev->dev);
+
+ drm_dev_unplug(&npac->drm);
+
+ dev_info(&rpdev->dev, "NPAC Client Driver removed\n");
+}
+
+static struct rpmsg_device_id npac_id_table[] = {
+ { .name = NPAC_RPMSG_SERVICE_NAME },
+ {},
+};
+MODULE_DEVICE_TABLE(rpmsg, npac_id_table);
+
+static struct rpmsg_driver npac_driver = {
+ .drv.name = KBUILD_MODNAME,
+ .id_table = npac_id_table,
+ .probe = npac_probe,
+ .callback = npac_cb,
+ .remove = npac_remove,
+};
+
+module_rpmsg_driver(npac_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("NPAC Client Driver");
+MODULE_AUTHOR("Jaspinder Budhal <j-budhal@ti.com>");
--
2.34.1
prev parent reply other threads:[~2026-07-01 6:25 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 6:25 [RFC PATCH 0/2] Add NPAC driver to accel subsystem Jaspinder Budhal
2026-07-01 6:25 ` [RFC PATCH 1/2] Documentation: accel: Add NPAC client driver documentation Jaspinder Budhal
2026-07-01 6:25 ` Jaspinder Budhal [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260701062505.1091840-3-j-budhal@ti.com \
--to=j-budhal@ti.com \
--cc=corbet@lwn.net \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ogabbay@kernel.org \
--cc=s-vadapalli@ti.com \
--cc=skhan@linuxfoundation.org \
--cc=srk@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox