18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
58c2ecf20Sopenharmony_ci * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
68c2ecf20Sopenharmony_ci * Copyright (C) Tomi Manninen OH2BNS (oh2bns@sral.fi)
78c2ecf20Sopenharmony_ci * Copyright (C) Darryl Miles G7LED (dlm@g7led.demon.co.uk)
88c2ecf20Sopenharmony_ci * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
98c2ecf20Sopenharmony_ci * Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
108c2ecf20Sopenharmony_ci * Copyright (C) 2002 Ralf Baechle DO1GRB (ralf@gnu.org)
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci#include <linux/errno.h>
138c2ecf20Sopenharmony_ci#include <linux/types.h>
148c2ecf20Sopenharmony_ci#include <linux/socket.h>
158c2ecf20Sopenharmony_ci#include <linux/in.h>
168c2ecf20Sopenharmony_ci#include <linux/kernel.h>
178c2ecf20Sopenharmony_ci#include <linux/module.h>
188c2ecf20Sopenharmony_ci#include <linux/jiffies.h>
198c2ecf20Sopenharmony_ci#include <linux/timer.h>
208c2ecf20Sopenharmony_ci#include <linux/string.h>
218c2ecf20Sopenharmony_ci#include <linux/sockios.h>
228c2ecf20Sopenharmony_ci#include <linux/net.h>
238c2ecf20Sopenharmony_ci#include <net/ax25.h>
248c2ecf20Sopenharmony_ci#include <linux/inet.h>
258c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
268c2ecf20Sopenharmony_ci#include <linux/skbuff.h>
278c2ecf20Sopenharmony_ci#include <net/sock.h>
288c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
298c2ecf20Sopenharmony_ci#include <linux/fcntl.h>
308c2ecf20Sopenharmony_ci#include <linux/mm.h>
318c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_cistatic void ax25_heartbeat_expiry(struct timer_list *);
348c2ecf20Sopenharmony_cistatic void ax25_t1timer_expiry(struct timer_list *);
358c2ecf20Sopenharmony_cistatic void ax25_t2timer_expiry(struct timer_list *);
368c2ecf20Sopenharmony_cistatic void ax25_t3timer_expiry(struct timer_list *);
378c2ecf20Sopenharmony_cistatic void ax25_idletimer_expiry(struct timer_list *);
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_civoid ax25_setup_timers(ax25_cb *ax25)
408c2ecf20Sopenharmony_ci{
418c2ecf20Sopenharmony_ci	timer_setup(&ax25->timer, ax25_heartbeat_expiry, 0);
428c2ecf20Sopenharmony_ci	timer_setup(&ax25->t1timer, ax25_t1timer_expiry, 0);
438c2ecf20Sopenharmony_ci	timer_setup(&ax25->t2timer, ax25_t2timer_expiry, 0);
448c2ecf20Sopenharmony_ci	timer_setup(&ax25->t3timer, ax25_t3timer_expiry, 0);
458c2ecf20Sopenharmony_ci	timer_setup(&ax25->idletimer, ax25_idletimer_expiry, 0);
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_civoid ax25_start_heartbeat(ax25_cb *ax25)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci	mod_timer(&ax25->timer, jiffies + 5 * HZ);
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_civoid ax25_start_t1timer(ax25_cb *ax25)
548c2ecf20Sopenharmony_ci{
558c2ecf20Sopenharmony_ci	mod_timer(&ax25->t1timer, jiffies + ax25->t1);
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_civoid ax25_start_t2timer(ax25_cb *ax25)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	mod_timer(&ax25->t2timer, jiffies + ax25->t2);
618c2ecf20Sopenharmony_ci}
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_civoid ax25_start_t3timer(ax25_cb *ax25)
648c2ecf20Sopenharmony_ci{
658c2ecf20Sopenharmony_ci	if (ax25->t3 > 0)
668c2ecf20Sopenharmony_ci		mod_timer(&ax25->t3timer, jiffies + ax25->t3);
678c2ecf20Sopenharmony_ci	else
688c2ecf20Sopenharmony_ci		del_timer(&ax25->t3timer);
698c2ecf20Sopenharmony_ci}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_civoid ax25_start_idletimer(ax25_cb *ax25)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	if (ax25->idle > 0)
748c2ecf20Sopenharmony_ci		mod_timer(&ax25->idletimer, jiffies + ax25->idle);
758c2ecf20Sopenharmony_ci	else
768c2ecf20Sopenharmony_ci		del_timer(&ax25->idletimer);
778c2ecf20Sopenharmony_ci}
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_civoid ax25_stop_heartbeat(ax25_cb *ax25)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	del_timer(&ax25->timer);
828c2ecf20Sopenharmony_ci}
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_civoid ax25_stop_t1timer(ax25_cb *ax25)
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	del_timer(&ax25->t1timer);
878c2ecf20Sopenharmony_ci}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_civoid ax25_stop_t2timer(ax25_cb *ax25)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	del_timer(&ax25->t2timer);
928c2ecf20Sopenharmony_ci}
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_civoid ax25_stop_t3timer(ax25_cb *ax25)
958c2ecf20Sopenharmony_ci{
968c2ecf20Sopenharmony_ci	del_timer(&ax25->t3timer);
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_civoid ax25_stop_idletimer(ax25_cb *ax25)
1008c2ecf20Sopenharmony_ci{
1018c2ecf20Sopenharmony_ci	del_timer(&ax25->idletimer);
1028c2ecf20Sopenharmony_ci}
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ciint ax25_t1timer_running(ax25_cb *ax25)
1058c2ecf20Sopenharmony_ci{
1068c2ecf20Sopenharmony_ci	return timer_pending(&ax25->t1timer);
1078c2ecf20Sopenharmony_ci}
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ciunsigned long ax25_display_timer(struct timer_list *timer)
1108c2ecf20Sopenharmony_ci{
1118c2ecf20Sopenharmony_ci	if (!timer_pending(timer))
1128c2ecf20Sopenharmony_ci		return 0;
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	return timer->expires - jiffies;
1158c2ecf20Sopenharmony_ci}
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ax25_display_timer);
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_cistatic void ax25_heartbeat_expiry(struct timer_list *t)
1208c2ecf20Sopenharmony_ci{
1218c2ecf20Sopenharmony_ci	int proto = AX25_PROTO_STD_SIMPLEX;
1228c2ecf20Sopenharmony_ci	ax25_cb *ax25 = from_timer(ax25, t, timer);
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	if (ax25->ax25_dev)
1258c2ecf20Sopenharmony_ci		proto = ax25->ax25_dev->values[AX25_VALUES_PROTOCOL];
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	switch (proto) {
1288c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_SIMPLEX:
1298c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_DUPLEX:
1308c2ecf20Sopenharmony_ci		ax25_std_heartbeat_expiry(ax25);
1318c2ecf20Sopenharmony_ci		break;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
1348c2ecf20Sopenharmony_ci	case AX25_PROTO_DAMA_SLAVE:
1358c2ecf20Sopenharmony_ci		if (ax25->ax25_dev->dama.slave)
1368c2ecf20Sopenharmony_ci			ax25_ds_heartbeat_expiry(ax25);
1378c2ecf20Sopenharmony_ci		else
1388c2ecf20Sopenharmony_ci			ax25_std_heartbeat_expiry(ax25);
1398c2ecf20Sopenharmony_ci		break;
1408c2ecf20Sopenharmony_ci#endif
1418c2ecf20Sopenharmony_ci	}
1428c2ecf20Sopenharmony_ci}
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_cistatic void ax25_t1timer_expiry(struct timer_list *t)
1458c2ecf20Sopenharmony_ci{
1468c2ecf20Sopenharmony_ci	ax25_cb *ax25 = from_timer(ax25, t, t1timer);
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
1498c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_SIMPLEX:
1508c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_DUPLEX:
1518c2ecf20Sopenharmony_ci		ax25_std_t1timer_expiry(ax25);
1528c2ecf20Sopenharmony_ci		break;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
1558c2ecf20Sopenharmony_ci	case AX25_PROTO_DAMA_SLAVE:
1568c2ecf20Sopenharmony_ci		if (!ax25->ax25_dev->dama.slave)
1578c2ecf20Sopenharmony_ci			ax25_std_t1timer_expiry(ax25);
1588c2ecf20Sopenharmony_ci		break;
1598c2ecf20Sopenharmony_ci#endif
1608c2ecf20Sopenharmony_ci	}
1618c2ecf20Sopenharmony_ci}
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistatic void ax25_t2timer_expiry(struct timer_list *t)
1648c2ecf20Sopenharmony_ci{
1658c2ecf20Sopenharmony_ci	ax25_cb *ax25 = from_timer(ax25, t, t2timer);
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
1688c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_SIMPLEX:
1698c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_DUPLEX:
1708c2ecf20Sopenharmony_ci		ax25_std_t2timer_expiry(ax25);
1718c2ecf20Sopenharmony_ci		break;
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
1748c2ecf20Sopenharmony_ci	case AX25_PROTO_DAMA_SLAVE:
1758c2ecf20Sopenharmony_ci		if (!ax25->ax25_dev->dama.slave)
1768c2ecf20Sopenharmony_ci			ax25_std_t2timer_expiry(ax25);
1778c2ecf20Sopenharmony_ci		break;
1788c2ecf20Sopenharmony_ci#endif
1798c2ecf20Sopenharmony_ci	}
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic void ax25_t3timer_expiry(struct timer_list *t)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	ax25_cb *ax25 = from_timer(ax25, t, t3timer);
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
1878c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_SIMPLEX:
1888c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_DUPLEX:
1898c2ecf20Sopenharmony_ci		ax25_std_t3timer_expiry(ax25);
1908c2ecf20Sopenharmony_ci		break;
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
1938c2ecf20Sopenharmony_ci	case AX25_PROTO_DAMA_SLAVE:
1948c2ecf20Sopenharmony_ci		if (ax25->ax25_dev->dama.slave)
1958c2ecf20Sopenharmony_ci			ax25_ds_t3timer_expiry(ax25);
1968c2ecf20Sopenharmony_ci		else
1978c2ecf20Sopenharmony_ci			ax25_std_t3timer_expiry(ax25);
1988c2ecf20Sopenharmony_ci		break;
1998c2ecf20Sopenharmony_ci#endif
2008c2ecf20Sopenharmony_ci	}
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_cistatic void ax25_idletimer_expiry(struct timer_list *t)
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	ax25_cb *ax25 = from_timer(ax25, t, idletimer);
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
2088c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_SIMPLEX:
2098c2ecf20Sopenharmony_ci	case AX25_PROTO_STD_DUPLEX:
2108c2ecf20Sopenharmony_ci		ax25_std_idletimer_expiry(ax25);
2118c2ecf20Sopenharmony_ci		break;
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci#ifdef CONFIG_AX25_DAMA_SLAVE
2148c2ecf20Sopenharmony_ci	case AX25_PROTO_DAMA_SLAVE:
2158c2ecf20Sopenharmony_ci		if (ax25->ax25_dev->dama.slave)
2168c2ecf20Sopenharmony_ci			ax25_ds_idletimer_expiry(ax25);
2178c2ecf20Sopenharmony_ci		else
2188c2ecf20Sopenharmony_ci			ax25_std_idletimer_expiry(ax25);
2198c2ecf20Sopenharmony_ci		break;
2208c2ecf20Sopenharmony_ci#endif
2218c2ecf20Sopenharmony_ci	}
2228c2ecf20Sopenharmony_ci}
223