mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Damien Riégel" <damien.riegel@silabs.com>
To: greybus-dev@lists.linaro.org, Johan Hovold <johan@kernel.org>,
	Alex Elder <elder@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-kernel@vger.kernel.org
Cc: "Silicon Labs Kernel Team" <linux-devel@silabs.com>,
	"Damien Riégel" <damien.riegel@silabs.com>
Subject: [PATCH v3 12/14] greybus: cpc: let host device drivers dequeue TX frames
Date: Thu, 12 Feb 2026 09:43:50 -0500	[thread overview]
Message-ID: <20260212144352.93043-13-damien.riegel@silabs.com> (raw)
In-Reply-To: <20260212144352.93043-1-damien.riegel@silabs.com>

This lets the CPC host device drivers dequeue frames when it's
convenient for them to do so, instead of forcing each to them to
implement a queue to store pending skbs.

The callback is changed from `transmit` to `wake_tx` and let CPC core
notify these drivers when there is something to transmit.

Signed-off-by: Damien Riégel <damien.riegel@silabs.com>
---
 drivers/greybus/cpc/host.c | 74 ++++++++++++++++++++++++++++++++++++--
 drivers/greybus/cpc/host.h | 12 +++++--
 2 files changed, 81 insertions(+), 5 deletions(-)

