isdnl2.c revision ba2d6ccb1df6ebb2c1b2322518ce7be25c1e3469
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* $Id: isdnl2.c,v 2.30.2.4 2004/02/11 13:21:34 keil Exp $ 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author Karsten Keil 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * based on the teles driver from Jan den Ouden 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright by Karsten Keil <keil@isdn4linux.de> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference. 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For changes and modifications please read 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Documentation/isdn/HiSax.cert 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Thanks to Jan den Ouden 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Fritz Elfert 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hisax.h" 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "isdnl2.h" 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsconst char *l2_revision = "$Revision: 2.30.2.4 $"; 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void l2m_debug(struct FsmInst *fi, char *fmt, ...); 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct Fsm l2fsm; 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum { 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_1, 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_2, 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_3, 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_4, 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_5, 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_6, 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_7, 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_8, 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define L2_STATE_COUNT (ST_L2_8+1) 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *strL2State[] = 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_1", 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_2", 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_3", 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_4", 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_5", 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_6", 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_7", 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_8", 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum { 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_UI, 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_SABME, 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DISC, 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DM, 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_UA, 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_FRMR, 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_SUPER, 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_I, 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DL_DATA, 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_ACK_PULL, 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DL_UNIT_DATA, 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DL_ESTABLISH_REQ, 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DL_RELEASE_REQ, 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_MDL_ASSIGN, 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_MDL_REMOVE, 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_MDL_ERROR, 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L1_DEACTIVATE, 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T200, 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T203, 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_SET_OWN_BUSY, 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_CLEAR_OWN_BUSY, 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_FRAME_ERROR, 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR+1) 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *strL2Event[] = 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_UI", 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_SABME", 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DISC", 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DM", 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_UA", 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_FRMR", 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_SUPER", 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_I", 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DL_DATA", 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_ACK_PULL", 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DL_UNIT_DATA", 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DL_ESTABLISH_REQ", 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DL_RELEASE_REQ", 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_MDL_ASSIGN", 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_MDL_REMOVE", 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_MDL_ERROR", 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L1_DEACTIVATE", 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_T200", 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_T203", 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_SET_OWN_BUSY", 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_CLEAR_OWN_BUSY", 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_FRAME_ERROR", 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int l2addrsize(struct Layer2 *l2); 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsset_peer_busy(struct Layer2 *l2) { 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_PEER_BUSY, &l2->flag); 111b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&l2->i_queue) || 112b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller !skb_queue_empty(&l2->ui_queue)) 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L2BLOCK, &l2->flag); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsclear_peer_busy(struct Layer2 *l2) { 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_PEER_BUSY, &l2->flag)) 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L2BLOCK, &l2->flag); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsInitWin(struct Layer2 *l2) 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_WINDOW; i++) 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->windowar[i] = NULL; 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfreewin1(struct Layer2 *l2) 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, cnt = 0; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_WINDOW; i++) { 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (l2->windowar[i]) { 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt++; 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(l2->windowar[i]); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->windowar[i] = NULL; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return cnt; 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 146672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfreewin(struct PStack *st) 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin1(&st->l2); 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsReleaseWin(struct Layer2 *l2) 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cnt; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((cnt = freewin1(l2))) 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt); 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 161672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline unsigned int 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscansend(struct PStack *st) 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int p1; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(test_bit(FLG_MOD128, &st->l2.flag)) 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (st->l2.vs - st->l2.va) % 128; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (st->l2.vs - st->l2.va) % 8; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((p1 < st->l2.window) && !test_bit(FLG_PEER_BUSY, &st->l2.flag)); 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 173672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsclear_exception(struct Layer2 *l2) 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &l2->flag); 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_REJEXC, &l2->flag); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_OWN_BUSY, &l2->flag); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_peer_busy(l2); 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 182672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2headersize(struct Layer2 *l2, int ui) 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) + 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1)); 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsinline int 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2addrsize(struct Layer2 *l2) 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1); 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssethdraddr(struct Layer2 *l2, u_char * header, int rsp) 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *ptr = header; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int crbit = rsp; 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &l2->flag)) { 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = (l2->sap << 2) | (rsp ? 2 : 0); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = (l2->tei << 1) | 1; 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (2); 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &l2->flag)) 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds crbit = !crbit; 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (crbit) 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = 1; 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = 3; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21677933d7276ee8fa0e2947641941a6f7a100a327bJesper Juhlstatic inline void 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenqueue_super(struct PStack *st, 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs->tx_cnt += skb->len; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_DATA | REQUEST, skb); 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define enqueue_ui(a, b) enqueue_super(a, b) 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 227672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsUI(u_char * data) 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((data[0] & 0xef) == UI); 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 233672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsUA(u_char * data) 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((data[0] & 0xef) == UA); 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 239672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsDM(u_char * data) 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((data[0] & 0xef) == DM); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 245672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsDISC(u_char * data) 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((data[0] & 0xef) == DISC); 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsSFrame(u_char * data, struct PStack *st) 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_char d = *data; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_bit(FLG_MOD128, &st->l2.flag)) 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds d &= 0xf; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c)); 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsSABME(u_char * data, struct PStack *st) 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char d = data[0] & ~0x10; 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (test_bit(FLG_MOD128, &st->l2.flag) ? d == SABME : d == SABM); 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 269672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsREJ(u_char * data, struct PStack *st) 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == REJ : (data[0] & 0xf) == REJ); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 275672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsFRMR(u_char * data) 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((data[0] & 0xef) == FRMR); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 281672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsRNR(u_char * data, struct PStack *st) 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == RNR : (data[0] & 0xf) == RNR); 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 287672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsiframe_error(struct PStack *st, struct sk_buff *skb) 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rsp = *skb->data & 0x2; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &st->l2.flag)) 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rsp) 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'L'; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len < i) 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'N'; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((skb->len - i) > st->l2.maxlen) 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'O'; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 310672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuper_error(struct PStack *st, struct sk_buff *skb) 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len != l2addrsize(&st->l2) + 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1)) 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'N'; 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 320672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp) 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rsp = (*skb->data & 0x2) >> 1; 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &st->l2.flag)) 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rsp != wantrsp) 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'L'; 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len != l2addrsize(&st->l2) + 1) 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'N'; 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 336672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsUI_error(struct PStack *st, struct sk_buff *skb) 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rsp = *skb->data & 0x2; 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &st->l2.flag)) 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rsp) 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'L'; 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len > st->l2.maxlen + l2addrsize(&st->l2) + 1) 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'O'; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 352672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsFRMR_error(struct PStack *st, struct sk_buff *skb) 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int headers = l2addrsize(&st->l2) + 1; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *datap = skb->data + headers; 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rsp = *skb->data & 0x2; 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &st->l2.flag)) 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!rsp) 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'L'; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &st->l2.flag)) { 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len < headers + 5) 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'N'; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x %2x %2x", 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds datap[0], datap[1], datap[2], 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds datap[3], datap[4]); 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len < headers + 3) 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'N'; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x", 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds datap[0], datap[1], datap[2]); 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslegalnr(struct PStack *st, unsigned int nr) 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(test_bit(FLG_MOD128, &l2->flag)) 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128); 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8); 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetva(struct PStack *st, unsigned int nr) 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&l2->lock, flags); 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (l2->va != nr) { 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (l2->va)++; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(test_bit(FLG_MOD128, &l2->flag)) 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->va %= 128; 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->va %= 8; 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = l2->windowar[l2->sow]->len; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (PACKET_NOACK == l2->windowar[l2->sow]->pkt_type) 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = -1; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(l2->windowar[l2->sow]); 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->windowar[l2->sow] = NULL; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->sow = (l2->sow + 1) % l2->window; 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&l2->lock, flags); 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LLI_L2WAKEUP, &st->lli.flag) && (len >=0)) 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lli_writewakeup(st, len); 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&l2->lock, flags); 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&l2->lock, flags); 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssend_uframe(struct PStack *st, u_char cmd, u_char cr) 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char tmp[MAX_HEADER_LEN]; 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = sethdraddr(&st->l2, tmp, cr); 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp[i++] = cmd; 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(skb = alloc_skb(i, GFP_ATOMIC))) { 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "isdl2 can't alloc sbbuff for send_uframe\n"); 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(skb_put(skb, i), tmp, i); 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enqueue_super(st, skb); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 439672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline u_char 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsget_PollFlag(struct PStack * st, struct sk_buff * skb) 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (skb->data[l2addrsize(&(st->l2))] & 0x10); 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 445672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline u_char 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsget_PollFlagFree(struct PStack *st, struct sk_buff *skb) 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char PF; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PF = get_PollFlag(st, skb); 451672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (PF); 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 455672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstart_t200(struct PStack *st, int i) 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_T200_RUN, &st->l2.flag); 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 462672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrestart_t200(struct PStack *st, int i) 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_T200_RUN, &st->l2.flag); 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 469672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstop_t200(struct PStack *st, int i) 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t200, i); 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 476672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsst5_dl_release_l2l3(struct PStack *st) 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int pr; 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr = DL_RELEASE | CONFIRM; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr = DL_RELEASE | INDICATION; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, pr, NULL); 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 489672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslapb_dl_release_l2l3(struct PStack *st, int f) 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | f, NULL); 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsestablishlink(struct FsmInst *fi) 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char cmd; 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_exception(&st->l2); 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc = 0; 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = (test_bit(FLG_MOD128, &st->l2.flag) ? SABME : SABM) | 0x10; 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, cmd, CMD); 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 1); 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restart_t200(st, 1); 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_PEND_REL, &st->l2.flag); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_5); 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_mdl_error_ua(struct FsmInst *fi, int event, void *arg) 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_PollFlagFree(st, skb)) 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'C'); 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'D'); 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_mdl_error_dm(struct FsmInst *fi, int event, void *arg) 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_PollFlagFree(st, skb)) 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg) 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_PollFlagFree(st, skb)) 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_go_st3(struct FsmInst *fi, int event, void *arg) 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_3); 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_mdl_assign(struct FsmInst *fi, int event, void *arg) 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_3); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL); 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_queue_ui_assign(struct FsmInst *fi, int event, void *arg) 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.ui_queue, skb); 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_2); 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL); 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_queue_ui(struct FsmInst *fi, int event, void *arg) 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.ui_queue, skb); 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstx_ui(struct PStack *st) 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char header[MAX_HEADER_LEN]; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = sethdraddr(&(st->l2), header, CMD); 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header[i++] = UI; 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((skb = skb_dequeue(&st->l2.ui_queue))) { 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(skb_push(skb, i), header, i); 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enqueue_ui(st, skb); 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_send_ui(struct FsmInst *fi, int event, void *arg) 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.ui_queue, skb); 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tx_ui(st); 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_got_ui(struct FsmInst *fi, int event, void *arg) 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(skb, l2headersize(&st->l2, 1)); 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_UNIT_DATA | INDICATION, skb); 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in states 1-3 for broadcast 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_establish(struct FsmInst *fi, int event, void *arg) 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L3_INIT, &st->l2.flag); 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_discard_i_setl3(struct FsmInst *fi, int event, void *arg) 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L3_INIT, &st->l2.flag); 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_PEND_REL, &st->l2.flag); 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_l3_reestablish(struct FsmInst *fi, int event, void *arg) 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L3_INIT, &st->l2.flag); 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_release(struct FsmInst *fi, int event, void *arg) 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_pend_rel(struct FsmInst *fi, int event, void *arg) 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_PEND_REL, &st->l2.flag); 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_disconnect(struct FsmInst *fi, int event, void *arg) 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_6); 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc = 0; 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, DISC | 0x10, CMD); 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 1); 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restart_t200(st, 2); 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_start_multi(struct FsmInst *fi, int event, void *arg) 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_exception(&st->l2); 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vs = 0; 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.va = 0; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vr = 0; 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.sow = 0; 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_7); 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 3); 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL); 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_send_UA(struct FsmInst *fi, int event, void *arg) 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_send_DM(struct FsmInst *fi, int event, void *arg) 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, DM | get_PollFlagFree(st, skb), RSP); 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_restart_multi(struct FsmInst *fi, int event, void *arg) 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int est = 0, state; 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds state = fi->state; 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'F'); 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (st->l2.vs != st->l2.va) { 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds est = 1; 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_exception(&st->l2); 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vs = 0; 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.va = 0; 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vr = 0; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.sow = 0; 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_7); 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 3); 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 3); 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (est) 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL); 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ST_L2_7==state) || (ST_L2_8 == state)) 758b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&st->l2.i_queue) && cansend(st)) 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_stop_multi(struct FsmInst *fi, int event, void *arg) 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 3); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 4); 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lapb_dl_release_l2l3(st, INDICATION); 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_connected(struct FsmInst *fi, int event, void *arg) 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int pr=-1; 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!get_PollFlag(st, skb)) { 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2_mdl_error_ua(fi, event, arg); 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 790672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2_disconnect(fi, event, arg); 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_L3_INIT, &st->l2.flag)) { 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr = DL_ESTABLISH | CONFIRM; 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (st->l2.vs != st->l2.va) { 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr = DL_ESTABLISH | INDICATION; 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 5); 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vr = 0; 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vs = 0; 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.va = 0; 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.sow = 0; 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_7); 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 4); 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pr != -1) 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, pr, NULL); 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 814b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&st->l2.i_queue) && cansend(st)) 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_released(struct FsmInst *fi, int event, void *arg) 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!get_PollFlag(st, skb)) { 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2_mdl_error_ua(fi, event, arg); 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 828672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 6); 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lapb_dl_release_l2l3(st, CONFIRM); 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_reestablish(struct FsmInst *fi, int event, void *arg) 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!get_PollFlagFree(st, skb)) { 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L3_INIT, &st->l2.flag); 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st5_dm_release(struct FsmInst *fi, int event, void *arg) 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_PollFlagFree(st, skb)) { 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 7); 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_bit(FLG_L3_INIT, &st->l2.flag)) 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st5_dl_release_l2l3(st); 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st6_dm_release(struct FsmInst *fi, int event, void *arg) 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_PollFlagFree(st, skb)) { 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 8); 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lapb_dl_release_l2l3(st, CONFIRM); 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 877672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf) 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2; 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char tmp[MAX_HEADER_LEN]; 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2 = &st->l2; 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = sethdraddr(l2, tmp, cr); 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &l2->flag)) { 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp[i++] = typ; 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0); 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0); 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(skb = alloc_skb(i, GFP_ATOMIC))) { 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "isdl2 can't alloc sbbuff for enquiry_cr\n"); 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(skb_put(skb, i), tmp, i); 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enqueue_super(st, skb); 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 900672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenquiry_response(struct PStack *st) 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RNR, RSP, 1); 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RR, RSP, 1); 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 910672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstransmit_enquiry(struct PStack *st) 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RNR, CMD, 1); 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RR, CMD, 1); 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_t200(st, 9); 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsnrerrorrecovery(struct FsmInst *fi) 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'J'); 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsinvoke_retransmission(struct PStack *st, unsigned int nr) 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_int p1; 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&l2->lock, flags); 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (l2->vs != nr) { 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (l2->vs != nr) { 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (l2->vs)--; 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(test_bit(FLG_MOD128, &l2->flag)) { 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vs %= 128; 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (l2->vs - l2->va) % 128; 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vs %= 8; 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (l2->vs - l2->va) % 8; 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (p1 + l2->sow) % l2->window; 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &l2->flag)) 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs->tx_cnt += l2->windowar[p1]->len + l2headersize(l2, 0); 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head(&l2->i_queue, l2->windowar[p1]); 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->windowar[p1] = NULL; 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&l2->lock, flags); 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&l2->lock, flags); 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st7_got_super(struct FsmInst *fi, int event, void *arg) 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int PollFlag, rsp, typ = RR; 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int nr; 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = *skb->data & 0x2; 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &l2->flag)) 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(skb, l2addrsize(l2)); 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IsRNR(skb->data, st)) { 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_peer_busy(l2); 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds typ = RNR; 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_peer_busy(l2); 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IsREJ(skb->data, st)) 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds typ = REJ; 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &l2->flag)) { 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = (skb->data[1] & 0x1) == 0x1; 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = skb->data[1] >> 1; 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = (skb->data[0] & 0x10); 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = (skb->data[0] >> 5) & 0x7; 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 992672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (PollFlag) { 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rsp) 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'A'); 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_response(st); 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (legalnr(st, nr)) { 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (typ == REJ) { 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds invoke_retransmission(st, nr); 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 10); 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (FsmAddTimer(&st->l2.t203, st->l2.T203, 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T203, NULL, 6)) 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2m_debug(&st->l2.l2m, "Restart T203 ST7 REJ"); 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((nr == l2->vs) && (typ == RR)) { 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 11); 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmRestartTimer(&st->l2.t203, st->l2.T203, 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T203, NULL, 7); 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((l2->va != nr) || (typ == RNR)) { 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(typ != RR) FsmDelTimer(&st->l2.t203, 9); 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restart_t200(st, 12); 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1018b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&st->l2.i_queue) && (typ == RR)) 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nrerrorrecovery(fi); 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg) 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_bit(FLG_L3_INIT, &st->l2.flag)) 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.i_queue, skb); 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1035672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_feed_i_pull(struct FsmInst *fi, int event, void *arg) 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.i_queue, skb); 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_feed_iqueue(struct FsmInst *fi, int event, void *arg) 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.i_queue, skb); 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_got_iframe(struct FsmInst *fi, int event, void *arg) 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &(st->l2); 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int PollFlag, ns, i; 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int nr; 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = l2addrsize(l2); 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &l2->flag)) { 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = ((skb->data[i + 1] & 0x1) == 0x1); 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ns = skb->data[i] >> 1; 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = (skb->data[i + 1] >> 1) & 0x7f; 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = (skb->data[i] & 0x10); 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ns = (skb->data[i] >> 1) & 0x7; 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = (skb->data[i] >> 5) & 0x7; 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_OWN_BUSY, &l2->flag)) { 1081672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(PollFlag) enquiry_response(st); 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (l2->vr == ns) { 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (l2->vr)++; 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(test_bit(FLG_MOD128, &l2->flag)) 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vr %= 128; 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vr %= 8; 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_REJEXC, &l2->flag); 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (PollFlag) 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_response(st); 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_ACK_PEND, &l2->flag); 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(skb, l2headersize(l2, 0)); 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_DATA | INDICATION, skb); 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* n(s)!=v(r) */ 1099672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_set_bit(FLG_REJEXC, &l2->flag)) { 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (PollFlag) 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_response(st); 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, REJ, RSP, PollFlag); 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &l2->flag); 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (legalnr(st, nr)) { 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_bit(FLG_PEER_BUSY, &st->l2.flag) && (fi->state == ST_L2_7)) { 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nr == st->l2.vs) { 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 13); 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmRestartTimer(&st->l2.t203, st->l2.T203, 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T203, NULL, 7); 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (nr != st->l2.va) 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restart_t200(st, 14); 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nrerrorrecovery(fi); 11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1124b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&st->l2.i_queue) && (fi->state == ST_L2_7)) 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag)) 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RR, RSP, 0); 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_got_tei(struct FsmInst *fi, int event, void *arg) 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = (long) arg; 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fi->state == ST_L2_3) { 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L3_INIT, &st->l2.flag); 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 1142b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&st->l2.ui_queue)) 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tx_ui(st); 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st5_tout_200(struct FsmInst *fi, int event, void *arg) 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) && 11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { 11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); 11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (st->l2.rc == st->l2.N200) { 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'G'); 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st5_dl_release_l2l3(st); 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc++; 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, (test_bit(FLG_MOD128, &st->l2.flag) ? SABME : SABM) 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | 0x10, CMD); 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st6_tout_200(struct FsmInst *fi, int event, void *arg) 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) && 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (st->l2.rc == st->l2.N200) { 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'H'); 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lapb_dl_release_l2l3(st, CONFIRM); 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc++; 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 9); 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, DISC | 0x10, CMD); 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st7_tout_200(struct FsmInst *fi, int event, void *arg) 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) && 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc = 0; 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_8); 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds transmit_enquiry(st); 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc++; 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st8_tout_200(struct FsmInst *fi, int event, void *arg) 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) && 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (st->l2.rc == st->l2.N200) { 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'I'); 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds transmit_enquiry(st); 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc++; 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st7_tout_203(struct FsmInst *fi, int event, void *arg) 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) && 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 9); 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_8); 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds transmit_enquiry(st); 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc = 0; 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_pull_iqueue(struct FsmInst *fi, int event, void *arg) 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb, *oskb; 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char header[MAX_HEADER_LEN]; 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int unsigned p1; 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!cansend(st)) 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb = skb_dequeue(&l2->i_queue); 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!skb) 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&l2->lock, flags); 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(test_bit(FLG_MOD128, &l2->flag)) 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (l2->vs - l2->va) % 128; 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (l2->vs - l2->va) % 8; 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (p1 + l2->sow) % l2->window; 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (l2->windowar[p1]) { 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n", 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1); 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(l2->windowar[p1]); 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->windowar[p1] = skb_clone(skb, GFP_ATOMIC); 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = sethdraddr(&st->l2, header, CMD); 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &l2->flag)) { 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header[i++] = l2->vs << 1; 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header[i++] = l2->vr << 1; 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vs = (l2->vs + 1) % 128; 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header[i++] = (l2->vr << 5) | (l2->vs << 1); 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vs = (l2->vs + 1) % 8; 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&l2->lock, flags); 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = skb->data - skb->head; 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p1 >= i) 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(skb_push(skb, i), header, i); 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "isdl2 pull_iqueue skb header(%d/%d) too short\n", i, p1); 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oskb = skb; 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb = alloc_skb(oskb->len + i, GFP_ATOMIC); 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(skb_put(skb, i), header, i); 1296d626f62b11e00c16e81e4308ab93d3f13551812aArnaldo Carvalho de Melo skb_copy_from_linear_data(oskb, 1297d626f62b11e00c16e81e4308ab93d3f13551812aArnaldo Carvalho de Melo skb_put(skb, oskb->len), oskb->len); 1298672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(oskb); 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | INDICATION, skb); 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(FLG_T200_RUN, &st->l2.flag)) { 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 13); 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 11); 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1306b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&l2->i_queue) && cansend(st)) 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st8_got_super(struct FsmInst *fi, int event, void *arg) 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int PollFlag, rsp, rnr = 0; 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int nr; 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = *skb->data & 0x2; 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &l2->flag)) 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(skb, l2addrsize(l2)); 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IsRNR(skb->data, st)) { 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_peer_busy(l2); 13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rnr = 1; 13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_peer_busy(l2); 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &l2->flag)) { 13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = (skb->data[1] & 0x1) == 0x1; 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = skb->data[1] >> 1; 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = (skb->data[0] & 0x10); 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = (skb->data[0] >> 5) & 0x7; 13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1338672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rsp && PollFlag) { 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (legalnr(st, nr)) { 13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rnr) { 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restart_t200(st, 15); 13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 16); 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&l2->t203, l2->T203, 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T203, NULL, 5); 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds invoke_retransmission(st, nr); 13511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_7); 1352b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&l2->i_queue) && cansend(st)) 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nrerrorrecovery(fi); 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!rsp && PollFlag) 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_response(st); 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (legalnr(st, nr)) { 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nrerrorrecovery(fi); 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_got_FRMR(struct FsmInst *fi, int event, void *arg) 13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(skb, l2addrsize(&st->l2) + 1); 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */ 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (IsUA(skb->data) && (fi->state == ST_L2_7))) { 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'K'); 13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1380672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st24_tei_remove(struct FsmInst *fi, int event, void *arg) 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = -1; 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_1); 13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st3_tei_remove(struct FsmInst *fi, int event, void *arg) 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = -1; 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_1); 14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st5_tei_remove(struct FsmInst *fi, int event, void *arg) 14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = -1; 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 17); 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st5_dl_release_l2l3(st); 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_1); 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st6_tei_remove(struct FsmInst *fi, int event, void *arg) 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = -1; 14251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 18); 14261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); 14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_1); 14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_tei_remove(struct FsmInst *fi, int event, void *arg) 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = -1; 14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 17); 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 19); 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_1); 14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14466b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardtl2_st14_persistent_da(struct FsmInst *fi, int event, void *arg) 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag)) 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14576b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardtl2_st5_persistent_da(struct FsmInst *fi, int event, void *arg) 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 19); 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st5_dl_release_l2l3(st); 14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14706b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardtl2_st6_persistent_da(struct FsmInst *fi, int event, void *arg) 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 20); 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14816b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardtl2_persistent_da(struct FsmInst *fi, int event, void *arg) 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 19); 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 19); 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_set_own_busy(struct FsmInst *fi, int event, void *arg) 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!test_and_set_bit(FLG_OWN_BUSY, &st->l2.flag)) { 15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RNR, RSP, 0); 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_clear_own_busy(struct FsmInst *fi, int event, void *arg) 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!test_and_clear_bit(FLG_OWN_BUSY, &st->l2.flag)) { 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RR, RSP, 0); 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_frame_error(struct FsmInst *fi, int event, void *arg) 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, arg); 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_frame_error_reest(struct FsmInst *fi, int event, void *arg) 15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, arg); 15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct FsmNode L2FnList[] __initdata = 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign}, 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3}, 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish}, 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3}, 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish}, 15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish}, 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release}, 15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel}, 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect}, 15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect}, 15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest}, 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull}, 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue}, 15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_1, EV_L2_DL_UNIT_DATA, l2_queue_ui_assign}, 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L2_DL_UNIT_DATA, l2_queue_ui}, 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_3, EV_L2_DL_UNIT_DATA, l2_queue_ui}, 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_DL_UNIT_DATA, l2_send_ui}, 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DL_UNIT_DATA, l2_send_ui}, 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_DL_UNIT_DATA, l2_send_ui}, 15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DL_UNIT_DATA, l2_send_ui}, 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DL_UNIT_DATA, l2_send_ui}, 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei}, 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei}, 15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei}, 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L2_MDL_ERROR, l2_st24_tei_remove}, 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove}, 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove}, 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove}, 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_tei_remove}, 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove}, 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove}, 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_SABME, l2_start_multi}, 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_SABME, l2_send_UA}, 15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_SABME, l2_send_DM}, 15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_SABME, l2_restart_multi}, 15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_SABME, l2_restart_multi}, 15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_DISC, l2_send_DM}, 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DISC, l2_send_DM}, 15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_DISC, l2_send_UA}, 15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DISC, l2_stop_multi}, 15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DISC, l2_stop_multi}, 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_UA, l2_mdl_error_ua}, 15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_UA, l2_connected}, 15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_UA, l2_released}, 15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_UA, l2_mdl_error_ua}, 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_UA, l2_mdl_error_ua}, 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_DM, l2_reestablish}, 15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DM, l2_st5_dm_release}, 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_DM, l2_st6_dm_release}, 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DM, l2_mdl_error_dm}, 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DM, l2_st8_mdl_error_dm}, 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_1, EV_L2_UI, l2_got_ui}, 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L2_UI, l2_got_ui}, 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_3, EV_L2_UI, l2_got_ui}, 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_UI, l2_got_ui}, 15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_UI, l2_got_ui}, 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_UI, l2_got_ui}, 15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_UI, l2_got_ui}, 15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_UI, l2_got_ui}, 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_FRMR, l2_got_FRMR}, 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_FRMR, l2_got_FRMR}, 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_SUPER, l2_st7_got_super}, 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_SUPER, l2_st8_got_super}, 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_I, l2_got_iframe}, 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_I, l2_got_iframe}, 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_T200, l2_st5_tout_200}, 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_T200, l2_st6_tout_200}, 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_T200, l2_st7_tout_200}, 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_T200, l2_st8_tout_200}, 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_T203, l2_st7_tout_203}, 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue}, 16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy}, 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy}, 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy}, 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy}, 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error}, 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error}, 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error}, 16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest}, 16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest}, 16166b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da}, 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove}, 16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove}, 16196b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da}, 16206b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da}, 16216b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da}, 16226b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da}, 16236b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da}, 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsisdnl2_l1l2(struct PStack *st, int pr, void *arg) 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *datap; 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 1, len; 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (pr) { 16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (PH_DATA | INDICATION): 16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds datap = skb->data; 16371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = l2addrsize(&st->l2); 16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len > len) 16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds datap += len; 16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N'); 1642672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(*datap & 1)) { /* I-Frame */ 16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(c = iframe_error(st, skb))) 16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = FsmEvent(&st->l2.l2m, EV_L2_I, skb); 16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (IsSFrame(datap, st)) { /* S-Frame */ 16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(c = super_error(st, skb))) 16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = FsmEvent(&st->l2.l2m, EV_L2_SUPER, skb); 16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (IsUI(datap)) { 16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(c = UI_error(st, skb))) 16531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = FsmEvent(&st->l2.l2m, EV_L2_UI, skb); 16541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (IsSABME(datap, st)) { 16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(c = unnum_error(st, skb, CMD))) 16561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = FsmEvent(&st->l2.l2m, EV_L2_SABME, skb); 16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (IsUA(datap)) { 16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(c = unnum_error(st, skb, RSP))) 16591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = FsmEvent(&st->l2.l2m, EV_L2_UA, skb); 16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (IsDISC(datap)) { 16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(c = unnum_error(st, skb, CMD))) 16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, skb); 16631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (IsDM(datap)) { 16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(c = unnum_error(st, skb, RSP))) 16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = FsmEvent(&st->l2.l2m, EV_L2_DM, skb); 16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (IsFRMR(datap)) { 16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!(c = FRMR_error(st,skb))) 16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb); 16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 16701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L'); 1671672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = 0; 16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(c) { 1675672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c); 16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = 0; 16781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret) 1680672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (PH_PULL | CONFIRM): 16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg); 16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (PH_PAUSE | INDICATION): 16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_DCHAN_BUSY, &st->l2.flag); 16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (PH_PAUSE | CONFIRM): 16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_DCHAN_BUSY, &st->l2.flag); 16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (PH_ACTIVATE | CONFIRM): 16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (PH_ACTIVATE | INDICATION): 16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L1_ACTIV, &st->l2.flag); 16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag)) 16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg); 16961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (PH_DEACTIVATE | INDICATION): 16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (PH_DEACTIVATE | CONFIRM): 16991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L1_ACTIV, &st->l2.flag); 17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L1_DEACTIVATE, arg); 17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2m_debug(&st->l2.l2m, "l2 unknown pr %04x", pr); 17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsisdnl2_l3l2(struct PStack *st, int pr, void *arg) 17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (pr) { 17121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (DL_DATA | REQUEST): 17131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg)) { 17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb((struct sk_buff *) arg); 17151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (DL_UNIT_DATA | REQUEST): 17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg)) { 17191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb((struct sk_buff *) arg); 17201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (DL_ESTABLISH | REQUEST): 17231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_L1_ACTIV, &st->l2.flag)) { 17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) || 17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_bit(FLG_ORIG, &st->l2.flag)) { 17261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg); 17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) || 17301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_bit(FLG_ORIG, &st->l2.flag)) { 17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_ESTAB_PEND, &st->l2.flag); 17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_ACTIVATE, NULL); 17341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (DL_RELEASE | REQUEST): 17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) { 17381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_DEACTIVATE, NULL); 17391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE_REQ, arg); 17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (MDL_ASSIGN | REQUEST): 17431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L2_MDL_ASSIGN, arg); 17441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (MDL_REMOVE | REQUEST): 17461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L2_MDL_REMOVE, arg); 17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (MDL_ERROR | RESPONSE): 17491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmEvent(&st->l2.l2m, EV_L2_MDL_ERROR, arg); 17501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsreleasestack_isdnl2(struct PStack *st) 17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t200, 21); 17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 16); 17591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ReleaseWin(&st->l2); 17621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 17651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2m_debug(struct FsmInst *fi, char *fmt, ...) 17661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_list args; 17681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 17691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_start(args, fmt); 17711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VHiSax_putstatus(st->l1.hardware, st->l2.debug_id, fmt, args); 17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_end(args); 17731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 17761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetstack_isdnl2(struct PStack *st, char *debug_id) 17771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&st->l2.lock); 17791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.l1l2 = isdnl2_l1l2; 17801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l3.l3l2 = isdnl2_l3l2; 17811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head_init(&st->l2.i_queue); 17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head_init(&st->l2.ui_queue); 17841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds InitWin(&st->l2); 17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.debug = 0; 17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.fsm = &l2fsm; 17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.state = ST_L2_4; 17901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 17911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.state = ST_L2_1; 17921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.debug = 0; 17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.userdata = st; 17941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.userint = 0; 17951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.printdebug = l2m_debug; 17961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(st->l2.debug_id, debug_id); 17971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmInitTimer(&st->l2.l2m, &st->l2.t200); 17991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmInitTimer(&st->l2.l2m, &st->l2.t203); 18001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 18031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstransl2_l3l2(struct PStack *st, int pr, void *arg) 18041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (pr) { 18061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (DL_DATA | REQUEST): 18071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (DL_UNIT_DATA | REQUEST): 18081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_DATA | REQUEST, arg); 18091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 18101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (DL_ESTABLISH | REQUEST): 18111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL); 18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 18131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case (DL_RELEASE | REQUEST): 18141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); 18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetstack_transl2(struct PStack *st) 18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l3.l3l2 = transl2_l3l2; 18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsreleasestack_transl2(struct PStack *st) 18271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init 18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsdnl2New(void) 18321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2fsm.state_count = L2_STATE_COUNT; 18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2fsm.event_count = L2_EVENT_COUNT; 18351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2fsm.strEvent = strL2Event; 18361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2fsm.strState = strL2State; 1837ba2d6ccb1df6ebb2c1b2322518ce7be25c1e3469Karsten Keil return FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList)); 18381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsdnl2Free(void) 18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmFree(&l2fsm); 18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1845