- for (flen = fragsize; flen > 0; flen -= fnb) {
- fnb = flen;
- if (fnb > mtu + 2 - hdrlen)
- fnb = mtu + 2 - hdrlen;
- if (fnb >= len)
- bits |= E;
- frag = alloc_skb(fnb + hdrlen, GFP_ATOMIC);
- if (frag == 0)
- goto noskb;
- q = skb_put(frag, fnb + hdrlen);
- /* make the MP header */
- q[0] = PPP_MP >> 8;
- q[1] = PPP_MP;
- if (ppp->flags & SC_MP_XSHORTSEQ) {
- q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
- q[3] = ppp->nxseq;
- } else {
- q[2] = bits;
- q[3] = ppp->nxseq >> 16;
- q[4] = ppp->nxseq >> 8;
- q[5] = ppp->nxseq;
- }
-
- /* copy the data in */
- memcpy(q + hdrlen, p, fnb);
-
- /* try to send it down the channel */
- chan = pch->chan;
- if (!chan->ops->start_xmit(chan, frag))
- skb_queue_tail(&pch->file.xq, frag);
- pch->had_frag = 1;
- p += fnb;
- len -= fnb;
- ++ppp->nxseq;
- bits = 0;
+ flen = fragsize;
+ mtu = pch->chan->mtu + 2 - hdrlen;
+ if (mtu < 4)
+ mtu = 4;
+ if (flen > mtu)
+ flen = mtu;
+ if (flen == len && nfree == 0)
+ bits |= E;
+ frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
+ if (frag == 0)
+ goto noskb;
+ q = skb_put(frag, flen + hdrlen);
+
+ /* make the MP header */
+ q[0] = PPP_MP >> 8;
+ q[1] = PPP_MP;
+ if (ppp->flags & SC_MP_XSHORTSEQ) {
+ q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
+ q[3] = ppp->nxseq;
+ } else {
+ q[2] = bits;
+ q[3] = ppp->nxseq >> 16;
+ q[4] = ppp->nxseq >> 8;
+ q[5] = ppp->nxseq;