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> 6475be4d85a274d0961593db41cf85689db1d583cJoe Perches * 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> 195a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hisax.h" 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "isdnl2.h" 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsconst char *l2_revision = "$Revision: 2.30.2.4 $"; 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void l2m_debug(struct FsmInst *fi, char *fmt, ...); 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct Fsm l2fsm; 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum { 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_1, 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_2, 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_3, 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_4, 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_5, 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_6, 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_7, 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ST_L2_8, 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define L2_STATE_COUNT (ST_L2_8 + 1) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *strL2State[] = 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_1", 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_2", 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_3", 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_4", 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_5", 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_6", 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_7", 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ST_L2_8", 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum { 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_UI, 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_SABME, 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DISC, 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DM, 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_UA, 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_FRMR, 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_SUPER, 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_I, 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DL_DATA, 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_ACK_PULL, 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DL_UNIT_DATA, 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DL_ESTABLISH_REQ, 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_DL_RELEASE_REQ, 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_MDL_ASSIGN, 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_MDL_REMOVE, 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_MDL_ERROR, 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L1_DEACTIVATE, 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T200, 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T203, 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_SET_OWN_BUSY, 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_CLEAR_OWN_BUSY, 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_FRAME_ERROR, 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 79475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR + 1) 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *strL2Event[] = 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_UI", 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_SABME", 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DISC", 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DM", 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_UA", 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_FRMR", 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_SUPER", 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_I", 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DL_DATA", 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_ACK_PULL", 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DL_UNIT_DATA", 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DL_ESTABLISH_REQ", 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_DL_RELEASE_REQ", 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_MDL_ASSIGN", 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_MDL_REMOVE", 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_MDL_ERROR", 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L1_DEACTIVATE", 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_T200", 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_T203", 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_SET_OWN_BUSY", 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_CLEAR_OWN_BUSY", 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "EV_L2_FRAME_ERROR", 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int l2addrsize(struct Layer2 *l2); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsset_peer_busy(struct Layer2 *l2) { 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_PEER_BUSY, &l2->flag); 112b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&l2->i_queue) || 113b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller !skb_queue_empty(&l2->ui_queue)) 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L2BLOCK, &l2->flag); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsclear_peer_busy(struct Layer2 *l2) { 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_PEER_BUSY, &l2->flag)) 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L2BLOCK, &l2->flag); 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsInitWin(struct Layer2 *l2) 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_WINDOW; i++) 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->windowar[i] = NULL; 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfreewin1(struct Layer2 *l2) 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, cnt = 0; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_WINDOW; i++) { 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (l2->windowar[i]) { 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt++; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(l2->windowar[i]); 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->windowar[i] = NULL; 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return cnt; 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 147672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfreewin(struct PStack *st) 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin1(&st->l2); 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsReleaseWin(struct Layer2 *l2) 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cnt; 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 158475be4d85a274d0961593db41cf85689db1d583cJoe Perches if ((cnt = freewin1(l2))) 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt); 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 162672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline unsigned int 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscansend(struct PStack *st) 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int p1; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 167475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_MOD128, &st->l2.flag)) 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (st->l2.vs - st->l2.va) % 128; 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (st->l2.vs - st->l2.va) % 8; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((p1 < st->l2.window) && !test_bit(FLG_PEER_BUSY, &st->l2.flag)); 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 174672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsclear_exception(struct Layer2 *l2) 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &l2->flag); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_REJEXC, &l2->flag); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_OWN_BUSY, &l2->flag); 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_peer_busy(l2); 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 183672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2headersize(struct Layer2 *l2, int ui) 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) + 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1)); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsinline int 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2addrsize(struct Layer2 *l2) 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1); 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 197475be4d85a274d0961593db41cf85689db1d583cJoe Perchessethdraddr(struct Layer2 *l2, u_char *header, int rsp) 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *ptr = header; 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int crbit = rsp; 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &l2->flag)) { 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = (l2->sap << 2) | (rsp ? 2 : 0); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = (l2->tei << 1) | 1; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (2); 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &l2->flag)) 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds crbit = !crbit; 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (crbit) 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = 1; 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ptr++ = 3; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21777933d7276ee8fa0e2947641941a6f7a100a327bJesper Juhlstatic inline void 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenqueue_super(struct PStack *st, 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb) 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs->tx_cnt += skb->len; 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_DATA | REQUEST, skb); 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define enqueue_ui(a, b) enqueue_super(a, b) 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 228672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 229475be4d85a274d0961593db41cf85689db1d583cJoe PerchesIsUI(u_char *data) 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((data[0] & 0xef) == UI); 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 234672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 235475be4d85a274d0961593db41cf85689db1d583cJoe PerchesIsUA(u_char *data) 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((data[0] & 0xef) == UA); 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 240672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 241475be4d85a274d0961593db41cf85689db1d583cJoe PerchesIsDM(u_char *data) 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((data[0] & 0xef) == DM); 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 246672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 247475be4d85a274d0961593db41cf85689db1d583cJoe PerchesIsDISC(u_char *data) 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((data[0] & 0xef) == DISC); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 252672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 253475be4d85a274d0961593db41cf85689db1d583cJoe PerchesIsSFrame(u_char *data, struct PStack *st) 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register u_char d = *data; 256475be4d85a274d0961593db41cf85689db1d583cJoe Perches 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_bit(FLG_MOD128, &st->l2.flag)) 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds d &= 0xf; 259475be4d85a274d0961593db41cf85689db1d583cJoe Perches return (((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c)); 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 262672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 263475be4d85a274d0961593db41cf85689db1d583cJoe PerchesIsSABME(u_char *data, struct PStack *st) 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char d = data[0] & ~0x10; 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (test_bit(FLG_MOD128, &st->l2.flag) ? d == SABME : d == SABM); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 270672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 271475be4d85a274d0961593db41cf85689db1d583cJoe PerchesIsREJ(u_char *data, struct PStack *st) 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == REJ : (data[0] & 0xf) == REJ); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 276672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 277475be4d85a274d0961593db41cf85689db1d583cJoe PerchesIsFRMR(u_char *data) 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((data[0] & 0xef) == FRMR); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 282672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline int 283475be4d85a274d0961593db41cf85689db1d583cJoe PerchesIsRNR(u_char *data, struct PStack *st) 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == RNR : (data[0] & 0xf) == RNR); 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 288672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsiframe_error(struct PStack *st, struct sk_buff *skb) 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1); 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rsp = *skb->data & 0x2; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &st->l2.flag)) 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rsp) 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'L'; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len < i) 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'N'; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((skb->len - i) > st->l2.maxlen) 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'O'; 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuper_error(struct PStack *st, struct sk_buff *skb) 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len != l2addrsize(&st->l2) + 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1)) 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'N'; 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 321672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp) 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rsp = (*skb->data & 0x2) >> 1; 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &st->l2.flag)) 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rsp != wantrsp) 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'L'; 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len != l2addrsize(&st->l2) + 1) 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'N'; 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 337672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsUI_error(struct PStack *st, struct sk_buff *skb) 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rsp = *skb->data & 0x2; 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &st->l2.flag)) 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rsp) 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'L'; 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len > st->l2.maxlen + l2addrsize(&st->l2) + 1) 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'O'; 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 353672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic int 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsFRMR_error(struct PStack *st, struct sk_buff *skb) 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int headers = l2addrsize(&st->l2) + 1; 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *datap = skb->data + headers; 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rsp = *skb->data & 0x2; 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &st->l2.flag)) 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!rsp) 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'L'; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &st->l2.flag)) { 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len < headers + 5) 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'N'; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x %2x %2x", 371475be4d85a274d0961593db41cf85689db1d583cJoe Perches datap[0], datap[1], datap[2], 372475be4d85a274d0961593db41cf85689db1d583cJoe Perches datap[3], datap[4]); 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (skb->len < headers + 3) 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 'N'; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2m_debug(&st->l2.l2m, "FRMR information %2x %2x %2x", 378475be4d85a274d0961593db41cf85689db1d583cJoe Perches datap[0], datap[1], datap[2]); 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslegalnr(struct PStack *st, unsigned int nr) 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 387475be4d85a274d0961593db41cf85689db1d583cJoe Perches struct Layer2 *l2 = &st->l2; 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 389475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_MOD128, &l2->flag)) 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128); 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8); 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetva(struct PStack *st, unsigned int nr) 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&l2->lock, flags); 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (l2->va != nr) { 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (l2->va)++; 405475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_MOD128, &l2->flag)) 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->va %= 128; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->va %= 8; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = l2->windowar[l2->sow]->len; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (PACKET_NOACK == l2->windowar[l2->sow]->pkt_type) 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = -1; 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(l2->windowar[l2->sow]); 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->windowar[l2->sow] = NULL; 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->sow = (l2->sow + 1) % l2->window; 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&l2->lock, flags); 416475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_LLI_L2WAKEUP, &st->lli.flag) && (len >= 0)) 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lli_writewakeup(st, len); 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&l2->lock, flags); 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&l2->lock, flags); 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssend_uframe(struct PStack *st, u_char cmd, u_char cr) 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char tmp[MAX_HEADER_LEN]; 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = sethdraddr(&st->l2, tmp, cr); 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp[i++] = cmd; 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(skb = alloc_skb(i, GFP_ATOMIC))) { 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "isdl2 can't alloc sbbuff for send_uframe\n"); 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(skb_put(skb, i), tmp, i); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enqueue_super(st, skb); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 440672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline u_char 441475be4d85a274d0961593db41cf85689db1d583cJoe Perchesget_PollFlag(struct PStack *st, struct sk_buff *skb) 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (skb->data[l2addrsize(&(st->l2))] & 0x10); 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 446672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline u_char 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsget_PollFlagFree(struct PStack *st, struct sk_buff *skb) 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char PF; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PF = get_PollFlag(st, skb); 452672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (PF); 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 456672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstart_t200(struct PStack *st, int i) 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_T200_RUN, &st->l2.flag); 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 463672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrestart_t200(struct PStack *st, int i) 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i); 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_T200_RUN, &st->l2.flag); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 470672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstop_t200(struct PStack *st, int i) 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 473475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag)) 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t200, i); 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 477672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsst5_dl_release_l2l3(struct PStack *st) 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 480475be4d85a274d0961593db41cf85689db1d583cJoe Perches int pr; 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 482475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) 483475be4d85a274d0961593db41cf85689db1d583cJoe Perches pr = DL_RELEASE | CONFIRM; 484475be4d85a274d0961593db41cf85689db1d583cJoe Perches else 485475be4d85a274d0961593db41cf85689db1d583cJoe Perches pr = DL_RELEASE | INDICATION; 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 487475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l2.l2l3(st, pr, NULL); 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 490672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslapb_dl_release_l2l3(struct PStack *st, int f) 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 493475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_LAPB, &st->l2.flag)) 494475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); 495475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l2.l2l3(st, DL_RELEASE | f, NULL); 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsestablishlink(struct FsmInst *fi) 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char cmd; 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_exception(&st->l2); 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc = 0; 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmd = (test_bit(FLG_MOD128, &st->l2.flag) ? SABME : SABM) | 0x10; 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, cmd, CMD); 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 1); 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restart_t200(st, 1); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_PEND_REL, &st->l2.flag); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_5); 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_mdl_error_ua(struct FsmInst *fi, int event, void *arg) 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_PollFlagFree(st, skb)) 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'C'); 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'D'); 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_mdl_error_dm(struct FsmInst *fi, int event, void *arg) 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_PollFlagFree(st, skb)) 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg) 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_PollFlagFree(st, skb)) 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B'); 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E'); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_go_st3(struct FsmInst *fi, int event, void *arg) 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 560475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmChangeState(fi, ST_L2_3); 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_mdl_assign(struct FsmInst *fi, int event, void *arg) 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 568475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmChangeState(fi, ST_L2_3); 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL); 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_queue_ui_assign(struct FsmInst *fi, int event, void *arg) 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.ui_queue, skb); 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_2); 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL); 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_queue_ui(struct FsmInst *fi, int event, void *arg) 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.ui_queue, skb); 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstx_ui(struct PStack *st) 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char header[MAX_HEADER_LEN]; 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = sethdraddr(&(st->l2), header, CMD); 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header[i++] = UI; 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((skb = skb_dequeue(&st->l2.ui_queue))) { 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(skb_push(skb, i), header, i); 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enqueue_ui(st, skb); 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_send_ui(struct FsmInst *fi, int event, void *arg) 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.ui_queue, skb); 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tx_ui(st); 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_got_ui(struct FsmInst *fi, int event, void *arg) 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(skb, l2headersize(&st->l2, 1)); 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_UNIT_DATA | INDICATION, skb); 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in states 1-3 for broadcast 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_establish(struct FsmInst *fi, int event, void *arg) 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L3_INIT, &st->l2.flag); 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_discard_i_setl3(struct FsmInst *fi, int event, void *arg) 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L3_INIT, &st->l2.flag); 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_PEND_REL, &st->l2.flag); 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_l3_reestablish(struct FsmInst *fi, int event, void *arg) 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L3_INIT, &st->l2.flag); 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_release(struct FsmInst *fi, int event, void *arg) 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_pend_rel(struct FsmInst *fi, int event, void *arg) 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_PEND_REL, &st->l2.flag); 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_disconnect(struct FsmInst *fi, int event, void *arg) 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_6); 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc = 0; 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, DISC | 0x10, CMD); 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 1); 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restart_t200(st, 2); 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_start_multi(struct FsmInst *fi, int event, void *arg) 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_exception(&st->l2); 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vs = 0; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.va = 0; 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vr = 0; 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.sow = 0; 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_7); 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 3); 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL); 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_send_UA(struct FsmInst *fi, int event, void *arg) 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_send_DM(struct FsmInst *fi, int event, void *arg) 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, DM | get_PollFlagFree(st, skb), RSP); 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_restart_multi(struct FsmInst *fi, int event, void *arg) 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int est = 0, state; 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds state = fi->state; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'F'); 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (st->l2.vs != st->l2.va) { 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds est = 1; 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_exception(&st->l2); 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vs = 0; 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.va = 0; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vr = 0; 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.sow = 0; 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_7); 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 3); 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmRestartTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 3); 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (est) 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL); 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 758475be4d85a274d0961593db41cf85689db1d583cJoe Perches if ((ST_L2_7 == state) || (ST_L2_8 == state)) 759b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&st->l2.i_queue) && cansend(st)) 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_stop_multi(struct FsmInst *fi, int event, void *arg) 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 3); 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 4); 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, UA | get_PollFlagFree(st, skb), RSP); 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lapb_dl_release_l2l3(st, INDICATION); 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_connected(struct FsmInst *fi, int event, void *arg) 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 785475be4d85a274d0961593db41cf85689db1d583cJoe Perches int pr = -1; 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!get_PollFlag(st, skb)) { 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2_mdl_error_ua(fi, event, arg); 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 791672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag)) 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2_disconnect(fi, event, arg); 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_L3_INIT, &st->l2.flag)) { 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr = DL_ESTABLISH | CONFIRM; 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (st->l2.vs != st->l2.va) { 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pr = DL_ESTABLISH | INDICATION; 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 5); 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vr = 0; 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.vs = 0; 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.va = 0; 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.sow = 0; 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_7); 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 4); 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pr != -1) 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, pr, NULL); 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 815b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&st->l2.i_queue) && cansend(st)) 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_released(struct FsmInst *fi, int event, void *arg) 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!get_PollFlag(st, skb)) { 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2_mdl_error_ua(fi, event, arg); 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 829672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 6); 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lapb_dl_release_l2l3(st, CONFIRM); 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_reestablish(struct FsmInst *fi, int event, void *arg) 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!get_PollFlagFree(st, skb)) { 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L3_INIT, &st->l2.flag); 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st5_dm_release(struct FsmInst *fi, int event, void *arg) 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_PollFlagFree(st, skb)) { 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 7); 856475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!test_bit(FLG_L3_INIT, &st->l2.flag)) 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st5_dl_release_l2l3(st); 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st6_dm_release(struct FsmInst *fi, int event, void *arg) 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_PollFlagFree(st, skb)) { 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 8); 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lapb_dl_release_l2l3(st, CONFIRM); 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 878672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf) 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb; 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2; 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char tmp[MAX_HEADER_LEN]; 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2 = &st->l2; 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = sethdraddr(l2, tmp, cr); 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &l2->flag)) { 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp[i++] = typ; 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0); 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0); 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(skb = alloc_skb(i, GFP_ATOMIC))) { 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "isdl2 can't alloc sbbuff for enquiry_cr\n"); 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(skb_put(skb, i), tmp, i); 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enqueue_super(st, skb); 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenquiry_response(struct PStack *st) 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RNR, RSP, 1); 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RR, RSP, 1); 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic inline void 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstransmit_enquiry(struct PStack *st) 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_OWN_BUSY, &st->l2.flag)) 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RNR, CMD, 1); 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RR, CMD, 1); 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_t200(st, 9); 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsnrerrorrecovery(struct FsmInst *fi) 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'J'); 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsinvoke_retransmission(struct PStack *st, unsigned int nr) 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_int p1; 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&l2->lock, flags); 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (l2->vs != nr) { 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (l2->vs != nr) { 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (l2->vs)--; 944475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_MOD128, &l2->flag)) { 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vs %= 128; 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (l2->vs - l2->va) % 128; 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vs %= 8; 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (l2->vs - l2->va) % 8; 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (p1 + l2->sow) % l2->window; 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &l2->flag)) 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs->tx_cnt += l2->windowar[p1]->len + l2headersize(l2, 0); 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head(&l2->i_queue, l2->windowar[p1]); 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->windowar[p1] = NULL; 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&l2->lock, flags); 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&l2->lock, flags); 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st7_got_super(struct FsmInst *fi, int event, void *arg) 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int PollFlag, rsp, typ = RR; 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int nr; 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = *skb->data & 0x2; 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &l2->flag)) 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(skb, l2addrsize(l2)); 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IsRNR(skb->data, st)) { 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_peer_busy(l2); 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds typ = RNR; 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_peer_busy(l2); 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IsREJ(skb->data, st)) 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds typ = REJ; 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &l2->flag)) { 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = (skb->data[1] & 0x1) == 0x1; 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = skb->data[1] >> 1; 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = (skb->data[0] & 0x10); 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = (skb->data[0] >> 5) & 0x7; 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 993672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (PollFlag) { 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rsp) 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'A'); 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_response(st); 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (legalnr(st, nr)) { 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (typ == REJ) { 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds invoke_retransmission(st, nr); 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 10); 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (FsmAddTimer(&st->l2.t203, st->l2.T203, 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T203, NULL, 6)) 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2m_debug(&st->l2.l2m, "Restart T203 ST7 REJ"); 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((nr == l2->vs) && (typ == RR)) { 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 11); 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmRestartTimer(&st->l2.t203, st->l2.T203, 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T203, NULL, 7); 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((l2->va != nr) || (typ == RNR)) { 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 1016475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (typ != RR) FsmDelTimer(&st->l2.t203, 9); 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restart_t200(st, 12); 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1019b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&st->l2.i_queue) && (typ == RR)) 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nrerrorrecovery(fi); 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg) 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_bit(FLG_L3_INIT, &st->l2.flag)) 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.i_queue, skb); 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1036672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_feed_i_pull(struct FsmInst *fi, int event, void *arg) 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.i_queue, skb); 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_feed_iqueue(struct FsmInst *fi, int event, void *arg) 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.bcs->tx_cnt += skb->len + l2headersize(&st->l2, 0); 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_tail(&st->l2.i_queue, skb); 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_got_iframe(struct FsmInst *fi, int event, void *arg) 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &(st->l2); 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int PollFlag, ns, i; 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int nr; 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = l2addrsize(l2); 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &l2->flag)) { 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = ((skb->data[i + 1] & 0x1) == 0x1); 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ns = skb->data[i] >> 1; 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = (skb->data[i + 1] >> 1) & 0x7f; 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = (skb->data[i] & 0x10); 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ns = (skb->data[i] >> 1) & 0x7; 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = (skb->data[i] >> 5) & 0x7; 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_OWN_BUSY, &l2->flag)) { 1082672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 1083475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (PollFlag) enquiry_response(st); 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (l2->vr == ns) { 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (l2->vr)++; 1086475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_MOD128, &l2->flag)) 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vr %= 128; 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vr %= 8; 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_REJEXC, &l2->flag); 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (PollFlag) 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_response(st); 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_ACK_PEND, &l2->flag); 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(skb, l2headersize(l2, 0)); 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_DATA | INDICATION, skb); 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* n(s)!=v(r) */ 1100672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_set_bit(FLG_REJEXC, &l2->flag)) { 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (PollFlag) 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_response(st); 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, REJ, RSP, PollFlag); 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &l2->flag); 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (legalnr(st, nr)) { 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_bit(FLG_PEER_BUSY, &st->l2.flag) && (fi->state == ST_L2_7)) { 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nr == st->l2.vs) { 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 13); 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmRestartTimer(&st->l2.t203, st->l2.T203, 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T203, NULL, 7); 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (nr != st->l2.va) 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restart_t200(st, 14); 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nrerrorrecovery(fi); 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1125b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&st->l2.i_queue) && (fi->state == ST_L2_7)) 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag)) 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RR, RSP, 0); 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_got_tei(struct FsmInst *fi, int event, void *arg) 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = (long) arg; 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fi->state == ST_L2_3) { 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_set_bit(FLG_L3_INIT, &st->l2.flag); 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 1143b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&st->l2.ui_queue)) 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tx_ui(st); 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st5_tout_200(struct FsmInst *fi, int event, void *arg) 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) && 1153475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { 11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (st->l2.rc == st->l2.N200) { 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'G'); 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st5_dl_release_l2l3(st); 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc++; 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, (test_bit(FLG_MOD128, &st->l2.flag) ? SABME : SABM) 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | 0x10, CMD); 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st6_tout_200(struct FsmInst *fi, int event, void *arg) 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) && 1177475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (st->l2.rc == st->l2.N200) { 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'H'); 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lapb_dl_release_l2l3(st, CONFIRM); 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc++; 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 9); 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds send_uframe(st, DISC | 0x10, CMD); 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st7_tout_200(struct FsmInst *fi, int event, void *arg) 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) && 1198475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc = 0; 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_8); 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds transmit_enquiry(st); 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc++; 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st8_tout_200(struct FsmInst *fi, int event, void *arg) 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) && 1216475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 9); 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_T200_RUN, &st->l2.flag); 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (st->l2.rc == st->l2.N200) { 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'I'); 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds transmit_enquiry(st); 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc++; 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st7_tout_203(struct FsmInst *fi, int event, void *arg) 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPD, &st->l2.flag) && 1237475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_bit(FLG_DCHAN_BUSY, &st->l2.flag)) { 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t203, st->l2.T203, EV_L2_T203, NULL, 9); 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_8); 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds transmit_enquiry(st); 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.rc = 0; 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_pull_iqueue(struct FsmInst *fi, int event, void *arg) 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 1250c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller struct sk_buff *skb; 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char header[MAX_HEADER_LEN]; 1253c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller int i, hdr_space_needed; 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int unsigned p1; 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_long flags; 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!cansend(st)) 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb = skb_dequeue(&l2->i_queue); 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!skb) 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12646d90e8f45697c633f522269368297d7416fd8783David S. Miller hdr_space_needed = l2headersize(l2, 0); 1265c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller if (hdr_space_needed > skb_headroom(skb)) { 1266c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller struct sk_buff *orig_skb = skb; 1267c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller 1268c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller skb = skb_realloc_headroom(skb, hdr_space_needed); 1269c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller if (!skb) { 1270c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller dev_kfree_skb(orig_skb); 1271c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller return; 1272c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller } 1273c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller } 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&l2->lock, flags); 1275475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_MOD128, &l2->flag)) 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (l2->vs - l2->va) % 128; 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (l2->vs - l2->va) % 8; 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1 = (p1 + l2->sow) % l2->window; 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (l2->windowar[p1]) { 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n", 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p1); 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev_kfree_skb(l2->windowar[p1]); 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->windowar[p1] = skb_clone(skb, GFP_ATOMIC); 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = sethdraddr(&st->l2, header, CMD); 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &l2->flag)) { 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header[i++] = l2->vs << 1; 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header[i++] = l2->vr << 1; 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vs = (l2->vs + 1) % 128; 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds header[i++] = (l2->vr << 5) | (l2->vs << 1); 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2->vs = (l2->vs + 1) % 8; 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&l2->lock, flags); 1298c978e7bb77dfd2cd3d1f547fa4e395cfe47f02b2David S. Miller memcpy(skb_push(skb, i), header, i); 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | INDICATION, skb); 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!test_and_set_bit(FLG_T200_RUN, &st->l2.flag)) { 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 13); 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 11); 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1305b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&l2->i_queue) && cansend(st)) 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st8_got_super(struct FsmInst *fi, int event, void *arg) 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int PollFlag, rsp, rnr = 0; 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int nr; 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct Layer2 *l2 = &st->l2; 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = *skb->data & 0x2; 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_ORIG, &l2->flag)) 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rsp = !rsp; 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(skb, l2addrsize(l2)); 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (IsRNR(skb->data, st)) { 13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_peer_busy(l2); 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rnr = 1; 13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clear_peer_busy(l2); 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_MOD128, &l2->flag)) { 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = (skb->data[1] & 0x1) == 0x1; 13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = skb->data[1] >> 1; 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PollFlag = (skb->data[0] & 0x10); 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nr = (skb->data[0] >> 5) & 0x7; 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1337672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rsp && PollFlag) { 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (legalnr(st, nr)) { 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rnr) { 13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restart_t200(st, 15); 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 16); 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmAddTimer(&l2->t203, l2->T203, 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds EV_L2_T203, NULL, 5); 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds invoke_retransmission(st, nr); 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_7); 1351b03efcfb2180289718991bb984044ce6c5b7d1b0David S. Miller if (!skb_queue_empty(&l2->i_queue) && cansend(st)) 13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l1(st, PH_PULL | REQUEST, NULL); 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nrerrorrecovery(fi); 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!rsp && PollFlag) 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_response(st); 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (legalnr(st, nr)) { 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setva(st, nr); 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nrerrorrecovery(fi); 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_got_FRMR(struct FsmInst *fi, int event, void *arg) 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_pull(skb, l2addrsize(&st->l2) + 1); 13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */ 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (IsUA(skb->data) && (fi->state == ST_L2_7))) { 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'K'); 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1379672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunk dev_kfree_skb(skb); 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st24_tei_remove(struct FsmInst *fi, int event, void *arg) 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = -1; 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_1); 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st3_tei_remove(struct FsmInst *fi, int event, void *arg) 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 13961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = -1; 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_1); 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st5_tei_remove(struct FsmInst *fi, int event, void *arg) 14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = -1; 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 17); 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st5_dl_release_l2l3(st); 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_1); 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_st6_tei_remove(struct FsmInst *fi, int event, void *arg) 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = -1; 14241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 18); 14251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); 14261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_1); 14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_tei_remove(struct FsmInst *fi, int event, void *arg) 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.tei = -1; 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 17); 14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 19); 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_1); 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14456b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardtl2_st14_persistent_da(struct FsmInst *fi, int event, void *arg) 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 1448475be4d85a274d0961593db41cf85689db1d583cJoe Perches 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag)) 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14566b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardtl2_st5_persistent_da(struct FsmInst *fi, int event, void *arg) 14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 19); 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st5_dl_release_l2l3(st); 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14696b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardtl2_st6_persistent_da(struct FsmInst *fi, int event, void *arg) 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 20); 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL); 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14806b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardtl2_persistent_da(struct FsmInst *fi, int event, void *arg) 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds freewin(st); 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stop_t200(st, 19); 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 19); 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL); 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmChangeState(fi, ST_L2_4); 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_set_own_busy(struct FsmInst *fi, int event, void *arg) 14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1498475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!test_and_set_bit(FLG_OWN_BUSY, &st->l2.flag)) { 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RNR, RSP, 0); 15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_clear_own_busy(struct FsmInst *fi, int event, void *arg) 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1509475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!test_and_clear_bit(FLG_OWN_BUSY, &st->l2.flag)) { 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enquiry_cr(st, RR, RSP, 0); 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag); 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_frame_error(struct FsmInst *fi, int event, void *arg) 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, arg); 15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2_frame_error_reest(struct FsmInst *fi, int event, void *arg) 15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->ma.layer(st, MDL_ERROR | INDICATION, arg); 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds establishlink(fi); 15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds test_and_clear_bit(FLG_L3_INIT, &st->l2.flag); 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct FsmNode L2FnList[] __initdata = 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign}, 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3}, 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish}, 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3}, 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish}, 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish}, 15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release}, 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel}, 15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect}, 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect}, 15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest}, 15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull}, 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue}, 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_1, EV_L2_DL_UNIT_DATA, l2_queue_ui_assign}, 15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L2_DL_UNIT_DATA, l2_queue_ui}, 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_3, EV_L2_DL_UNIT_DATA, l2_queue_ui}, 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_DL_UNIT_DATA, l2_send_ui}, 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DL_UNIT_DATA, l2_send_ui}, 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_DL_UNIT_DATA, l2_send_ui}, 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DL_UNIT_DATA, l2_send_ui}, 15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DL_UNIT_DATA, l2_send_ui}, 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei}, 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei}, 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei}, 15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L2_MDL_ERROR, l2_st24_tei_remove}, 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove}, 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove}, 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove}, 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_tei_remove}, 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove}, 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove}, 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_SABME, l2_start_multi}, 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_SABME, l2_send_UA}, 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_SABME, l2_send_DM}, 15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_SABME, l2_restart_multi}, 15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_SABME, l2_restart_multi}, 15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_DISC, l2_send_DM}, 15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DISC, l2_send_DM}, 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_DISC, l2_send_UA}, 15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DISC, l2_stop_multi}, 15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DISC, l2_stop_multi}, 15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_UA, l2_mdl_error_ua}, 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_UA, l2_connected}, 15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_UA, l2_released}, 15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_UA, l2_mdl_error_ua}, 15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_UA, l2_mdl_error_ua}, 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_DM, l2_reestablish}, 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_DM, l2_st5_dm_release}, 15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_DM, l2_st6_dm_release}, 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_DM, l2_mdl_error_dm}, 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_DM, l2_st8_mdl_error_dm}, 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_1, EV_L2_UI, l2_got_ui}, 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L2_UI, l2_got_ui}, 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_3, EV_L2_UI, l2_got_ui}, 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_UI, l2_got_ui}, 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_UI, l2_got_ui}, 15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_UI, l2_got_ui}, 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_UI, l2_got_ui}, 15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_UI, l2_got_ui}, 15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_FRMR, l2_got_FRMR}, 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_FRMR, l2_got_FRMR}, 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_SUPER, l2_st7_got_super}, 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_SUPER, l2_st8_got_super}, 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_I, l2_got_iframe}, 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_I, l2_got_iframe}, 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_T200, l2_st5_tout_200}, 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_T200, l2_st6_tout_200}, 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_T200, l2_st7_tout_200}, 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_T200, l2_st8_tout_200}, 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_T203, l2_st7_tout_203}, 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue}, 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy}, 16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy}, 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy}, 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy}, 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error}, 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error}, 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error}, 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest}, 16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest}, 16156b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da}, 16161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove}, 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove}, 16186b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da}, 16196b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da}, 16206b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da}, 16216b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da}, 16226b44d4e69c6144d0df71ab47ec90d2009237d48fJan Engelhardt {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da}, 16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsisdnl2_l1l2(struct PStack *st, int pr, void *arg) 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct sk_buff *skb = arg; 16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u_char *datap; 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = 1, len; 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c = 0; 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (pr) { 1634475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DATA | INDICATION): 1635475be4d85a274d0961593db41cf85689db1d583cJoe Perches datap = skb->data; 1636475be4d85a274d0961593db41cf85689db1d583cJoe Perches len = l2addrsize(&st->l2); 1637475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (skb->len > len) 1638475be4d85a274d0961593db41cf85689db1d583cJoe Perches datap += len; 1639475be4d85a274d0961593db41cf85689db1d583cJoe Perches else { 1640475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N'); 1641475be4d85a274d0961593db41cf85689db1d583cJoe Perches dev_kfree_skb(skb); 1642475be4d85a274d0961593db41cf85689db1d583cJoe Perches return; 1643475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1644475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(*datap & 1)) { /* I-Frame */ 1645475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(c = iframe_error(st, skb))) 1646475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = FsmEvent(&st->l2.l2m, EV_L2_I, skb); 1647475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else if (IsSFrame(datap, st)) { /* S-Frame */ 1648475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(c = super_error(st, skb))) 1649475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = FsmEvent(&st->l2.l2m, EV_L2_SUPER, skb); 1650475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else if (IsUI(datap)) { 1651475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(c = UI_error(st, skb))) 1652475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = FsmEvent(&st->l2.l2m, EV_L2_UI, skb); 1653475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else if (IsSABME(datap, st)) { 1654475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(c = unnum_error(st, skb, CMD))) 1655475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = FsmEvent(&st->l2.l2m, EV_L2_SABME, skb); 1656475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else if (IsUA(datap)) { 1657475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(c = unnum_error(st, skb, RSP))) 1658475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = FsmEvent(&st->l2.l2m, EV_L2_UA, skb); 1659475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else if (IsDISC(datap)) { 1660475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(c = unnum_error(st, skb, CMD))) 1661475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, skb); 1662475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else if (IsDM(datap)) { 1663475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(c = unnum_error(st, skb, RSP))) 1664475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = FsmEvent(&st->l2.l2m, EV_L2_DM, skb); 1665475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else if (IsFRMR(datap)) { 1666475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (!(c = FRMR_error(st, skb))) 1667475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb); 1668475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 1669475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L'); 1670475be4d85a274d0961593db41cf85689db1d583cJoe Perches dev_kfree_skb(skb); 1671475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = 0; 1672475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1673475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (c) { 1674475be4d85a274d0961593db41cf85689db1d583cJoe Perches dev_kfree_skb(skb); 1675475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c); 1676475be4d85a274d0961593db41cf85689db1d583cJoe Perches ret = 0; 1677475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1678475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (ret) 1679475be4d85a274d0961593db41cf85689db1d583cJoe Perches dev_kfree_skb(skb); 1680475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1681475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PULL | CONFIRM): 1682475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg); 1683475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1684475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PAUSE | INDICATION): 1685475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_set_bit(FLG_DCHAN_BUSY, &st->l2.flag); 1686475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1687475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_PAUSE | CONFIRM): 1688475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_clear_bit(FLG_DCHAN_BUSY, &st->l2.flag); 1689475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1690475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_ACTIVATE | CONFIRM): 1691475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_ACTIVATE | INDICATION): 1692475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_set_bit(FLG_L1_ACTIV, &st->l2.flag); 1693475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_and_clear_bit(FLG_ESTAB_PEND, &st->l2.flag)) 1694475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg); 1695475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1696475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DEACTIVATE | INDICATION): 1697475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (PH_DEACTIVATE | CONFIRM): 1698475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_clear_bit(FLG_L1_ACTIV, &st->l2.flag); 1699475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L1_DEACTIVATE, arg); 1700475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1701475be4d85a274d0961593db41cf85689db1d583cJoe Perches default: 1702475be4d85a274d0961593db41cf85689db1d583cJoe Perches l2m_debug(&st->l2.l2m, "l2 unknown pr %04x", pr); 1703475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsisdnl2_l3l2(struct PStack *st, int pr, void *arg) 17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (pr) { 1711475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (DL_DATA | REQUEST): 1712475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg)) { 1713475be4d85a274d0961593db41cf85689db1d583cJoe Perches dev_kfree_skb((struct sk_buff *) arg); 1714475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1715475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1716475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (DL_UNIT_DATA | REQUEST): 1717475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg)) { 1718475be4d85a274d0961593db41cf85689db1d583cJoe Perches dev_kfree_skb((struct sk_buff *) arg); 1719475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1720475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1721475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (DL_ESTABLISH | REQUEST): 1722475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_L1_ACTIV, &st->l2.flag)) { 1723475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_LAPD, &st->l2.flag) || 1724475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_bit(FLG_ORIG, &st->l2.flag)) { 1725475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH_REQ, arg); 17261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1727475be4d85a274d0961593db41cf85689db1d583cJoe Perches } else { 1728475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_LAPD, &st->l2.flag) || 1729475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_bit(FLG_ORIG, &st->l2.flag)) { 1730475be4d85a274d0961593db41cf85689db1d583cJoe Perches test_and_set_bit(FLG_ESTAB_PEND, &st->l2.flag); 17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1732475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l2.l2l1(st, PH_ACTIVATE, NULL); 1733475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1734475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1735475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (DL_RELEASE | REQUEST): 1736475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (test_bit(FLG_LAPB, &st->l2.flag)) { 1737475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l2.l2l1(st, PH_DEACTIVATE, NULL); 1738475be4d85a274d0961593db41cf85689db1d583cJoe Perches } 1739475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE_REQ, arg); 1740475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1741475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (MDL_ASSIGN | REQUEST): 1742475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L2_MDL_ASSIGN, arg); 1743475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1744475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (MDL_REMOVE | REQUEST): 1745475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L2_MDL_REMOVE, arg); 1746475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1747475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (MDL_ERROR | RESPONSE): 1748475be4d85a274d0961593db41cf85689db1d583cJoe Perches FsmEvent(&st->l2.l2m, EV_L2_MDL_ERROR, arg); 1749475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 17501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsreleasestack_isdnl2(struct PStack *st) 17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t200, 21); 17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmDelTimer(&st->l2.t203, 16); 17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.i_queue); 17591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_purge(&st->l2.ui_queue); 17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ReleaseWin(&st->l2); 17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 17641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsl2m_debug(struct FsmInst *fi, char *fmt, ...) 17651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_list args; 17671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct PStack *st = fi->userdata; 17681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_start(args, fmt); 17701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VHiSax_putstatus(st->l1.hardware, st->l2.debug_id, fmt, args); 17711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_end(args); 17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 17751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetstack_isdnl2(struct PStack *st, char *debug_id) 17761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&st->l2.lock); 17781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l1.l1l2 = isdnl2_l1l2; 17791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l3.l3l2 = isdnl2_l3l2; 17801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head_init(&st->l2.i_queue); 17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds skb_queue_head_init(&st->l2.ui_queue); 17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds InitWin(&st->l2); 17841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.debug = 0; 17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.fsm = &l2fsm; 17871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_bit(FLG_LAPB, &st->l2.flag)) 17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.state = ST_L2_4; 17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1790475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l2.l2m.state = ST_L2_1; 17911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.debug = 0; 17921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.userdata = st; 17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.userint = 0; 17941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l2.l2m.printdebug = l2m_debug; 17951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(st->l2.debug_id, debug_id); 17961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmInitTimer(&st->l2.l2m, &st->l2.t200); 17981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmInitTimer(&st->l2.l2m, &st->l2.t203); 17991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 18021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstransl2_l3l2(struct PStack *st, int pr, void *arg) 18031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (pr) { 1805475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (DL_DATA | REQUEST): 1806475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (DL_UNIT_DATA | REQUEST): 1807475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l2.l2l1(st, PH_DATA | REQUEST, arg); 1808475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1809475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (DL_ESTABLISH | REQUEST): 1810475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL); 1811475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 1812475be4d85a274d0961593db41cf85689db1d583cJoe Perches case (DL_RELEASE | REQUEST): 1813475be4d85a274d0961593db41cf85689db1d583cJoe Perches st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL); 1814475be4d85a274d0961593db41cf85689db1d583cJoe Perches break; 18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 18191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetstack_transl2(struct PStack *st) 18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st->l3.l3l2 = transl2_l3l2; 18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsreleasestack_transl2(struct PStack *st) 18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init 18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsdnl2New(void) 18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2fsm.state_count = L2_STATE_COUNT; 18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2fsm.event_count = L2_EVENT_COUNT; 18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2fsm.strEvent = strL2Event; 18351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds l2fsm.strState = strL2State; 1836ba2d6ccb1df6ebb2c1b2322518ce7be25c1e3469Karsten Keil return FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList)); 18371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 18401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsIsdnl2Free(void) 18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FsmFree(&l2fsm); 18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1844