Thread (5 messages) read the whole thread 5 messages, 3 authors, 2026-05-05
STALE80d

[RFC PATCH 1/1] xe/xe_mctp_mailbox: Add support for MCTP transport over mailbox

From: Badal Nilawar <hidden>
Date: 2026-05-04 19:23:29
Also in: dri-devel, intel-xe, lkml
Subsystem: drm drivers, intel drm xe driver (lunar lake and newer), the rest · Maintainers: David Airlie, Simona Vetter, Matthew Brost, Thomas Hellström, Rodrigo Vivi, Linus Torvalds

Add support for MCTP transport over the Intel vendor-specific mailbox
protocol to enable in-band firmware updates for GPU/AMC via PLDM

Signed-off-by: Badal Nilawar <redacted>
---
 drivers/gpu/drm/xe/Makefile          |   1 +
 drivers/gpu/drm/xe/xe_device.c       |   3 +
 drivers/gpu/drm/xe/xe_device_types.h |   4 +
 drivers/gpu/drm/xe/xe_mctp_mailbox.c | 186 +++++++++++++++++++++++++++
 drivers/gpu/drm/xe/xe_mctp_mailbox.h |  14 ++
 5 files changed, 208 insertions(+)
 create mode 100644 drivers/gpu/drm/xe/xe_mctp_mailbox.c
 create mode 100644 drivers/gpu/drm/xe/xe_mctp_mailbox.h
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index 09661f079d03..d427152bc3fd 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -89,6 +89,7 @@ xe-y += xe_bb.o \
 	xe_late_bind_fw.o \
 	xe_lrc.o \
 	xe_mem_pool.o \
+	xe_mctp_mailbox.o \
 	xe_migrate.o \
 	xe_mmio.o \
 	xe_mmio_gem.o \
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 4b45b617a039..ebf456f580d1 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -49,6 +49,7 @@
 #include "xe_i2c.h"
 #include "xe_irq.h"
 #include "xe_late_bind_fw.h"
+#include "xe_mctp_mailbox.h"
 #include "xe_mmio.h"
 #include "xe_module.h"
 #include "xe_nvm.h"
@@ -1065,6 +1066,8 @@ int xe_device_probe(struct xe_device *xe)
 	for_each_gt(gt, xe, id)
 		xe_gt_sanitize_freq(gt);
 
+	xe_mctp_mailbox_init(xe);
+
 	xe_vsec_init(xe);
 
 	err = xe_sriov_init_late(xe);
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 89437de3001a..9cfe70428c71 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -38,6 +38,7 @@
 struct drm_pagemap_shrinker;
 struct intel_display;
 struct intel_dg_nvm_dev;
+struct xe_mctp_mailbox;
 struct xe_ggtt;
 struct xe_i2c;
 struct xe_pat_ops;
@@ -500,6 +501,9 @@ struct xe_device {
 		struct llist_head async_list;
 	} bo_device;
 
+	/** @mctp_mailbox: mctp mailbox */
+	struct xe_mctp_mailbox *mctp_mailbox;
+
 	/** @pmu: performance monitoring unit */
 	struct xe_pmu pmu;
 
