aboutsummaryrefslogtreecommitdiffstats
path: root/net/lapb/lapb_in.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/lapb/lapb_in.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'net/lapb/lapb_in.c')
-rw-r--r--net/lapb/lapb_in.c724
1 files changed, 724 insertions, 0 deletions
diff --git a/net/lapb/lapb_in.c b/net/lapb/lapb_in.c
new file mode 100644
index 000000000000..b0f8713f66ca
--- /dev/null
+++ b/net/lapb/lapb_in.c
@@ -0,0 +1,724 @@
1/*
2 * LAPB release 002
3 *
4 * This code REQUIRES 2.1.15 or higher/ NET3.038
5 *
6 * This module:
7 * This module is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
12 * History
13 * LAPB 001 Jonathan Naulor Started Coding
14 * LAPB 002 Jonathan Naylor New timer architecture.
15 * 2000-10-29 Henner Eisen lapb_data_indication() return status.
16 */
17
18#include <linux/errno.h>
19#include <linux/types.h>
20#include <linux/socket.h>
21#include <linux/in.h>
22#include <linux/kernel.h>
23#include <linux/sched.h>
24#include <linux/timer.h>
25#include <linux/string.h>
26#include <linux/sockios.h>
27#include <linux/net.h>
28#include <linux/inet.h>
29#include <linux/netdevice.h>
30#include <linux/skbuff.h>
31#include <net/sock.h>
32#include <asm/uaccess.h>
33#include <asm/system.h>
34#include <linux/fcntl.h>
35#include <linux/mm.h>
36#include <linux/interrupt.h>
37#include <net/lapb.h>
38
39/*
40 * State machine for state 0, Disconnected State.
41 * The handling of the timer(s) is in file lapb_timer.c.
42 */
43static void lapb_state0_machine(struct lapb_cb *lapb, struct sk_buff *skb,
44 struct lapb_frame *frame)
45{
46 switch (frame->type) {
47 case LAPB_SABM:
48#if LAPB_DEBUG > 1
49 printk(KERN_DEBUG "lapb: (%p) S0 RX SABM(%d)\n",
50 lapb->dev, frame->pf);
51#endif
52 if (lapb->mode & LAPB_EXTENDED) {
53#if LAPB_DEBUG > 1
54 printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n",
55 lapb->dev, frame->pf);
56#endif
57 lapb_send_control(lapb, LAPB_DM, frame->pf,
58 LAPB_RESPONSE);
59 } else {
60#if LAPB_DEBUG > 1
61 printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n",
62 lapb->dev, frame->pf);
63#endif
64#if LAPB_DEBUG > 0
65 printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n",
66 lapb->dev);
67#endif
68 lapb_send_control(lapb, LAPB_UA, frame->pf,
69 LAPB_RESPONSE);
70 lapb_stop_t1timer(lapb);
71 lapb_stop_t2timer(lapb);
72 lapb->state = LAPB_STATE_3;
73 lapb->condition = 0x00;
74 lapb->n2count = 0;
75 lapb->vs = 0;
76 lapb->vr = 0;
77 lapb->va = 0;
78 lapb_connect_indication(lapb, LAPB_OK);
79 }
80 break;
81
82 case LAPB_SABME:
83#if LAPB_DEBUG > 1
84 printk(KERN_DEBUG "lapb: (%p) S0 RX SABME(%d)\n",
85 lapb->dev, frame->pf);
86#endif
87 if (lapb->mode & LAPB_EXTENDED) {
88#if LAPB_DEBUG > 1
89 printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n",
90 lapb->dev, frame->pf);
91#endif
92#if LAPB_DEBUG > 0
93 printk(KERN_DEBUG "lapb: (%p) S0 -> S3\n",
94 lapb->dev);
95#endif
96 lapb_send_control(lapb, LAPB_UA, frame->pf,
97 LAPB_RESPONSE);
98 lapb_stop_t1timer(lapb);
99 lapb_stop_t2timer(lapb);
100 lapb->state = LAPB_STATE_3;
101 lapb->condition = 0x00;
102 lapb->n2count = 0;
103 lapb->vs = 0;
104 lapb->vr = 0;
105 lapb->va = 0;
106 lapb_connect_indication(lapb, LAPB_OK);
107 } else {
108#if LAPB_DEBUG > 1
109 printk(KERN_DEBUG "lapb: (%p) S0 TX DM(%d)\n",
110 lapb->dev, frame->pf);
111#endif
112 lapb_send_control(lapb, LAPB_DM, frame->pf,
113 LAPB_RESPONSE);
114 }
115 break;
116
117 case LAPB_DISC:
118#if LAPB_DEBUG > 1
119 printk(KERN_DEBUG "lapb: (%p) S0 RX DISC(%d)\n",
120 lapb->dev, frame->pf);
121 printk(KERN_DEBUG "lapb: (%p) S0 TX UA(%d)\n",
122 lapb->dev, frame->pf);
123#endif
124 lapb_send_control(lapb, LAPB_UA, frame->pf,
125 LAPB_RESPONSE);
126 break;
127
128 default:
129 break;
130 }
131
132 kfree_skb(skb);
133}
134
135/*
136 * State machine for state 1, Awaiting Connection State.
137 * The handling of the timer(s) is in file lapb_timer.c.
138 */
139static void lapb_state1_machine(struct lapb_cb *lapb, struct sk_buff *skb,
140 struct lapb_frame *frame)
141{
142 switch (frame->type) {
143 case LAPB_SABM:
144#if LAPB_DEBUG > 1
145 printk(KERN_DEBUG "lapb: (%p) S1 RX SABM(%d)\n",
146 lapb->dev, frame->pf);
147#endif
148 if (lapb->mode & LAPB_EXTENDED) {
149#if LAPB_DEBUG > 1
150 printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n",
151 lapb->dev, frame->pf);
152#endif
153 lapb_send_control(lapb, LAPB_DM, frame->pf,
154 LAPB_RESPONSE);
155 } else {
156#if LAPB_DEBUG > 1
157 printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n",
158 lapb->dev, frame->pf);
159#endif
160 lapb_send_control(lapb, LAPB_UA, frame->pf,
161 LAPB_RESPONSE);
162 }
163 break;
164
165 case LAPB_SABME:
166#if LAPB_DEBUG > 1
167 printk(KERN_DEBUG "lapb: (%p) S1 RX SABME(%d)\n",
168 lapb->dev, frame->pf);
169#endif
170 if (lapb->mode & LAPB_EXTENDED) {
171#if LAPB_DEBUG > 1
172 printk(KERN_DEBUG "lapb: (%p) S1 TX UA(%d)\n",
173 lapb->dev, frame->pf);
174#endif
175 lapb_send_control(lapb, LAPB_UA, frame->pf,
176 LAPB_RESPONSE);
177 } else {
178#if LAPB_DEBUG > 1
179 printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n",
180 lapb->dev, frame->pf);
181#endif
182 lapb_send_control(lapb, LAPB_DM, frame->pf,
183 LAPB_RESPONSE);
184 }
185 break;
186
187 case LAPB_DISC:
188#if LAPB_DEBUG > 1
189 printk(KERN_DEBUG "lapb: (%p) S1 RX DISC(%d)\n",
190 lapb->dev, frame->pf);
191 printk(KERN_DEBUG "lapb: (%p) S1 TX DM(%d)\n",
192 lapb->dev, frame->pf);
193#endif
194 lapb_send_control(lapb, LAPB_DM, frame->pf,
195 LAPB_RESPONSE);
196 break;
197
198 case LAPB_UA:
199#if LAPB_DEBUG > 1
200 printk(KERN_DEBUG "lapb: (%p) S1 RX UA(%d)\n",
201 lapb->dev, frame->pf);
202#endif
203 if (frame->pf) {
204#if LAPB_DEBUG > 0
205 printk(KERN_DEBUG "lapb: (%p) S1 -> S3\n",
206 lapb->dev);
207#endif
208 lapb_stop_t1timer(lapb);
209 lapb_stop_t2timer(lapb);
210 lapb->state = LAPB_STATE_3;
211 lapb->condition = 0x00;
212 lapb->n2count = 0;
213 lapb->vs = 0;
214 lapb->vr = 0;
215 lapb->va = 0;
216 lapb_connect_confirmation(lapb, LAPB_OK);
217 }
218 break;
219
220 case LAPB_DM:
221#if LAPB_DEBUG > 1
222 printk(KERN_DEBUG "lapb: (%p) S1 RX DM(%d)\n",
223 lapb->dev, frame->pf);
224#endif
225 if (frame->pf) {
226#if LAPB_DEBUG > 0
227 printk(KERN_DEBUG "lapb: (%p) S1 -> S0\n",
228 lapb->dev);
229#endif
230 lapb_clear_queues(lapb);
231 lapb->state = LAPB_STATE_0;
232 lapb_start_t1timer(lapb);
233 lapb_stop_t2timer(lapb);
234 lapb_disconnect_indication(lapb, LAPB_REFUSED);
235 }
236 break;
237 }
238
239 kfree_skb(skb);
240}
241
242/*
243 * State machine for state 2, Awaiting Release State.
244 * The handling of the timer(s) is in file lapb_timer.c
245 */
246static void lapb_state2_machine(struct lapb_cb *lapb, struct sk_buff *skb,
247 struct lapb_frame *frame)
248{
249 switch (frame->type) {
250 case LAPB_SABM:
251 case LAPB_SABME:
252#if LAPB_DEBUG > 1
253 printk(KERN_DEBUG "lapb: (%p) S2 RX {SABM,SABME}(%d)\n",
254 lapb->dev, frame->pf);
255 printk(KERN_DEBUG "lapb: (%p) S2 TX DM(%d)\n",
256 lapb->dev, frame->pf);
257#endif
258 lapb_send_control(lapb, LAPB_DM, frame->pf,
259 LAPB_RESPONSE);
260 break;
261
262 case LAPB_DISC:
263#if LAPB_DEBUG > 1
264 printk(KERN_DEBUG "lapb: (%p) S2 RX DISC(%d)\n",
265 lapb->dev, frame->pf);
266 printk(KERN_DEBUG "lapb: (%p) S2 TX UA(%d)\n",
267 lapb->dev, frame->pf);
268#endif
269 lapb_send_control(lapb, LAPB_UA, frame->pf,
270 LAPB_RESPONSE);
271 break;
272
273 case LAPB_UA:
274#if LAPB_DEBUG > 1
275 printk(KERN_DEBUG "lapb: (%p) S2 RX UA(%d)\n",
276 lapb->dev, frame->pf);
277#endif
278 if (frame->pf) {
279#if LAPB_DEBUG > 0
280 printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n",
281 lapb->dev);
282#endif
283 lapb->state = LAPB_STATE_0;
284 lapb_start_t1timer(lapb);
285 lapb_stop_t2timer(lapb);
286 lapb_disconnect_confirmation(lapb, LAPB_OK);
287 }
288 break;
289
290 case LAPB_DM:
291#if LAPB_DEBUG > 1
292 printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n",
293 lapb->dev, frame->pf);
294#endif
295 if (frame->pf) {
296#if LAPB_DEBUG > 0
297 printk(KERN_DEBUG "lapb: (%p) S2 -> S0\n",
298 lapb->dev);
299#endif
300 lapb->state = LAPB_STATE_0;
301 lapb_start_t1timer(lapb);
302 lapb_stop_t2timer(lapb);
303 lapb_disconnect_confirmation(lapb,
304 LAPB_NOTCONNECTED);
305 }
306 break;
307
308 case LAPB_I:
309 case LAPB_REJ:
310 case LAPB_RNR:
311 case LAPB_RR:
312#if LAPB_DEBUG > 1
313 printk(KERN_DEBUG "lapb: (%p) S2 RX {I,REJ,RNR,RR}"
314 "(%d)\n", lapb->dev, frame->pf);
315 printk(KERN_DEBUG "lapb: (%p) S2 RX DM(%d)\n",
316 lapb->dev, frame->pf);
317#endif
318 if (frame->pf)
319 lapb_send_control(lapb, LAPB_DM, frame->pf,
320 LAPB_RESPONSE);
321 break;
322 }
323
324 kfree_skb(skb);
325}
326
327/*
328 * State machine for state 3, Connected State.
329 * The handling of the timer(s) is in file lapb_timer.c
330 */
331static void lapb_state3_machine(struct lapb_cb *lapb, struct sk_buff *skb,
332 struct lapb_frame *frame)
333{
334 int queued = 0;
335 int modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS :
336 LAPB_SMODULUS;
337
338 switch (frame->type) {
339 case LAPB_SABM:
340#if LAPB_DEBUG > 1
341 printk(KERN_DEBUG "lapb: (%p) S3 RX SABM(%d)\n",
342 lapb->dev, frame->pf);
343#endif
344 if (lapb->mode & LAPB_EXTENDED) {
345#if LAPB_DEBUG > 1
346 printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n",
347 lapb->dev, frame->pf);
348#endif
349 lapb_send_control(lapb, LAPB_DM, frame->pf,
350 LAPB_RESPONSE);
351 } else {
352#if LAPB_DEBUG > 1
353 printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n",
354 lapb->dev, frame->pf);
355#endif
356 lapb_send_control(lapb, LAPB_UA, frame->pf,
357 LAPB_RESPONSE);
358 lapb_stop_t1timer(lapb);
359 lapb_stop_t2timer(lapb);
360 lapb->condition = 0x00;
361 lapb->n2count = 0;
362 lapb->vs = 0;
363 lapb->vr = 0;
364 lapb->va = 0;
365 lapb_requeue_frames(lapb);
366 }
367 break;
368
369 case LAPB_SABME:
370#if LAPB_DEBUG > 1
371 printk(KERN_DEBUG "lapb: (%p) S3 RX SABME(%d)\n",
372 lapb->dev, frame->pf);
373#endif
374 if (lapb->mode & LAPB_EXTENDED) {
375#if LAPB_DEBUG > 1
376 printk(KERN_DEBUG "lapb: (%p) S3 TX UA(%d)\n",
377 lapb->dev, frame->pf);
378#endif
379 lapb_send_control(lapb, LAPB_UA, frame->pf,
380 LAPB_RESPONSE);
381 lapb_stop_t1timer(lapb);
382 lapb_stop_t2timer(lapb);
383 lapb->condition = 0x00;
384 lapb->n2count = 0;
385 lapb->vs = 0;
386 lapb->vr = 0;
387 lapb->va = 0;
388 lapb_requeue_frames(lapb);
389 } else {
390#if LAPB_DEBUG > 1
391 printk(KERN_DEBUG "lapb: (%p) S3 TX DM(%d)\n",
392 lapb->dev, frame->pf);
393#endif
394 lapb_send_control(lapb, LAPB_DM, frame->pf,
395 LAPB_RESPONSE);
396 }
397 break;
398
399 case LAPB_DISC:
400#if LAPB_DEBUG > 1
401 printk(KERN_DEBUG "lapb: (%p) S3 RX DISC(%d)\n",
402 lapb->dev, frame->pf);
403#endif
404#if LAPB_DEBUG > 0
405 printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n",
406 lapb->dev);
407#endif
408 lapb_clear_queues(lapb);
409 lapb_send_control(lapb, LAPB_UA, frame->pf,
410 LAPB_RESPONSE);
411 lapb_start_t1timer(lapb);
412 lapb_stop_t2timer(lapb);
413 lapb->state = LAPB_STATE_0;
414 lapb_disconnect_indication(lapb, LAPB_OK);
415 break;
416
417 case LAPB_DM:
418#if LAPB_DEBUG > 1
419 printk(KERN_DEBUG "lapb: (%p) S3 RX DM(%d)\n",
420 lapb->dev, frame->pf);
421#endif
422#if LAPB_DEBUG > 0
423 printk(KERN_DEBUG "lapb: (%p) S3 -> S0\n",
424 lapb->dev);
425#endif
426 lapb_clear_queues(lapb);
427 lapb->state = LAPB_STATE_0;
428 lapb_start_t1timer(lapb);
429 lapb_stop_t2timer(lapb);
430 lapb_disconnect_indication(lapb, LAPB_NOTCONNECTED);
431 break;
432
433 case LAPB_RNR:
434#if LAPB_DEBUG > 1
435 printk(KERN_DEBUG "lapb: (%p) S3 RX RNR(%d) R%d\n",
436 lapb->dev, frame->pf, frame->nr);
437#endif
438 lapb->condition |= LAPB_PEER_RX_BUSY_CONDITION;
439 lapb_check_need_response(lapb, frame->cr, frame->pf);
440 if (lapb_validate_nr(lapb, frame->nr)) {
441 lapb_check_iframes_acked(lapb, frame->nr);
442 } else {
443 lapb->frmr_data = *frame;
444 lapb->frmr_type = LAPB_FRMR_Z;
445 lapb_transmit_frmr(lapb);
446#if LAPB_DEBUG > 0
447 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n",
448 lapb->dev);
449#endif
450 lapb_start_t1timer(lapb);
451 lapb_stop_t2timer(lapb);
452 lapb->state = LAPB_STATE_4;
453 lapb->n2count = 0;
454 }
455 break;
456
457 case LAPB_RR:
458#if LAPB_DEBUG > 1
459 printk(KERN_DEBUG "lapb: (%p) S3 RX RR(%d) R%d\n",
460 lapb->dev, frame->pf, frame->nr);
461#endif
462 lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
463 lapb_check_need_response(lapb, frame->cr, frame->pf);
464 if (lapb_validate_nr(lapb, frame->nr)) {
465 lapb_check_iframes_acked(lapb, frame->nr);
466 } else {
467 lapb->frmr_data = *frame;
468 lapb->frmr_type = LAPB_FRMR_Z;
469 lapb_transmit_frmr(lapb);
470#if LAPB_DEBUG > 0
471 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n",
472 lapb->dev);
473#endif
474 lapb_start_t1timer(lapb);
475 lapb_stop_t2timer(lapb);
476 lapb->state = LAPB_STATE_4;
477 lapb->n2count = 0;
478 }
479 break;
480
481 case LAPB_REJ:
482#if LAPB_DEBUG > 1
483 printk(KERN_DEBUG "lapb: (%p) S3 RX REJ(%d) R%d\n",
484 lapb->dev, frame->pf, frame->nr);
485#endif
486 lapb->condition &= ~LAPB_PEER_RX_BUSY_CONDITION;
487 lapb_check_need_response(lapb, frame->cr, frame->pf);
488 if (lapb_validate_nr(lapb, frame->nr)) {
489 lapb_frames_acked(lapb, frame->nr);
490 lapb_stop_t1timer(lapb);
491 lapb->n2count = 0;
492 lapb_requeue_frames(lapb);
493 } else {
494 lapb->frmr_data = *frame;
495 lapb->frmr_type = LAPB_FRMR_Z;
496 lapb_transmit_frmr(lapb);
497#if LAPB_DEBUG > 0
498 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n",
499 lapb->dev);
500#endif
501 lapb_start_t1timer(lapb);
502 lapb_stop_t2timer(lapb);
503 lapb->state = LAPB_STATE_4;
504 lapb->n2count = 0;
505 }
506 break;
507
508 case LAPB_I:
509#if LAPB_DEBUG > 1
510 printk(KERN_DEBUG "lapb: (%p) S3 RX I(%d) S%d R%d\n",
511 lapb->dev, frame->pf, frame->ns, frame->nr);
512#endif
513 if (!lapb_validate_nr(lapb, frame->nr)) {
514 lapb->frmr_data = *frame;
515 lapb->frmr_type = LAPB_FRMR_Z;
516 lapb_transmit_frmr(lapb);
517#if LAPB_DEBUG > 0
518 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n",
519 lapb->dev);
520#endif
521 lapb_start_t1timer(lapb);
522 lapb_stop_t2timer(lapb);
523 lapb->state = LAPB_STATE_4;
524 lapb->n2count = 0;
525 break;
526 }
527 if (lapb->condition & LAPB_PEER_RX_BUSY_CONDITION)
528 lapb_frames_acked(lapb, frame->nr);
529 else
530 lapb_check_iframes_acked(lapb, frame->nr);
531
532 if (frame->ns == lapb->vr) {
533 int cn;
534 cn = lapb_data_indication(lapb, skb);
535 queued = 1;
536 /*
537 * If upper layer has dropped the frame, we
538 * basically ignore any further protocol
539 * processing. This will cause the peer
540 * to re-transmit the frame later like
541 * a frame lost on the wire.
542 */
543 if (cn == NET_RX_DROP) {
544 printk(KERN_DEBUG
545 "LAPB: rx congestion\n");
546 break;
547 }
548 lapb->vr = (lapb->vr + 1) % modulus;
549 lapb->condition &= ~LAPB_REJECT_CONDITION;
550 if (frame->pf)
551 lapb_enquiry_response(lapb);
552 else {
553 if (!(lapb->condition &
554 LAPB_ACK_PENDING_CONDITION)) {
555 lapb->condition |= LAPB_ACK_PENDING_CONDITION;
556 lapb_start_t2timer(lapb);
557 }
558 }
559 } else {
560 if (lapb->condition & LAPB_REJECT_CONDITION) {
561 if (frame->pf)
562 lapb_enquiry_response(lapb);
563 } else {
564#if LAPB_DEBUG > 1
565 printk(KERN_DEBUG
566 "lapb: (%p) S3 TX REJ(%d) R%d\n",
567 lapb->dev, frame->pf, lapb->vr);
568#endif
569 lapb->condition |= LAPB_REJECT_CONDITION;
570 lapb_send_control(lapb, LAPB_REJ,
571 frame->pf,
572 LAPB_RESPONSE);
573 lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
574 }
575 }
576 break;
577
578 case LAPB_FRMR:
579#if LAPB_DEBUG > 1
580 printk(KERN_DEBUG "lapb: (%p) S3 RX FRMR(%d) %02X "
581 "%02X %02X %02X %02X\n", lapb->dev, frame->pf,
582 skb->data[0], skb->data[1], skb->data[2],
583 skb->data[3], skb->data[4]);
584#endif
585 lapb_establish_data_link(lapb);
586#if LAPB_DEBUG > 0
587 printk(KERN_DEBUG "lapb: (%p) S3 -> S1\n",
588 lapb->dev);
589#endif
590 lapb_requeue_frames(lapb);
591 lapb->state = LAPB_STATE_1;
592 break;
593
594 case LAPB_ILLEGAL:
595#if LAPB_DEBUG > 1
596 printk(KERN_DEBUG "lapb: (%p) S3 RX ILLEGAL(%d)\n",
597 lapb->dev, frame->pf);
598#endif
599 lapb->frmr_data = *frame;
600 lapb->frmr_type = LAPB_FRMR_W;
601 lapb_transmit_frmr(lapb);
602#if LAPB_DEBUG > 0
603 printk(KERN_DEBUG "lapb: (%p) S3 -> S4\n", lapb->dev);
604#endif
605 lapb_start_t1timer(lapb);
606 lapb_stop_t2timer(lapb);
607 lapb->state = LAPB_STATE_4;
608 lapb->n2count = 0;
609 break;
610 }
611
612 if (!queued)
613 kfree_skb(skb);
614}
615
616/*
617 * State machine for state 4, Frame Reject State.
618 * The handling of the timer(s) is in file lapb_timer.c.
619 */
620static void lapb_state4_machine(struct lapb_cb *lapb, struct sk_buff *skb,
621 struct lapb_frame *frame)
622{
623 switch (frame->type) {
624 case LAPB_SABM:
625#if LAPB_DEBUG > 1
626 printk(KERN_DEBUG "lapb: (%p) S4 RX SABM(%d)\n",
627 lapb->dev, frame->pf);
628#endif
629 if (lapb->mode & LAPB_EXTENDED) {
630#if LAPB_DEBUG > 1
631 printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n",
632 lapb->dev, frame->pf);
633#endif
634 lapb_send_control(lapb, LAPB_DM, frame->pf,
635 LAPB_RESPONSE);
636 } else {
637#if LAPB_DEBUG > 1
638 printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n",
639 lapb->dev, frame->pf);
640#endif
641#if LAPB_DEBUG > 0
642 printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n",
643 lapb->dev);
644#endif
645 lapb_send_control(lapb, LAPB_UA, frame->pf,
646 LAPB_RESPONSE);
647 lapb_stop_t1timer(lapb);
648 lapb_stop_t2timer(lapb);
649 lapb->state = LAPB_STATE_3;
650 lapb->condition = 0x00;
651 lapb->n2count = 0;
652 lapb->vs = 0;
653 lapb->vr = 0;
654 lapb->va = 0;
655 lapb_connect_indication(lapb, LAPB_OK);
656 }
657 break;
658
659 case LAPB_SABME:
660#if LAPB_DEBUG > 1
661 printk(KERN_DEBUG "lapb: (%p) S4 RX SABME(%d)\n",
662 lapb->dev, frame->pf);
663#endif
664 if (lapb->mode & LAPB_EXTENDED) {
665#if LAPB_DEBUG > 1
666 printk(KERN_DEBUG "lapb: (%p) S4 TX UA(%d)\n",
667 lapb->dev, frame->pf);
668#endif
669#if LAPB_DEBUG > 0
670 printk(KERN_DEBUG "lapb: (%p) S4 -> S3\n",
671 lapb->dev);
672#endif
673 lapb_send_control(lapb, LAPB_UA, frame->pf,
674 LAPB_RESPONSE);
675 lapb_stop_t1timer(lapb);
676 lapb_stop_t2timer(lapb);
677 lapb->state = LAPB_STATE_3;
678 lapb->condition = 0x00;
679 lapb->n2count = 0;
680 lapb->vs = 0;
681 lapb->vr = 0;
682 lapb->va = 0;
683 lapb_connect_indication(lapb, LAPB_OK);
684 } else {
685#if LAPB_DEBUG > 1
686 printk(KERN_DEBUG "lapb: (%p) S4 TX DM(%d)\n",
687 lapb->dev, frame->pf);
688#endif
689 lapb_send_control(lapb, LAPB_DM, frame->pf,
690 LAPB_RESPONSE);
691 }
692 break;
693 }
694
695 kfree_skb(skb);
696}
697
698/*
699 * Process an incoming LAPB frame
700 */
701void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *skb)
702{
703 struct lapb_frame frame;
704
705 if (lapb_decode(lapb, skb, &frame) < 0) {
706 kfree_skb(skb);
707 return;
708 }
709
710 switch (lapb->state) {
711 case LAPB_STATE_0:
712 lapb_state0_machine(lapb, skb, &frame); break;
713 case LAPB_STATE_1:
714 lapb_state1_machine(lapb, skb, &frame); break;
715 case LAPB_STATE_2:
716 lapb_state2_machine(lapb, skb, &frame); break;
717 case LAPB_STATE_3:
718 lapb_state3_machine(lapb, skb, &frame); break;
719 case LAPB_STATE_4:
720 lapb_state4_machine(lapb, skb, &frame); break;
721 }
722
723 lapb_kick(lapb);
724}