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/errno.h>
18 #include <linux/types.h>
19 #include <linux/socket.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.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/skbuff.h>
30 #include <asm/uaccess.h>
31 #include <asm/system.h>
32 #include <linux/fcntl.h>
34 #include <linux/interrupt.h>
38 * This procedure is passed a buffer descriptor for an iframe. It builds
39 * the rest of the control part of the frame and then writes it out.
41 static void lapb_send_iframe(struct lapb_cb
*lapb
, struct sk_buff
*skb
, int poll_bit
)
48 if (lapb
->mode
& LAPB_EXTENDED
) {
49 frame
= skb_push(skb
, 2);
52 frame
[0] |= lapb
->vs
<< 1;
53 frame
[1] = poll_bit
? LAPB_EPF
: 0;
54 frame
[1] |= lapb
->vr
<< 1;
56 frame
= skb_push(skb
, 1);
59 *frame
|= poll_bit
? LAPB_SPF
: 0;
60 *frame
|= lapb
->vr
<< 5;
61 *frame
|= lapb
->vs
<< 1;
65 printk(KERN_DEBUG
"lapb: (%p) S%d TX I(%d) S%d R%d\n",
66 lapb
->dev
, lapb
->state
, poll_bit
, lapb
->vs
, lapb
->vr
);
69 lapb_transmit_buffer(lapb
, skb
, LAPB_COMMAND
);
72 void lapb_kick(struct lapb_cb
*lapb
)
74 struct sk_buff
*skb
, *skbn
;
75 unsigned short modulus
, start
, end
;
77 modulus
= (lapb
->mode
& LAPB_EXTENDED
) ? LAPB_EMODULUS
: LAPB_SMODULUS
;
78 start
= !skb_peek(&lapb
->ack_queue
) ? lapb
->va
: lapb
->vs
;
79 end
= (lapb
->va
+ lapb
->window
) % modulus
;
81 if (!(lapb
->condition
& LAPB_PEER_RX_BUSY_CONDITION
) &&
82 start
!= end
&& skb_peek(&lapb
->write_queue
)) {
86 * Dequeue the frame and copy it.
88 skb
= skb_dequeue(&lapb
->write_queue
);
91 if ((skbn
= skb_clone(skb
, GFP_ATOMIC
)) == NULL
) {
92 skb_queue_head(&lapb
->write_queue
, skb
);
97 skb_set_owner_w(skbn
, skb
->sk
);
100 * Transmit the frame copy.
102 lapb_send_iframe(lapb
, skbn
, LAPB_POLLOFF
);
104 lapb
->vs
= (lapb
->vs
+ 1) % modulus
;
107 * Requeue the original data frame.
109 skb_queue_tail(&lapb
->ack_queue
, skb
);
111 } while (lapb
->vs
!= end
&& (skb
= skb_dequeue(&lapb
->write_queue
)) != NULL
);
113 lapb
->condition
&= ~LAPB_ACK_PENDING_CONDITION
;
115 if (!lapb_t1timer_running(lapb
))
116 lapb_start_t1timer(lapb
);
120 void lapb_transmit_buffer(struct lapb_cb
*lapb
, struct sk_buff
*skb
, int type
)
124 ptr
= skb_push(skb
, 1);
126 if (lapb
->mode
& LAPB_MLP
) {
127 if (lapb
->mode
& LAPB_DCE
) {
128 if (type
== LAPB_COMMAND
)
130 if (type
== LAPB_RESPONSE
)
133 if (type
== LAPB_COMMAND
)
135 if (type
== LAPB_RESPONSE
)
139 if (lapb
->mode
& LAPB_DCE
) {
140 if (type
== LAPB_COMMAND
)
142 if (type
== LAPB_RESPONSE
)
145 if (type
== LAPB_COMMAND
)
147 if (type
== LAPB_RESPONSE
)
153 printk(KERN_DEBUG
"lapb: (%p) S%d TX %02X %02X %02X\n",
154 lapb
->dev
, lapb
->state
,
155 skb
->data
[0], skb
->data
[1], skb
->data
[2]);
158 if (!lapb_data_transmit(lapb
, skb
))
162 void lapb_establish_data_link(struct lapb_cb
*lapb
)
164 lapb
->condition
= 0x00;
167 if (lapb
->mode
& LAPB_EXTENDED
) {
169 printk(KERN_DEBUG
"lapb: (%p) S%d TX SABME(1)\n",
170 lapb
->dev
, lapb
->state
);
172 lapb_send_control(lapb
, LAPB_SABME
, LAPB_POLLON
, LAPB_COMMAND
);
175 printk(KERN_DEBUG
"lapb: (%p) S%d TX SABM(1)\n",
176 lapb
->dev
, 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(struct lapb_cb
*lapb
)
188 printk(KERN_DEBUG
"lapb: (%p) S%d TX RR(1) R%d\n",
189 lapb
->dev
, lapb
->state
, lapb
->vr
);
192 lapb_send_control(lapb
, LAPB_RR
, LAPB_POLLON
, LAPB_RESPONSE
);
194 lapb
->condition
&= ~LAPB_ACK_PENDING_CONDITION
;
197 void lapb_timeout_response(struct lapb_cb
*lapb
)
200 printk(KERN_DEBUG
"lapb: (%p) S%d TX RR(0) R%d\n",
201 lapb
->dev
, lapb
->state
, lapb
->vr
);
203 lapb_send_control(lapb
, LAPB_RR
, LAPB_POLLOFF
, LAPB_RESPONSE
);
205 lapb
->condition
&= ~LAPB_ACK_PENDING_CONDITION
;
208 void lapb_check_iframes_acked(struct lapb_cb
*lapb
, unsigned short nr
)
210 if (lapb
->vs
== nr
) {
211 lapb_frames_acked(lapb
, nr
);
212 lapb_stop_t1timer(lapb
);
214 } else if (lapb
->va
!= nr
) {
215 lapb_frames_acked(lapb
, nr
);
216 lapb_start_t1timer(lapb
);
220 void lapb_check_need_response(struct lapb_cb
*lapb
, int type
, int pf
)
222 if (type
== LAPB_COMMAND
&& pf
)
223 lapb_enquiry_response(lapb
);