1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
5 * Copyright (C) 2002 Ralf Baechle DO1GRB (ralf@gnu.org)
7 #include <linux/errno.h>
8 #include <linux/types.h>
9 #include <linux/socket.h>
11 #include <linux/kernel.h>
12 #include <linux/jiffies.h>
13 #include <linux/timer.h>
14 #include <linux/string.h>
15 #include <linux/sockios.h>
16 #include <linux/net.h>
18 #include <linux/inet.h>
19 #include <linux/netdevice.h>
20 #include <linux/skbuff.h>
22 #include <net/tcp_states.h>
23 #include <linux/fcntl.h>
25 #include <linux/interrupt.h>
28 static void rose_heartbeat_expiry(struct timer_list
*t
);
29 static void rose_timer_expiry(struct timer_list
*);
30 static void rose_idletimer_expiry(struct timer_list
*);
32 void rose_start_heartbeat(struct sock
*sk
)
34 del_timer(&sk
->sk_timer
);
36 sk
->sk_timer
.function
= rose_heartbeat_expiry
;
37 sk
->sk_timer
.expires
= jiffies
+ 5 * HZ
;
39 add_timer(&sk
->sk_timer
);
42 void rose_start_t1timer(struct sock
*sk
)
44 struct rose_sock
*rose
= rose_sk(sk
);
46 del_timer(&rose
->timer
);
48 rose
->timer
.function
= rose_timer_expiry
;
49 rose
->timer
.expires
= jiffies
+ rose
->t1
;
51 add_timer(&rose
->timer
);
54 void rose_start_t2timer(struct sock
*sk
)
56 struct rose_sock
*rose
= rose_sk(sk
);
58 del_timer(&rose
->timer
);
60 rose
->timer
.function
= rose_timer_expiry
;
61 rose
->timer
.expires
= jiffies
+ rose
->t2
;
63 add_timer(&rose
->timer
);
66 void rose_start_t3timer(struct sock
*sk
)
68 struct rose_sock
*rose
= rose_sk(sk
);
70 del_timer(&rose
->timer
);
72 rose
->timer
.function
= rose_timer_expiry
;
73 rose
->timer
.expires
= jiffies
+ rose
->t3
;
75 add_timer(&rose
->timer
);
78 void rose_start_hbtimer(struct sock
*sk
)
80 struct rose_sock
*rose
= rose_sk(sk
);
82 del_timer(&rose
->timer
);
84 rose
->timer
.function
= rose_timer_expiry
;
85 rose
->timer
.expires
= jiffies
+ rose
->hb
;
87 add_timer(&rose
->timer
);
90 void rose_start_idletimer(struct sock
*sk
)
92 struct rose_sock
*rose
= rose_sk(sk
);
94 del_timer(&rose
->idletimer
);
97 rose
->idletimer
.function
= rose_idletimer_expiry
;
98 rose
->idletimer
.expires
= jiffies
+ rose
->idle
;
100 add_timer(&rose
->idletimer
);
104 void rose_stop_heartbeat(struct sock
*sk
)
106 del_timer(&sk
->sk_timer
);
109 void rose_stop_timer(struct sock
*sk
)
111 del_timer(&rose_sk(sk
)->timer
);
114 void rose_stop_idletimer(struct sock
*sk
)
116 del_timer(&rose_sk(sk
)->idletimer
);
119 static void rose_heartbeat_expiry(struct timer_list
*t
)
121 struct sock
*sk
= from_timer(sk
, t
, sk_timer
);
122 struct rose_sock
*rose
= rose_sk(sk
);
125 switch (rose
->state
) {
127 /* Magic here: If we listen() and a new link dies before it
128 is accepted() it isn't 'dead' so doesn't get removed. */
129 if (sock_flag(sk
, SOCK_DESTROY
) ||
130 (sk
->sk_state
== TCP_LISTEN
&& sock_flag(sk
, SOCK_DEAD
))) {
132 rose_destroy_socket(sk
);
139 * Check for the state of the receive buffer.
141 if (atomic_read(&sk
->sk_rmem_alloc
) < (sk
->sk_rcvbuf
/ 2) &&
142 (rose
->condition
& ROSE_COND_OWN_RX_BUSY
)) {
143 rose
->condition
&= ~ROSE_COND_OWN_RX_BUSY
;
144 rose
->condition
&= ~ROSE_COND_ACK_PENDING
;
146 rose_write_internal(sk
, ROSE_RR
);
147 rose_stop_timer(sk
); /* HB */
153 rose_start_heartbeat(sk
);
157 static void rose_timer_expiry(struct timer_list
*t
)
159 struct rose_sock
*rose
= from_timer(rose
, t
, timer
);
160 struct sock
*sk
= &rose
->sock
;
163 switch (rose
->state
) {
164 case ROSE_STATE_1
: /* T1 */
165 case ROSE_STATE_4
: /* T2 */
166 rose_write_internal(sk
, ROSE_CLEAR_REQUEST
);
167 rose
->state
= ROSE_STATE_2
;
168 rose_start_t3timer(sk
);
171 case ROSE_STATE_2
: /* T3 */
172 rose
->neighbour
->use
--;
173 rose_disconnect(sk
, ETIMEDOUT
, -1, -1);
176 case ROSE_STATE_3
: /* HB */
177 if (rose
->condition
& ROSE_COND_ACK_PENDING
) {
178 rose
->condition
&= ~ROSE_COND_ACK_PENDING
;
179 rose_enquiry_response(sk
);
186 static void rose_idletimer_expiry(struct timer_list
*t
)
188 struct rose_sock
*rose
= from_timer(rose
, t
, idletimer
);
189 struct sock
*sk
= &rose
->sock
;
192 rose_clear_queues(sk
);
194 rose_write_internal(sk
, ROSE_CLEAR_REQUEST
);
195 rose_sk(sk
)->state
= ROSE_STATE_2
;
197 rose_start_t3timer(sk
);
199 sk
->sk_state
= TCP_CLOSE
;
201 sk
->sk_shutdown
|= SEND_SHUTDOWN
;
203 if (!sock_flag(sk
, SOCK_DEAD
)) {
204 sk
->sk_state_change(sk
);
205 sock_set_flag(sk
, SOCK_DEAD
);