cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

lapb_timer.c (4985B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *	LAPB release 002
      4 *
      5 *	This code REQUIRES 2.1.15 or higher/ NET3.038
      6 *
      7 *	History
      8 *	LAPB 001	Jonathan Naylor	Started Coding
      9 *	LAPB 002	Jonathan Naylor	New timer architecture.
     10 */
     11
     12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     13
     14#include <linux/errno.h>
     15#include <linux/types.h>
     16#include <linux/socket.h>
     17#include <linux/in.h>
     18#include <linux/kernel.h>
     19#include <linux/jiffies.h>
     20#include <linux/timer.h>
     21#include <linux/string.h>
     22#include <linux/sockios.h>
     23#include <linux/net.h>
     24#include <linux/inet.h>
     25#include <linux/skbuff.h>
     26#include <net/sock.h>
     27#include <linux/uaccess.h>
     28#include <linux/fcntl.h>
     29#include <linux/mm.h>
     30#include <linux/interrupt.h>
     31#include <net/lapb.h>
     32
     33static void lapb_t1timer_expiry(struct timer_list *);
     34static void lapb_t2timer_expiry(struct timer_list *);
     35
     36void lapb_start_t1timer(struct lapb_cb *lapb)
     37{
     38	del_timer(&lapb->t1timer);
     39
     40	lapb->t1timer.function = lapb_t1timer_expiry;
     41	lapb->t1timer.expires  = jiffies + lapb->t1;
     42
     43	lapb->t1timer_running = true;
     44	add_timer(&lapb->t1timer);
     45}
     46
     47void lapb_start_t2timer(struct lapb_cb *lapb)
     48{
     49	del_timer(&lapb->t2timer);
     50
     51	lapb->t2timer.function = lapb_t2timer_expiry;
     52	lapb->t2timer.expires  = jiffies + lapb->t2;
     53
     54	lapb->t2timer_running = true;
     55	add_timer(&lapb->t2timer);
     56}
     57
     58void lapb_stop_t1timer(struct lapb_cb *lapb)
     59{
     60	lapb->t1timer_running = false;
     61	del_timer(&lapb->t1timer);
     62}
     63
     64void lapb_stop_t2timer(struct lapb_cb *lapb)
     65{
     66	lapb->t2timer_running = false;
     67	del_timer(&lapb->t2timer);
     68}
     69
     70int lapb_t1timer_running(struct lapb_cb *lapb)
     71{
     72	return lapb->t1timer_running;
     73}
     74
     75static void lapb_t2timer_expiry(struct timer_list *t)
     76{
     77	struct lapb_cb *lapb = from_timer(lapb, t, t2timer);
     78
     79	spin_lock_bh(&lapb->lock);
     80	if (timer_pending(&lapb->t2timer)) /* A new timer has been set up */
     81		goto out;
     82	if (!lapb->t2timer_running) /* The timer has been stopped */
     83		goto out;
     84
     85	if (lapb->condition & LAPB_ACK_PENDING_CONDITION) {
     86		lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
     87		lapb_timeout_response(lapb);
     88	}
     89	lapb->t2timer_running = false;
     90
     91out:
     92	spin_unlock_bh(&lapb->lock);
     93}
     94
     95static void lapb_t1timer_expiry(struct timer_list *t)
     96{
     97	struct lapb_cb *lapb = from_timer(lapb, t, t1timer);
     98
     99	spin_lock_bh(&lapb->lock);
    100	if (timer_pending(&lapb->t1timer)) /* A new timer has been set up */
    101		goto out;
    102	if (!lapb->t1timer_running) /* The timer has been stopped */
    103		goto out;
    104
    105	switch (lapb->state) {
    106
    107		/*
    108		 *	If we are a DCE, send DM up to N2 times, then switch to
    109		 *	STATE_1 and send SABM(E).
    110		 */
    111		case LAPB_STATE_0:
    112			if (lapb->mode & LAPB_DCE &&
    113			    lapb->n2count != lapb->n2) {
    114				lapb->n2count++;
    115				lapb_send_control(lapb, LAPB_DM, LAPB_POLLOFF, LAPB_RESPONSE);
    116			} else {
    117				lapb->state = LAPB_STATE_1;
    118				lapb_establish_data_link(lapb);
    119			}
    120			break;
    121
    122		/*
    123		 *	Awaiting connection state, send SABM(E), up to N2 times.
    124		 */
    125		case LAPB_STATE_1:
    126			if (lapb->n2count == lapb->n2) {
    127				lapb_clear_queues(lapb);
    128				lapb->state = LAPB_STATE_0;
    129				lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
    130				lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev);
    131				lapb->t1timer_running = false;
    132				goto out;
    133			} else {
    134				lapb->n2count++;
    135				if (lapb->mode & LAPB_EXTENDED) {
    136					lapb_dbg(1, "(%p) S1 TX SABME(1)\n",
    137						 lapb->dev);
    138					lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND);
    139				} else {
    140					lapb_dbg(1, "(%p) S1 TX SABM(1)\n",
    141						 lapb->dev);
    142					lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND);
    143				}
    144			}
    145			break;
    146
    147		/*
    148		 *	Awaiting disconnection state, send DISC, up to N2 times.
    149		 */
    150		case LAPB_STATE_2:
    151			if (lapb->n2count == lapb->n2) {
    152				lapb_clear_queues(lapb);
    153				lapb->state = LAPB_STATE_0;
    154				lapb_disconnect_confirmation(lapb, LAPB_TIMEDOUT);
    155				lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev);
    156				lapb->t1timer_running = false;
    157				goto out;
    158			} else {
    159				lapb->n2count++;
    160				lapb_dbg(1, "(%p) S2 TX DISC(1)\n", lapb->dev);
    161				lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND);
    162			}
    163			break;
    164
    165		/*
    166		 *	Data transfer state, restransmit I frames, up to N2 times.
    167		 */
    168		case LAPB_STATE_3:
    169			if (lapb->n2count == lapb->n2) {
    170				lapb_clear_queues(lapb);
    171				lapb->state = LAPB_STATE_0;
    172				lapb_stop_t2timer(lapb);
    173				lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
    174				lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev);
    175				lapb->t1timer_running = false;
    176				goto out;
    177			} else {
    178				lapb->n2count++;
    179				lapb_requeue_frames(lapb);
    180				lapb_kick(lapb);
    181			}
    182			break;
    183
    184		/*
    185		 *	Frame reject state, restransmit FRMR frames, up to N2 times.
    186		 */
    187		case LAPB_STATE_4:
    188			if (lapb->n2count == lapb->n2) {
    189				lapb_clear_queues(lapb);
    190				lapb->state = LAPB_STATE_0;
    191				lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
    192				lapb_dbg(0, "(%p) S4 -> S0\n", lapb->dev);
    193				lapb->t1timer_running = false;
    194				goto out;
    195			} else {
    196				lapb->n2count++;
    197				lapb_transmit_frmr(lapb);
    198			}
    199			break;
    200	}
    201
    202	lapb_start_t1timer(lapb);
    203
    204out:
    205	spin_unlock_bh(&lapb->lock);
    206}