diff --git a/drivers/greybus/cpc/host.c b/drivers/greybus/cpc/host.c
index 9a0f8158504..d5ceb657fa9 100644
--- a/drivers/greybus/cpc/host.c
+++ b/drivers/greybus/cpc/host.c
@@ -161,6 +161,7 @@ static struct gb_hd_driver cpc_gb_driver = {
 static void cpc_hd_init(struct cpc_host_device *cpc_hd)
 {
 	mutex_init(&cpc_hd->lock);
+	skb_queue_head_init(&cpc_hd->tx_queue);
 }
 
 struct cpc_host_device *cpc_hd_create(struct cpc_hd_driver *driver, struct device *parent)
@@ -168,7 +169,7 @@ struct cpc_host_device *cpc_hd_create(struct cpc_hd_driver *driver, struct devic
 	struct cpc_host_device *cpc_hd;
 	struct gb_host_device *hd;
 
-	if (!driver->transmit) {
+	if (!driver->wake_tx) {
 		dev_err(parent, "missing mandatory callback\n");
 		return ERR_PTR(-EINVAL);
 	}
@@ -237,13 +238,80 @@ EXPORT_SYMBOL_GPL(cpc_hd_rcvd);
  * @cpc_hd: Host device to send SKB over.
  * @skb: SKB to send.
  */
-int cpc_hd_send_skb(struct cpc_host_device *cpc_hd, struct sk_buff *skb)
+void cpc_hd_send_skb(struct cpc_host_device *cpc_hd, struct sk_buff *skb)
 {
 	const struct cpc_hd_driver *drv = cpc_hd->driver;
 
-	return drv->transmit(cpc_hd, skb);
+	mutex_lock(&cpc_hd->lock);
+	skb_queue_tail(&cpc_hd->tx_queue, skb);
+	mutex_unlock(&cpc_hd->lock);
+
+	drv->wake_tx(cpc_hd);
 }
 
+/**
+ * cpc_hd_tx_queue_empty() - Check if transmit queue is empty.
+ * @cpc_hd: CPC Host Device.
+ *
+ * Return: True if transmit queue is empty, false otherwise.
+ */
+bool cpc_hd_tx_queue_empty(struct cpc_host_device *cpc_hd)
+{
+	bool empty;
+
+	mutex_lock(&cpc_hd->lock);
+	empty = skb_queue_empty(&cpc_hd->tx_queue);
+	mutex_unlock(&cpc_hd->lock);
+
+	return empty;
+}
+EXPORT_SYMBOL_GPL(cpc_hd_tx_queue_empty);
+
+/**
+ * cpc_hd_dequeue() - Get the next SKB that was queued for transmission.
+ * @cpc_hd: CPC Host Device.
+ *
+ * Get an SKB that was previously queued by cpc_hd_send_skb().
+ *
+ * Return: An SKB, or %NULL if queue was empty.
+ */
+struct sk_buff *cpc_hd_dequeue(struct cpc_host_device *cpc_hd)
+{
+	struct sk_buff *skb;
+
+	mutex_lock(&cpc_hd->lock);
+	skb = skb_dequeue(&cpc_hd->tx_queue);
+	mutex_unlock(&cpc_hd->lock);
+
+	return skb;
+}
+EXPORT_SYMBOL_GPL(cpc_hd_dequeue);
+
+/**
+ * cpc_hd_dequeue_many() - Get the next max_frames SKBs that were queued for transmission.
+ * @cpc_hd: CPC host device.
+ * @frame_list: Caller-provided sk_buff_head to fill with dequeued frames.
+ * @max_frames: Maximum number of frames to dequeue.
+ *
+ * Return: Number of frames actually dequeued.
+ */
+u32 cpc_hd_dequeue_many(struct cpc_host_device *cpc_hd, struct sk_buff_head *frame_list,
+			unsigned int max_frames)
+{
+	struct sk_buff *skb;
+	unsigned int count = 0;
+
+	mutex_lock(&cpc_hd->lock);
+	while (count < max_frames && (skb = skb_dequeue(&cpc_hd->tx_queue))) {
+		skb_queue_tail(frame_list, skb);
+		count++;
+	}
+	mutex_unlock(&cpc_hd->lock);
+
+	return count;
+}
+EXPORT_SYMBOL_GPL(cpc_hd_dequeue_many);
+
 MODULE_DESCRIPTION("Greybus over CPC");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Silicon Laboratories, Inc.");
diff --git a/drivers/greybus/cpc/host.h b/drivers/greybus/cpc/host.h
index 8f05877b2be..ee6a86de309 100644
--- a/drivers/greybus/cpc/host.h
+++ b/drivers/greybus/cpc/host.h
@@ -9,6 +9,7 @@
 #include <linux/device.h>
 #include <linux/greybus.h>
 #include <linux/mutex.h>
+#include <linux/skbuff.h>
 #include <linux/types.h>
 
 #define GB_CPC_MSG_SIZE_MAX 4096
@@ -18,7 +19,7 @@ struct cpc_cport;
 struct cpc_host_device;
 
 struct cpc_hd_driver {
-	int (*transmit)(struct cpc_host_device *hd, struct sk_buff *skb);
+	int (*wake_tx)(struct cpc_host_device *cpc_hd);
 };
 
 /**
@@ -34,6 +35,8 @@ struct cpc_host_device {
 
 	struct mutex lock; /* Synchronize access to cports */
 	struct cpc_cport *cports[GB_CPC_NUM_CPORTS];
+
+	struct sk_buff_head tx_queue;
 };
 
 static inline struct device *cpc_hd_dev(struct cpc_host_device *cpc_hd)
@@ -47,6 +50,11 @@ void cpc_hd_put(struct cpc_host_device *cpc_hd);
 void cpc_hd_del(struct cpc_host_device *cpc_hd);
 void cpc_hd_rcvd(struct cpc_host_device *cpc_hd, struct sk_buff *skb);
 
-int cpc_hd_send_skb(struct cpc_host_device *cpc_hd, struct sk_buff *skb);
+void cpc_hd_send_skb(struct cpc_host_device *cpc_hd, struct sk_buff *skb);
+
+bool cpc_hd_tx_queue_empty(struct cpc_host_device *cpc_hd);
+struct sk_buff *cpc_hd_dequeue(struct cpc_host_device *cpc_hd);
+u32 cpc_hd_dequeue_many(struct cpc_host_device *cpc_hd, struct sk_buff_head *frame_list,
+			unsigned int max_frames);
 
 #endif
-- 
2.52.0


  parent reply	other threads:[~2026-02-12 15:01 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-12 14:43 [PATCH v3 00/14] greybus: introduce CPC as transport layer Damien Riégel
2026-02-12 14:43 ` [PATCH v3 01/14] greybus: cpc: add minimal CPC Host Device infrastructure Damien Riégel
2026-02-12 14:43 ` [PATCH v3 02/14] greybus: cpc: introduce CPC cport structure Damien Riégel
2026-02-12 14:43 ` [PATCH v3 03/14] greybus: cpc: use socket buffers instead of gb_message in TX path Damien Riégel
2026-02-12 14:43 ` [PATCH v3 04/14] greybus: cpc: pack cport ID in Greybus header Damien Riégel
2026-02-12 14:43 ` [PATCH v3 05/14] greybus: cpc: switch RX path to socket buffers Damien Riégel
2026-02-12 14:43 ` [PATCH v3 06/14] greybus: cpc: introduce CPC header structure Damien Riégel
2026-02-12 14:43 ` [PATCH v3 07/14] greybus: cpc: account for CPC header size in RX and TX path Damien Riégel
2026-02-12 14:43 ` [PATCH v3 08/14] greybus: cpc: add and validate sequence numbers Damien Riégel
2026-02-12 14:43 ` [PATCH v3 09/14] greybus: cpc: acknowledge all incoming messages Damien Riégel
2026-02-12 14:43 ` [PATCH v3 10/14] greybus: cpc: use holding queue instead of sending out immediately Damien Riégel
2026-02-13  6:44   ` kernel test robot
2026-02-12 14:43 ` [PATCH v3 11/14] greybus: cpc: honour remote's RX window Damien Riégel
2026-02-13 21:56   ` kernel test robot
2026-02-12 14:43 ` Damien Riégel [this message]
2026-02-12 14:43 ` [PATCH v3 13/14] greybus: cpc: add private data pointer in CPC Host Device Damien Riégel
2026-02-12 14:43 ` [PATCH v3 14/14] greybus: cpc: add CPC SDIO host driver Damien Riégel
2026-02-13  0:31   ` kernel test robot
2026-02-13  9:35   ` Jérôme Pouiller
2026-02-13 16:00     ` Damien Riégel
2026-02-19 14:38       ` Damien Riégel

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=20260212144352.93043-13-damien.riegel@silabs.com \
    --to=damien.riegel@silabs.com \
    --cc=elder@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=greybus-dev@lists.linaro.org \
    --cc=johan@kernel.org \
    --cc=linux-devel@silabs.com \
    --cc=linux-kernel@vger.kernel.org \
    /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

all inboxes | Powered by JetHome®