From: Arun Kumar Neelakantam <ane...@codeaurora.org>

With current design the transport can send packets of size upto
FIFO_SIZE which is 16k and return failure for all packets above 16k.

Add TX_DATA_CONT command to send packets greater than 16k by splitting
into 8K chunks.

Signed-off-by: Arun Kumar Neelakantam <ane...@codeaurora.org>
Signed-off-by: Deepak Kumar Singh <dee...@codeaurora.org>
---
 drivers/rpmsg/qcom_glink_native.c | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/rpmsg/qcom_glink_native.c 
b/drivers/rpmsg/qcom_glink_native.c
index df3c608..ac179b1 100644
--- a/drivers/rpmsg/qcom_glink_native.c
+++ b/drivers/rpmsg/qcom_glink_native.c
@@ -1289,6 +1289,8 @@ static int __qcom_glink_send(struct glink_channel 
*channel,
        } __packed req;
        int ret;
        unsigned long flags;
+       int chunk_size = len;
+       int left_size = 0;
 
        if (!glink->intentless) {
                while (!intent) {
@@ -1322,18 +1324,46 @@ static int __qcom_glink_send(struct glink_channel 
*channel,
                iid = intent->id;
        }
 
+       if (wait && (chunk_size > SZ_8K)) {
+               chunk_size = SZ_8K;
+               left_size = len - chunk_size;
+       }
        req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA);
        req.msg.param1 = cpu_to_le16(channel->lcid);
        req.msg.param2 = cpu_to_le32(iid);
-       req.chunk_size = cpu_to_le32(len);
-       req.left_size = cpu_to_le32(0);
+       req.chunk_size = cpu_to_le32(chunk_size);
+       req.left_size = cpu_to_le32(left_size);
 
-       ret = qcom_glink_tx(glink, &req, sizeof(req), data, len, wait);
+       ret = qcom_glink_tx(glink, &req, sizeof(req), data, chunk_size, wait);
 
        /* Mark intent available if we failed */
-       if (ret && intent)
+       if (ret && intent) {
                intent->in_use = false;
+               return ret;
+       }
 
+       while (left_size > 0) {
+               data = (void *)((char *)data + chunk_size);
+               chunk_size = left_size;
+               if (chunk_size > SZ_8K)
+                       chunk_size = SZ_8K;
+               left_size -= chunk_size;
+
+               req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA_CONT);
+               req.msg.param1 = cpu_to_le16(channel->lcid);
+               req.msg.param2 = cpu_to_le32(iid);
+               req.chunk_size = cpu_to_le32(chunk_size);
+               req.left_size = cpu_to_le32(left_size);
+
+               ret = qcom_glink_tx(glink, &req, sizeof(req), data,
+                                   chunk_size, wait);
+
+               /* Mark intent available if we failed */
+               if (ret && intent) {
+                       intent->in_use = false;
+                       break;
+               }
+       }
        return ret;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

Reply via email to