Linux Audio

Check our new training course

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