msm: rmnet_bam: correct error handling
The error handling of msm_bam_dmux_write() should recognize -EAGAIN as a
valid error code and not mask it out. -EAGAIN needs to be handled
differently than other error codes.
CRs-Fixed: 325621
Change-Id: I69b6b5094fcf93c933971a0eae60c6bca0a12299
Signed-off-by: Jeffrey Hugo <jhugo@codeaurora.org>
diff --git a/drivers/net/msm_rmnet_bam.c b/drivers/net/msm_rmnet_bam.c
index e40edc3..a0924ed 100644
--- a/drivers/net/msm_rmnet_bam.c
+++ b/drivers/net/msm_rmnet_bam.c
@@ -311,13 +311,13 @@
/* if write() succeeds, skb access is unsafe in this process */
bam_ret = msm_bam_dmux_write(p->ch_id, skb);
- if (bam_ret != 0) {
+ if (bam_ret != 0 && bam_ret != -EAGAIN) {
pr_err("[%s] %s: write returned error %d",
dev->name, __func__, bam_ret);
- return -EAGAIN;
+ return -EPERM;
}
- return 0;
+ return bam_ret;
}
static void bam_write_done(void *dev, struct sk_buff *skb)
@@ -455,13 +455,25 @@
}
if (!ul_is_connected) {
+ netif_stop_queue(dev);
p->waiting_for_ul = 1;
msm_bam_dmux_kickoff_ul_wakeup();
return NETDEV_TX_BUSY;
}
ret = _rmnet_xmit(skb, dev);
+ if (ret == -EPERM)
+ return NETDEV_TX_BUSY;
+
if (ret == -EAGAIN) {
- netif_start_queue(dev);
+ /*
+ * This should not happen
+ * EAGAIN means we attempted to overflow the high watermark
+ * Clearly the queue is not stopped like it should be, so
+ * stop it and return BUSY to the TCP/IP framework. It will
+ * retry this packet with the queue is restarted which happens
+ * in the write_done callback when the low watermark is hit.
+ */
+ netif_stop_queue(dev);
return NETDEV_TX_BUSY;
}