net: wireless: sd8797: Marvell sd8797 Wi-Fi driver
[linux-2.6.git] / drivers / net / ppp_generic.c
index 1d4fb34..edfa15d 100644 (file)
@@ -48,7 +48,7 @@
 #include <linux/slab.h>
 #include <asm/unaligned.h>
 #include <net/slhc_vj.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
 
 #include <linux/nsproxy.h>
 #include <net/net_namespace.h>
@@ -1448,7 +1448,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
 
                /*
                 *check if we are on the last channel or
-                *we exceded the lenght of the data to
+                *we exceded the length of the data to
                 *fragment
                 */
                if ((nfree <= 0) || (flen > len))
@@ -1465,7 +1465,12 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
                        continue;
                }
 
-               mtu = pch->chan->mtu - hdrlen;
+               /*
+                * hdrlen includes the 2-byte PPP protocol field, but the
+                * MTU counts only the payload excluding the protocol field.
+                * (RFC1661 Section 2)
+                */
+               mtu = pch->chan->mtu - (hdrlen - 2);
                if (mtu < 4)
                        mtu = 4;
                if (flen > mtu)
@@ -1998,7 +2003,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
        u32 seq = ppp->nextseq;
        u32 minseq = ppp->minseq;
        struct sk_buff_head *list = &ppp->mrq;
-       struct sk_buff *p, *next;
+       struct sk_buff *p, *tmp;
        struct sk_buff *head, *tail;
        struct sk_buff *skb = NULL;
        int lost = 0, len = 0;
@@ -2007,14 +2012,15 @@ ppp_mp_reconstruct(struct ppp *ppp)
                return NULL;
        head = list->next;
        tail = NULL;
-       for (p = head; p != (struct sk_buff *) list; p = next) {
-               next = p->next;
+       skb_queue_walk_safe(list, p, tmp) {
+       again:
                if (seq_before(PPP_MP_CB(p)->sequence, seq)) {
                        /* this can't happen, anyway ignore the skb */
                        netdev_err(ppp->dev, "ppp_mp_reconstruct bad "
                                   "seq %u < %u\n",
                                   PPP_MP_CB(p)->sequence, seq);
-                       head = next;
+                       __skb_unlink(p, list);
+                       kfree_skb(p);
                        continue;
                }
                if (PPP_MP_CB(p)->sequence != seq) {
@@ -2026,8 +2032,7 @@ ppp_mp_reconstruct(struct ppp *ppp)
                        lost = 1;
                        seq = seq_before(minseq, PPP_MP_CB(p)->sequence)?
                                minseq + 1: PPP_MP_CB(p)->sequence;
-                       next = p;
-                       continue;
+                       goto again;
                }
 
                /*
@@ -2067,9 +2072,17 @@ ppp_mp_reconstruct(struct ppp *ppp)
                 * and we haven't found a complete valid packet yet,
                 * we can discard up to and including this fragment.
                 */
-               if (PPP_MP_CB(p)->BEbits & E)
-                       head = next;
+               if (PPP_MP_CB(p)->BEbits & E) {
+                       struct sk_buff *tmp2;
 
+                       skb_queue_reverse_walk_from_safe(list, p, tmp2) {
+                               __skb_unlink(p, list);
+                               kfree_skb(p);
+                       }
+                       head = skb_peek(list);
+                       if (!head)
+                               break;
+               }
                ++seq;
        }
 
@@ -2110,13 +2123,6 @@ ppp_mp_reconstruct(struct ppp *ppp)
                }
 
                ppp->nextseq = PPP_MP_CB(tail)->sequence + 1;
-               head = tail->next;
-       }
-
-       /* Discard all the skbuffs that we can't use. */
-       while ((p = list->next) != head) {
-               __skb_unlink(p, list);
-               kfree_skb(p);
        }
 
        return skb;