All of lore.kernel.org
 help / color / mirror / Atom feed
From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
To: mhi@lists.linux.dev
Cc: hemantk@codeaurora.org, bbhatt@codeaurora.org,
	quic_jhugo@quicinc.com, vinod.koul@linaro.org,
	bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org,
	skananth@codeaurora.org, vpernami@codeaurora.org,
	vbadigan@codeaurora.org, linux-arm-msm@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Subject: [PATCH 18/20] bus: mhi: ep: Add support for queueing SKBs over MHI bus
Date: Thu,  2 Dec 2021 17:05:50 +0530	[thread overview]
Message-ID: <20211202113553.238011-19-manivannan.sadhasivam@linaro.org> (raw)
In-Reply-To: <20211202113553.238011-1-manivannan.sadhasivam@linaro.org>

Add support for queueing SKBs over MHI bus in the MHI endpoint stack.
The mhi_ep_queue_skb() API will be used by the client networking drivers
to queue the SKBs to the host over MHI.

Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/bus/mhi/ep/main.c | 132 ++++++++++++++++++++++++++++++++++++++
 include/linux/mhi_ep.h    |  12 ++++
 2 files changed, 144 insertions(+)

diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
index 26d551eb63ce..cc3da846ed36 100644
--- a/drivers/bus/mhi/ep/main.c
+++ b/drivers/bus/mhi/ep/main.c
@@ -522,6 +522,138 @@ int mhi_ep_process_tre_ring(struct mhi_ep_ring *ring, struct mhi_ep_ring_element
 	return ret;
 }
 
+static void skip_to_next_td(struct mhi_ep_chan *mhi_chan, struct mhi_ep_ring *ring)
+{
+	struct mhi_ep_ring_element *el;
+	u32 td_boundary_reached = 0;
+
+	mhi_chan->skip_td = 1;
+	el = &ring->ring_cache[ring->rd_offset];
+	while (ring->rd_offset != ring->wr_offset) {
+		if (td_boundary_reached) {
+			mhi_chan->skip_td = 0;
+			break;
+		}
+
+		if (!MHI_EP_TRE_GET_CHAIN(el))
+			td_boundary_reached = 1;
+
+		mhi_ep_ring_inc_index(ring);
+		el = &ring->ring_cache[ring->rd_offset];
+	}
+}
+
+int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir,
+		     struct sk_buff *skb, size_t len, enum mhi_flags mflags)
+{
+	struct mhi_ep_chan *mhi_chan = (dir == DMA_FROM_DEVICE) ? mhi_dev->dl_chan :
+							       mhi_dev->ul_chan;
+	struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl;
+	enum mhi_ev_ccs code = MHI_EV_CC_INVALID;
+	struct mhi_ep_ring_element *el;
+	u64 write_to_loc, skip_tre = 0;
+	struct mhi_ep_ring *ring;
+	size_t bytes_to_write;
+	void __iomem *tre_buf;
+	phys_addr_t tre_phys;
+	void *read_from_loc;
+	u32 buf_remaining;
+	u32 tre_len;
+	int ret = 0;
+
+	if (dir == DMA_TO_DEVICE)
+		return -EINVAL;
+
+	buf_remaining = len;
+	ring = &mhi_cntrl->mhi_chan[mhi_chan->chan].ring;
+
+	mutex_lock(&mhi_chan->lock);
+	if (mhi_chan->skip_td)
+		skip_to_next_td(mhi_chan, ring);
+
+	do {
+		/* Don't process the transfer ring if the channel is not in RUNNING state */
+		if (mhi_chan->state != MHI_CH_STATE_RUNNING) {
+			dev_err(&mhi_chan->mhi_dev->dev, "Channel not available");
+			ret = -ENODEV;
+			goto err_exit;
+		}
+
+		if (mhi_ep_queue_is_empty(mhi_dev, dir)) {
+			dev_err(&mhi_chan->mhi_dev->dev, "TRE not available!\n");
+			ret = -EINVAL;
+			goto err_exit;
+		}
+
+		el = &ring->ring_cache[ring->rd_offset];
+		tre_len = MHI_EP_TRE_GET_LEN(el);
+		if (skb->len > tre_len) {
+			dev_err(&mhi_chan->mhi_dev->dev, "Buffer size (%d) is too large!\n",
+				skb->len);
+			ret = -ENOMEM;
+			goto err_exit;
+		}
+
+		bytes_to_write = min(buf_remaining, tre_len);
+		read_from_loc = skb->data;
+		write_to_loc = MHI_EP_TRE_GET_PTR(el);
+
+		tre_buf = mhi_cntrl->alloc_addr(mhi_cntrl, &tre_phys, bytes_to_write);
+		if (!tre_buf) {
+			dev_err(&mhi_chan->mhi_dev->dev, "Failed to allocate TRE buffer\n");
+			ret = -ENOMEM;
+			goto err_exit;
+		}
+
+		ret = mhi_cntrl->map_addr(mhi_cntrl, tre_phys, write_to_loc, bytes_to_write);
+		if (ret) {
+			dev_err(&mhi_chan->mhi_dev->dev, "Failed to map TRE buffer\n");
+			goto err_tre_free;
+		}
+
+		dev_dbg(&mhi_chan->mhi_dev->dev, "Writing %d bytes", bytes_to_write);
+		memcpy_toio(tre_buf, read_from_loc, bytes_to_write);
+
+		mhi_cntrl->unmap_addr(mhi_cntrl, tre_phys);
+		mhi_cntrl->free_addr(mhi_cntrl, tre_phys, tre_buf, bytes_to_write);
+
+		buf_remaining -= bytes_to_write;
+		if (buf_remaining) {
+			if (!MHI_EP_TRE_GET_CHAIN(el))
+				code = MHI_EV_CC_OVERFLOW;
+			else if (MHI_EP_TRE_GET_IEOB(el))
+				code = MHI_EV_CC_EOB;
+		} else {
+			if (MHI_EP_TRE_GET_CHAIN(el))
+				skip_tre = 1;
+			code = MHI_EV_CC_EOT;
+		}
+
+		ret = mhi_ep_send_completion_event(mhi_cntrl, ring, bytes_to_write, code);
+		if (ret) {
+			dev_err(&mhi_chan->mhi_dev->dev, "Error sending completion event");
+			goto err_exit;
+		}
+
+		mhi_ep_ring_inc_index(ring);
+	} while (!skip_tre && buf_remaining);
+
+	if (skip_tre)
+		skip_to_next_td(mhi_chan, ring);
+
+	mutex_unlock(&mhi_chan->lock);
+
+	return 0;
+
+err_tre_free:
+	mhi_cntrl->free_addr(mhi_cntrl, tre_phys, tre_buf, bytes_to_write);
+err_exit:
+	mutex_unlock(&mhi_chan->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mhi_ep_queue_skb);
+
 static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl)
 {
 	struct device *dev = &mhi_cntrl->mhi_dev->dev;
diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h
index 260a181d3fab..a7715f8066ed 100644
--- a/include/linux/mhi_ep.h
+++ b/include/linux/mhi_ep.h
@@ -274,4 +274,16 @@ void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl);
  */
 bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir);
 
