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;
 	}