From: hwg <hwg@rock-chips.com>
Date: Tue, 18 Jun 2013 12:09:52 +0000 (+0800)
Subject: solve usb buffer align problem to support usb tether(rndis)
X-Git-Tag: firefly_0821_release~6965^2~64
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=5263c43067b341a1fcc6921575a41ddb11ee0c5c;p=firefly-linux-kernel-4.4.55.git

solve usb buffer align problem to support usb tether(rndis)
---

diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 51d572eae9ad..273718441c38 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -31,6 +31,7 @@
 
 #include "u_ether.h"
 
+static gfp_t g_gfp_flags;
 
 /*
  * This component encapsulates the Ethernet link glue needed to provide
@@ -253,7 +254,7 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
 	 * but on at least one, checksumming fails otherwise.  Note:
 	 * RNDIS headers involve variable numbers of LE32 values.
 	 */
-	skb_reserve(skb, NET_IP_ALIGN);
+	//skb_reserve(skb, NET_IP_ALIGN);
 
 	req->buf = skb->data;
 	req->length = size;
@@ -577,6 +578,21 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
 
 		length = skb->len;
 	}
+	
+	// for tx fixup
+	{
+		struct sk_buff *tx_skb;
+		if ((unsigned long)skb->data % 4) {
+			tx_skb = alloc_skb(skb->len + NET_IP_ALIGN, g_gfp_flags);
+			if (tx_skb)
+				memcpy(skb_put(tx_skb, skb->len), skb->data, skb->len);
+			dev_kfree_skb_any(skb);
+			skb = tx_skb;
+		}
+		length = skb->len;
+	}	
+	// for tx fixup
+	
 	req->buf = skb->data;
 	req->context = skb;
 	req->complete = tx_complete;
@@ -632,6 +648,8 @@ drop:
 static void eth_start(struct eth_dev *dev, gfp_t gfp_flags)
 {
 	DBG(dev, "%s\n", __func__);
+	
+	g_gfp_flags = gfp_flags;
 
 	/* fill the rx queue */
 	rx_fill(dev, gfp_flags);