+/**
+ * mhi_ep_queue_skb - Send SKBs to host over MHI Endpoint
+ * @mhi_dev: Device associated with the channels
+ * @dir: DMA direction for the channel
+ * @skb: Buffer for holding SKBs
+ * @len: Buffer length
+ * @mflags: MHI Endpoint transfer flags used for the transfer
+ *
+ * Return: 0 if the SKBs has been sent successfully, a negative error code otherwise.
+ */
+int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir,
+		     struct sk_buff *skb, size_t len, enum mhi_flags mflags);
 #endif
-- 
2.25.1


  parent reply	other threads:[~2021-12-02 11:38 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-02 11:35 [PATCH 00/20] Add initial support for MHI endpoint stack Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 01/20] bus: mhi: Move host MHI code to "host" directory Manivannan Sadhasivam
2021-12-07  1:52   ` Hemant Kumar
2022-01-06  0:20   ` Alex Elder
2021-12-02 11:35 ` [PATCH 02/20] bus: mhi: Move common MHI definitions out of host directory Manivannan Sadhasivam
2022-01-06  0:22   ` Alex Elder
2022-02-03 10:29     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 03/20] bus: mhi: Make mhi_state_str[] array static const and move to common.h Manivannan Sadhasivam
2022-01-06  0:22   ` Alex Elder
2022-02-03 10:34     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 04/20] bus: mhi: Cleanup the register definitions used in headers Manivannan Sadhasivam
2022-01-06  0:23   ` Alex Elder
2022-02-03 11:26     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 05/20] bus: mhi: ep: Add support for registering MHI endpoint controllers Manivannan Sadhasivam
2022-01-06  0:26   ` Alex Elder
2022-02-03 14:50     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 06/20] bus: mhi: ep: Add support for registering MHI endpoint client drivers Manivannan Sadhasivam
2022-01-06  0:27   ` Alex Elder
2022-02-03 14:53     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 07/20] bus: mhi: ep: Add support for creating and destroying MHI EP devices Manivannan Sadhasivam
2022-01-06  0:28   ` Alex Elder
2022-02-03 15:13     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 08/20] bus: mhi: ep: Add support for managing MMIO registers Manivannan Sadhasivam
2022-01-06  0:29   ` Alex Elder
2022-02-03 15:55     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 09/20] bus: mhi: ep: Add support for ring management Manivannan Sadhasivam
2022-01-06  0:30   ` Alex Elder
2022-02-04  9:21     ` Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 10/20] bus: mhi: ep: Add support for sending events to the host Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 11/20] bus: mhi: ep: Add support for managing MHI state machine Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 12/20] bus: mhi: ep: Add support for processing MHI endpoint interrupts Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 13/20] bus: mhi: ep: Add support for powering up the MHI endpoint stack Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 14/20] bus: mhi: ep: Add support for powering down " Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 15/20] bus: mhi: ep: Add support for handling MHI_RESET Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 16/20] bus: mhi: ep: Add support for handling SYS_ERR condition Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 17/20] bus: mhi: ep: Add support for processing command and TRE rings Manivannan Sadhasivam
2021-12-02 11:35 ` Manivannan Sadhasivam [this message]
2021-12-02 11:35 ` [PATCH 19/20] bus: mhi: ep: Add support for suspending and resuming channels Manivannan Sadhasivam
2021-12-02 11:35 ` [PATCH 20/20] bus: mhi: ep: Add uevent support for module autoloading Manivannan Sadhasivam
2022-01-06  0:20 ` [PATCH 00/20] Add initial support for MHI endpoint stack Alex Elder

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=20211202113553.238011-19-manivannan.sadhasivam@linaro.org \
    --to=manivannan.sadhasivam@linaro.org \
    --cc=bbhatt@codeaurora.org \
    --cc=bjorn.andersson@linaro.org \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=hemantk@codeaurora.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhi@lists.linux.dev \
    --cc=quic_jhugo@quicinc.com \
    --cc=skananth@codeaurora.org \
    --cc=vbadigan@codeaurora.org \
    --cc=vinod.koul@linaro.org \
    --cc=vpernami@codeaurora.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.