4 * This code REQUIRES 2.1.15 or higher/ NET3.038
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.
13 * LAPB 001 Jonathan Naylor Started Coding
14 * LAPB 002 Jonathan Naylor New timer architecture.
17 #include <linux/config.h>
18 #if defined(CONFIG_LAPB) || defined(CONFIG_LAPB_MODULE)
19 #include <linux/errno.h>
20 #include <linux/types.h>
21 #include <linux/socket.h>
23 #include <linux/kernel.h>
24 #include <linux/sched.h>
25 #include <linux/timer.h>
26 #include <linux/string.h>
27 #include <linux/sockios.h>
28 #include <linux/net.h>
29 #include <linux/inet.h>
30 #include <linux/skbuff.h>
32 #include <asm/uaccess.h>
33 #include <asm/system.h>
34 #include <linux/fcntl.h>
36 #include <linux/interrupt.h>
40 * This procedure is passed a buffer descriptor for an iframe. It builds
41 * the rest of the control part of the frame and then writes it out.
43 static void lapb_send_iframe(lapb_cb
*lapb
, struct sk_buff
*skb
, int poll_bit
)
50 if (lapb
->mode
& LAPB_EXTENDED
) {
51 frame
= skb_push(skb
, 2);
54 frame
[0] |= (lapb
->vs
<< 1);
55 frame
[1] = (poll_bit
) ? LAPB_EPF
: 0;
56 frame
[1] |= (lapb
->vr
<< 1);
58 frame
= skb_push(skb
, 1);
61 *frame
|= (poll_bit
) ? LAPB_SPF
: 0;
62 *frame
|= (lapb
->vr
<< 5);
63 *frame
|= (lapb
->vs
<< 1);
67 printk(KERN_DEBUG
"lapb: (%p) S%d TX I(%d) S%d R%d\n", lapb
->token
, lapb
->state
, poll_bit
, lapb
->vs
, lapb
->vr
);
70 lapb_transmit_buffer(lapb
, skb
, LAPB_COMMAND
);
73 void lapb_kick(lapb_cb
*lapb
)
75 struct sk_buff
*skb
, *skbn
;
76 unsigned short modulus
, start
, end
;
78 modulus
= (lapb
->mode
& LAPB_EXTENDED
) ? LAPB_EMODULUS
: LAPB_SMODULUS
;
80 start
= (skb_peek(&lapb
->ack_queue
) == NULL
) ? lapb
->va
: lapb
->vs
;
81 end
= (lapb
->va
+ lapb
->window
) % modulus
;
83 if (!(lapb
->condition
& LAPB_PEER_RX_BUSY_CONDITION
) &&
85 skb_peek(&lapb
->write_queue
) != NULL
) {
90 * Dequeue the frame and copy it.
92 skb
= skb_dequeue(&lapb
->write_queue
);
95 if ((skbn
= skb_clone(skb
, GFP_ATOMIC
)) == NULL
) {
96 skb_queue_head(&lapb
->write_queue
, skb
);
101 skb_set_owner_w(skbn
, skb
->sk
);
104 * Transmit the frame copy.
106 lapb_send_iframe(lapb
, skbn
, LAPB_POLLOFF
);
108 lapb
->vs
= (lapb
->vs
+ 1) % modulus
;
111 * Requeue the original data frame.
113 skb_queue_tail(&lapb
->ack_queue
, skb
);
115 } while (lapb
->vs
!= end
&& (skb
= skb_dequeue(&lapb
->write_queue
)) != NULL
);
117 lapb
->condition
&= ~LAPB_ACK_PENDING_CONDITION
;
119 if (!lapb_t1timer_running(lapb
))
120 lapb_start_t1timer(lapb
);
124 void lapb_transmit_buffer(lapb_cb
*lapb
, struct sk_buff
*skb
, int type
)
128 ptr
= skb_push(skb
, 1);
130 if (lapb
->mode
& LAPB_MLP
) {
131 if (lapb
->mode
& LAPB_DCE
) {
132 if (type
== LAPB_COMMAND
)
134 if (type
== LAPB_RESPONSE
)
137 if (type
== LAPB_COMMAND
)
139 if (type
== LAPB_RESPONSE
)
143 if (lapb
->mode
& LAPB_DCE
) {
144 if (type
== LAPB_COMMAND
)
146 if (type
== LAPB_RESPONSE
)
149 if (type
== LAPB_COMMAND
)
151 if (type
== LAPB_RESPONSE
)
157 printk(KERN_DEBUG
"lapb: (%p) S%d TX %02X %02X %02X\n", lapb
->token
, lapb
->state
, skb
->data
[0], skb
->data
[1], skb
->data
[2]);
160 if (!lapb_data_transmit(lapb
, skb
))
164 void lapb_establish_data_link(lapb_cb
*lapb
)
166 lapb
->condition
= 0x00;
169 if (lapb
->mode
& LAPB_EXTENDED
) {
171 printk(KERN_DEBUG
"lapb: (%p) S%d TX SABME(1)\n", lapb
->token
, lapb
->state
);
173 lapb_send_control(lapb
, LAPB_SABME
, LAPB_POLLON
, LAPB_COMMAND
);
176 printk(KERN_DEBUG
"lapb: (%p) S%d TX SABM(1)\n", lapb
->token
, lapb
->state
);
178 lapb_send_control(lapb
, LAPB_SABM
, LAPB_POLLON
, LAPB_COMMAND
);
181 lapb_start_t1timer(lapb
);
182 lapb_stop_t2timer(lapb
);
185 void lapb_enquiry_response(lapb_cb
*lapb
)
188 printk(KERN_DEBUG
"lapb: (%p) S%d TX RR(1) R%d\n", lapb
->token
, lapb
->state
, lapb
->vr
);
191 lapb_send_control(lapb
, LAPB_RR
, LAPB_POLLON
, LAPB_RESPONSE
);
193 lapb
->condition
&= ~LAPB_ACK_PENDING_CONDITION
;
196 void lapb_timeout_response(lapb_cb
*lapb
)
199 printk(KERN_DEBUG
"lapb: (%p) S%d TX RR(0) R%d\n", lapb
->token
, lapb
->state
, lapb
->vr
);
202 lapb_send_control(lapb
, LAPB_RR
, LAPB_POLLOFF
, LAPB_RESPONSE
);
204 lapb
->condition
&= ~LAPB_ACK_PENDING_CONDITION
;
207 void lapb_check_iframes_acked(lapb_cb
*lapb
, unsigned short nr
)
209 if (lapb
->vs
== nr
) {
210 lapb_frames_acked(lapb
, nr
);
211 lapb_stop_t1timer(lapb
);
214 if (lapb
->va
!= nr
) {
215 lapb_frames_acked(lapb
, nr
);
216 lapb_start_t1timer(lapb
);
221 void lapb_check_need_response(lapb_cb
*lapb
, int type
, int pf
)
223 if (type
== LAPB_COMMAND
&& pf
)
224 lapb_enquiry_response(lapb
);