backfire: ar71xx: fix broken LAN ports on the boards with AR8216 switch (closes ...
authorGabor Juhos <juhosg@openwrt.org>
Sat, 3 Apr 2010 16:58:04 +0000 (16:58 +0000)
committerGabor Juhos <juhosg@openwrt.org>
Sat, 3 Apr 2010 16:58:04 +0000 (16:58 +0000)
 * backport of r20673

SVN-Revision: 20677

target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ar8216.c
target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c

index c3137203f6a729833060572866e3cc34c4b71e5e..a64b4a8c5b9370699b8ac253078419b2586de478 100644 (file)
@@ -455,7 +455,8 @@ static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
 
 #ifdef CONFIG_AG71XX_AR8216_SUPPORT
 void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
-int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
+int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
+                               int pktlen);
 static inline int ag71xx_has_ar8216(struct ag71xx *ag)
 {
        return ag71xx_get_pdata(ag)->has_ar8216;
@@ -467,7 +468,8 @@ static inline void ag71xx_add_ar8216_header(struct ag71xx *ag,
 }
 
 static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag,
-                                             struct sk_buff *skb)
+                                             struct sk_buff *skb,
+                                             int pktlen)
 {
        return 0;
 }
index 564fae7eb59fe78da858555bb86fde93fd9f5f47..7801b9f0ed8f240041a27abc8f868f961c48b533 100644 (file)
@@ -25,19 +25,21 @@ void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb)
        skb->data[1] = 0x80;
 }
 
-int ag71xx_remove_ar8216_header(struct ag71xx *ag,
-                               struct sk_buff *skb)
+int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
+                               int pktlen)
 {
        u8 type;
 
        type = skb->data[1] & AR8216_PACKET_TYPE_MASK;
        switch (type) {
        case AR8216_PACKET_TYPE_NORMAL:
-               skb_pull(skb, AR8216_HEADER_LEN);
                break;
+
        default:
                return -EINVAL;
        }
 
+       skb_put(skb, pktlen);
+       skb_pull(skb, AR8216_HEADER_LEN);
        return 0;
 }
index 989ed0e8a50b3f80bd5840e1df6b97b631e3ac0d..4b35b1f251b84660250ff35e781816858d09a0c7 100644 (file)
@@ -770,6 +770,8 @@ static int ag71xx_rx_copy_skb(struct ag71xx *ag, struct sk_buff **pskb,
 
        skb_reserve(copy_skb, NET_IP_ALIGN);
        skb_copy_from_linear_data(*pskb, copy_skb->data, pktlen);
+       skb_put(copy_skb, pktlen);
+
        dev_kfree_skb_any(*pskb);
        *pskb = copy_skb;
 
@@ -814,7 +816,7 @@ static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
                dev->stats.rx_bytes += pktlen;
 
                if (ag71xx_has_ar8216(ag))
-                       err = ag71xx_remove_ar8216_header(ag, skb);
+                       err = ag71xx_remove_ar8216_header(ag, skb, pktlen);
                else
                        err = ag71xx_rx_copy_skb(ag, &skb, pktlen);
 
@@ -822,8 +824,6 @@ static int ag71xx_rx_packets(struct ag71xx *ag, int limit)
                        dev->stats.rx_dropped++;
                        kfree_skb(skb);
                } else {
-                       skb_put(skb, pktlen);
-
                        skb->dev = dev;
                        skb->ip_summed = CHECKSUM_NONE;
                        skb->protocol = eth_type_trans(skb, dev);