diff --git a/drivers/gpu/drm/xe/xe_mctp_mailbox.c b/drivers/gpu/drm/xe/xe_mctp_mailbox.c
new file mode 100644
index 000000000000..f1a81208a9a1
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_mctp_mailbox.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: MIT
+/*
+ * MCTP-over-MAILBOX transport for Xe.
+ *
+ * Copyright 2026 Intel Corporation
+ */
+
+#include "xe_device_types.h"
+
+#include <linux/netdevice.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
+
+#include <net/mctp.h>
+#include <net/mctpdevice.h>
+#include <net/pkt_sched.h>
+
+#include <uapi/linux/if_arp.h>
+
+#include "xe_mctp_mailbox.h"
+
+#define XE_MCTP_MAILBOX_RX_POLL_MS 100
+
+/** @mctp_mailbox: Struct for mctp over mailbox */
+struct xe_mctp_mailbox {
+	/** @mctp_mailbox.netdev: network device  */
+	struct net_device *netdev;
+	/** @running: true while netdev is opened */
+	bool running;
+	/** @work: worker to handle mctp requests from firmware */
+	struct delayed_work work;
+	/** @wq: workqueue to schecdule mctp rx worker */
+	struct workqueue_struct *wq;
+};
+
+/*
+ * mailbox protocol is interrupt free so for receive path i.e. endpoint to host
+ * there is no irq available so rx handler need to be polled in worker periodically.
+ */
+static void mctp_mailbox_rx_handler(struct work_struct *work)
+{
+	struct xe_mctp_mailbox *mctp_mailbox =
+		container_of(work, struct xe_mctp_mailbox, work.work);
+	struct net_device *netdev = mctp_mailbox->netdev;
+
+	if (!netdev)
+		return;
+
+	dev_hold(netdev);
+
+	/*
+	 * if (mctp_mailbox_rx_ready()) {
+	 * Get data over MAILBOX
+	 * Allocate skb and copy rx data to skb
+	 * Queue skb to upper layer
+	 * netif_rx(skb);
+	}
+	 */
+	dev_put(netdev);
+
+	if (mctp_mailbox->running)
+		queue_delayed_work(mctp_mailbox->wq, &mctp_mailbox->work,
+				   msecs_to_jiffies(XE_MCTP_MAILBOX_RX_POLL_MS));
+}
+
+static netdev_tx_t mctp_mailbox_start_xmit(struct sk_buff *skb,
+					   struct net_device *dev)
+{
+	/* RFC stub: send skb over MAILBOX */
+	dev_dstats_tx_dropped(dev);
+	kfree_skb(skb);
+
+	return NETDEV_TX_OK;
+}
+
+static int mctp_mailbox_open(struct net_device *dev)
+{
+	struct xe_mctp_mailbox *mctp_mailbox = netdev_priv(dev);
+
+	mctp_mailbox->running = true;
+	netif_start_queue(dev);
+
+	queue_delayed_work(mctp_mailbox->wq, &mctp_mailbox->work, 0);
+
+	return 0;
+}
+
+static int mctp_mailbox_stop(struct net_device *dev)
+{
+	struct xe_mctp_mailbox *mctp_mailbox = netdev_priv(dev);
+
+	mctp_mailbox->running = false;
+	netif_stop_queue(dev);
+
+	cancel_delayed_work_sync(&mctp_mailbox->work);
+	flush_workqueue(mctp_mailbox->wq);
+
+	return 0;
+}
+
+static const struct net_device_ops mctp_mailbox_netdev_ops = {
+	.ndo_start_xmit = mctp_mailbox_start_xmit,
+	.ndo_open = mctp_mailbox_open,
+	.ndo_stop = mctp_mailbox_stop,
+};
+
+static void mctp_mailbox_netdev_setup(struct net_device *dev)
+{
+	/* Populate netdev structure */
+	dev->type = ARPHRD_MCTP;
+	/*
+	 *	dev->mtu = MCTP_MAILBOX_MTU_MIN;
+	 *	dev->min_mtu = MCTP_MAILBOX_MTU_MIN;
+	 *	dev->max_mtu = MCTP_MAILBOX_MTU_MAX;
+	 *
+	 *	dev->hard_header_len = sizeof(struct mctp_mailbox_hdr);
+	 *	dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
+	 */
+	dev->flags = IFF_NOARP;
+	dev->netdev_ops = &mctp_mailbox_netdev_ops;
+	dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS;
+}
+
+static void xe_mctp_mailbox_fini(void *arg)
+{
+	struct xe_device *xe = arg;
+	struct xe_mctp_mailbox *mctp_mailbox = xe->mctp_mailbox;
+	struct net_device *netdev;
+
+	if (!mctp_mailbox)
+		return;
+
+	netdev = mctp_mailbox->netdev;
+	if (!netdev) {
+		xe->mctp_mailbox = NULL;
+		return;
+	}
+
+	if (mctp_mailbox->wq) {
+		mctp_mailbox->running = false;
+		cancel_delayed_work_sync(&mctp_mailbox->work);
+		destroy_workqueue(mctp_mailbox->wq);
+		mctp_mailbox->wq = NULL;
+	}
+
+	xe->mctp_mailbox = NULL;
+	mctp_unregister_netdev(netdev);
+	free_netdev(netdev);
+}
+
+int xe_mctp_mailbox_init(struct xe_device *xe)
+{
+	struct xe_mctp_mailbox *mctp_mailbox;
+	struct net_device *netdev;
+	int ret, err;
+
+	netdev = alloc_netdev(sizeof(*mctp_mailbox), "mctp_mailbox%d", NET_NAME_ENUM,
+			      mctp_mailbox_netdev_setup);
+	if (!netdev)
+		return -ENOMEM;
+
+	SET_NETDEV_DEV(netdev, xe->drm.dev);
+	mctp_mailbox = netdev_priv(netdev);
+	mctp_mailbox->netdev = netdev;
+
+	ret = mctp_register_netdev(netdev, NULL, MCTP_PHYS_BINDING_VENDOR);
+	if (ret) {
+		free_netdev(netdev);
+		return ret;
+	}
+
+	INIT_DELAYED_WORK(&mctp_mailbox->work, mctp_mailbox_rx_handler);
+	mctp_mailbox->wq = alloc_ordered_workqueue("mctp-mailbox-ordered-wq", 0);
+	if (!mctp_mailbox->wq) {
+		mctp_unregister_netdev(netdev);
+		free_netdev(netdev);
+		return -ENOMEM;
+	}
+
+	xe->mctp_mailbox = mctp_mailbox;
+	err = devm_add_action_or_reset(xe->drm.dev, xe_mctp_mailbox_fini, xe);
+	if (err)
+		return err;
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/xe/xe_mctp_mailbox.h b/drivers/gpu/drm/xe/xe_mctp_mailbox.h
new file mode 100644
index 000000000000..318ae173aaa1
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_mctp_mailbox.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ *
+ * Copyright 2026 Intel Corporation
+ */
+
+#ifndef _XE_MCTP_MAILBOX_H_
+#define _XE_MCTP_MAILBOX_H_
+
+struct xe_device;
+
+int xe_mctp_mailbox_init(struct xe_device *xe);
+
+#endif /* _XE_MCTP_MAILBOX_H_ */
-- 
2.54.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help