199821Sjoerg// SPDX-License-Identifier: GPL-2.0-or-later
299821Sjoerg/*
399373Sjohan *
499373Sjohan * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
599373Sjohan * Copyright (C) 2002 Ralf Baechle DO1GRB (ralf@gnu.org)
699373Sjohan */
799373Sjohan#include <linux/errno.h>
899373Sjohan#include <linux/types.h>
999373Sjohan#include <linux/socket.h>
1099373Sjohan#include <linux/in.h>
1199373Sjohan#include <linux/kernel.h>
1299373Sjohan#include <linux/jiffies.h>
1399821Sjoerg#include <linux/timer.h>
1499821Sjoerg#include <linux/string.h>
1599821Sjoerg#include <linux/sockios.h>
1699821Sjoerg#include <linux/net.h>
1799821Sjoerg#include <net/ax25.h>
1899821Sjoerg#include <linux/inet.h>
1999821Sjoerg#include <linux/netdevice.h>
2099821Sjoerg#include <linux/skbuff.h>
2199821Sjoerg#include <net/sock.h>
2299821Sjoerg#include <net/tcp_states.h>
2399821Sjoerg#include <linux/fcntl.h>
2499373Sjohan#include <linux/mm.h>
2599373Sjohan#include <linux/interrupt.h>
2699821Sjoerg#include <net/rose.h>
2799821Sjoerg
2899821Sjoergstatic void rose_heartbeat_expiry(struct timer_list *t);
2999821Sjoergstatic void rose_timer_expiry(struct timer_list *);
3099821Sjoergstatic void rose_idletimer_expiry(struct timer_list *);
3199821Sjoerg
3299373Sjohanvoid rose_start_heartbeat(struct sock *sk)
3399821Sjoerg{
3499373Sjohan	sk_stop_timer(sk, &sk->sk_timer);
3599406Sjohan
3699406Sjohan	sk->sk_timer.function = rose_heartbeat_expiry;
3799373Sjohan	sk->sk_timer.expires  = jiffies + 5 * HZ;
3899373Sjohan
3999373Sjohan	sk_reset_timer(sk, &sk->sk_timer, sk->sk_timer.expires);
4099821Sjoerg}
4199373Sjohan
4299373Sjohanvoid rose_start_t1timer(struct sock *sk)
43132198Stjr{
4499821Sjoerg	struct rose_sock *rose = rose_sk(sk);
4599373Sjohan
4699373Sjohan	sk_stop_timer(sk, &rose->timer);
4799373Sjohan
4899821Sjoerg	rose->timer.function = rose_timer_expiry;
4999373Sjohan	rose->timer.expires  = jiffies + rose->t1;
5099373Sjohan
5199821Sjoerg	sk_reset_timer(sk, &rose->timer, rose->timer.expires);
5299373Sjohan}
53102246Sjohan
54102246Sjohanvoid rose_start_t2timer(struct sock *sk)
55102246Sjohan{
56102246Sjohan	struct rose_sock *rose = rose_sk(sk);
5799821Sjoerg
5899821Sjoerg	sk_stop_timer(sk, &rose->timer);
59102246Sjohan
6099821Sjoerg	rose->timer.function = rose_timer_expiry;
6199821Sjoerg	rose->timer.expires  = jiffies + rose->t2;
6299821Sjoerg
6399821Sjoerg	sk_reset_timer(sk, &rose->timer, rose->timer.expires);
6499821Sjoerg}
6599821Sjoerg
6699821Sjoergvoid rose_start_t3timer(struct sock *sk)
6799821Sjoerg{
6899821Sjoerg	struct rose_sock *rose = rose_sk(sk);
6999821Sjoerg
7099821Sjoerg	sk_stop_timer(sk, &rose->timer);
7199821Sjoerg
7299821Sjoerg	rose->timer.function = rose_timer_expiry;
7399821Sjoerg	rose->timer.expires  = jiffies + rose->t3;
7499821Sjoerg
7599821Sjoerg	sk_reset_timer(sk, &rose->timer, rose->timer.expires);
7699821Sjoerg}
7799821Sjoerg
7899821Sjoergvoid rose_start_hbtimer(struct sock *sk)
7999821Sjoerg{
8099821Sjoerg	struct rose_sock *rose = rose_sk(sk);
8199821Sjoerg
8299821Sjoerg	sk_stop_timer(sk, &rose->timer);
8399821Sjoerg
8499821Sjoerg	rose->timer.function = rose_timer_expiry;
8599821Sjoerg	rose->timer.expires  = jiffies + rose->hb;
8699821Sjoerg
8799821Sjoerg	sk_reset_timer(sk, &rose->timer, rose->timer.expires);
8899821Sjoerg}
8999821Sjoerg
9099373Sjohanvoid rose_start_idletimer(struct sock *sk)
91141657Sru{
92141657Sru	struct rose_sock *rose = rose_sk(sk);
93141657Sru
9499821Sjoerg	sk_stop_timer(sk, &rose->idletimer);
9599373Sjohan
9699821Sjoerg	if (rose->idle > 0) {
9799821Sjoerg		rose->idletimer.function = rose_idletimer_expiry;
9899821Sjoerg		rose->idletimer.expires  = jiffies + rose->idle;
9999821Sjoerg
10099821Sjoerg		sk_reset_timer(sk, &rose->idletimer, rose->idletimer.expires);
10199821Sjoerg	}
10299821Sjoerg}
10399821Sjoerg
10499821Sjoergvoid rose_stop_heartbeat(struct sock *sk)
10599821Sjoerg{
10699821Sjoerg	sk_stop_timer(sk, &sk->sk_timer);
10799821Sjoerg}
10899821Sjoerg
109102246Sjohanvoid rose_stop_timer(struct sock *sk)
11099821Sjoerg{
11199821Sjoerg	sk_stop_timer(sk, &rose_sk(sk)->timer);
11299821Sjoerg}
11399821Sjoerg
11499821Sjoergvoid rose_stop_idletimer(struct sock *sk)
11599821Sjoerg{
11699821Sjoerg	sk_stop_timer(sk, &rose_sk(sk)->idletimer);
11799821Sjoerg}
11899821Sjoerg
11999821Sjoergstatic void rose_heartbeat_expiry(struct timer_list *t)
12099821Sjoerg{
12199821Sjoerg	struct sock *sk = from_timer(sk, t, sk_timer);
12299821Sjoerg	struct rose_sock *rose = rose_sk(sk);
123102072Sjohan
124102072Sjohan	bh_lock_sock(sk);
12599821Sjoerg	switch (rose->state) {
12699821Sjoerg	case ROSE_STATE_0:
12799821Sjoerg		/* Magic here: If we listen() and a new link dies before it
12899821Sjoerg		   is accepted() it isn't 'dead' so doesn't get removed. */
12999821Sjoerg		if (sock_flag(sk, SOCK_DESTROY) ||
130102072Sjohan		    (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
13199821Sjoerg			bh_unlock_sock(sk);
13299821Sjoerg			rose_destroy_socket(sk);
13399821Sjoerg			sock_put(sk);
13499821Sjoerg			return;
135102246Sjohan		}
136102246Sjohan		break;
137102246Sjohan
138102246Sjohan	case ROSE_STATE_3:
13999821Sjoerg		/*
14099821Sjoerg		 * Check for the state of the receive buffer.
14199821Sjoerg		 */
14299821Sjoerg		if (atomic_read(&sk->sk_rmem_alloc) < (sk->sk_rcvbuf / 2) &&
14399821Sjoerg		    (rose->condition & ROSE_COND_OWN_RX_BUSY)) {
14499821Sjoerg			rose->condition &= ~ROSE_COND_OWN_RX_BUSY;
14599821Sjoerg			rose->condition &= ~ROSE_COND_ACK_PENDING;
14699821Sjoerg			rose->vl         = rose->vr;
14799821Sjoerg			rose_write_internal(sk, ROSE_RR);
14899821Sjoerg			rose_stop_timer(sk);	/* HB */
14999821Sjoerg			break;
15099821Sjoerg		}
15199821Sjoerg		break;
15299821Sjoerg	}
15399821Sjoerg
15499821Sjoerg	rose_start_heartbeat(sk);
15599821Sjoerg	bh_unlock_sock(sk);
15699821Sjoerg	sock_put(sk);
15799821Sjoerg}
15899821Sjoerg
15999821Sjoergstatic void rose_timer_expiry(struct timer_list *t)
16099821Sjoerg{
16199821Sjoerg	struct rose_sock *rose = from_timer(rose, t, timer);
16299821Sjoerg	struct sock *sk = &rose->sock;
16399821Sjoerg
16499821Sjoerg	bh_lock_sock(sk);
16599821Sjoerg	switch (rose->state) {
16699373Sjohan	case ROSE_STATE_1:	/* T1 */
16799373Sjohan	case ROSE_STATE_4:	/* T2 */
16899373Sjohan		rose_write_internal(sk, ROSE_CLEAR_REQUEST);
16999821Sjoerg		rose->state = ROSE_STATE_2;
17099821Sjoerg		rose_start_t3timer(sk);
17199373Sjohan		break;
17299821Sjoerg
17399821Sjoerg	case ROSE_STATE_2:	/* T3 */
17499373Sjohan		rose->neighbour->use--;
17599821Sjoerg		rose_disconnect(sk, ETIMEDOUT, -1, -1);
17699821Sjoerg		break;
17799821Sjoerg
17899821Sjoerg	case ROSE_STATE_3:	/* HB */
17999821Sjoerg		if (rose->condition & ROSE_COND_ACK_PENDING) {
18099821Sjoerg			rose->condition &= ~ROSE_COND_ACK_PENDING;
18199821Sjoerg			rose_enquiry_response(sk);
18299821Sjoerg		}
18399821Sjoerg		break;
18499821Sjoerg	}
18599821Sjoerg	bh_unlock_sock(sk);
18699821Sjoerg	sock_put(sk);
18799821Sjoerg}
18899821Sjoerg
18999821Sjoergstatic void rose_idletimer_expiry(struct timer_list *t)
19099373Sjohan{
19199821Sjoerg	struct rose_sock *rose = from_timer(rose, t, idletimer);
19299821Sjoerg	struct sock *sk = &rose->sock;
19399373Sjohan
19499821Sjoerg	bh_lock_sock(sk);
19599821Sjoerg	rose_clear_queues(sk);
19699821Sjoerg
19799821Sjoerg	rose_write_internal(sk, ROSE_CLEAR_REQUEST);
19899821Sjoerg	rose_sk(sk)->state = ROSE_STATE_2;
19999821Sjoerg
20099821Sjoerg	rose_start_t3timer(sk);
20199821Sjoerg
20299821Sjoerg	sk->sk_state     = TCP_CLOSE;
20399821Sjoerg	sk->sk_err       = 0;
20499821Sjoerg	sk->sk_shutdown |= SEND_SHUTDOWN;
20599821Sjoerg
20699821Sjoerg	if (!sock_flag(sk, SOCK_DEAD)) {
20799821Sjoerg		sk->sk_state_change(sk);
20899821Sjoerg		sock_set_flag(sk, SOCK_DEAD);
20999821Sjoerg	}
21099821Sjoerg	bh_unlock_sock(sk);
21199821Sjoerg	sock_put(sk);
21299821Sjoerg}
21399821Sjoerg