solve usb ethernet align problem: method form box
authorhwg <hwg@rock-chips.com>
Sun, 9 Jun 2013 02:02:16 +0000 (10:02 +0800)
committerhwg <hwg@rock-chips.com>
Sun, 9 Jun 2013 02:02:27 +0000 (10:02 +0800)
drivers/net/usb/cdc_ether.c
drivers/net/usb/usbnet.c

index 5fe4f5bcf9177482d33dbaa5507fd42f68faefcc..544c309e0d9590febd679a0c561ea1bd70f7cbfd 100644 (file)
@@ -460,23 +460,6 @@ static int cdc_manage_power(struct usbnet *dev, int on)
        return 0;
 }
 
-static struct sk_buff *android_tx_fixup(struct usbnet *dev,
-                                       struct sk_buff *skb,
-                                       gfp_t flags)
-{
-       struct sk_buff *tx_skb;
-
-       if ((unsigned long)skb->data % 4) {
-               tx_skb = alloc_skb(skb->len + NET_IP_ALIGN, flags);
-               if (tx_skb)
-                       memcpy(skb_put(tx_skb, skb->len), skb->data, skb->len);
-               dev_kfree_skb_any(skb);
-       } else
-               tx_skb = skb;
-
-       return tx_skb;
-}
-
 static const struct driver_info        cdc_info = {
        .description =  "CDC Ethernet Device",
        .flags =        FLAG_ETHER | FLAG_POINTTOPOINT,
@@ -485,7 +468,6 @@ static const struct driver_info     cdc_info = {
        .unbind =       usbnet_cdc_unbind,
        .status =       usbnet_cdc_status,
        .manage_power = cdc_manage_power,
-        .tx_fixup =    android_tx_fixup,
 };
 
 static const struct driver_info wwan_info = {
index d1ab1698e3066a84f2dc0988e91bdfbcac3fa838..48c0cd144a2db9089c33cc0c6e471de7816f5906 100644 (file)
@@ -1103,6 +1103,30 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
                        }
                }
        }
+       
+//$_rbox_$_modify_$_chenzhi
+//$_rbox_$_modify_$_begin
+/* data must be 4-byte aligned */
+        length = ((unsigned long)skb->data) & 0x3;
+        if (length) {
+                if (skb_cloned(skb) ||
+                    ((skb_headroom(skb) < length) &&
+                     (skb_tailroom(skb) < (4-length)))) {
+                        struct sk_buff *skb2;
+                        /* copy skb with proper alignment */
+                        skb2 = skb_copy_expand(skb, 0, 4, GFP_ATOMIC);
+                        dev_kfree_skb_any(skb);
+                        skb = skb2;
+                        if (!skb)
+                                goto drop;
+                } else {
+                        /* move data inside buffer */
+                        length = ((skb_headroom(skb) >= length) ? 0 : 4)-length;
+                        memmove(skb->data+length, skb->data, skb->len);
+                        skb_reserve(skb, length);
+                }
+        }
+//$_rbox_$_modify_$_end        
        length = skb->len;
 
        if (!(urb = usb_alloc_urb (0, GFP_ATOMIC))) {