aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ppp_generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ppp_generic.c')
-rw-r--r--drivers/net/ppp_generic.c122
1 files changed, 61 insertions, 61 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 2282e729edb..6d61602208c 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -167,7 +167,7 @@ struct channel {
167 u8 avail; /* flag used in multilink stuff */ 167 u8 avail; /* flag used in multilink stuff */
168 u8 had_frag; /* >= 1 fragments have been sent */ 168 u8 had_frag; /* >= 1 fragments have been sent */
169 u32 lastseq; /* MP: last sequence # received */ 169 u32 lastseq; /* MP: last sequence # received */
170 int speed; /* speed of the corresponding ppp channel*/ 170 int speed; /* speed of the corresponding ppp channel*/
171#endif /* CONFIG_PPP_MULTILINK */ 171#endif /* CONFIG_PPP_MULTILINK */
172}; 172};
173 173
@@ -1293,13 +1293,13 @@ ppp_push(struct ppp *ppp)
1293 */ 1293 */
1294static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) 1294static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
1295{ 1295{
1296 int len, totlen; 1296 int len, totlen;
1297 int i, bits, hdrlen, mtu; 1297 int i, bits, hdrlen, mtu;
1298 int flen; 1298 int flen;
1299 int navail, nfree, nzero; 1299 int navail, nfree, nzero;
1300 int nbigger; 1300 int nbigger;
1301 int totspeed; 1301 int totspeed;
1302 int totfree; 1302 int totfree;
1303 unsigned char *p, *q; 1303 unsigned char *p, *q;
1304 struct list_head *list; 1304 struct list_head *list;
1305 struct channel *pch; 1305 struct channel *pch;
@@ -1307,21 +1307,21 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
1307 struct ppp_channel *chan; 1307 struct ppp_channel *chan;
1308 1308
1309 totspeed = 0; /*total bitrate of the bundle*/ 1309 totspeed = 0; /*total bitrate of the bundle*/
1310 nfree = 0; /* # channels which have no packet already queued */ 1310 nfree = 0; /* # channels which have no packet already queued */
1311 navail = 0; /* total # of usable channels (not deregistered) */ 1311 navail = 0; /* total # of usable channels (not deregistered) */
1312 nzero = 0; /* number of channels with zero speed associated*/ 1312 nzero = 0; /* number of channels with zero speed associated*/
1313 totfree = 0; /*total # of channels available and 1313 totfree = 0; /*total # of channels available and
1314 *having no queued packets before 1314 *having no queued packets before
1315 *starting the fragmentation*/ 1315 *starting the fragmentation*/
1316 1316
1317 hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; 1317 hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
1318 i = 0; 1318 i = 0;
1319 list_for_each_entry(pch, &ppp->channels, clist) { 1319 list_for_each_entry(pch, &ppp->channels, clist) {
1320 navail += pch->avail = (pch->chan != NULL); 1320 navail += pch->avail = (pch->chan != NULL);
1321 pch->speed = pch->chan->speed; 1321 pch->speed = pch->chan->speed;
1322 if (pch->avail) { 1322 if (pch->avail) {
1323 if (skb_queue_empty(&pch->file.xq) || 1323 if (skb_queue_empty(&pch->file.xq) ||
1324 !pch->had_frag) { 1324 !pch->had_frag) {
1325 if (pch->speed == 0) 1325 if (pch->speed == 0)
1326 nzero++; 1326 nzero++;
1327 else 1327 else
@@ -1331,60 +1331,60 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
1331 ++nfree; 1331 ++nfree;
1332 ++totfree; 1332 ++totfree;
1333 } 1333 }
1334 if (!pch->had_frag && i < ppp->nxchan) 1334 if (!pch->had_frag && i < ppp->nxchan)
1335 ppp->nxchan = i; 1335 ppp->nxchan = i;
1336 } 1336 }
1337 ++i; 1337 ++i;
1338 } 1338 }
1339 /* 1339 /*
1340 * Don't start sending this packet unless at least half of 1340 * Don't start sending this packet unless at least half of
1341 * the channels are free. This gives much better TCP 1341 * the channels are free. This gives much better TCP
1342 * performance if we have a lot of channels. 1342 * performance if we have a lot of channels.
1343 */ 1343 */
1344 if (nfree == 0 || nfree < navail / 2) 1344 if (nfree == 0 || nfree < navail / 2)
1345 return 0; /* can't take now, leave it in xmit_pending */ 1345 return 0; /* can't take now, leave it in xmit_pending */
1346 1346
1347 /* Do protocol field compression (XXX this should be optional) */ 1347 /* Do protocol field compression (XXX this should be optional) */
1348 p = skb->data; 1348 p = skb->data;
1349 len = skb->len; 1349 len = skb->len;
1350 if (*p == 0) { 1350 if (*p == 0) {
1351 ++p; 1351 ++p;
1352 --len; 1352 --len;
1353 } 1353 }
1354 1354
1355 totlen = len; 1355 totlen = len;
1356 nbigger = len % nfree; 1356 nbigger = len % nfree;
1357 1357
1358 /* skip to the channel after the one we last used 1358 /* skip to the channel after the one we last used
1359 and start at that one */ 1359 and start at that one */
1360 list = &ppp->channels; 1360 list = &ppp->channels;
1361 for (i = 0; i < ppp->nxchan; ++i) { 1361 for (i = 0; i < ppp->nxchan; ++i) {
1362 list = list->next; 1362 list = list->next;
1363 if (list == &ppp->channels) { 1363 if (list == &ppp->channels) {
1364 i = 0; 1364 i = 0;
1365 break; 1365 break;
1366 } 1366 }
1367 } 1367 }
1368 1368
1369 /* create a fragment for each channel */ 1369 /* create a fragment for each channel */
1370 bits = B; 1370 bits = B;
1371 while (len > 0) { 1371 while (len > 0) {
1372 list = list->next; 1372 list = list->next;
1373 if (list == &ppp->channels) { 1373 if (list == &ppp->channels) {
1374 i = 0; 1374 i = 0;
1375 continue; 1375 continue;
1376 } 1376 }
1377 pch = list_entry(list, struct channel, clist); 1377 pch = list_entry(list, struct channel, clist);
1378 ++i; 1378 ++i;
1379 if (!pch->avail) 1379 if (!pch->avail)
1380 continue; 1380 continue;
1381 1381
1382 /* 1382 /*
1383 * Skip this channel if it has a fragment pending already and 1383 * Skip this channel if it has a fragment pending already and
1384 * we haven't given a fragment to all of the free channels. 1384 * we haven't given a fragment to all of the free channels.
1385 */ 1385 */
1386 if (pch->avail == 1) { 1386 if (pch->avail == 1) {
1387 if (nfree > 0) 1387 if (nfree > 0)
1388 continue; 1388 continue;
1389 } else { 1389 } else {
1390 pch->avail = 1; 1390 pch->avail = 1;
@@ -1393,32 +1393,32 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
1393 /* check the channel's mtu and whether it is still attached. */ 1393 /* check the channel's mtu and whether it is still attached. */
1394 spin_lock_bh(&pch->downl); 1394 spin_lock_bh(&pch->downl);
1395 if (pch->chan == NULL) { 1395 if (pch->chan == NULL) {
1396 /* can't use this channel, it's being deregistered */ 1396 /* can't use this channel, it's being deregistered */
1397 if (pch->speed == 0) 1397 if (pch->speed == 0)
1398 nzero--; 1398 nzero--;
1399 else 1399 else
1400 totspeed -= pch->speed; 1400 totspeed -= pch->speed;
1401 1401
1402 spin_unlock_bh(&pch->downl); 1402 spin_unlock_bh(&pch->downl);
1403 pch->avail = 0; 1403 pch->avail = 0;
1404 totlen = len; 1404 totlen = len;
1405 totfree--; 1405 totfree--;
1406 nfree--; 1406 nfree--;
1407 if (--navail == 0) 1407 if (--navail == 0)
1408 break; 1408 break;
1409 continue; 1409 continue;
1410 } 1410 }
1411 1411
1412 /* 1412 /*
1413 *if the channel speed is not set divide 1413 *if the channel speed is not set divide
1414 *the packet evenly among the free channels; 1414 *the packet evenly among the free channels;
1415 *otherwise divide it according to the speed 1415 *otherwise divide it according to the speed
1416 *of the channel we are going to transmit on 1416 *of the channel we are going to transmit on
1417 */ 1417 */
1418 flen = len; 1418 flen = len;
1419 if (nfree > 0) { 1419 if (nfree > 0) {
1420 if (pch->speed == 0) { 1420 if (pch->speed == 0) {
1421 flen = totlen/nfree ; 1421 flen = totlen/nfree;
1422 if (nbigger > 0) { 1422 if (nbigger > 0) {
1423 flen++; 1423 flen++;
1424 nbigger--; 1424 nbigger--;
@@ -1436,8 +1436,8 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
1436 } 1436 }
1437 1437
1438 /* 1438 /*
1439 *check if we are on the last channel or 1439 *check if we are on the last channel or
1440 *we exceded the lenght of the data to 1440 *we exceded the lenght of the data to
1441 *fragment 1441 *fragment
1442 */ 1442 */
1443 if ((nfree <= 0) || (flen > len)) 1443 if ((nfree <= 0) || (flen > len))
@@ -1448,29 +1448,29 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
1448 *above formula will be equal or less than zero. 1448 *above formula will be equal or less than zero.
1449 *Skip the channel in this case 1449 *Skip the channel in this case
1450 */ 1450 */
1451 if (flen <= 0) { 1451 if (flen <= 0) {
1452 pch->avail = 2; 1452 pch->avail = 2;
1453 spin_unlock_bh(&pch->downl); 1453 spin_unlock_bh(&pch->downl);
1454 continue; 1454 continue;
1455 } 1455 }
1456 1456
1457 mtu = pch->chan->mtu - hdrlen; 1457 mtu = pch->chan->mtu - hdrlen;
1458 if (mtu < 4) 1458 if (mtu < 4)
1459 mtu = 4; 1459 mtu = 4;
1460 if (flen > mtu) 1460 if (flen > mtu)
1461 flen = mtu; 1461 flen = mtu;
1462 if (flen == len) 1462 if (flen == len)
1463 bits |= E; 1463 bits |= E;
1464 frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC); 1464 frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
1465 if (!frag) 1465 if (!frag)
1466 goto noskb; 1466 goto noskb;
1467 q = skb_put(frag, flen + hdrlen); 1467 q = skb_put(frag, flen + hdrlen);
1468 1468
1469 /* make the MP header */ 1469 /* make the MP header */
1470 q[0] = PPP_MP >> 8; 1470 q[0] = PPP_MP >> 8;
1471 q[1] = PPP_MP; 1471 q[1] = PPP_MP;
1472 if (ppp->flags & SC_MP_XSHORTSEQ) { 1472 if (ppp->flags & SC_MP_XSHORTSEQ) {
1473 q[2] = bits + ((ppp->nxseq >> 8) & 0xf); 1473 q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
1474 q[3] = ppp->nxseq; 1474 q[3] = ppp->nxseq;
1475 } else { 1475 } else {
1476 q[2] = bits; 1476 q[2] = bits;
@@ -1483,24 +1483,24 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
1483 1483
1484 /* try to send it down the channel */ 1484 /* try to send it down the channel */
1485 chan = pch->chan; 1485 chan = pch->chan;
1486 if (!skb_queue_empty(&pch->file.xq) || 1486 if (!skb_queue_empty(&pch->file.xq) ||
1487 !chan->ops->start_xmit(chan, frag)) 1487 !chan->ops->start_xmit(chan, frag))
1488 skb_queue_tail(&pch->file.xq, frag); 1488 skb_queue_tail(&pch->file.xq, frag);
1489 pch->had_frag = 1; 1489 pch->had_frag = 1;
1490 p += flen; 1490 p += flen;
1491 len -= flen; 1491 len -= flen;
1492 ++ppp->nxseq; 1492 ++ppp->nxseq;
1493 bits = 0; 1493 bits = 0;
1494 spin_unlock_bh(&pch->downl); 1494 spin_unlock_bh(&pch->downl);
1495 } 1495 }
1496 ppp->nxchan = i; 1496 ppp->nxchan = i;
1497 1497
1498 return 1; 1498 return 1;
1499 1499
1500 noskb: 1500 noskb:
1501 spin_unlock_bh(&pch->downl); 1501 spin_unlock_bh(&pch->downl);
1502 if (ppp->debug & 1) 1502 if (ppp->debug & 1)
1503 printk(KERN_ERR "PPP: no memory (fragment)\n"); 1503 printk(KERN_ERR "PPP: no memory (fragment)\n");
1504 ++ppp->dev->stats.tx_errors; 1504 ++ppp->dev->stats.tx_errors;
1505 ++ppp->nxseq; 1505 ++ppp->nxseq;
1506 return 1; /* abandon the frame */ 1506 return 1; /* abandon the frame */