Merge tag 'devicetree-fixes-for-5.12-1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / net / lapb / lapb_timer.c
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
33 static void lapb_t1timer_expiry(struct timer_list *);
34 static void lapb_t2timer_expiry(struct timer_list *);
35
36 void 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_stop = false;
44         add_timer(&lapb->t1timer);
45 }
46
47 void 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_stop = false;
55         add_timer(&lapb->t2timer);
56 }
57
58 void lapb_stop_t1timer(struct lapb_cb *lapb)
59 {
60         lapb->t1timer_stop = true;
61         del_timer(&lapb->t1timer);
62 }
63
64 void lapb_stop_t2timer(struct lapb_cb *lapb)
65 {
66         lapb->t2timer_stop = true;
67         del_timer(&lapb->t2timer);
68 }
69
70 int lapb_t1timer_running(struct lapb_cb *lapb)
71 {
72         return timer_pending(&lapb->t1timer);
73 }
74
75 static 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_stop) /* 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
90 out:
91         spin_unlock_bh(&lapb->lock);
92 }
93
94 static void lapb_t1timer_expiry(struct timer_list *t)
95 {
96         struct lapb_cb *lapb = from_timer(lapb, t, t1timer);
97
98         spin_lock_bh(&lapb->lock);
99         if (timer_pending(&lapb->t1timer)) /* A new timer has been set up */
100                 goto out;
101         if (lapb->t1timer_stop) /* The timer has been stopped */
102                 goto out;
103
104         switch (lapb->state) {
105
106                 /*
107                  *      If we are a DCE, send DM up to N2 times, then switch to
108                  *      STATE_1 and send SABM(E).
109                  */
110                 case LAPB_STATE_0:
111                         if (lapb->mode & LAPB_DCE &&
112                             lapb->n2count != lapb->n2) {
113                                 lapb->n2count++;
114                                 lapb_send_control(lapb, LAPB_DM, LAPB_POLLOFF, LAPB_RESPONSE);
115                         } else {
116                                 lapb->state = LAPB_STATE_1;
117                                 lapb_establish_data_link(lapb);
118                         }
119                         break;
120
121                 /*
122                  *      Awaiting connection state, send SABM(E), up to N2 times.
123                  */
124                 case LAPB_STATE_1:
125                         if (lapb->n2count == lapb->n2) {
126                                 lapb_clear_queues(lapb);
127                                 lapb->state = LAPB_STATE_0;
128                                 lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
129                                 lapb_dbg(0, "(%p) S1 -> S0\n", lapb->dev);
130                                 goto out;
131                         } else {
132                                 lapb->n2count++;
133                                 if (lapb->mode & LAPB_EXTENDED) {
134                                         lapb_dbg(1, "(%p) S1 TX SABME(1)\n",
135                                                  lapb->dev);
136                                         lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND);
137                                 } else {
138                                         lapb_dbg(1, "(%p) S1 TX SABM(1)\n",
139                                                  lapb->dev);
140                                         lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND);
141                                 }
142                         }
143                         break;
144
145                 /*
146                  *      Awaiting disconnection state, send DISC, up to N2 times.
147                  */
148                 case LAPB_STATE_2:
149                         if (lapb->n2count == lapb->n2) {
150                                 lapb_clear_queues(lapb);
151                                 lapb->state = LAPB_STATE_0;
152                                 lapb_disconnect_confirmation(lapb, LAPB_TIMEDOUT);
153                                 lapb_dbg(0, "(%p) S2 -> S0\n", lapb->dev);
154                                 goto out;
155                         } else {
156                                 lapb->n2count++;
157                                 lapb_dbg(1, "(%p) S2 TX DISC(1)\n", lapb->dev);
158                                 lapb_send_control(lapb, LAPB_DISC, LAPB_POLLON, LAPB_COMMAND);
159                         }
160                         break;
161
162                 /*
163                  *      Data transfer state, restransmit I frames, up to N2 times.
164                  */
165                 case LAPB_STATE_3:
166                         if (lapb->n2count == lapb->n2) {
167                                 lapb_clear_queues(lapb);
168                                 lapb->state = LAPB_STATE_0;
169                                 lapb_stop_t2timer(lapb);
170                                 lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
171                                 lapb_dbg(0, "(%p) S3 -> S0\n", lapb->dev);
172                                 goto out;
173                         } else {
174                                 lapb->n2count++;
175                                 lapb_requeue_frames(lapb);
176                                 lapb_kick(lapb);
177                         }
178                         break;
179
180                 /*
181                  *      Frame reject state, restransmit FRMR frames, up to N2 times.
182                  */
183                 case LAPB_STATE_4:
184                         if (lapb->n2count == lapb->n2) {
185                                 lapb_clear_queues(lapb);
186                                 lapb->state = LAPB_STATE_0;
187                                 lapb_disconnect_indication(lapb, LAPB_TIMEDOUT);
188                                 lapb_dbg(0, "(%p) S4 -> S0\n", lapb->dev);
189                                 goto out;
190                         } else {
191                                 lapb->n2count++;
192                                 lapb_transmit_frmr(lapb);
193                         }
194                         break;
195         }
196
197         lapb_start_t1timer(lapb);
198
199 out:
200         spin_unlock_bh(&lapb->lock);
201 }