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 * ROSE 001 Jonathan(G4KLX) Cloned from nr_timer.c
14 * ROSE 003 Jonathan(G4KLX) New timer architecture.
15 * Implemented idle timer.
18 #include <linux/errno.h>
19 #include <linux/types.h>
20 #include <linux/socket.h>
22 #include <linux/kernel.h>
23 #include <linux/sched.h>
24 #include <linux/timer.h>
25 #include <linux/string.h>
26 #include <linux/sockios.h>
27 #include <linux/net.h>
29 #include <linux/inet.h>
30 #include <linux/netdevice.h>
31 #include <linux/skbuff.h>
33 #include <asm/segment.h>
34 #include <asm/system.h>
35 #include <linux/fcntl.h>
37 #include <linux/interrupt.h>
40 static void rose_heartbeat_expiry(unsigned long);
41 static void rose_timer_expiry(unsigned long);
42 static void rose_idletimer_expiry(unsigned long);
44 void rose_start_heartbeat(struct sock *sk)
46 del_timer(&sk->timer);
48 sk->timer.data = (unsigned long)sk;
49 sk->timer.function = &rose_heartbeat_expiry;
50 sk->timer.expires = jiffies + 5 * HZ;
52 add_timer(&sk->timer);
55 void rose_start_t1timer(struct sock *sk)
57 del_timer(&sk->protinfo.rose->timer);
59 sk->protinfo.rose->timer.data = (unsigned long)sk;
60 sk->protinfo.rose->timer.function = &rose_timer_expiry;
61 sk->protinfo.rose->timer.expires = jiffies + sk->protinfo.rose->t1;
63 add_timer(&sk->protinfo.rose->timer);
66 void rose_start_t2timer(struct sock *sk)
68 del_timer(&sk->protinfo.rose->timer);
70 sk->protinfo.rose->timer.data = (unsigned long)sk;
71 sk->protinfo.rose->timer.function = &rose_timer_expiry;
72 sk->protinfo.rose->timer.expires = jiffies + sk->protinfo.rose->t2;
74 add_timer(&sk->protinfo.rose->timer);
77 void rose_start_t3timer(struct sock *sk)
79 del_timer(&sk->protinfo.rose->timer);
81 sk->protinfo.rose->timer.data = (unsigned long)sk;
82 sk->protinfo.rose->timer.function = &rose_timer_expiry;
83 sk->protinfo.rose->timer.expires = jiffies + sk->protinfo.rose->t3;
85 add_timer(&sk->protinfo.rose->timer);
88 void rose_start_hbtimer(struct sock *sk)
90 del_timer(&sk->protinfo.rose->timer);
92 sk->protinfo.rose->timer.data = (unsigned long)sk;
93 sk->protinfo.rose->timer.function = &rose_timer_expiry;
94 sk->protinfo.rose->timer.expires = jiffies + sk->protinfo.rose->hb;
96 add_timer(&sk->protinfo.rose->timer);
99 void rose_start_idletimer(struct sock *sk)
101 del_timer(&sk->protinfo.rose->idletimer);
103 if (sk->protinfo.rose->idle > 0) {
104 sk->protinfo.rose->idletimer.data = (unsigned long)sk;
105 sk->protinfo.rose->idletimer.function = &rose_idletimer_expiry;
106 sk->protinfo.rose->idletimer.expires = jiffies + sk->protinfo.rose->idle;
108 add_timer(&sk->protinfo.rose->idletimer);
112 void rose_stop_heartbeat(struct sock *sk)
114 del_timer(&sk->timer);
117 void rose_stop_timer(struct sock *sk)
119 del_timer(&sk->protinfo.rose->timer);
122 void rose_stop_idletimer(struct sock *sk)
124 del_timer(&sk->protinfo.rose->idletimer);
127 static void rose_heartbeat_expiry(unsigned long param)
129 struct sock *sk = (struct sock *)param;
131 switch (sk->protinfo.rose->state) {
134 /* Magic here: If we listen() and a new link dies before it
135 is accepted() it isn't 'dead' so doesn't get removed. */
136 if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
137 rose_destroy_socket(sk);
144 * Check for the state of the receive buffer.
146 if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
147 (sk->protinfo.rose->condition & ROSE_COND_OWN_RX_BUSY)) {
148 sk->protinfo.rose->condition &= ~ROSE_COND_OWN_RX_BUSY;
149 sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
150 sk->protinfo.rose->vl = sk->protinfo.rose->vr;
151 rose_write_internal(sk, ROSE_RR);
152 rose_stop_timer(sk); /* HB */
158 rose_start_heartbeat(sk);
161 static void rose_timer_expiry(unsigned long param)
163 struct sock *sk = (struct sock *)param;
165 switch (sk->protinfo.rose->state) {
167 case ROSE_STATE_1: /* T1 */
168 case ROSE_STATE_4: /* T2 */
169 rose_write_internal(sk, ROSE_CLEAR_REQUEST);
170 sk->protinfo.rose->state = ROSE_STATE_2;
171 rose_start_t3timer(sk);
174 case ROSE_STATE_2: /* T3 */
175 sk->protinfo.rose->neighbour->use--;
176 rose_disconnect(sk, ETIMEDOUT, -1, -1);
179 case ROSE_STATE_3: /* HB */
180 if (sk->protinfo.rose->condition & ROSE_COND_ACK_PENDING) {
181 sk->protinfo.rose->condition &= ~ROSE_COND_ACK_PENDING;
182 rose_enquiry_response(sk);
188 static void rose_idletimer_expiry(unsigned long param)
190 struct sock *sk = (struct sock *)param;
192 rose_clear_queues(sk);
194 rose_write_internal(sk, ROSE_CLEAR_REQUEST);
195 sk->protinfo.rose->state = ROSE_STATE_2;
197 rose_start_t3timer(sk);
199 sk->state = TCP_CLOSE;
201 sk->shutdown |= SEND_SHUTDOWN;
204 sk->state_change(sk);