summaryrefslogtreecommitdiff
path: root/net/lapb/lapb_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/lapb/lapb_timer.c')
-rw-r--r--net/lapb/lapb_timer.c84
1 files changed, 56 insertions, 28 deletions
diff --git a/net/lapb/lapb_timer.c b/net/lapb/lapb_timer.c
index 54563ad8aeb1..9fde6cf20f10 100644
--- a/net/lapb/lapb_timer.c
+++ b/net/lapb/lapb_timer.c
@@ -1,14 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* LAPB release 002
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
- * This module:
- * This module is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
* History
* LAPB 001 Jonathan Naylor Started Coding
* LAPB 002 Jonathan Naylor New timer architecture.
@@ -29,74 +24,99 @@
#include <linux/inet.h>
#include <linux/skbuff.h>
#include <net/sock.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <net/lapb.h>
-static void lapb_t1timer_expiry(unsigned long);
-static void lapb_t2timer_expiry(unsigned long);
+static void lapb_t1timer_expiry(struct timer_list *);
+static void lapb_t2timer_expiry(struct timer_list *);
void lapb_start_t1timer(struct lapb_cb *lapb)
{
- del_timer(&lapb->t1timer);
+ timer_delete(&lapb->t1timer);
- lapb->t1timer.data = (unsigned long)lapb;
- lapb->t1timer.function = &lapb_t1timer_expiry;
+ lapb->t1timer.function = lapb_t1timer_expiry;
lapb->t1timer.expires = jiffies + lapb->t1;
+ lapb->t1timer_running = true;
add_timer(&lapb->t1timer);
}
void lapb_start_t2timer(struct lapb_cb *lapb)
{
- del_timer(&lapb->t2timer);
+ timer_delete(&lapb->t2timer);
- lapb->t2timer.data = (unsigned long)lapb;
- lapb->t2timer.function = &lapb_t2timer_expiry;
+ lapb->t2timer.function = lapb_t2timer_expiry;
lapb->t2timer.expires = jiffies + lapb->t2;
+ lapb->t2timer_running = true;
add_timer(&lapb->t2timer);
}
void lapb_stop_t1timer(struct lapb_cb *lapb)
{
- del_timer(&lapb->t1timer);
+ lapb->t1timer_running = false;
+ timer_delete(&lapb->t1timer);
}
void lapb_stop_t2timer(struct lapb_cb *lapb)
{
- del_timer(&lapb->t2timer);
+ lapb->t2timer_running = false;
+ timer_delete(&lapb->t2timer);
}
int lapb_t1timer_running(struct lapb_cb *lapb)
{
- return timer_pending(&lapb->t1timer);
+ return lapb->t1timer_running;
}
-static void lapb_t2timer_expiry(unsigned long param)
+static void lapb_t2timer_expiry(struct timer_list *t)
{
- struct lapb_cb *lapb = (struct lapb_cb *)param;
+ struct lapb_cb *lapb = timer_container_of(lapb, t, t2timer);
+
+ spin_lock_bh(&lapb->lock);
+ if (timer_pending(&lapb->t2timer)) /* A new timer has been set up */
+ goto out;
+ if (!lapb->t2timer_running) /* The timer has been stopped */
+ goto out;
if (lapb->condition & LAPB_ACK_PENDING_CONDITION) {
lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
lapb_timeout_response(lapb);
}
+ lapb->t2timer_running = false;
+
+out:
+ spin_unlock_bh(&lapb->lock);
}
-static void lapb_t1timer_expiry(unsigned long param)
+static void lapb_t1timer_expiry(struct timer_list *t)
{
- struct lapb_cb *lapb = (struct lapb_cb *)param;
+ struct lapb_cb *lapb = timer_container_of(lapb, t, t1timer);
+
+ spin_lock_bh(&lapb->lock);
+ if (timer_pending(&lapb->t1timer)) /* A new timer has been set up */
+ goto out;
+ if (!lapb->t1timer_running) /* The timer has been stopped */
+ goto out;
switch (lapb->state) {
/*
- * If we are a DCE, keep going DM .. DM .. DM
+ * If we are a DCE, send DM up to N2 times, then switch to
+ * STATE_1 and send SABM(E).
*/
case LAPB_STATE_0:
- if (lapb->mode & LAPB_DCE)
+ if (lapb->mode & LAPB_DCE &&
+ lapb->n2count != lapb->n2) {
+ lapb->n2count++;
lapb_send_control(lapb, LAPB_DM, LAPB_POLLOFF, LAPB_RESPONSE);
+ } else {
+ lapb->state = LAPB_STATE_1;
+ lapb_establish_data_link(lapb);
+ }
break;
/*
@@ -108,7 +128,8 @@ static void lapb_t1timer_expiry(unsigned long param)
lapb->state = LAPB_STATE_0;
lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev);
- return;
+ lapb->t1timer_running = false;
+ goto out;
} else {
lapb->n2count++;
if (lapb->mode & LAPB_EXTENDED) {
@@ -132,7 +153,8 @@ static void lapb_t1timer_expiry(unsigned long param)
lapb->state = LAPB_STATE_0;
lapb_disconnect_confirmation(lapb, LAPB_TIMEDOUT);
lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev);
- return;
+ lapb->t1timer_running = false;
+ goto out;
} else {
lapb->n2count++;
lapb_dbg(1, "(%p) S2 TX DISC(1)\n", lapb->dev);
@@ -150,10 +172,12 @@ static void lapb_t1timer_expiry(unsigned long param)
lapb_stop_t2timer(lapb);
lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev);
- return;
+ lapb->t1timer_running = false;
+ goto out;
} else {
lapb->n2count++;
lapb_requeue_frames(lapb);
+ lapb_kick(lapb);
}
break;
@@ -166,7 +190,8 @@ static void lapb_t1timer_expiry(unsigned long param)
lapb->state = LAPB_STATE_0;
lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
lapb_dbg(0, "(%p) S4 -> S0\n", lapb->dev);
- return;
+ lapb->t1timer_running = false;
+ goto out;
} else {
lapb->n2count++;
lapb_transmit_frmr(lapb);
@@ -175,4 +200,7 @@ static void lapb_t1timer_expiry(unsigned long param)
}
lapb_start_t1timer(lapb);
+
+out:
+ spin_unlock_bh(&lapb->lock);
}