diff options
author | 2020-07-30 10:48:13 +0530 | |
---|---|---|
committer | 2021-10-15 10:35:20 -0500 | |
commit | 8956927faed366b60b0355f4a4317a10e281ced7 (patch) | |
tree | 5aa68d5cc3b722b43ba125b80e5f501f31c30780 /drivers/rpmsg | |
parent | rpmsg: virtio_rpmsg_bus: use dev_warn_ratelimited for msg with no recipient (diff) | |
download | linux-8956927faed366b60b0355f4a4317a10e281ced7.tar.gz linux-8956927faed366b60b0355f4a4317a10e281ced7.tar.bz2 linux-8956927faed366b60b0355f4a4317a10e281ced7.zip |
rpmsg: glink: Add TX_DATA_CONT command while sending
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 <aneela@codeaurora.org>
Signed-off-by: Deepak Kumar Singh <deesin@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/1596086296-28529-4-git-send-email-deesin@codeaurora.org
Diffstat (limited to 'drivers/rpmsg')
-rw-r--r-- | drivers/rpmsg/qcom_glink_native.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index c7b9de655080..c525f667286d 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1271,6 +1271,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) { @@ -1304,18 +1306,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; } |