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/timer.h>
23 #include <linux/string.h>
24 #include <linux/sockios.h>
25 #include <linux/net.h>
26 #include <linux/inet.h>
27 #include <linux/skbuff.h>
29 #include <asm/uaccess.h>
30 #include <asm/system.h>
31 #include <linux/fcntl.h>
33 #include <linux/interrupt.h>
37 * This procedure is passed a buffer descriptor for an iframe. It builds
38 * the rest of the control part of the frame and then writes it out.
40 static void lapb_send_iframe(struct lapb_cb
*lapb
, struct sk_buff
*skb
, int poll_bit
)
47 if (lapb
->mode
& LAPB_EXTENDED
) {
48 frame
= skb_push(skb
, 2);
51 frame
[0] |= lapb
->vs
<< 1;
52 frame
[1] = poll_bit
? LAPB_EPF
: 0;
53 frame
[1] |= lapb
->vr
<< 1;
55 frame
= skb_push(skb
, 1);
58 *frame
|= poll_bit
? LAPB_SPF
: 0;
59 *frame
|= lapb
->vr
<< 5;
60 *frame
|= lapb
->vs
<< 1;
64 printk(KERN_DEBUG
"lapb: (%p) S%d TX I(%d) S%d R%d\n",
65 lapb
->dev
, lapb
->state
, poll_bit
, lapb
->vs
, lapb
->vr
);
68 lapb_transmit_buffer(lapb
, skb
, LAPB_COMMAND
);
71 void lapb_kick(struct lapb_cb
*lapb
)
73 struct sk_buff
*skb
, *skbn
;
74 unsigned short modulus
, start
, end
;
76 modulus
= (lapb
->mode
& LAPB_EXTENDED
) ? LAPB_EMODULUS
: LAPB_SMODULUS
;
77 start
= !skb_peek(&lapb
->ack_queue
) ? lapb
->va
: lapb
->vs
;
78 end
= (lapb
->va
+ lapb
->window
) % modulus
;
80 if (!(lapb
->condition
& LAPB_PEER_RX_BUSY_CONDITION
) &&
81 start
!= end
&& skb_peek(&lapb
->write_queue
)) {
85 * Dequeue the frame and copy it.
87 skb
= skb_dequeue(&lapb
->write_queue
);
90 if ((skbn
= skb_clone(skb
, GFP_ATOMIC
)) == NULL
) {
91 skb_queue_head(&lapb
->write_queue
, skb
);
96 skb_set_owner_w(skbn
, skb
->sk
);
99 * Transmit the frame copy.
101 lapb_send_iframe(lapb
, skbn
, LAPB_POLLOFF
);
103 lapb
->vs
= (lapb
->vs
+ 1) % modulus
;
106 * Requeue the original data frame.
108 skb_queue_tail(&lapb
->ack_queue
, skb
);
110 } while (lapb
->vs
!= end
&& (skb
= skb_dequeue(&lapb
->write_queue
)) != NULL
);
112 lapb
->condition
&= ~LAPB_ACK_PENDING_CONDITION
;
114 if (!lapb_t1timer_running(lapb
))
115 lapb_start_t1timer(lapb
);
119 void lapb_transmit_buffer(struct lapb_cb
*lapb
, struct sk_buff
*skb
, int type
)
123 ptr
= skb_push(skb
, 1);
125 if (lapb
->mode
& LAPB_MLP
) {
126 if (lapb
->mode
& LAPB_DCE
) {
127 if (type
== LAPB_COMMAND
)
129 if (type
== LAPB_RESPONSE
)
132 if (type
== LAPB_COMMAND
)
134 if (type
== LAPB_RESPONSE
)
138 if (lapb
->mode
& LAPB_DCE
) {
139 if (type
== LAPB_COMMAND
)
141 if (type
== LAPB_RESPONSE
)
144 if (type
== LAPB_COMMAND
)
146 if (type
== LAPB_RESPONSE
)
152 printk(KERN_DEBUG
"lapb: (%p) S%d TX %02X %02X %02X\n",
153 lapb
->dev
, lapb
->state
,
154 skb
->data
[0], skb
->data
[1], skb
->data
[2]);
157 if (!lapb_data_transmit(lapb
, skb
))
161 void lapb_establish_data_link(struct lapb_cb
*lapb
)
163 lapb
->condition
= 0x00;
166 if (lapb
->mode
& LAPB_EXTENDED
) {
168 printk(KERN_DEBUG
"lapb: (%p) S%d TX SABME(1)\n",
169 lapb
->dev
, lapb
->state
);
171 lapb_send_control(lapb
, LAPB_SABME
, LAPB_POLLON
, LAPB_COMMAND
);
174 printk(KERN_DEBUG
"lapb: (%p) S%d TX SABM(1)\n",
175 lapb
->dev
, lapb
->state
);
177 lapb_send_control(lapb
, LAPB_SABM
, LAPB_POLLON
, LAPB_COMMAND
);
180 lapb_start_t1timer(lapb
);
181 lapb_stop_t2timer(lapb
);
184 void lapb_enquiry_response(struct lapb_cb
*lapb
)
187 printk(KERN_DEBUG
"lapb: (%p) S%d TX RR(1) R%d\n",
188 lapb
->dev
, 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(struct lapb_cb
*lapb
)
199 printk(KERN_DEBUG
"lapb: (%p) S%d TX RR(0) R%d\n",
200 lapb
->dev
, 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(struct lapb_cb
*lapb
, unsigned short nr
)
209 if (lapb
->vs
== nr
) {
210 lapb_frames_acked(lapb
, nr
);
211 lapb_stop_t1timer(lapb
);
213 } else if (lapb
->va
!= nr
) {
214 lapb_frames_acked(lapb
, nr
);
215 lapb_start_t1timer(lapb
);
219 void lapb_check_need_response(struct lapb_cb
*lapb
, int type
, int pf
)
221 if (type
== LAPB_COMMAND
&& pf
)
222 lapb_enquiry_response(lapb
);