Blame view

net/lapb/lapb_in.c 17.5 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  /*
   *	LAPB release 002
   *
   *	This code REQUIRES 2.1.15 or higher/ NET3.038
   *
   *	This module:
   *		This module is free software; you can redistribute it and/or
   *		modify it under the terms of the GNU General Public License
   *		as published by the Free Software Foundation; either version
   *		2 of the License, or (at your option) any later version.
   *
   *	History
   *	LAPB 001	Jonathan Naulor	Started Coding
   *	LAPB 002	Jonathan Naylor	New timer architecture.
   *	2000-10-29	Henner Eisen	lapb_data_indication() return status.
   */
  
  #include <linux/errno.h>
  #include <linux/types.h>
  #include <linux/socket.h>
  #include <linux/in.h>
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
26
27
28
29
  #include <linux/timer.h>
  #include <linux/string.h>
  #include <linux/sockios.h>
  #include <linux/net.h>
  #include <linux/inet.h>
  #include <linux/netdevice.h>
  #include <linux/skbuff.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
30
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  #include <net/sock.h>
  #include <asm/uaccess.h>
  #include <asm/system.h>
  #include <linux/fcntl.h>
  #include <linux/mm.h>
  #include <linux/interrupt.h>
  #include <net/lapb.h>
  
  /*
   *	State machine for state 0, Disconnected State.
   *	The handling of the timer(s) is in file lapb_timer.c.
   */
  static void lapb_state0_machine(struct lapb_cb *lapb, struct sk_buff *skb,
  				struct lapb_frame *frame)
  {
  	switch (frame->type) {
fcb261f35   Joe Perches   lapb: Reduce swit...
47
  	case LAPB_SABM:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
49
50
51
  		printk(KERN_DEBUG "lapb: (%p) S0 RX SABM(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
53
  		if (lapb->mode & LAPB_EXTENDED) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
55
56
57
  			printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
59
60
61
  			lapb_send_control(lapb, LAPB_DM, frame->pf,
  					  LAPB_RESPONSE);
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
63
64
65
  			printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
  #endif
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
68
69
  			printk(KERN_DEBUG "lapb: (%p) S0 -> S3
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
71
72
73
74
75
76
77
78
79
80
81
82
83
  			lapb_send_control(lapb, LAPB_UA, frame->pf,
  					  LAPB_RESPONSE);
  			lapb_stop_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->state     = LAPB_STATE_3;
  			lapb->condition = 0x00;
  			lapb->n2count   = 0;
  			lapb->vs        = 0;
  			lapb->vr        = 0;
  			lapb->va        = 0;
  			lapb_connect_indication(lapb, LAPB_OK);
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84

fcb261f35   Joe Perches   lapb: Reduce swit...
85
  	case LAPB_SABME:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
87
88
89
  		printk(KERN_DEBUG "lapb: (%p) S0 RX SABME(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
91
  		if (lapb->mode & LAPB_EXTENDED) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
93
94
95
  			printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
  #endif
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
98
99
  			printk(KERN_DEBUG "lapb: (%p) S0 -> S3
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  			lapb_send_control(lapb, LAPB_UA, frame->pf,
  					  LAPB_RESPONSE);
  			lapb_stop_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->state     = LAPB_STATE_3;
  			lapb->condition = 0x00;
  			lapb->n2count   = 0;
  			lapb->vs        = 0;
  			lapb->vr        = 0;
  			lapb->va        = 0;
  			lapb_connect_indication(lapb, LAPB_OK);
  		} else {
  #if LAPB_DEBUG > 1
  			printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
118
119
120
121
  			lapb_send_control(lapb, LAPB_DM, frame->pf,
  					  LAPB_RESPONSE);
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122

fcb261f35   Joe Perches   lapb: Reduce swit...
123
  	case LAPB_DISC:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
125
126
127
128
129
130
  		printk(KERN_DEBUG "lapb: (%p) S0 RX DISC(%d)
  ",
  		       lapb->dev, frame->pf);
  		printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
132
133
  		lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134

fcb261f35   Joe Perches   lapb: Reduce swit...
135
136
  	default:
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
139
140
141
142
143
144
145
146
147
148
149
  	}
  
  	kfree_skb(skb);
  }
  
  /*
   *	State machine for state 1, Awaiting Connection State.
   *	The handling of the timer(s) is in file lapb_timer.c.
   */
  static void lapb_state1_machine(struct lapb_cb *lapb, struct sk_buff *skb,
  				struct lapb_frame *frame)
  {
  	switch (frame->type) {
fcb261f35   Joe Perches   lapb: Reduce swit...
150
  	case LAPB_SABM:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
152
153
154
  		printk(KERN_DEBUG "lapb: (%p) S1 RX SABM(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
156
  		if (lapb->mode & LAPB_EXTENDED) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
158
159
160
  			printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
162
163
164
  			lapb_send_control(lapb, LAPB_DM, frame->pf,
  					  LAPB_RESPONSE);
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
166
167
  			printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
  			       lapb->dev, frame->pf);
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
170
171
172
173
174
175
  			lapb_send_control(lapb, LAPB_UA, frame->pf,
  					  LAPB_RESPONSE);
  		}
  		break;
  
  	case LAPB_SABME:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
177
178
179
  		printk(KERN_DEBUG "lapb: (%p) S1 RX SABME(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
181
  		if (lapb->mode & LAPB_EXTENDED) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
183
184
185
  			printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
187
188
189
  			lapb_send_control(lapb, LAPB_UA, frame->pf,
  					  LAPB_RESPONSE);
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
  #if LAPB_DEBUG > 1
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
193
194
195
196
  			printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)
  ",
  			       lapb->dev, frame->pf);
  #endif
  			lapb_send_control(lapb, LAPB_DM, frame->pf,
  					  LAPB_RESPONSE);
fcb261f35   Joe Perches   lapb: Reduce swit...
197
198
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199

fcb261f35   Joe Perches   lapb: Reduce swit...
200
  	case LAPB_DISC:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
202
203
204
205
206
207
  		printk(KERN_DEBUG "lapb: (%p) S1 RX DISC(%d)
  ",
  		       lapb->dev, frame->pf);
  		printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
209
210
  		lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211

fcb261f35   Joe Perches   lapb: Reduce swit...
212
  	case LAPB_UA:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
214
215
216
  		printk(KERN_DEBUG "lapb: (%p) S1 RX UA(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
218
  		if (frame->pf) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
  			printk(KERN_DEBUG "lapb: (%p) S1 -> S3
  ", lapb->dev);
  #endif
  			lapb_stop_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->state     = LAPB_STATE_3;
  			lapb->condition = 0x00;
  			lapb->n2count   = 0;
  			lapb->vs        = 0;
  			lapb->vr        = 0;
  			lapb->va        = 0;
  			lapb_connect_confirmation(lapb, LAPB_OK);
  		}
  		break;
  
  	case LAPB_DM:
  #if LAPB_DEBUG > 1
  		printk(KERN_DEBUG "lapb: (%p) S1 RX DM(%d)
  ",
  		       lapb->dev, frame->pf);
  #endif
  		if (frame->pf) {
  #if LAPB_DEBUG > 0
  			printk(KERN_DEBUG "lapb: (%p) S1 -> S0
  ", lapb->dev);
  #endif
  			lapb_clear_queues(lapb);
  			lapb->state = LAPB_STATE_0;
  			lapb_start_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb_disconnect_indication(lapb, LAPB_REFUSED);
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
254
255
256
257
258
259
260
261
262
263
264
265
  	}
  
  	kfree_skb(skb);
  }
  
  /*
   *	State machine for state 2, Awaiting Release State.
   *	The handling of the timer(s) is in file lapb_timer.c
   */
  static void lapb_state2_machine(struct lapb_cb *lapb, struct sk_buff *skb,
  				struct lapb_frame *frame)
  {
  	switch (frame->type) {
fcb261f35   Joe Perches   lapb: Reduce swit...
266
267
  	case LAPB_SABM:
  	case LAPB_SABME:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
269
270
271
272
273
274
  		printk(KERN_DEBUG "lapb: (%p) S2 RX {SABM,SABME}(%d)
  ",
  		       lapb->dev, frame->pf);
  		printk(KERN_DEBUG "lapb: (%p) S2 TX DM(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
276
277
  		lapb_send_control(lapb, LAPB_DM, frame->pf, LAPB_RESPONSE);
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278

fcb261f35   Joe Perches   lapb: Reduce swit...
279
  	case LAPB_DISC:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
281
282
283
284
285
286
  		printk(KERN_DEBUG "lapb: (%p) S2 RX DISC(%d)
  ",
  		       lapb->dev, frame->pf);
  		printk(KERN_DEBUG "lapb: (%p) S2 TX UA(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
288
289
  		lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290

fcb261f35   Joe Perches   lapb: Reduce swit...
291
  	case LAPB_UA:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
293
294
295
  		printk(KERN_DEBUG "lapb: (%p) S2 RX UA(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
297
  		if (frame->pf) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
299
300
  			printk(KERN_DEBUG "lapb: (%p) S2 -> S0
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
302
303
304
305
306
307
  			lapb->state = LAPB_STATE_0;
  			lapb_start_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb_disconnect_confirmation(lapb, LAPB_OK);
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308

fcb261f35   Joe Perches   lapb: Reduce swit...
309
  	case LAPB_DM:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
311
312
313
  		printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
315
  		if (frame->pf) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
317
318
319
320
321
322
323
324
325
  			printk(KERN_DEBUG "lapb: (%p) S2 -> S0
  ", lapb->dev);
  #endif
  			lapb->state = LAPB_STATE_0;
  			lapb_start_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb_disconnect_confirmation(lapb, LAPB_NOTCONNECTED);
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326

fcb261f35   Joe Perches   lapb: Reduce swit...
327
328
329
330
  	case LAPB_I:
  	case LAPB_REJ:
  	case LAPB_RNR:
  	case LAPB_RR:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
332
333
334
335
336
337
  		printk(KERN_DEBUG "lapb: (%p) S2 RX {I,REJ,RNR,RR}(%d)
  ",
  		       lapb->dev, frame->pf);
  		printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
339
340
341
342
  		if (frame->pf)
  			lapb_send_control(lapb, LAPB_DM, frame->pf,
  					  LAPB_RESPONSE);
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
  	}
  
  	kfree_skb(skb);
  }
  
  /*
   *	State machine for state 3, Connected State.
   *	The handling of the timer(s) is in file lapb_timer.c
   */
  static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb,
  				struct lapb_frame *frame)
  {
  	int queued = 0;
  	int modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS :
  						     LAPB_SMODULUS;
  
  	switch (frame->type) {
fcb261f35   Joe Perches   lapb: Reduce swit...
360
  	case LAPB_SABM:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
362
363
364
  		printk(KERN_DEBUG "lapb: (%p) S3 RX SABM(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
366
  		if (lapb->mode & LAPB_EXTENDED) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
368
369
370
  			printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
371
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
372
373
374
  			lapb_send_control(lapb, LAPB_DM, frame->pf,
  					  LAPB_RESPONSE);
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
376
377
378
  			printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
380
381
382
383
384
385
386
387
388
389
390
391
  			lapb_send_control(lapb, LAPB_UA, frame->pf,
  					  LAPB_RESPONSE);
  			lapb_stop_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->condition = 0x00;
  			lapb->n2count   = 0;
  			lapb->vs        = 0;
  			lapb->vr        = 0;
  			lapb->va        = 0;
  			lapb_requeue_frames(lapb);
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
392

fcb261f35   Joe Perches   lapb: Reduce swit...
393
  	case LAPB_SABME:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
395
396
397
  		printk(KERN_DEBUG "lapb: (%p) S3 RX SABME(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
399
  		if (lapb->mode & LAPB_EXTENDED) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
401
402
403
  			printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
405
406
407
408
409
410
411
412
413
414
415
  			lapb_send_control(lapb, LAPB_UA, frame->pf,
  					  LAPB_RESPONSE);
  			lapb_stop_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->condition = 0x00;
  			lapb->n2count   = 0;
  			lapb->vs        = 0;
  			lapb->vr        = 0;
  			lapb->va        = 0;
  			lapb_requeue_frames(lapb);
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
417
418
419
  			printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
421
422
423
424
  			lapb_send_control(lapb, LAPB_DM, frame->pf,
  					  LAPB_RESPONSE);
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
425

fcb261f35   Joe Perches   lapb: Reduce swit...
426
  	case LAPB_DISC:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
428
429
430
  		printk(KERN_DEBUG "lapb: (%p) S3 RX DISC(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
432
  #endif
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
433
434
  		printk(KERN_DEBUG "lapb: (%p) S3 -> S0
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
436
437
438
439
440
441
442
  		lapb_clear_queues(lapb);
  		lapb_send_control(lapb, LAPB_UA, frame->pf, LAPB_RESPONSE);
  		lapb_start_t1timer(lapb);
  		lapb_stop_t2timer(lapb);
  		lapb->state = LAPB_STATE_0;
  		lapb_disconnect_indication(lapb, LAPB_OK);
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
443

fcb261f35   Joe Perches   lapb: Reduce swit...
444
  	case LAPB_DM:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
446
447
448
  		printk(KERN_DEBUG "lapb: (%p) S3 RX DM(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
450
  #endif
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
451
452
  		printk(KERN_DEBUG "lapb: (%p) S3 -> S0
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
453
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
454
455
456
457
458
459
  		lapb_clear_queues(lapb);
  		lapb->state = LAPB_STATE_0;
  		lapb_start_t1timer(lapb);
  		lapb_stop_t2timer(lapb);
  		lapb_disconnect_indication(lapb, LAPB_NOTCONNECTED);
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460

fcb261f35   Joe Perches   lapb: Reduce swit...
461
  	case LAPB_RNR:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
463
464
465
  		printk(KERN_DEBUG "lapb: (%p) S3 RX RNR(%d) R%d
  ",
  		       lapb->dev, frame->pf, frame->nr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
466
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
467
468
469
470
471
472
473
474
  		lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION;
  		lapb_check_need_response(lapb, frame->cr, frame->pf);
  		if (lapb_validate_nr(lapb, frame->nr)) {
  			lapb_check_iframes_acked(lapb, frame->nr);
  		} else {
  			lapb->frmr_data = *frame;
  			lapb->frmr_type = LAPB_FRMR_Z;
  			lapb_transmit_frmr(lapb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
476
477
  			printk(KERN_DEBUG "lapb: (%p) S3 -> S4
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
478
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
479
480
481
482
483
484
  			lapb_start_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->state   = LAPB_STATE_4;
  			lapb->n2count = 0;
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485

fcb261f35   Joe Perches   lapb: Reduce swit...
486
  	case LAPB_RR:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
487
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
488
489
490
  		printk(KERN_DEBUG "lapb: (%p) S3 RX RR(%d) R%d
  ",
  		       lapb->dev, frame->pf, frame->nr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
492
493
494
495
496
497
498
499
  		lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
  		lapb_check_need_response(lapb, frame->cr, frame->pf);
  		if (lapb_validate_nr(lapb, frame->nr)) {
  			lapb_check_iframes_acked(lapb, frame->nr);
  		} else {
  			lapb->frmr_data = *frame;
  			lapb->frmr_type = LAPB_FRMR_Z;
  			lapb_transmit_frmr(lapb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
500
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
501
502
  			printk(KERN_DEBUG "lapb: (%p) S3 -> S4
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
504
505
506
507
508
509
  			lapb_start_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->state   = LAPB_STATE_4;
  			lapb->n2count = 0;
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510

fcb261f35   Joe Perches   lapb: Reduce swit...
511
  	case LAPB_REJ:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
513
514
515
  		printk(KERN_DEBUG "lapb: (%p) S3 RX REJ(%d) R%d
  ",
  		       lapb->dev, frame->pf, frame->nr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
517
518
519
520
521
522
523
524
525
526
527
  		lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
  		lapb_check_need_response(lapb, frame->cr, frame->pf);
  		if (lapb_validate_nr(lapb, frame->nr)) {
  			lapb_frames_acked(lapb, frame->nr);
  			lapb_stop_t1timer(lapb);
  			lapb->n2count = 0;
  			lapb_requeue_frames(lapb);
  		} else {
  			lapb->frmr_data = *frame;
  			lapb->frmr_type = LAPB_FRMR_Z;
  			lapb_transmit_frmr(lapb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
529
530
  			printk(KERN_DEBUG "lapb: (%p) S3 -> S4
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
532
533
534
535
536
537
  			lapb_start_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->state   = LAPB_STATE_4;
  			lapb->n2count = 0;
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538

fcb261f35   Joe Perches   lapb: Reduce swit...
539
  	case LAPB_I:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
540
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
541
542
543
  		printk(KERN_DEBUG "lapb: (%p) S3 RX I(%d) S%d R%d
  ",
  		       lapb->dev, frame->pf, frame->ns, frame->nr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
544
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
545
546
547
548
  		if (!lapb_validate_nr(lapb, frame->nr)) {
  			lapb->frmr_data = *frame;
  			lapb->frmr_type = LAPB_FRMR_Z;
  			lapb_transmit_frmr(lapb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
549
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
550
551
  			printk(KERN_DEBUG "lapb: (%p) S3 -> S4
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
  			lapb_start_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->state   = LAPB_STATE_4;
  			lapb->n2count = 0;
  			break;
  		}
  		if (lapb->condition & LAPB_PEER_RX_BUSY_CONDITION)
  			lapb_frames_acked(lapb, frame->nr);
  		else
  			lapb_check_iframes_acked(lapb, frame->nr);
  
  		if (frame->ns == lapb->vr) {
  			int cn;
  			cn = lapb_data_indication(lapb, skb);
  			queued = 1;
  			/*
  			 * If upper layer has dropped the frame, we
  			 * basically ignore any further protocol
  			 * processing. This will cause the peer
  			 * to re-transmit the frame later like
  			 * a frame lost on the wire.
  			 */
  			if (cn == NET_RX_DROP) {
  				printk(KERN_DEBUG "LAPB: rx congestion
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
578
579
  				break;
  			}
fcb261f35   Joe Perches   lapb: Reduce swit...
580
581
582
583
584
585
586
587
588
  			lapb->vr = (lapb->vr + 1) % modulus;
  			lapb->condition &= ~LAPB_REJECT_CONDITION;
  			if (frame->pf)
  				lapb_enquiry_response(lapb);
  			else {
  				if (!(lapb->condition &
  				      LAPB_ACK_PENDING_CONDITION)) {
  					lapb->condition |= LAPB_ACK_PENDING_CONDITION;
  					lapb_start_t2timer(lapb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589
  				}
fcb261f35   Joe Perches   lapb: Reduce swit...
590
591
592
  			}
  		} else {
  			if (lapb->condition & LAPB_REJECT_CONDITION) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
593
594
  				if (frame->pf)
  					lapb_enquiry_response(lapb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
  			} else {
fcb261f35   Joe Perches   lapb: Reduce swit...
596
597
598
599
600
601
602
603
604
605
  #if LAPB_DEBUG > 1
  				printk(KERN_DEBUG
  				       "lapb: (%p) S3 TX REJ(%d) R%d
  ",
  				       lapb->dev, frame->pf, lapb->vr);
  #endif
  				lapb->condition |= LAPB_REJECT_CONDITION;
  				lapb_send_control(lapb, LAPB_REJ, frame->pf,
  						  LAPB_RESPONSE);
  				lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606
  			}
fcb261f35   Joe Perches   lapb: Reduce swit...
607
608
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609

fcb261f35   Joe Perches   lapb: Reduce swit...
610
  	case LAPB_FRMR:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
612
613
614
615
616
  		printk(KERN_DEBUG "lapb: (%p) S3 RX FRMR(%d) %02X "
  		       "%02X %02X %02X %02X
  ", lapb->dev, frame->pf,
  		       skb->data[0], skb->data[1], skb->data[2],
  		       skb->data[3], skb->data[4]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
617
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
618
  		lapb_establish_data_link(lapb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
620
621
  		printk(KERN_DEBUG "lapb: (%p) S3 -> S1
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
623
624
625
  		lapb_requeue_frames(lapb);
  		lapb->state = LAPB_STATE_1;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626

fcb261f35   Joe Perches   lapb: Reduce swit...
627
  	case LAPB_ILLEGAL:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
629
630
631
  		printk(KERN_DEBUG "lapb: (%p) S3 RX ILLEGAL(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
632
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
633
634
635
  		lapb->frmr_data = *frame;
  		lapb->frmr_type = LAPB_FRMR_W;
  		lapb_transmit_frmr(lapb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
637
638
  		printk(KERN_DEBUG "lapb: (%p) S3 -> S4
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
639
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
640
641
642
643
644
  		lapb_start_t1timer(lapb);
  		lapb_stop_t2timer(lapb);
  		lapb->state   = LAPB_STATE_4;
  		lapb->n2count = 0;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
645
646
647
648
649
650
651
652
653
654
655
656
657
658
  	}
  
  	if (!queued)
  		kfree_skb(skb);
  }
  
  /*
   *	State machine for state 4, Frame Reject State.
   *	The handling of the timer(s) is in file lapb_timer.c.
   */
  static void lapb_state4_machine(struct lapb_cb *lapb, struct sk_buff *skb,
  				struct lapb_frame *frame)
  {
  	switch (frame->type) {
fcb261f35   Joe Perches   lapb: Reduce swit...
659
  	case LAPB_SABM:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
660
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
661
662
663
  		printk(KERN_DEBUG "lapb: (%p) S4 RX SABM(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
665
  		if (lapb->mode & LAPB_EXTENDED) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
667
668
669
  			printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
671
672
673
  			lapb_send_control(lapb, LAPB_DM, frame->pf,
  					  LAPB_RESPONSE);
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
675
676
677
  			printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
678
679
  #endif
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
680
681
  			printk(KERN_DEBUG "lapb: (%p) S4 -> S3
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
682
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
683
684
685
686
687
688
689
690
691
692
693
694
695
  			lapb_send_control(lapb, LAPB_UA, frame->pf,
  					  LAPB_RESPONSE);
  			lapb_stop_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->state     = LAPB_STATE_3;
  			lapb->condition = 0x00;
  			lapb->n2count   = 0;
  			lapb->vs        = 0;
  			lapb->vr        = 0;
  			lapb->va        = 0;
  			lapb_connect_indication(lapb, LAPB_OK);
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
696

fcb261f35   Joe Perches   lapb: Reduce swit...
697
  	case LAPB_SABME:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
698
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
699
700
701
  		printk(KERN_DEBUG "lapb: (%p) S4 RX SABME(%d)
  ",
  		       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
703
  		if (lapb->mode & LAPB_EXTENDED) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
  #if LAPB_DEBUG > 1
fcb261f35   Joe Perches   lapb: Reduce swit...
705
706
707
  			printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708
709
  #endif
  #if LAPB_DEBUG > 0
fcb261f35   Joe Perches   lapb: Reduce swit...
710
711
  			printk(KERN_DEBUG "lapb: (%p) S4 -> S3
  ", lapb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
712
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
  			lapb_send_control(lapb, LAPB_UA, frame->pf,
  					  LAPB_RESPONSE);
  			lapb_stop_t1timer(lapb);
  			lapb_stop_t2timer(lapb);
  			lapb->state     = LAPB_STATE_3;
  			lapb->condition = 0x00;
  			lapb->n2count   = 0;
  			lapb->vs        = 0;
  			lapb->vr        = 0;
  			lapb->va        = 0;
  			lapb_connect_indication(lapb, LAPB_OK);
  		} else {
  #if LAPB_DEBUG > 1
  			printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)
  ",
  			       lapb->dev, frame->pf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
729
  #endif
fcb261f35   Joe Perches   lapb: Reduce swit...
730
731
732
733
  			lapb_send_control(lapb, LAPB_DM, frame->pf,
  					  LAPB_RESPONSE);
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
  	}
  
  	kfree_skb(skb);
  }
  
  /*
   *	Process an incoming LAPB frame
   */
  void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *skb)
  {
  	struct lapb_frame frame;
  
  	if (lapb_decode(lapb, skb, &frame) < 0) {
  		kfree_skb(skb);
  		return;
  	}
  
  	switch (lapb->state) {
  	case LAPB_STATE_0:
  		lapb_state0_machine(lapb, skb, &frame); break;
  	case LAPB_STATE_1:
  		lapb_state1_machine(lapb, skb, &frame); break;
  	case LAPB_STATE_2:
  		lapb_state2_machine(lapb, skb, &frame); break;
  	case LAPB_STATE_3:
  		lapb_state3_machine(lapb, skb, &frame); break;
  	case LAPB_STATE_4:
  		lapb_state4_machine(lapb, skb, &frame); break;
  	}
  
  	lapb_kick(lapb);
  }